python基于VGG19实现图像风格迁移

news2024/10/7 6:46:28

目录

1、原理

2、代码实现


1、原理

图像风格迁移是一种将一张图片的内容与另一张图片的风格进行合成的技术。

风格(style)是指图像中不同空间尺度的纹理、颜色和视觉图案,内容(content)是指图像的高级宏观结构。

实现风格迁移背后的关键概念与所有深度学习算法的核心思想是一样的:定义一个损失函数来指定想要实现的目标,然后将这个损失最小化。你知道想要实现的目标是什么,就是保存原始图像的内容,同时采用参考图像的风格。

在Python中,我们可以使用基于深度学习的模型来实现这一技术。​神经风格迁移可以用任何预训练卷积神经网络来实现。我们这里将使用    Gatys等人所使用的 VGG19网络。

2、代码实现

​以下是一个基于VGG19模型的简单图像风格迁移的实现过程:

(1)创建一个网络,它能够同时计算风格参考图像、目标图像和生成图像的 VGG19层激活。

(2)使用这三张图像上计算的层激活来定义之前所述的损失函数,为了实现风格迁移,需要将这个损失函数最小化。

(3)设置梯度下降过程来将这个损失函数最小化

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
​
for param in vgg.parameters():
    param.requires_grad_(False)
​
​
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
​
vgg.to(device)
​
​
def load_image(img_path, max_size=400):
​
    image = Image.open(img_path)
    
    if max(image.size) > max_size:
        size = max_size
    else:
        size = max(image.size)
        
    image_transform = transforms.Compose([
                        transforms.Resize(size),
                        transforms.ToTensor(),
                        transforms.Normalize((0.485, 0.456, 0.406), 
                                             (0.229, 0.224, 0.225))])
​
    image = image_transform(image).unsqueeze(0)
    
    return image
​
​
content = load_image('dogs_and_cats.jpg').to(device)
style = load_image('picasso.jpg').to(device)
​
​
assert style.size() == content.size(), "输入的风格图片和内容图片大小需要一致"
​
​
plt.ion()
def imshow(tensor,title=None):
    
    image = tensor.cpu().clone().detach()
    image = image.numpy().squeeze()
    image = image.transpose(1,2,0)
    image = image * np.array((0.229, 0.224, 0.225)) + np.array((0.485, 0.456, 0.406))
    plt.imshow(image)
    if title is not None:
        plt.title(title)
    plt.pause(0.1)
​
plt.figure()
imshow(style, title='Style Image')
​
plt.figure()
imshow(content, title='Content Image')
​
​
​
​
def get_features(image, model, layers=None):
   
    if layers is None:
        layers = {'0': 'conv1_1',
                  '5': 'conv2_1', 
                  '10': 'conv3_1', 
                  '19': 'conv4_1',
                  '21': 'conv4_2',  
                  '28': 'conv5_1'}
        
    features = {}
    x = image
    for name, layer in model._modules.items():
        x = layer(x)
        if name in layers:
            features[layers[name]] = x
            
    return features
​
content_features = get_features(content, vgg)
style_features = get_features(style, vgg)
​
def gram_matrix(tensor):
    
    _, d, h, w = tensor.size() 
    tensor = tensor.view(d, h * w)
    gram = torch.mm(tensor, tensor.t())
    return gram
​
style_grams={}
for layer in style_features:
  style_grams[layer] = gram_matrix(style_features[layer])
​
import torch.nn.functional as F
​
def ContentLoss(target_features,content_features):
  content_loss = F.mse_loss(target_features['conv4_2'],content_features['conv4_2'])
  return content_loss
​
def StyleLoss(target_features,style_grams,style_weights):
    style_loss = 0
    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] * F.mse_loss(target_gram,style_gram)
        style_loss += layer_style_loss / (d * h * w)
​
    return style_loss
​
​
style_weights = {'conv1_1': 1.,
                 'conv2_1': 0.75,
                 'conv3_1': 0.2,
                 'conv4_1': 0.2,
                 'conv5_1': 0.2}
​
alpha = 1  # alpha
beta = 1e6  # beta
​
​
show_every = 100
steps = 2000 
​
target = content.clone().requires_grad_(True).to(device)
optimizer = optim.Adam([target], lr=0.003)
​
​
for ii in range(1, steps+1):
    
    target_features = get_features(target, vgg)
    
    content_loss = ContentLoss(target_features,content_features)
    
    style_loss = StyleLoss(target_features,style_grams,style_weights)
        
    total_loss = alpha * content_loss + beta * style_loss
    
    optimizer.zero_grad()
    total_loss.backward()
    optimizer.step()
    #print(ii)
    
    if  ii % show_every == 0:
        print('Total loss: ', total_loss.item())
        plt.figure()      
        imshow(target)
​
plt.figure()
imshow(target,"Target Image")
plt.ioff()
plt.show()
​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1155749.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小程序制作(超详解!!!)第十一节 成绩计算器

设计一个计算学生平均成绩的小程序。当输入学生信息和各门功课成绩并提交后&#xff0c;能够显示学生的信息及平均成绩。 1.index.wxml <view classbox><view classtitle>成绩计算器</view><input placeholder"请输入你的名字" placeholder-c…

台积电熊本厂力拚明年如期量产 | 百能云芯

台积电&#xff08;TSMC&#xff09;正在积极推进其在日本熊本的新工厂项目&#xff0c;该项目正在如火如荼地建设中。根据了解&#xff0c;该工厂的员工总数将超过千人。台积电的目标是确保该新工厂按计划于2024年开始量产&#xff0c;这将使其成为首个因应客户需求和地缘政治…

食品行业小程序开发攻略

想要设计一个食品小程序商城&#xff0c;却担心自己没有任何设计经验&#xff1f;别担心&#xff0c;现在有了一些简单易用的小程序制作工具&#xff0c;零基础也能成为一个小程序商城设计师&#xff01;接下来&#xff0c;我们将一步步教你如何使用这些工具快速上手。 首先&am…

Easy Javadoc插件的使用教程

目录 一、安装Easy Javadoc插件 二、配置注释模板 三、配置翻译 一、安装Easy Javadoc插件 在idea的File-Settings-Plugins中搜索Easy Javadoc插件&#xff0c;点击install进行安装&#xff0c;安装完成后需要restart IDE&#xff0c;重启后插件生效。 二、配置注释模板 …

相关性网络图 |显著性标记

一边学习&#xff0c;一边总结&#xff0c;一边分享&#xff01; 本期教程 写在前面 此图是一位同学看到后&#xff0c;想出的一期教程。 最近&#xff0c;自己的事情比较多&#xff0c;会无暇顾及社群和公众号教程。 1 安装和加载相关的R包 library(ggraph) library(tidy…

AI大模型在短视频处理和剪辑中的应用,文末送书

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

【Elasticsearch 未授权访问漏洞复现】

文章目录 一、漏洞描述二、漏洞复现三、修复建议 一、漏洞描述 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasticsearch是用Java开发的&#xff0c;并作为Apache许可条款下的开放源码发布&am…

信号类型(通信)——QPSK、OQPSK、IJF_OQPSK调制信号

系列文章目录 《信号类型&#xff08;通信&#xff09;——仿真》 《信号类型&#xff08;通信&#xff09;——QAM调制信号》 文章目录 前言 一、QPSK通信调制信号 1.1、原理 1.2、仿真 二、OQPSK通信调制信号 1.1、原理 1.2、仿真 三、IJF_OQPSK通信调制信号 1.1、…

java--方法的其他形式

1.方法定义时&#xff1a;需要按照方法解决的实际业务需求&#xff0c;来设计合理的方法形式解决问题。 1.注意事项 ①如果方法不需要返回数据&#xff0c;返回值类型必须申明成void(无返回值申明)&#xff0c;此时方法内部不可以使用return返回数据。 ②方法如果不需要接收数…

[HNCTF 2022 WEEK2]easy_include 文件包含遇上nginx

这道纯粹记录 完全没想到 <?php //WEB手要懂得搜索if(isset($_GET[file])){$file $_GET[file];if(preg_match("/php|flag|data|\~|\!|\|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\|\/i", $file)){die("error");}include($file); }else{highlight_file(__…

【C#】winform打包,桌面快捷方式设置图标无效

使用visual stdiong的打包工具插件&#xff1a;Microsoft Visual Studio Installer Projects时&#xff0c;发现无论怎么设置软件的快捷方式图标&#xff0c;都无法设置成功&#xff0c;尝试多次设置快捷方式图标均无效。 此时使用Greenfish Icon Editor Pro软件对图片进行像素…

微信小程序获取最新隐私协议授权 以及涉及隐私API权限申请

最近小程序新推出的隐私政策&#xff0c;导致之前小程序一些相关api无法调用&#xff0c;甚至连登录都出现了问题... 话不多说&#xff0c;来点实在的 提示用户同意隐私授权的弹窗结构&#xff0c;样式就不粘了... <u-popup :show"showPrivacy" mode"cente…

如何利用自定义数据对象(元数据)实现全场景身份数据治理

在数字化时代背景下&#xff0c;5G、云计算、大数据、物联网、人工智能等技术的发展&#xff0c;为企业数据管理提供了基础技术支撑。数字化浪潮推动企业快速升级迭代&#xff0c;在数据管理和数字化转型过程中&#xff0c;企业内部的数据情况常常错综复杂&#xff0c;并伴随着…

java毕业设计基于springboot+vue气象观测数据样本构建与分析系统-天气预报网站

项目介绍 本系统是利用Spring Boot框架而设计的一款结合用户的实际情况而设计的平台&#xff0c;利用VUE技术来将可供用户和管理员来使用的所有界面来显示出来&#xff0c;利用Java语言技术来编程实现用户和管理员所执行的各类操作业务逻辑&#xff0c;以MySQL数据库来存取系统…

线程池是什么?如何合理的配置线程池核心线程数?

前几天写了这个博客&#xff1a; Java实现业务异步的几种方案-CSDN博客 应粉丝要求&#xff0c;写一下线程池细节方面的东西&#xff0c;在看了很多资料和讲解视频后做如下讲解&#xff1a; 一、线程池解决的问题 为什么有异步任务不去手动的new&#xff0c;而是基于线程池…

Vue3前端100个必要的知识点

为什么是必要的&#xff0c;就是这100个知识点学完后&#xff0c;能独立完成一个小项目。最终能得到一个解决方案。也算是前端知识的积累。如果后面有需要的地方可以回来查。100个其实比较多&#xff0c;我会按新手老鸟&#xff0c;大神来分成3个等级&#xff0c;话不多说&…

2023年10月13日,美国材料与试验协会(ASTM)发布了新版玩具安全标准ASTM F963-23

新标准发布 2023年10月13日&#xff0c;美国材料与试验协会&#xff08;ASTM&#xff09;发布了新版玩具安全标准ASTM F963-23。 主要更新内容 与ASTM F963-17相比&#xff0c;此次更新包括&#xff1a;单独描述了基材重金属元素的豁免情况&#xff0c;更新了邻苯二甲酸酯的管…

英语——歌曲篇——500 Miles(离家五百里)

乡村音乐&#xff08;country music&#xff09;《500 Miles(离家五百里)》以一种怀乡、寻根 的意识&#xff0c;用思念留住时光还有一点哲理的味道&#xff0c;乡村音乐多年以来都不曾淡出大家的视野&#xff0c;确实有值得留恋的情怀。 500 Miles [The Brothers Four离家五…

云计算的基本概念

目录 云计算基本概念 什么是云计算 云计算的优势&#xff08;关键特征&#xff09; 云计算发展历程 云计算发展阶段 云计算的三种服务模式 云计算的四类部署模式 云计算的应用 云计算基本概念 什么是云计算 云计算的基本概念 云计算&#xff08;Cloud Computing&…

【Java SE】运算符详解

本篇是了解Java SE中的各种运算符&#xff0c;并且熟练并掌握它们&#xff1b; 目录 1. 什么是运算符 2. 算术运算符 2.1 基本四则运算符 2.2 增量运算符 2.3.自增/自减运算符 3. 关系运算符 4. 逻辑运算符(重点) 4.1.逻辑与 && 4.2 逻辑或 || 3. 逻辑非 ! 5…