Pytorch学习笔记——风格迁移

原创 2018年04月17日 19:10:03


import torch
import torch.nn as nn
from torch.autograd import Variable
import torchvision
from torchvision import transforms, models
from PIL import Image
import argparse
import numpy as np
import os

use_gpu = torch.cuda.is_available()# 是否能够使用GPU

dtype = torch.cuda.FloatTensor if use_gpu else torch.FloatTensor  #判断数据允许GPU 否则CPU tensor
#导入数据
def load_image(image_path, transforms=None, max_size=None, shape=None):
    image = Image.open(image_path)#打开图片  image_path 为图片路径
    image_size = image.size #图片大小

    if max_size is not None:
        #获取图像size,为sequence
        image_size = image.size
        #转化为float的array
        size = np.array(image_size).astype(float)
        size = max_size / size * size;
        image = image.resize(size.astype(int), Image.ANTIALIAS)
#Image.ANTIALIAS在当前的PIL版本中,这个滤波器只用于改变尺寸和缩略图方法。
if shape is not None: image = image.resize(shape, Image.LANCZOS)#Image.LANCZOS 缩小图片比例
#必须提供transform.ToTensor,转化为4D Tensor .unsqueeze(0)表示增维 .squeeze(0)为降维
if transforms is not None: image = transforms(image).unsqueeze(0) #是否拷贝到GPU return image.type(dtype)class VGGNet(nn.Module): def __init__(self): super(VGGNet, self).__init__() self.select = ['0', '5', '10', '19', '28']#设置需要提取的 self.vgg19 = models.vgg19(pretrained = True).features def forward(self, x): features = [] #name类型为str,x为Variable for name, layer in self.vgg19._modules.items(): x = layer(x) if name in self.select: features.append(x) return featuresdef main(config): #定义图像变换操作,必须定义.ToTensor()。 transform = transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)) ]) #加速content和style图像,style图像resize成同样大小 content.size(0-3):0表示batch 1表示通道,2,3表示图片大小 content = load_image(config.content, transform, max_size = config.max_size) style = load_image(config.style, transform, shape = [content.size(2), content.size(3)]) #.clone()将concent复制一份作为target,并需要计算梯度,作为最终的输出
target = Variable(content.clone(), requires_grad = True) optimizer = torch.optim.Adam([target], lr = config.lr, betas=[0.5, 0.999]) vgg = VGGNet() if use_gpu: vgg = vgg.cuda() for step in range(config.total_step): #分别计算5个特征图 target_features = vgg(target) content_features = vgg(Variable(content)) style_features = vgg(Variable(style)) content_loss = 0.0 style_loss = 0.0 for f1, f2, f3 in zip(target_features, content_features, style_features): #计算content_loss content_loss += torch.mean((f1 - f2)**2) # **表示上标 **2 表示平方 n, c, h, w = f1.size() #将特征reshape成二维矩阵相乘,求gram矩阵 f1 = f1.view(c, h * w) f3 = f3.view(c, h * w) f1 = torch.mm(f1, f1.t())#f1.t() 表示f1的转置,但不改变f1
f3 = torch.mm(f3, f3.t()) #计算style_loss style_loss += torch.mean((f1 - f3)**2) / (c * h * w) #计算总的loss loss = content_loss + style_loss * config.style_weight #反向求导与优化 optimizer.zero_grad() loss.backward() optimizer.step() if (step+1) % config.log_step == 0: print ('Step [%d/%d], Content Loss: %.4f, Style Loss: %.4f' %(step+1, config.total_step, content_loss.data[0], style_loss.data[0])) if (step+1) % config.sample_step == 0: # Save the generated image denorm = transforms.Normalize((-2.12, -2.04, -1.80), (4.37, 4.46, 4.44)) img = target.clone().cpu().squeeze() img = denorm(img.data).clamp_(0, 1) torchvision.utils.save_image(img, 'output-%d.png' %(step+1))if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('--content', type=str, default='content.jpg') parser.add_argument('--style', type=str, default='style.jpg') parser.add_argument('--max_size', type=int, default=400) parser.add_argument('--total_step', type=int, default=5000) parser.add_argument('--log_step', type=int, default=10) parser.add_argument('--sample_step', type=int, default=1000) parser.add_argument('--style_weight', type=float, default=100) parser.add_argument('--lr', type=float, default=0.003) config = parser.parse_args() print(config) main(config)

下图为Pytorch 自带VGG19的网络结构,程序所取卷积层为1,3,5,9,12。


左侧图片是content,右侧图片是style


下面是左上到右下分别是迭代1000,2000,3000,4000的风格迁移后的图片


【PyTorch】PyTorch之风格迁移

前面介绍了PyTorch在深度学习上的一些简单应用,这一节讲解PyTorch在风格迁移上的用法。 基础知识 numpy.array() 将矩阵或者拥有__array____array_...
  • q295684174
  • q295684174
  • 2018-01-15 15:23:39
  • 398

基于PyTorch的深度学习入门教程(八)——图像风格迁移

前言 本文介绍怎样执行Neural-Style算法。Neural-Style或者叫做Neural-Transfer,将一个内容图像和一个风格图像作为输入,返回一个按照所选择的风格图像加工的内容图像。...
  • zzlyw
  • zzlyw
  • 2017-12-20 09:26:41
  • 814

利用pytorch实现神经网络风格迁移Neural Transfer

风格迁移 Neural Transfer风格迁移,即获取两个图片(一张内容图片content-image、一张风格图片style-image),从而生成一张新的拥有style-image图像风格的内容...
  • IAMoldpan
  • IAMoldpan
  • 2017-12-05 17:58:54
  • 196

度学习实践:如何使用Tensorflow实现快速风格迁移?

一、风格迁移简介 风格迁移(Style Transfer)是深度学习众多应用中非常有趣的一种,如图,我们可以使用这种方法把一张图片的风格“迁移”到另一张图片上: 然而,原始的风格迁...
  • c2a2o2
  • c2a2o2
  • 2017-11-24 09:23:57
  • 178

使用pytorch进行迁移学习

说明:本篇文章整理Transfer Learning tutorial上的知识点;关于迁移学习,请移步:cs231n notes 简要说明为何需要迁移学习:  在实际中,我们很少会训练...
  • Jason__sz
  • Jason__sz
  • 2018-02-01 16:42:53
  • 93

pytorch学习-迁移模型

pytorch学习-迁移模型 迁移模型:即是用pretrained models而不是from scratch with random initialization 注意点:数据输入的格式变换以及...
  • Mulanshine
  • Mulanshine
  • 2017-11-04 15:44:04
  • 379

资源 | 注意迁移的PyTorch实现

选自Github 作者:szagoruyko 机器之心编译 参与:赵华龙、吴攀 本项目是论文《要更加注重注意力:通过注意迁移技术提升卷积神经网络的性能(Paying Mor...
  • AMDS123
  • AMDS123
  • 2017-04-12 17:34:17
  • 7882

风格迁移学习笔记(2):Universal Style Transfer via Feature Transforms

以下将分为3个部分介绍: 1.提出的background和sense2.proposal network pipeline3.results Background 先来review一下过去的...
  • u011534057
  • u011534057
  • 2017-12-29 22:00:34
  • 447

风格迁移学习笔记(1):Multimodal Transfer: A Hierarchical Deep Convolutional Neural Network for Fast

以下将分为3个部分介绍: 效果解決的問題How to solve it? 1.效果: 先来看一下效果 2.解决的问题: 通用框架下进行style transfer时候的笔触差异 原始的...
  • u011534057
  • u011534057
  • 2017-12-29 21:58:15
  • 325

图像风格迁移-Image Style Transfer Using Convolutional Neural Networks

论文:Image Style Transfer Using Convolutional Neural Networks 论文链接图像风格迁移最近两年比较火,看起来也比较有趣,所以这两天闲暇时候看了一...
  • u014380165
  • u014380165
  • 2017-07-29 07:35:06
  • 3041
收藏助手
不良信息举报
您举报文章:Pytorch学习笔记——风格迁移
举报原因:
原因补充:

(最多只允许输入30个字)