样式迁移
样式迁移
定义:将样式图片上的样式迁移到内容图片上得到合成图片
实线箭头和虚线箭头分别表示前向传播和反向传播
风格迁移常用的损失函数由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 的像素值