赞
踩
掌握如何使用Tensorflow实现风格迁移算法的训练
- #encoding=utf-8
- import tensorflow as tf, pdb
-
- WEIGHTS_INIT_STDEV = .1
-
- def net(image, type=0):
- # 该函数构建图像转换网络,image 为步骤 1 中读入的图像 ndarray 阵列,返回最后一层的输出结果
- # TODO:构建图像转换网络,每一层的输出作为下一层的输入
- conv1 = _conv_layer(image, 32, 9, 1, type) #default relu=True and type=0(use BN)
- conv2 = _conv_layer(conv1, 64 ,3, 2, type)
- conv3 = _conv_layer(conv2, 128 ,3, 2, type)
- # print(conv1.get_shape())
- # print(conv2.get_shape())
- # print(conv3.get_shape())
- # pdb.set_trace()
- residual1 = _residual_block(conv3, 3, type=1)
- residual2 = _residual_block(residual1, 3, type=1)
- residual3 = _residual_block(residual2, 3, type=1)
- residual4 = _residual_block(residual3, 3, type=1)
- residual5 = _residual_block(residual4, 3, type=1)
-
- conv_transpose1 = _conv_tranpose_layer(residual5, 64, 3, 2)
- conv_transpose2 = _conv_tranpose_layer(conv_transpose1, 32, 3, 2)
-
- conv4 = _conv_layer(conv_transpose2, 3, 9, 1)
-
- #TODO:最后一个卷积层的输出再经过 tanh 函数处理,最后的输出张量 preds 像素值需限定在 [0,255] 范围内
- preds = (tf.nn.tanh(conv4) + 1) * 255./2
- return preds
-
- def _conv_layer(net, num_filters, filter_size, strides, relu=True, type=0):
- # 该函数定义了卷积层的计算方法,net 为该卷积层的输入 ndarray 数组,num_filters 表示输出通道数,filter_size 表示卷积核尺
- # 寸,strides 表示卷积步长,该函数最后返回卷积层计算的结果
-
- # TODO:准备好权重的初值
- weights_init = _conv_init_vars(net, num_filters, filter_size) #weights shape: [k, k, cin, cout]
-
- # TODO:输入的 strides 参数为标量,需将其处理成卷积函数能够使用的数据形式
- strides_shape = [1] + list([strides]) * 2 + [1]
-
- # TODO:进行卷积计算
- net = tf.nn.conv2d(net, weights_init, strides=strides_shape, padding='SAME') + \
- tf.Variable(tf.zeros([num_filters], dtype=tf.float32)) #bias
-
- # 对卷积计算结果进行批归一化处理
- if type == 0:
- net = _batch_norm(net)
- elif type == 1:
- net = _instance_norm(net)
-
- if relu:
- # TODO:对归一化结果进行 ReLU 操作
- net = tf.nn.relu(net)
-
- return net
-
- def _conv_tranpose_layer(net, num_filters, filter_size, strides, type=0):
- #referrence to https://blog.csdn.net/baidu_33216040/article/details/102575278
- # TODO:准备好权重的初值
- weights_init = _conv_init_vars(net, num_filters, filter_size, transpose=True) #weights shape: [k, k, num_filters, cin]
- batch, rows, cols, channels = [i.value for i in net.get_shape()]
- # handmade mode: see more from experiment document
- # #1.flat InputData to: [batchsize, width*height, channel]
- # batch, rows, cols, channels = [i.value for i in net.get_shape()] #net shape: [batchsize, width, height, channel]
- # net = tf.reshape(net, [batch, rows*cols, -1])
- # #2. k*k kernel to (rows*cols, square((rows-1)*s+k))
- # #4.y = W.T * x
-
- # TODO:输入的 num_filters、strides 参数为标量,需将其处理成转置卷积函数能够使用的数据形式
- strides_shape = [1] + list([strides]) * 2 + [1]
- # output_shape = [batch] + list((rows-1)*strides+filter_size)* 2 + [num_filters] #padding = VALID
- new_shape = [batch, rows*strides, cols*strides, num_filters] #padding = SAME #only 2
-
- # if tf.__version__.startswith('0.1'):
- # output_shape = tf.pack(new_shape)
- # else:
- output_shape = tf.stack(new_shape)
- # TODO:进行转置卷积计算
- net = tf.nn.conv2d_transpose(net, weights_init, output_shape, strides_shape, padding='SAME') + \
- tf.Variable(tf.zeros([num_filters], dtype=tf.float32)) #bias
-
- # 对卷积计算结果进行批归一化处理
- if type == 0:
- net = _batch_norm(net)
- elif type == 1:
- net = _instance_norm(net)
-
- # TODO:对归一化结果进行 ReLU 操作
- net = tf.nn.relu(net)
-
- return net
-
- def _residual_block(net, filter_size=3, type=0):
- # TODO:调用之前实现的卷积层函数,实现残差块的计算
- #在该网络中,残差层的卷积核个数为128, strids=1;且网络未改变输出通道数(可采用1*1卷积改通道数)
- x_shape = net.get_shape()
- tmp = _conv_layer(net, 128, filter_size, 1, True) #conv1 + relu
- fx = _conv_layer(tmp, 128, filter_size, 1) #conv2
- fx_shape = fx.get_shape()
- assert x_shape[1] == fx_shape[1] and x_shape[2] == fx_shape[2], "x_shape[1] = %d, fx_shape[1] = %d" % (x_shape[1].value, fx_shape[1].value)
- #todo
- if not(x_shape[1] == fx_shape[1] and x_shape[2] == fx_shape[2]):#feature size改变,通过补零的方式
- pass
- net = tf.nn.relu(net+fx)
- return net
-
- def _batch_norm(net, train=True):
- batch, rows, cols, channels = [i.value for i in net.get_shape()]
- axes=list(range(len(net.get_shape())-1))
- mu, sigma_sq = tf.nn.moments(net, axes, keep_dims=True)
- var_shape = [channels]
- shift = tf.Variable(tf.zeros(var_shape)) #learnable parameter
- scale = tf.Variable(tf.ones(var_shape))
- epsilon = 1e-3
- return tf.nn.batch_normalization(net, mu, sigma_sq, shift, scale, epsilon)
-
- def _instance_norm(net, train=True):
- batch, rows, cols, channels = [i.value for i in net.get_shape()]
- var_shape = [channels]
- mu, sigma_sq = tf.nn.moments(net, [1,2], keep_dims=True)
- shift = tf.Variable(tf.zeros(var_shape))
- scale = tf.Variable(tf.ones(var_shape))
- epsilon = 1e-3
- normalized = (net-mu)/(sigma_sq + epsilon)**(.5)
- return scale * normalized + shift
-
- def _conv_init_vars(net, out_channels, filter_size, transpose=False):
- _, rows, cols, in_channels = [i.value for i in net.get_shape()]
- if not transpose:
- weights_shape = [filter_size, filter_size, in_channels, out_channels]
- else:
- weights_shape = [filter_size, filter_size, out_channels, in_channels]
-
- weights_init = tf.Variable(tf.truncated_normal(weights_shape, stddev=WEIGHTS_INIT_STDEV, seed=1), dtype=tf.float32)
- return weights_init
-
- # net(tf.placeholder(tf.float32, shape=[1, 336, 336, 3]))

- #encoding=utf-8
- # Copyright (c) 2015-2016 Anish Athalye. Released under GPLv3.
-
- import tensorflow as tf
- import numpy as np
- import scipy.io
- import pdb
-
- MEAN_PIXEL = np.array([ 123.68 , 116.779, 103.939])
-
- def net(data_path, input_image):
- layers = (
- 'conv1_1', 'relu1_1', 'conv1_2', 'relu1_2', 'pool1',
-
- 'conv2_1', 'relu2_1', 'conv2_2', 'relu2_2', 'pool2',
-
- 'conv3_1', 'relu3_1', 'conv3_2', 'relu3_2', 'conv3_3',
- 'relu3_3', 'conv3_4', 'relu3_4', 'pool3',
-
- 'conv4_1', 'relu4_1', 'conv4_2', 'relu4_2', 'conv4_3',
- 'relu4_3', 'conv4_4', 'relu4_4', 'pool4',
-
- 'conv5_1', 'relu5_1', 'conv5_2', 'relu5_2', 'conv5_3',
- 'relu5_3', 'conv5_4', 'relu5_4'
- )
-
- data = scipy.io.loadmat(data_path)
- mean = data['normalization'][0][0][0]
- mean_pixel = np.mean(mean, axis=(0, 1))
- weights = data['layers'][0]
-
- net = {}
- current = input_image
- for i, name in enumerate(layers):
- kind = name[:4]
- if kind == 'conv':
- # TODO:如果当前层为卷积层,则进行卷积计算,计算结果为 current
- kernels, bias = weights[i][0][0][0][0]
- kernels = np.transpose(kernels, [1,0,2,3])
- bias = bias.reshape(-1)
- current = _conv_layer(current, kernels, bias)
- elif kind == 'relu':
- # TODO:如果当前层为 ReLU 层,则进行 ReLU 计算,计算结果为 current
- current = tf.nn.relu(current)
- elif kind == 'pool':
- # TODO:如果当前层为池化层,则进行最大池化计算,计算结果为 current
- current = _pool_layer(current)
- net[name] = current
-
- assert len(net) == len(layers)
- return net
-
-
- def _conv_layer(input, weights, bias):
- conv = tf.nn.conv2d(input, tf.constant(weights), strides=(1, 1, 1, 1),
- padding='SAME')
- return tf.nn.bias_add(conv, bias)
-
-
- def _pool_layer(input):
- return tf.nn.max_pool(input, ksize=(1, 2, 2, 1), strides=(1, 2, 2, 1),
- padding='SAME')
-
-
- def preprocess(image):
- return image - MEAN_PIXEL
-
-
- def unprocess(image):
- return image + MEAN_PIXEL

- #encoding=utf-8
- from __future__ import print_function
- import functools
- import vgg, pdb, time
- import tensorflow as tf, numpy as np, os
- import transform
- from utils import get_img
-
- STYLE_LAYERS = ('relu1_1', 'relu2_1', 'relu3_1', 'relu4_1', 'relu5_1')
- CONTENT_LAYER = 'relu4_2'
- DEVICES = '/cpu:0' #'CUDA_VISIBLE_DEVICES'
-
- os.putenv('MLU_VISIBLE_DEVICES','')
-
- def loss_function(net, content_features, style_features, content_weight, style_weight, tv_weight, preds, batch_size):
- # 损失函数构建,net 为特征提取网络,content_features 为内容图像特征,style_features 为风格图像特征,content_weight、
- # style_weight 和 tv_weight 分别为特征重建损失、风格重建损失的权重和全变分正则化损失的权重
-
- batch_shape = (batch_size,256,256,3)
-
- # 计算内容损失
- # content_loss
- content_size = _tensor_size(content_features[CONTENT_LAYER])*batch_size
- assert _tensor_size(content_features[CONTENT_LAYER]) == _tensor_size(net[CONTENT_LAYER])
- content_loss = (1.0 / (4*content_size)) * tf.reduce_sum(tf.pow(net[CONTENT_LAYER]-content_features[CONTENT_LAYER], 2)) * content_weight
-
- # 计算风格损失
- # style_loss
- style_losses = []
- for style_layer in STYLE_LAYERS:
- layer = net[style_layer]
- bs, height, width, filters = map(lambda i:i.value,layer.get_shape())
- size = height * width * filters
- feats = tf.reshape(layer, (bs, height * width, filters))
- feats_T = tf.transpose(feats, perm=[0,2,1])
- grams = tf.matmul(feats_T, feats) / size
- style_gram = style_features[style_layer]
- # TODO: 计算 style_losses
- style_losses.append((1.0 / (4 * bs ** 2 * size ** 2)) * tf.reduce_sum(tf.pow(style_gram-grams, 2)) * style_weight)
- style_loss = style_weight * functools.reduce(tf.add, style_losses) / batch_size
-
- # 使用全变分正则化方法定义损失函数 tv_loss
- # tv_loss
- tv_y_size = _tensor_size(preds[:,1:,:,:])
- tv_x_size = _tensor_size(preds[:,:,1:,:])
- # TODO:将图像 preds 向水平和垂直方向各平移一个像素,分别与原图相减,分别计算二者的 声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/101386推荐阅读
相关标签
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。