风格迁移(Style Transfer)首次学习总结
0、写在前面
最近看了吴恩达老师风格迁移相关的讲解视频,深受启发,于是想着做做总结。
1、主要思想
目的:把一张内容图片(content image)的风格迁移成与另一张图片(style image)风格一致。
(图自论文:A Neural Algorithm of Artistic Style)
方法:通过约束 Content Loss 和 Style Loss 来生成最终的图片。
1.0 activation(representation)、kernel(filter)、channel 和 input
用一个已经 pretrained 好的网络(如 Resnet-50)作为 backbone 来提取图片每一层的特征。
每一个 filter 用来检测该层 input 的某一种特征,如果有这种特征,那么输出(activation)中对应 channel 就会被“点亮”(数值大)。
比如:假设这个 pretrained 好的网络中第一层有一个 filter 用来检测图像中处于水平状态的边缘,那么,如果图片(input)左上角有一些水平的边缘,那这个图片在该层的输出(activation)中对应 channel 左上角的数值就会比较大。
1.1 Content Loss
要保证 Style Transferred Image 和原 Content Image 的内容尽可能相似【即,原 Content Image 左上角有处于水平状态的边缘,那么 Style Transferred Image 左上角也要有处于水平状态的边缘】,就意味着 Content Image 和 Style Transferred Image 经过同一个 pretrained 好的网络后,其对应层的输出(activation)要尽可能一致。
比如 ,Content Image 左上角有一些水平的边缘,则 activation 中 channel i 的左上角数值就会比较大,那么,我们也希望 Style Transferred Image 的 activation 中 channel i 的左上角数值也比较大(尽可能接近)。
所以,Content Loss 定义如下:
(图自论文:A Neural Algorithm of Artistic Style)
公式中的 representation 就是 activation。
1.2 Style Loss
论文中关于 Style 的定义如下:
we built a style representation that computes the correlations between the different filter responses, where the expectation is taken over the spatial extend of the input imag
一张图片的 style 可以定义为某一层的 activation 里 channel 与 channel 之间的 correlation 矩阵。
比如:某张 Style 图片里左上角部分全是红色水平边缘的元素。
那么检测水平边缘特征的 filter 得到的 channel i 和检测红色特征的 filter 得到的 channel j 高亮(数值大)的地方就都会在左上角,那么,这两个 channel 对应位置相乘得到的数值就会比较大(10 * 10 = 100)。
假如此时还有一个检测蓝色特征的 filter,那么其对应得到的 channel k 左上角部分就不怎么会被点亮(数值小)【因为左上角部分全是红色水平边缘的元素】。那么,检测水平边缘特征的 filter 得到的 channel i 和 检测蓝色特征的 filter 得到的 channel k 对应位置的乘积就可能会比较小(10 * 0.5 = 5)。
那么,一张图片的 style 矩阵定义如下:
(图自吴恩达老师的课程 ppt)
其中,k 和 k' 代表两个不同的 channel;l 是指第 l 层。
那么要保证 Style Transferred Image 和 Style Image 的风格相近,也就是让两张图片的风格矩阵尽可能相似。所以 Style Loss 定义如下:
(图自论文:A Neural Algorithm of Artistic Style)
2、示例代码
我在 Github 上找了一个能跑得通的示例代码:https://github.com/Zhenye-Na/neural-style-pytorch
其中的核心代码如下:
Content Loss & Style Loss & Style Matrix
class ContentLoss(nn.Module):"""Content Loss."""def __init__(self, target,):"""Initialize content loss"""super(ContentLoss, self).__init__()# we 'detach' the target content from the tree used# to dynamically compute the gradient: this is a stated value,# not a variable. Otherwise the forward method of the criterion# will throw an error.self.target = target.detach()def forward(self, inputs):"""Forward pass."""self.loss = F.mse_loss(inputs, self.target)return inputsclass StyleLoss(nn.Module):"""Style Loss."""def __init__(self, target_feature):"""Initialize style loss."""super(StyleLoss, self).__init__()self.target = gram_matrix(target_feature).detach()def forward(self, inputs):"""Forward pass."""G = gram_matrix(inputs)self.loss = F.mse_loss(G, self.target)return inputsdef gram_matrix(inputs):"""Gram matrix."""a, b, c, d = inputs.size()# resise F_XL into \hat F_XLfeatures = inputs.view(a * b, c * d)# compute the gram productG = torch.mm(features, features.t())return G.div(a * b * c * d)
train
for epoch in range(0, self.args.epochs):def closure():# correct the values of updated input imageinput_img.data.clamp_(0, 1)self.optimizer.zero_grad()model(input_img)style_score = 0content_score = 0for sl in style_losses:style_score += sl.lossfor cl in content_losses:content_score += cl.lossstyle_score *= self.style_weightcontent_score *= self.content_weightloss = style_score + content_scoreloss.backward()if epoch % 5 == 0:print("Epoch {}: Style Loss : {:4f} Content Loss: {:4f}".format(epoch, style_score.item(), content_score.item()))return style_score + content_scoreself.optimizer.step(closure)
优化器
def _init_optimizer(self, input_img):"""Initialize LBFGS optimizer."""self.optimizer = optim.LBFGS([input_img.requires_grad_()])
注意!这里只更新 input image,网络是不进行学习的!
还有,这是一个我之前没用过的优化器:LBFGS,其中有一个参数:
max_iter (int): maximal number of iterations per optimization step (default: 20)
这也就是为什么训练结果里每一个 epoch 更新会有二十次打印信息(iteration)了,之前一直想不通,我还找半天代码里哪里有 20 这个数字。。。
运行结果
风格迁移(Style Transfer)首次学习总结相关推荐
- pytorch实现风格迁移 style transfer
本文给出简单代码实现风格迁移. 1,原理简介 风格迁移和上篇文章提到的deep dream算法比较接近,都是根据某种优化指标计算梯度来反向优化输入图像的像素.所以在学完deep dream之后 ...
- 风格迁移 Style transfer
本文个人博客访问地址: 点击查看 一.介绍 将一张图片的艺术风格应用在另外一张图片上 使用深度卷积网络CNN提取一张图片的内容和提取一张图片的风格, 然后将两者结合起来得到最后的结果 二. 方法 - ...
- MM2018/风格迁移-Style Separation and Synthesis via Generative Adversarial Networks通过生成性对抗网络进行风格分离和合成
Style Separation and Synthesis via Generative Adversarial Networks通过生成性对抗网络进行风格分离和合成 0.摘要 1.概述 2.相关工 ...
- 汉字风格迁移篇---中文字体风格迁移的多任务对抗学习
文章目录 Abstract I. INTRODUCTION II. RELATED WORK III. METHOD DESCRIPTION A. Problem F ormulation B. Ba ...
- 用Python深度学习来快速实现图片的风格迁移
先来看下效果: 上图是小编在甘南合作的米拉日巴佛阁外面拍下的一张照片,采用风格迁移技术后的效果为: 一些其它效果图: 下面进入正题. 近年来,由深度学习所引领的人工智能(AI)技术浪潮,开始越来越广泛 ...
- CV Code | 本周新出计算机视觉开源代码汇总(含自动驾驶目标检测、医学图像分割、风格迁移、语义分割、目标跟踪等)...
点击我爱计算机视觉标星,更快获取CVML新技术 刚刚过去的一周含五一假期,工作日第一天,CV君汇总了过去一周计算机视觉领域新出的开源代码,涉及到自动驾驶目标检测.医学图像分割.风格迁移.神经架构搜索. ...
- 用Python实现图片风格迁移,让你的图片更加的高逼格!
先来看下效果: 上图是老王在甘南合作的米拉日巴佛阁外面拍下的一张照片,采用风格迁移技术后的效果为: 一些其它效果图: 下面进入正题. 如果你依然在编程的世界里迷茫,可以加入我们的Python学习扣qu ...
- 让你的图片更有逼格,用Python实现图片风格迁移
点击上方 Python知识圈,选择置顶或星标 第一时间关注 Python 技术干货! 文章转自R语言和Python学堂,禁二次转载 阅读文本大概需要 3 分钟. 先来看下效果: 上图是小编在甘南合作的 ...
- python神经结构二层_《python深度学习》笔记---8.3、神经风格迁移
<python深度学习>笔记---8.3.神经风格迁移 一.总结 一句话总结: 神经风格迁移是指将参考图像的风格应用于目标图像,同时保留目标图像的内容. 1."神经风格迁移是指将 ...
- 深度学习六、图像风格迁移
所谓图像风格迁移,是指利用算法学习著名画作的风格,然后再把这种风格应用到另外一张图片上的技术. 1 图像风格迁移的原理 在学习原始的图像风格迁移之前,可以先回忆一下ImageNet图像识别模型VGGN ...
最新文章
- 通常,Node.js如何处理10,000个并发请求?
- Linux C编程--网络编程3--面向无连接的网络编程
- 2014年江苏省计算机二级c语言考试大纲,2009年江苏省计算机等级考试二级C语言考试大纲...
- PicGo五分钟打造你的私人图床(稳定、快速、免费)
- 张量的通俗理解和计算
- Win7启动修复MBR(Win7+Linux删除Linux后进入grub rescue的情况)
- ssg国际数字货币商城源码货币商城+数字货币+双端APP
- java jtable 单元格编辑_java – 在基于JTable面板的单元格编辑器中...
- FreeRTOS中列表和列表项插入函数分析
- 瑞波基因币靠谱吗_Fil币小矿工: IPFS国家认可吗?IPFS是靠谱项目吗?
- 韦东山linux学习之ubuntu 9.10 软件源 问题
- 大话数据结构Java版第一节
- SAP 固定资产模块上线配置
- Verilog语言要素(三)
- 给上层添加SuperSu来获取root权限
- k开头的英文单词计算机专业,K开头英语单词一览
- 蚂蚁金服开发文档中心
- 宽带服务器无响应678,宽带连接错误678解决方法
- 人工智能机器学习底层原理剖析,人造神经元,您一定能看懂,通俗解释把AI“黑话”转化为“白话文”
- 如何打造新时代的终端播放产品?