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. 学习笔记:图像风格迁移
相关实践学习
在云上部署ChatGLM2-6B大模型(GPU版)
ChatGLM2-6B是由智谱AI及清华KEG实验室于2023年6月发布的中英双语对话开源大模型。通过本实验,可以学习如何配置AIGC开发环境,如何部署ChatGLM2-6B大模型。
相关文章
|
7月前
|
人工智能 监控 前端开发
支付宝 AI 出行助手高效研发指南:4 人团队的架构迁移与提效实战
支付宝「AI 出行助手」是一款集成公交、地铁、火车票、机票、打车等多项功能的智能出行产品。
1133 21
支付宝 AI 出行助手高效研发指南:4 人团队的架构迁移与提效实战
|
6月前
|
机器学习/深度学习 人工智能 自然语言处理
迁移学习:让小数据也能驱动AI大模型
迁移学习:让小数据也能驱动AI大模型
406 99
|
5月前
|
人工智能 缓存 自然语言处理
Java与多模态AI:构建支持文本、图像和音频的智能应用
随着大模型从单一文本处理向多模态能力演进,现代AI应用需要同时处理文本、图像、音频等多种信息形式。本文深入探讨如何在Java生态中构建支持多模态AI能力的智能应用。我们将完整展示集成视觉模型、语音模型和语言模型的实践方案,涵盖从文件预处理、多模态推理到结果融合的全流程,为Java开发者打开通往下一代多模态AI应用的大门。
481 41
|
11月前
|
人工智能 编解码 物联网
设计师集体破防!UNO:字节跳动创新AI图像生成框架,多个参考主体同框生成,位置/材质/光影完美对齐
UNO是字节跳动开发的AI图像生成框架,通过渐进式跨模态对齐和通用旋转位置嵌入技术,解决了多主体场景下的生成一致性问题。该框架支持单主体特征保持与多主体组合生成,在虚拟试穿、产品设计等领域展现强大泛化能力。
720 4
设计师集体破防!UNO:字节跳动创新AI图像生成框架,多个参考主体同框生成,位置/材质/光影完美对齐
|
11月前
|
机器学习/深度学习 人工智能 计算机视觉
AI图像质感还原堪比专业摄影!Miracle F1:美图WHEE全新AI图像生成模型,支持超写实与多风格生成
美图WHEE推出的Miracle F1采用扩散模型技术,通过精准语义理解和多风格生成能力,可产出具有真实光影质感的专业级图像作品。
522 5
AI图像质感还原堪比专业摄影!Miracle F1:美图WHEE全新AI图像生成模型,支持超写实与多风格生成
|
5月前
|
人工智能 编解码 芯片
【AI绘画】你有多久没有打开SD了?
曾几何时,Stable Diffusion的复杂参数令人崩溃,如今即梦、可灵等AI工具已让生成图片变得轻而易举。哩布哩布发布2.0升级公告,看似迈向更易用的未来,却也悄然为那个钻研模型、拼接工作流的“拓荒时代”奏响终章。技术迭代飞快,但那份对创造的热爱与探索精神,永不褪色。
854 9
|
6月前
|
机器学习/深度学习 资源调度 算法框架/工具
AI-ANNE: 将神经网络迁移到微控制器的深度探索——论文阅读
AI-ANNE框架探索将深度学习模型迁移至微控制器的可行路径,基于MicroPython在Raspberry Pi Pico上实现神经网络核心组件,支持本地化推理,推动TinyML在边缘设备中的应用。
359 10
|
10月前
|
人工智能 弹性计算 智能设计
🎨 三步打造AI创意工坊 | 通义万相图像生成服务极速部署指南
🚀 从零到大师 | 通义万相智能创作系统部署指南