ContentLoss

首先是要定义一个内容差异损失函数,这里直接调用functional.mse_loss(input,self.target)就可以计算出其内容差异损失。

注意这里一般是定义一个网络模型,输入和输出一直,这样才在后面方便直接求出 loss

class ContentLoss(nn.Module):

    def __init__(self, target,):
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, input):
self.loss = F.mse_loss(input, self.target)
return input

detach是使他不能求梯度

StyleLoss

这里是定义风格差异损失函数,首先就先定一个一个gram函数来求 c*c c为层数

def gram_matrix(input):
a, b, c, d = input.size() # a=batch size(=1)
# b=number of feature maps
# (c,d)=dimensions of a f. map (N=c*d) features = input.view(a * b, c * d) # resise F_XL into \hat F_XL G = torch.mm(features, features.t()) # compute the gram product # we 'normalize' the values of the gram matrix
# by dividing by the number of element in each feature maps.
return G.div(a * b * c * d)

然后利用gram函数来求loss

class StyleLoss(nn.Module):
def __init__(self, target_feature):
super(StyleLoss, self).__init__()
self.target = gram_matrix(target_feature).detach() def forward(self, input):
G = gram_matrix(input)
self.loss = F.mse_loss(G, self.target)
return input

新定义网络

然后将 ContentLoss和 StyleLoss 加入新定义的迁移网络(normalization见下面)

cnn = models.vgg19(pretrained=True).features.to(device).eval()

content_layers_default = ['conv_4']
style_layers_default = ['conv_1', 'conv_2', 'conv_3', 'conv_4', 'conv_5'] def get_style_model_and_losses(cnn, normalization_mean, normalization_std,
style_img, content_img,
content_layers=content_layers_default,
style_layers=style_layers_default):
cnn = copy.deepcopy(cnn) # normalization module
normalization = Normalization(normalization_mean, normalization_std).to(device) # just in order to have an iterable access to or list of content/syle
# losses
content_losses = []
style_losses = [] # assuming that cnn is a nn.Sequential, so we make a new nn.Sequential
# to put in modules that are supposed to be activated sequentially
model = nn.Sequential(normalization)
# model = nn.Sequential()
i = 0 # increment every time we see a conv
for layer in cnn.children():
if isinstance(layer, nn.Conv2d):
i += 1
name = 'conv_{}'.format(i)
elif isinstance(layer, nn.ReLU):
name = 'relu_{}'.format(i)
# The in-place version doesn't play very nicely with the ContentLoss
# and StyleLoss we insert below. So we replace with out-of-place
# ones here. #********注意**************不能掉 vgg默认inplace=ture
layer = nn.ReLU(inplace=False) elif isinstance(layer, nn.MaxPool2d):
name = 'pool_{}'.format(i)
elif isinstance(layer, nn.BatchNorm2d):
name = 'bn_{}'.format(i)
else:
raise RuntimeError('Unrecognized layer: {}'.format(layer.__class__.__name__)) model.add_module(name, layer) if name in content_layers:
# add content loss:
target = model(content_img).detach()
content_loss = ContentLoss(target)
model.add_module("content_loss_{}".format(i), content_loss)
content_losses.append(content_loss) if name in style_layers:
# add style loss:
target_feature = model(style_img).detach()
style_loss = StyleLoss(target_feature)
model.add_module("style_loss_{}".format(i), style_loss)
style_losses.append(style_loss) # now we trim off the layers after the last content and style losses
for i in range(len(model) - 1, -1, -1):
if isinstance(model[i], ContentLoss) or isinstance(model[i], StyleLoss):
break model = model[:(i + 1)] return model, style_losses, content_losses

normalization模型

cnn_normalization_mean = torch.tensor([0.485, 0.456, 0.406]).to(device)
cnn_normalization_std = torch.tensor([0.229, 0.224, 0.225]).to(device) # create a module to normalize input image so we can easily put it in a
# nn.Sequential class Normalization(nn.Module):
def __init__(self, mean, std):
super(Normalization, self).__init__()
# .view the mean and std to make them [C x 1 x 1] so that they can
# directly work with image Tensor of shape [B x C x H x W].
# B is batch size. C is number of channels. H is height and W is width.
self.mean = torch.tensor(mean).view(-1, 1, 1)
self.std = torch.tensor(std).view(-1, 1, 1) def forward(self, img):
# normalize img
return (img - self.mean) / self.std

输入参数定义

input_img = content_img.clone()
optimizer = optim.LBFGS([input_img.requires_grad_()])
两种方式
#input_param = nn.Parameter(input_img.data)
#optimizer = optim.LBFGS([input_param])

更新input_img

注意梯度共轭和LBFGS 方法更新梯度的时候 要用闭包的形式

def run_style_transfer(cnn, normalization_mean, normalization_std,
content_img, style_img, input_img, num_steps=300,
style_weight=500000, content_weight=1):
"""Run the style transfer."""
print('Building the style transfer model..')
model, style_losses, content_losses = get_style_model_and_losses(cnn,
normalization_mean, normalization_std, style_img, content_img)
# optimizer = get_input_optimizer(input_img) print('Optimizing..')
run = [0]
while run[0] <= num_steps: def closure():
# correct the values of updated input image
input_img.data.clamp_(0, 1) optimizer.zero_grad()
model(input_img)
style_score = 0
content_score = 0 for sl in style_losses:
style_score += sl.loss
for cl in content_losses:
content_score += cl.loss
style_score *= style_weight
content_score *= content_weight loss = style_score + content_score
loss.backward() run[0] += 1
if run[0] % 50 == 0:
print("run {}:".format(run))
print('Style Loss : {:4f} Content Loss: {:4f}'.format(
style_score.item(), content_score.item()))
print() return style_score + content_score
optimizer.step(closure) # a last correction...
input_img.data.clamp_(0, 1) return input_img

其余代码参考 https://pytorch.org/tutorials/advanced/neural_style_tutorial.html#sphx-glr-advanced-neural-style-tutorial-py

neural_transfer风格迁移的更多相关文章

  1. 图像风格迁移(Pytorch)

    图像风格迁移 最后要生成的图片是怎样的是难以想象的,所以朴素的监督学习方法可能不会生效, Content Loss 根据输入图片和输出图片的像素差别可以比较损失 \(l_{content} = \fr ...

  2. keras图像风格迁移

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

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

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

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

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

  5. Keras实现风格迁移

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

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

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

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

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

  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. linux 安装weblogic12.1.3.0步骤

    此过程为jar包安装~ 需注意:fmw_12.1.3.0.0_wls.jar     需要jdk1.7.0_15以上的版本 1.安装JDK(若已装可跳过) (1)Oracle官网下载jdk linux ...

  2. 洛谷 P2671 求和

    题目描述 一条狭长的纸带被均匀划分出了nn个格子,格子编号从11到nn.每个格子上都染了一种颜色color\_icolor_i用[1,m][1,m]当中的一个整数表示),并且写了一个数字number\ ...

  3. 洛谷P2055 [ZJOI2009]假期的宿舍 题解

    题目链接: https://www.luogu.org/problemnew/show/P2055 分析: 这道题比较简单,二分图的练习题(当然最大流同理). 易得我们可以将人放在一侧,床放在一侧. ...

  4. leetcode 48 矩阵旋转可以这么简单

    一行代码解决矩阵旋转(方法三). 方法1: 坐标法 def rotate(self, matrix): n = len(matrix) # 求出矩阵长度 m = (n + 1) // 2 # 求出层数 ...

  5. SQL数据同步到ElasticSearch(三)- 使用Logstash+LastModifyTime同步数据

    在系列开篇,我提到了四种将SQL SERVER数据同步到ES中的方案,本文将采用最简单的一种方案,即使用LastModifyTime来追踪DB中在最近一段时间发生了变更的数据. 安装Java 安装部分 ...

  6. laravel 模型查询总结

    1.Model::find($id);//查找主键为$id的数据 2.Model::find([$key1,$key2]);//使用双主键进行查找 3.Model::findOrFail($id);/ ...

  7. Javaweb入门 数据库第二天

    接着说昨天语法中提到的drop,delete和truncate的区别 drop用于删除库和表,不能用于删除表记录 delete和truncate都可以用于删除表记录,不能用于删除库和表 而delete ...

  8. C#中属性的解析

    一.域的概念 C#中域是指成员变量和方法,在OOP编程中(面向对象编程)我们要求用户只知道类是干什么的,而不许知道如何完成的,或者说不允许访问类的内部,对于有必要在类外可见的域,我们用属性来表达,所以 ...

  9. MyBatis 核心配置综述之StatementHandler

    目录 MyBatis 核心配置综述之StatementHandler MyBatis 四大组件之StatementHandler StatementHandler 的基本构成 StatementHan ...

  10. mac下安装mongodb数据库教程

    前言 由于最近在学习node+express,学习到持久化存储章节需要连接mongodb数据库,然后之前也有试过安装mongodb但是失败了,这次就找了很多资料,终于安装完成了,故此记录下来安装步骤, ...