三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

样式迁移

样式迁移

样式迁移

定义:将样式图片上的样式迁移到内容图片上得到合成图片

实线箭头和虚线箭头分别表示前向传播和反向传播

风格迁移常用的损失函数由3部分组成:

(1)内容损失使合成图像与内容图像在内容特征上接近;

(2)风格损失使合成图像与风格图像在风格特征上接近;

(3)全变分损失则有助于减少合成图像中的噪点。

数据预处理:


图片尺寸resize,图片RGB数值归一化,图片格式从 (H,W,C) → (C,H,W) → (1,C,H,W)

数据后处理:

将CNN输出转化为“能看的”图片

模型使用VGG-19

选择相应的层作为内容层和风格层输出

深层特征保留物体结构、空间布局,去掉过多细节

从浅到深覆盖不同尺度的纹理:边缘→纹理→图案→全局风格

裁剪VGG,只保留需要的层

逐层提取特征:

风格迁移有三张图参与:

内容图像(固定不变),风格图像(固定不变),合成图像(每轮都在变)

提前算好内容目标和风格目标:

损失函数(内容损失,风格损失,全变分损失)

内容损失,利用均方误差:

风格损失:

Gram矩阵来定义什么是风格

给定一个特征图(CNN 某层的输出),把它拉平成矩阵 X (形状为 c×hw)

注意这里需要最后的数值归一化,避免出现较大的值影响判断

这样就可以基于gram矩阵来通过均方误差得到误差:

全变分损失:

是风格迁移中的"去噪器":它惩罚相邻像素之间的剧烈跳变,让合成图像更平滑自然。

本质:遍历每个像素,计算它和右边、下边两个邻居的差异,全部加起来。

风格转移的损失函数是内容损失、风格损失和总变化损失的加权和。 通过调节这些权重超参数,我们可以权衡合成图像在保留内容、迁移风格以及去噪三方面的相对重要性。

初始化合成图像:

合成的图像是训练期间唯一需要更新的变量。因此,我们可以定义一个简单的模型SynthesizedImage,并将合成的图像视为模型参数。模型的前向传播只需返回模型参数即可。

因为 MXNet/Gluon 的 Trainer 只能优化 nn.Block 的参数。我们套一个"模型壳",让框架以为我们在训练模型,实际上训练的是图像像素。使用Adam优化器(框架内部组件)

训练前的准备工作:

创建"模型",参数 = 图像像素

init.Constant(X):用内容图像素初始化合成图。一开始合成图 = 内容图原样

gluon.Trainer(..., 'adam', ...):Adam优化器,学习率 lr。优化对象是合成图像素

预计算风格图5个层的Gram矩阵(训练时不再重复算)

整体的训练模型:

核心循环:

extract_features(X, ...):合成图 X 过VGG网络,在目标层"截获"特征

compute_loss(...):比较合成图和内容图/风格图的特征差异,得到总损失 l

trainer.step(1):Adam优化器根据梯度,更新 X 的像素值

← 返回列表