AI绘画第二弹——图像风格迁移

简介:

简介

所谓图像风格迁移,是指将一幅内容图 A 的内容,和一幅风格图 B 的风格融合在一起,从而生成一张具有 A 图风格和 B 图内容的图片 C 的技术。目前这个技术已经得到了比较广泛的应用,这里安利一个 app——"大画家",这个软件可以将用户的照片自动变换为具有艺术家的风格的图片。

准备

其实刚开始写这篇文章的时候我是准备详细介绍下原理的,但是后来发现公式实在是太多了,就算写了估计也没什么人看,而且这篇文章本来定位的用户就是只需要实现功能的新人。此外,有关风格迁移的原理解析的博客实在是太多了,所以这里我就把重点放在如何使用 TensorFlow 实现一个快速风格迁移的应用上,原理的解析就一带而过了。如果只想实现这个效果的可以跳到"运行"一节。

第一步我们需要提前安装好 TensorFlow,如果有 GPU 的小伙伴可以参考我的这篇文章搭建一个 GPU 环境:《AI 绘画第一弹——用 GPU 为你的训练过程加速》,如果打算直接用 CPU 运行的话,执行下面一行话就可以了

pip install numpy tensorflow scipy

原理

本篇文章是基于A Neural Algorithm of Artistic Style一文提出的方法实现的,如果嫌看英文论文太麻烦的也可以查看我对这篇文章的翻译【译】一种有关艺术风格迁移的神经网络算法

为了将风格图的风格和内容图的内容进行融合,所生成的图片,在内容上应当尽可能接近内容图,在风格上应当尽可能接近风格图,因此需要定义内容损失函数风格损失函数,经过加权后作为总的损失函数。

预训练模型

CNN 具有抽象和理解图像的能力,因此可以考虑将各个卷积层的输出作为图像的内容,这里我们采用了利用 VGG19 训练好的模型来进行迁移学习,一般认为,卷积神经网络的训练是对数据集特征的一步步抽取的过程,从简单的特征,到复杂的特征。训练好的模型学习到的是对图像特征的抽取方法,而该模型就是在 imagenet 数据集上预训练的模型,所以理论上来说,也可以直接用于抽取其他图像的特征,虽然效果可能没有在原有数据集上训练出的模型好,但是能够节省大量的训练时间,在特定情况下非常有用。

加载预训练模型

def vggnet(self):
    # 读取预训练的vgg模型
    vgg = scipy.io.loadmat(settings.VGG_MODEL_PATH)
    vgg_layers = vgg['layers'][0]
    net = {}
    # 使用预训练的模型参数构建vgg网络的卷积层和池化层
    # 全连接层不需要
    # 注意,除了input之外,这里参数都为constant,即常量
    # 和平时不同,我们并不训练vgg的参数,它们保持不变
    # 需要进行训练的是input,它即是我们最终生成的图像
    net['input'] = tf.Variable(np.zeros([1, settings.IMAGE_HEIGHT, settings.IMAGE_WIDTH, 3]), dtype=tf.float32)
    # 参数对应的层数可以参考vgg模型图
    net['conv1_1'] = self.conv_relu(net['input'], self.get_wb(vgg_layers, 0))
    net['conv1_2'] = self.conv_relu(net['conv1_1'], self.get_wb(vgg_layers, 2))
    net['pool1'] = self.pool(net['conv1_2'])
    net['conv2_1'] = self.conv_relu(net['pool1'], self.get_wb(vgg_layers, 5))
    net['conv2_2'] = self.conv_relu(net['conv2_1'], self.get_wb(vgg_layers, 7))
    net['pool2'] = self.pool(net['conv2_2'])
    net['conv3_1'] = self.conv_relu(net['pool2'], self.get_wb(vgg_layers, 10))
    net['conv3_2'] = self.conv_relu(net['conv3_1'], self.get_wb(vgg_layers, 12))
    net['conv3_3'] = self.conv_relu(net['conv3_2'], self.get_wb(vgg_layers, 14))
    net['conv3_4'] = self.conv_relu(net['conv3_3'], self.get_wb(vgg_layers, 16))
    net['pool3'] = self.pool(net['conv3_4'])
    net['conv4_1'] = self.conv_relu(net['pool3'], self.get_wb(vgg_layers, 19))
    net['conv4_2'] = self.conv_relu(net['conv4_1'], self.get_wb(vgg_layers, 21))
    net['conv4_3'] = self.conv_relu(net['conv4_2'], self.get_wb(vgg_layers, 23))
    net['conv4_4'] = self.conv_relu(net['conv4_3'], self.get_wb(vgg_layers, 25))
    net['pool4'] = self.pool(net['conv4_4'])
    net['conv5_1'] = self.conv_relu(net['pool4'], self.get_wb(vgg_layers, 28))
    net['conv5_2'] = self.conv_relu(net['conv5_1'], self.get_wb(vgg_layers, 30))
    net['conv5_3'] = self.conv_relu(net['conv5_2'], self.get_wb(vgg_layers, 32))
    net['conv5_4'] = self.conv_relu(net['conv5_3'], self.get_wb(vgg_layers, 34))
    net['pool5'] = self.pool(net['conv5_4'])
    return net

训练思路

我们使用 VGG 中的一些层的输出来表示图片的内容特征和风格特征。比如,我使用[‘conv4_2’,’conv5_2’]表示内容特征,使用[‘conv1_1’,’conv2_1’,’conv3_1’,’conv4_1’]表示风格特征。在settings.py中进行配置。

# 定义计算内容损失的vgg层名称及对应权重的列表
CONTENT_LOSS_LAYERS = [('conv4_2', 0.5),('conv5_2',0.5)]
# 定义计算风格损失的vgg层名称及对应权重的列表
STYLE_LOSS_LAYERS = [('conv1_1', 0.2), ('conv2_1', 0.2), ('conv3_1', 0.2), ('conv4_1', 0.2), ('conv5_1', 0.2)]

内容损失函数

image-20190429151634583

其中,X 是噪声图片的特征矩阵,P 是内容图片的特征矩阵。M 是 P 的长*宽,N 是信道数。最终的内容损失为,每一层的内容损失加权和,再对层数取平均。

我知道很多人一看到数学公式就会头疼,简单理解就是这个公式可以让模型在训练过程中不断的抽取图片的内容。

风格损失函数

计算风格损失。我们使用风格图像在指定层上的特征矩阵的 GRAM 矩阵来衡量其风格,风格损失可以定义为风格图像和噪音图像特征矩阵的格莱姆矩阵的差值的 L2 范数。

对于每一层的风格损失函数,我们有:

其中 M 是特征矩阵的长*宽,N 是特征矩阵的信道数。G 为噪音图像特征的 Gram 矩阵,A 为风格图片特征的 GRAM 矩阵。最终的风格损失为,每一层的风格损失加权和,再对层数取平均。

同样的,看不懂公式没关系,你就把它理解为这个公式可以在训练过程中获取图片的风格。

计算总损失函数并训练模型

最后我们只需要将内容损失函数和风格损失函数带入刚开始的公式中即可,要做的就是控制一些风格的权重和内容的权重:

# 内容损失权重
ALPHA = 1
# 风格损失权重
BETA = 500

ALPHA 越大,则最后生成的图片内容信息越大;同理,BETA 越大,则最后生成的图片风格化更严重。

当训练开始时,我们根据内容图片和噪声,生成一张噪声图片。并将噪声图片喂给网络,计算 loss,再根据 loss 调整噪声图片。将调整后的图片喂给网络,重新计算 loss,再调整,再计算…直到达到指定迭代次数,此时,噪声图片已兼具内容图片的内容和风格图片的风格,进行保存即可。

运行

如果对上述原理不感兴趣的,想直接运行代码的可以去微信公众号「01 二进制」后台回复「图像风格迁移」获得源码。接下来我们来说说如何使用这个代码跑出自己的绘画。

首先看下项目结构:

images 下有两张图片,分别是内容图和风格图,output 下是训练过程中产生的文件,.mat 文件就是预训练模型,models.py 是我们实现的用于读取预训练模型的文件,settings.py 是配置文件,train.py 是最终的训练文件。

想要运行该项目,我们只需要执行python train.py即可,想更改风格和内容的的话只要在 images 文件中更换原先的图片即可。当然你也可以在settings.py中修改路径:

# 内容图片路径
CONTENT_IMAGE = 'images/content.jpg'
# 风格图片路径
STYLE_IMAGE = 'images/style.jpg'
# 输出图片路径
OUTPUT_IMAGE = 'output/output'
# 预训练的vgg模型路径
VGG_MODEL_PATH = 'imagenet-vgg-verydeep-19.mat'

我们来看看训练后的图片:

最后

虽然通过上述代码我们可以实现图像的风格迁移,但是他有一个最大的缺点,就是无法保存训练好的模型,每次转换风格都要重新跑一遍,如果使用 CPU 跑 1000 轮的话大约是在 30 分钟左右,因此推荐大家使用 GPU 进行训练。

但是即使使用上了 GPU,训练时间也无法满足商业使用的,那有没有什么办法可以保存训练好的风格模型,然后直接快速生成目标图片呢?当然是有的,斯坦福的李飞飞发表过一篇《Perceptual Losses for Real-Time Style Transfer and Super-Resolution》,通过使用 perceptual loss 来替代 per-pixels loss 使用 pre-trained 的 vgg model 来简化原先的 loss 计算,增加一个 transform Network,直接生成 Content image 的 style。这里就不再多说了,感兴趣的可以参考我下面给出的两个链接:

  1. 《深度有趣 | 30 快速图像风格迁移》
  2. 《风格迁移背后原理及 tensorflow 实现》

以上就是本篇文章的全部内容,个人做下来感觉还是挺有意思的,因个人能力有限,文中如有纰漏错误之处,还请各位大佬指正,万分感谢!

参考

  1. A Neural Algorithm of Artistic Style
  2. 深度学习实战(一)快速理解实现风格迁移
  3. 深度有趣 | 04 图像风格迁移
  4. 学习笔记:图像风格迁移
相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
1月前
|
人工智能 Windows Python
Windows下体验Stable Diffusion 近距离感受AI魔法绘画
Windows下体验Stable Diffusion 近距离感受AI魔法绘画
104 2
|
1月前
|
人工智能 编解码 物联网
Stability AI推出新的AI图像生成模型Stable Cascade,对比 SD2.1 的算力成本降低了10倍左右!
Stability AI推出新的AI图像生成模型Stable Cascade,对比 SD2.1 的算力成本降低了10倍左右!
|
27天前
|
人工智能 算法 安全
“AI黏土人”一夜爆火,图像生成类应用何去何从?
【6月更文挑战第1天】“AI黏土人”一夜爆火,图像生成类应用何去何从?
|
14天前
|
人工智能 API 流计算
[AI Stability] 开源AI新利器:Stable Diffusion 3 Medium震撼发布!文本到图像再升级!
探索 Stable Diffusion 3 Medium(SD3),Stability AI 的最新开源模型,正在彻底改变文本到图像的生成。了解其功能、许可选项和集成可能性。
[AI Stability] 开源AI新利器:Stable Diffusion 3 Medium震撼发布!文本到图像再升级!
|
1月前
|
人工智能 算法 搜索推荐
“AI黏土人”现象下的图像生成应用:长期留住用户的策略
近年来,随着科技的快速发展和社交媒体的普及,以及人工智能技术的快速发展,图像生成类应用成为了市场的新宠,图像生成类应用如“AI黏土人”等近期在各大平台上崭露头角,其独特的“丑萌”风格迅速赢得了广大用户的喜爱,吸引了大量用户的关注,这一现象不仅体现了技术创新的魅力,也展示了市场需求与资本聚焦的强大驱动力。但是在这个信息爆炸的时代,如何保持这种热度并避免昙花一现,如何在爆火之后长期留住用户,确保图像生成类应用的持续繁荣,成为了图像生成类应用面临的重要问题。那么本文就来简单聊一下,欢迎评论区留言交流。
31 2
“AI黏土人”现象下的图像生成应用:长期留住用户的策略
|
10天前
|
人工智能 Java 语音技术
Spring AI更多模型支持、图像和音频处理
Spring AI更多模型支持、图像和音频处理
17 1
|
16天前
|
人工智能 Python Shell
CodeFormer——AI驱动的面部图像修复与增强
CodeFormer是由南洋理工大学和商汤科技联合研发的AI人脸复原模型,结合VQGAN和Transformer技术,能从模糊或马赛克图像中生成清晰图像。它具备老照片修复、黑白照片彩色化、马赛克修复和低码率视频增强等功能。安装过程涉及miniconda3、Python环境配置、相关库的安装及模型训练数据下载。在测试视频增强时,虽然初期遇到ffmpeg导入问题,但通过安装ffmpeg-python得以解决,不过CPU占用率高。此外,还展示了对图片进行增强的命令行操作及结果示例。
|
20天前
|
存储 运维 安全
Greenplum闭源?平滑迁移到 AnalyticDB 开启Data+AI新范式
知名开源 MPP 数据库 Greenplum 由于其丰富的企业级特性和出色的数据处理能力成为很多企业构建数仓的首选。近期 GP 公开 Github 仓库无法访问仅保留只读归档代码,业界纷纷猜测 GP 即将闭源。云原生数仓 AnalyticDB PostgreSQL 版完全掌控内核代码,完全兼容GP语法,全自研计算及存储引擎较比开源GP有五倍性能提升,全自研企业级特性在实时计算、弹性扩展、安全增强、高可用等方面实现对GP的全面超越,并在数仓能力上扩展了向量检索及一站式 RAG 服务,帮助企业快速构建 AI 应用、开启 Data+AI 新范式。
58952 3
|
21天前
|
机器学习/深度学习 人工智能 算法
基于AI的图像风格转换系统:技术探索与实现
【6月更文挑战第7天】本文探讨了基于AI的图像风格转换系统的原理与实现,采用神经风格迁移技术,利用CNN分离并结合内容与风格。实现过程包括数据准备、构建模型(如VGG19和生成器网络)、定义内容及风格损失函数、训练模型、评估与调优,最终部署应用。尽管面临训练数据需求、计算复杂度和特定场景适应性的挑战,未来的研究将聚焦于技术提升、减少数据依赖及解决伦理隐私问题,以实现更高效智能的风格转换系统。
|
20天前
|
人工智能 算法
AIGC创作活动 | 智"绘"AI,使用PAI创造风格百变绘画助手
使用阿里云人工智能平台PAIx Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理,实现文本驱动的图像编辑功能单卡即可完成AIGC图片风格变化、背景变化和主体变化等功能。让我们一同开启这场旅程,为您的图像编辑添上无限可能性的翅膀吧。

热门文章

最新文章