# TensorFlow中的样式传输解释和实例

## 神经样式转移算法的工作

### 需要图书馆

``````import tensorflow as tf
#we transform and models because we will modify our images and we will use pre-trained model VGG-19
from torchvision import transforms, models  from PIL
import Image
import matplotlib.pyplot as plt
import numpy as np``````

## VGG-19模型

VGG-19型号类似于VGG-16型号。 Simonyan和Zisserman介绍了VGG模型。 VGG-19接受了ImageNet数据库中超过一百万张图像的培训。该模型具有19层深度神经网络, 可以将图像分类为1000个对象类别。

### 高层架构

• 内容图片(c)-我们要将样式转移到的图片
• 样式图像-我们要从中移动方法的图像
• 输入图像(g)-包含最终结果的图像。

## 下载并加载相关的VGG-16

#### 注意：我们必须尝试更多层。但是请注意我们的CPU和GPU的内存限制。

``````# This function takes in a file path to the file containing weights
# and an integer that denotes how many layers to be loaded.

### 定义功能以建立样式转移网络

• 内容图片(tf.placeholder)
• 样式图片(tf.placeholder)
• 生成的图像(tf.Variable and Trainable = True)
• 预先训练的体重和偏见(tf.Variable and Trainable = False)

``````def define_inputs (input_shape):
"""
This function defines the inputs (placeholders) and image to be generated (variable)
"""
content = tf.placeholder(name='content' , shape=input_shape, dtype=tf.float32)
style= tf.placeholder(name='style', shape=input_shape, dtype=tf.float32)
generated= tf.get_variable(name='generated', initializer=tf.random_normal_initalizer=tf.random_normal_initiallizer(), shape=input_shape, dtype=tf.float32, trainable=true)
return {'content':content, 'style, 'generated': generated}
def define_tf_weights():
"""
This function defines the tensorflow variables for VGG weights and biases
"""
for k, w_dict in vgg_layers.items():
w, b=w_dict['weights'], w_dict['bias']
with tf.variable_scope(k):
tf.get_variable(name='weights', initializer=tf.constant(w, dtype=tf.float32), trainable=false)
tf.get_variable(name='bias', initializer=tf.constant(b, dtype=tf.float32), trainable=False)``````

### 计算VGG净输出

``````Computing the VGG net output
Def build_vggnet(inp, layer_ids, pool_inds, on_cpu=False):
"This function computes the output of full VGG net """
outputs = OrderedDict()

out = inp

for lid in layer_ids:
with tf.variable_scope(lid, reuse=tf.AUTO_REUSE):
print('Computing outputs for the layer {}'.format(lid))
w, b = tf.get_variable('weights'), tf.get_variable('bias')
out = tf.nn.conv2d(filter=w, input=out, strides=[1, 1, 1, 1], padding='SAME')
outputs[lid] = out

if lid in pool_inds:
with tf.name_scope(lid.replace('conv', 'pool')):
out = tf.nn.avg_pool(input=out, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
outputs[lid.replace('conv', 'pool')] = out

return outputs``````

### 内容丢失背后的直觉

``````def define_content_loss(inputs, layer_ids, pool_inds, c_weight):
c_outputs= build_vggnet (inputs ["content"], layer_ids, pool_inds)
g_outputs= build_vggnet (inputs ["generated"], layer_ids, pool_inds)
content_loss= c_weight * tf.reduce_mean(0.5*(list(c_outputs.values())[-1]-list(g_outputs.values())[-1])**2)``````

### 风格失落的直觉

``````def define_style_matrix(layer_out):
"""
This function computes the style matrix, which essentially computes
how correlated the activations of a given filter to all the other filers.
Therefore, if there are C channels, the matrix will be of size C x C
"""
n_channels = layer_out.get_shape().as_list()[-1]
unwrapped_out = tf.reshape(layer_out, [-1, n_channels])
style_matrix = tf.matmul(unwrapped_out, unwrapped_out, transpose_a=True)
return style_matrix

def define_style_loss(inputs, layer_ids, pool_inds, s_weight, layer_weights=None):
"""
This function computes the style loss using the style matrix computed for
the style image and the generated image
"""
c_outputs = build_vggnet(inputs["style"], layer_ids, pool_inds)
g_outputs = build_vggnet(inputs["generated"], layer_ids, pool_inds)

c_grams = [define_style_matrix(v) for v in list(c_outputs.values())]
g_grams = [define_style_matrix(v) for v in list(g_outputs.values())]

if layer_weights is None:
style_loss =  s_weight * \
tf.reduce_sum([(1.0/len(layer_ids)) * tf.reduce_mean((c - g)**2) for c, g in zip(c_grams, g_grams)])
else:
style_loss = s_weight * \``````

• 回顶