VGG19图像风格迁移

——

1

引言

——

——

人工智能与艺术的交叉碰撞,不仅在相关的技术领域和艺术领域隐去广泛关注,以相关技术为基础的图像处理软件一经推出便吸引了广泛的关注,而在这背后的核心技术便是基于深度学习的图像风格迁移(style transfer)。

图像风格迁移是将一幅艺术图像的绘画风格迁移到另外一幅普通图像中,从而能够生成一张带有特定艺术风格的普通图像,增加图像的艺术信息。

基于神经网络的风格迁移算法“A Neural Algorithm of Artistic Style”最早由Gatys等人在2015年提出,随后发表在了CVPR 2016上。斯坦福大学的Justin Johnson给出了Torch实现neural-style。除此之外,这篇文章的作者还建立了一个在线艺术风格迁移的网站deepart.io。

以下是采用VGG19做风格迁移后的图像:

原始图像

毕加索风格

风格迁移后的图像

2

 VGG19 

——

    简单介绍下VGG网络:VGG网络是很经典的模型,该模型网络结构简单,因证明了增加网络的深度能够在一定程度上影响网络的最终性能而出名。VGG网络包含卷积层、池化层、全连接层,最后连接一个softmax层。

    VGG网络结构如下图所示:

       D为前面文章中介绍过得VGG16的基本结构,可以看到,VGG16和VGG19的差别并不大。VGG19相比于VGG16,在第3、4和5段卷积中,都多了一层卷积层,加深了网络层数结构,目的是使得特征的提取更加充分。

VGG19网络的相关参数如下:

input: 224*224大小的RGB图像

filter: 3*3的卷积核

stride: 步长为1

padding: 1个像素,padding=’SAME’,保留边界处的卷积结果

maxpool: 窗口大小为2*2,步长为2。降低维度,提取图像到的主要特征

FC层:前两个是FC-4096,有4096个通道,第三个是FC-1000,有1000个通道

activate function:用Relu作为激活函数

——

3

VGG-19图像风格迁移相关原理 

——

    VGG图像迁移的基本思想如下:把风格、内容和迁移图像一起输入到VGG模型,风格和内容和图像是我们自己定义的。

 生成目标的损失函数是内容损失函数和风格损失函数的加权和,损失函数计算公式如下:

——

4

结果

——

    随机选取几幅图像进行风格迁移实验,结果如下:

原始图像

毕加索风格

风格迁移后的图像

原始图像

梵高风格

风格迁移后的图像

原始图像

齐白石风格

风格迁移后的图像

参考:

https://blog.csdn.net/aaronjny/article/details/79681080

http://www.imooc.com/article/details/id/32660

AI计算机视觉

为您提供更多视觉算法文章

长按扫码关注我们

VGG19图像风格迁移是一种通过深度学习实现图像风格转移的方法,其基于深度神经网络VGG19。其代码实现可以分为以下几步: 1. 导入必要的库:包括numpy、tensorflow等。 2. 加载预训练的VGG19模型:使用tensorflow的tf.keras.applications中的VGG19模型进行预训练。 3. 提取内容图片和风格图片的特征:使用预训练的VGG19模型提取内容图片和风格图片的特征。 4. 定义损失函数:将内容损失和风格损失加权求和作为总损失函数。 5. 使用优化器进行训练:通过梯度下降优化器来更新生成图片。 以下是简单的代码实现: ``` import numpy as np import tensorflow as tf from tensorflow.keras.applications import VGG19 from tensorflow.keras.preprocessing.image import load_img, img_to_array # 加载VGG19模型,去掉最后一层输出 vgg = VGG19(include_top=False, weights='imagenet') # 定义内容图片和风格图片的路径 content_path = 'content.jpg' style_path = 'style.jpg' # 加载图片并进行预处理 def load_and_process_img(path): img = load_img(path) img = img_to_array(img) img = np.expand_dims(img, axis=0) img = tf.keras.applications.vgg19.preprocess_input(img) return img # 提取内容图片和风格图片的特征 def get_feature_representations(model, content_path, style_path): content_image = load_and_process_img(content_path) style_image = load_and_process_img(style_path) content_feature_maps = model.predict(content_image) style_feature_maps = model.predict(style_image) return content_feature_maps, style_feature_maps # 计算Gram矩阵 def gram_matrix(input_tensor): channels = int(input_tensor.shape[-1]) a = tf.reshape(input_tensor, [-1, channels]) n = tf.shape(a) gram = tf.matmul(a, a, transpose_a=True) return gram / tf.cast(n, tf.float32) # 定义内容损失 def get_content_loss(base_content, target): return tf.reduce_mean(tf.square(base_content - target)) # 定义风格损失 def get_style_loss(base_style, gram_target): return tf.reduce_mean(tf.square(gram_matrix(base_style) - gram_target)) # 定义总损失函数 def compute_loss(model, loss_weights, init_image, gram_style_features, content_features): style_weight, content_weight = loss_weights model_outputs = model(init_image) style_output_features = model_outputs[:len(gram_style_features)] content_output_features = model_outputs[len(gram_style_features):] style_score = 0 content_score = 0 weight_per_style_layer = 1.0 / float(len(style_output_features)) for target_style, comb_style in zip(gram_style_features, style_output_features): style_score += weight_per_style_layer * get_style_loss(comb_style, target_style) weight_per_content_layer = 1.0 / float(len(content_output_features)) for target_content, comb_content in zip(content_features, content_output_features): content_score += weight_per_content_layer* get_content_loss(comb_content, target_content) style_score *= style_weight content_score *= content_weight loss = style_score + content_score return loss # 定义优化器 def run_style_transfer(content_path, style_path, num_iterations=1000, content_weight=1e3, style_weight=1e-2): # 提取内容图片和风格图片的特征 content_features, style_features = get_feature_representations(vgg, content_path, style_path) gram_style_features = [gram_matrix(feature) for feature in style_features] init_image = load_and_process_img(content_path) init_image = tf.Variable(init_image, dtype=tf.float32) opt = tf.optimizers.Adam(learning_rate=5, beta_1=0.99, epsilon=1e-1) # 定义损失权重 loss_weights = (style_weight, content_weight) # 进行训练 for i in range(num_iterations): with tf.GradientTape() as tape: loss = compute_loss(vgg, loss_weights, init_image, gram_style_features, content_features) grad = tape.gradient(loss, init_image) opt.apply_gradients([(grad, init_image)]) clipped = tf.clip_by_value(init_image, clip_value_min=0.0, clip_value_max=255.0) init_image.assign(clipped) return init_image.numpy() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值