图像风格迁移

最后要生成的图片是怎样的是难以想象的,所以朴素的监督学习方法可能不会生效,

Content Loss

根据输入图片和输出图片的像素差别可以比较损失

\(l_{content} = \frac{1}{2}\sum (C_c-T_c)^2\)

Style Loss

从中间提取多个特征层来衡量损失。

利用\(Gram\) \(Matrix\)(格拉姆矩阵)可以衡量风格的相关性,对于一个实矩阵\(X\),矩阵\(XX^T\)是\(X\)的行向量的格拉姆矩阵

\(l_{style}=\sum wi(Ts-Ss)^2\)

总的损失函数

\(L_{total(S,C,T)}=\alpha l_{content}(C,T)+\beta L_{style}(S,T)\)


代码
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np import torch
import torch.optim as optim
from torchvision import transforms, models vgg = models.vgg19(pretrained=True).features #使用预训练的VGG19,features表示只提取不包括全连接层的部分 for i in vgg.parameters():
i.requires_grad_(False) #不要求训练VGG的参数

定义一个显示图片的函数

def load_img(path, max_size=400,shape=None):
img = Image.open(path).convert('RGB') if(max(img.size)) > max_size: #规定图像的最大尺寸
size = max_size
else:
size = max(img.size) if shape is not None:
size = shape
transform = transforms.Compose([
transforms.Resize(size),
transforms.ToTensor(),
transforms.Normalize((0.485, 0.456, 0.406),
(0.229, 0.224, 0.225))
])
'''删除alpha通道(jpg), 转为png,补足另一个维度-batch'''
img = transform(img)[:3,:,:].unsqueeze(0)
return img

载入图像

content  = load_img('./images/turtle.jpg')
style = load_img('./images/wave.jpg', shape=content.shape[-2:]) #让两张图尺寸一样 '''转换为plt可以画出来的形式'''
def im_convert(tensor):
img = tensor.clone().detach()
img = img.numpy().squeeze()
img = img.transpose(1,2,0)
img = img * np.array((0.229, 0.224, 0.225)) + np.array((0.485, 0.456, 0.406))
img = img.clip(0,1)
return img

使用的图像为(左边为Content Image,右边为Style Image):

定义几个待会要用到的函数

def get_features(img, model, layers=None):
'''获取特征层'''
if layers is None:
layers = {
'0':'conv1_1',
'5':'conv2_1',
'10':'conv3_1',
'19':'conv4_1',
'21':'conv4_2', #content层
'28':'conv5_1'
} features = {}
x = img
for name, layer in model._modules.items():
x = layer(x)
if name in layers:
features[layers[name]] = x return features def gram_matrix(tensor):
'''计算Gram matrix'''
_, d, h, w = tensor.size() #第一个是batch_size tensor = tensor.view(d, h*w) gram = torch.mm(tensor, tensor.t()) return gram content_features = get_features(content, vgg)
style_features = get_features(style, vgg) style_grams = {layer:gram_matrix(style_features[layer]) for layer in style_features} target = content.clone().requires_grad_(True) '''定义不同层的权重'''
style_weights = {
'conv1_1': 1,
'conv2_1': 0.8,
'conv3_1': 0.5,
'conv4_1': 0.3,
'conv5_1': 0.1,
}
'''定义2种损失对应的权重'''
content_weight = 1
style_weight = 1e6

训练过程

show_every = 400
optimizer = optim.Adam([target], lr=0.003)
steps = 2000 for ii in range(steps):
target_features = get_features(target, vgg) content_loss = torch.mean((target_features['conv4_2'] - content_features['conv4_2'])**2)
style_loss = 0
'''加上每一层的gram_matrix矩阵的损失'''
for layer in style_weights:
target_feature = target_features[layer]
target_gram = gram_matrix(target_feature)
_, d, h, w = target_feature.shape
style_gram = style_grams[layer]
layer_style_loss = style_weights[layer] * torch.mean((target_gram - style_gram)**2)
style_loss += layer_style_loss/(d*h*w) #加到总的style_loss里,除以大小 total_loss = content_weight * content_loss + style_weight * style_loss optimizer.zero_grad()
total_loss.backward()
optimizer.step() if ii % show_every == 0 :
print('Total Loss:',total_loss.item())
plt.imshow(im_convert(target))
plt.show()

将输入的图像和最后得到的混合图作比较:

没有达到最好的效果,还有可以优化的空间√

参考:
  1. Image Style Transfer Using Convolutional Neural Networks论文
  2. Udacity——PyTorch Scholarship Challenge

图像风格迁移(Pytorch)的更多相关文章

  1. keras图像风格迁移

    风格迁移: 在内容上尽量与基准图像保持一致,在风格上尽量与风格图像保持一致. 1. 使用预训练的VGG19网络提取特征 2. 损失函数之一是"内容损失"(content loss) ...

  2. fast neural style transfer图像风格迁移基于tensorflow实现

    引自:深度学习实践:使用Tensorflow实现快速风格迁移 一.风格迁移简介 风格迁移(Style Transfer)是深度学习众多应用中非常有趣的一种,如图,我们可以使用这种方法把一张图片的风格“ ...

  3. Distill详述「可微图像参数化」:神经网络可视化和风格迁移利器!

    近日,期刊平台 Distill 发布了谷歌研究人员的一篇文章,介绍一个适用于神经网络可视化和风格迁移的强大工具:可微图像参数化.这篇文章从多个方面介绍了该工具. 图像分类神经网络拥有卓越的图像生成能力 ...

  4. 使用 PyTorch 进行 风格迁移(Neural-Transfer)

    1.简介 本教程主要讲解如何实现由 Leon A. Gatys,Alexander S. Ecker和Matthias Bethge提出的Neural-Style 算法.Neural-Style 或者 ...

  5. Gram格拉姆矩阵在风格迁移中的应用

    Gram定义 n维欧式空间中任意k个向量之间两两的内积所组成的矩阵,称为这k个向量的格拉姆矩阵(Gram matrix) 根据定义可以看到,每个Gram矩阵背后都有一组向量,Gram矩阵就是由这一组向 ...

  6. 『cs231n』通过代码理解风格迁移

    『cs231n』卷积神经网络的可视化应用 文件目录 vgg16.py import os import numpy as np import tensorflow as tf from downloa ...

  7. Keras实现风格迁移

    风格迁移 风格迁移算法经历多次定义和更新,现在应用在许多智能手机APP上. 风格迁移在保留目标图片内容的基础上,将图片风格引用在目标图片上. 风格本质上是指在各种空间尺度上图像中的纹理,颜色和视觉图案 ...

  8. ng-深度学习-课程笔记-14: 人脸识别和风格迁移(Week4)

    1 什么是人脸识别( what is face recognition ) 在相关文献中经常会提到人脸验证(verification)和人脸识别(recognition). verification就 ...

  9. [DeeplearningAI笔记]卷积神经网络4.6-4.10神经网络风格迁移

    4.4特殊应用:人脸识别和神经网络风格转换 觉得有用的话,欢迎一起讨论相互学习~Follow Me 4.6什么是神经网络风格转换neural style transfer 将原图片作为内容图片Cont ...

随机推荐

  1. AOP面向切面编程C#实例

    原创: eleven 原文:https://mp.weixin.qq.com/s/8klfhCkagOxlF1R0qfZsgg [前言] AOP(Aspect-Oriented Programming ...

  2. qutebrowser 只用键盘操作的浏览器

    一个 Qt 库制作的最简化浏览器,内核是 Chromium.最大特点就是它自带命令行,可以完全用键盘操作. 下载地址: 链接:https://share.weiyun.com/5Y2Ajvn 密码:m ...

  3. tomcat部署项目后,war包是否可刪?war包存在必要性!

    在tomcat中webapps目錄上傳war包后,  对war解压时候. war不能在tomcat运行时删除,否则会删除自动解压的工程. 你可以停止tomcat后删除war. 当你重新部署的时候,如果 ...

  4. PHPCMS V9 添加二级导航

    今天看了看phpcms 写到二级导航时发现点问题,查询导航栏的信息时返回的$r[arrchildid]与自己想象的不符,文档上说是返回子栏目id但是却有些不同. 开始的思路: <ul class ...

  5. 设计模式系列6:适配器模式(Adapter Pattern)

    定义 将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.    --<设计模式>GoF UML类图 使用场景 在遗留代码复用,类 ...

  6. Eclipse常用快捷键速记

    补充 15 个 Eclipse 常用开发快捷键使用技巧 1.alt+? 或 alt+/:自动补全代码或者提示代码 2.ctrl+o:快速outline视图 3.ctrl+shift+r:打开资源列表 ...

  7. 《JavaScript高级程序设计》笔记:函数表达式(七)

    递归 function factorial(num){ if(num<=1){ return 1; }else { return num * arguments.callee(num-1); } ...

  8. 演示Eclipse插件实现代码提示和补全

    续上文重拾< 两周自制脚本语言 >- Eclipse插件实现语法高亮, 但仅达到了演示Eclipse本身功能的程度, 与石头语言并无直接联系. 源码库相同, 仍在同一插件. 演示效果如下: ...

  9. Dynamics CRM项目实例之七:站点地图修改,联系人-订单-积分管理

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复138或者20141229可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me!        前面文章发表后,不 ...

  10. Linux网络基本网络配置方法介绍

    网络信息查看 设置网络地址: cat /etc/sysconfig/network-scripts/ifcfg-eth0 你将会看到: DEVICE=eth0BOOTPROTO=staticsHWAD ...