📚 The CoCalc Library - books, templates and other resources
cocalc-examples / stanford-tensorflow-tutorials / 2017 / assignments / style_transfer / vgg_model.py
132937 viewsLicense: OTHER
""" Load VGGNet weights needed for the implementation of the paper1"A Neural Algorithm of Artistic Style" by Gatys et al. in TensorFlow.23Author: Chip Huyen ([email protected])4Prepared for the class CS 20SI: "TensorFlow for Deep Learning Research"5For more details, please read the assignment handout:6http://web.stanford.edu/class/cs20si/assignments/a2.pdf7"""89import numpy as np10import tensorflow as tf11import scipy.io1213def _weights(vgg_layers, layer, expected_layer_name):14""" Return the weights and biases already trained by VGG15"""16W = vgg_layers[0][layer][0][0][2][0][0]17b = vgg_layers[0][layer][0][0][2][0][1]18layer_name = vgg_layers[0][layer][0][0][0][0]19assert layer_name == expected_layer_name20return W, b.reshape(b.size)2122def _conv2d_relu(vgg_layers, prev_layer, layer, layer_name):23""" Return the Conv2D layer with RELU using the weights, biases from the VGG24model at 'layer'.25Inputs:26vgg_layers: holding all the layers of VGGNet27prev_layer: the output tensor from the previous layer28layer: the index to current layer in vgg_layers29layer_name: the string that is the name of the current layer.30It's used to specify variable_scope.3132Output:33relu applied on the convolution.3435Note that you first need to obtain W and b from vgg-layers using the function36_weights() defined above.37W and b returned from _weights() are numpy arrays, so you have38to convert them to TF tensors using tf.constant.39Note that you'll have to do apply relu on the convolution.40Hint for choosing strides size:41for small images, you probably don't want to skip any pixel42"""43with tf.variable_scope(layer_name) as scope:44W, b = _weights(vgg_layers, layer, layer_name)45W = tf.constant(W, name='weights')46b = tf.constant(b, name='bias')47conv2d = tf.nn.conv2d(prev_layer, filter=W, strides=[1, 1, 1, 1], padding='SAME')48return tf.nn.relu(conv2d + b)4950def _avgpool(prev_layer):51""" Return the average pooling layer. The paper suggests that average pooling52actually works better than max pooling.53Input:54prev_layer: the output tensor from the previous layer5556Output:57the output of the tf.nn.avg_pool() function.58Hint for choosing strides and kszie: choose what you feel appropriate59"""60return tf.nn.avg_pool(prev_layer, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],61padding='SAME', name='avg_pool_')6263def load_vgg(path, input_image):64""" Load VGG into a TensorFlow model.65Use a dictionary to hold the model instead of using a Python class66"""67vgg = scipy.io.loadmat(path)68vgg_layers = vgg['layers']6970graph = {}71graph['conv1_1'] = _conv2d_relu(vgg_layers, input_image, 0, 'conv1_1')72graph['conv1_2'] = _conv2d_relu(vgg_layers, graph['conv1_1'], 2, 'conv1_2')73graph['avgpool1'] = _avgpool(graph['conv1_2'])74graph['conv2_1'] = _conv2d_relu(vgg_layers, graph['avgpool1'], 5, 'conv2_1')75graph['conv2_2'] = _conv2d_relu(vgg_layers, graph['conv2_1'], 7, 'conv2_2')76graph['avgpool2'] = _avgpool(graph['conv2_2'])77graph['conv3_1'] = _conv2d_relu(vgg_layers, graph['avgpool2'], 10, 'conv3_1')78graph['conv3_2'] = _conv2d_relu(vgg_layers, graph['conv3_1'], 12, 'conv3_2')79graph['conv3_3'] = _conv2d_relu(vgg_layers, graph['conv3_2'], 14, 'conv3_3')80graph['conv3_4'] = _conv2d_relu(vgg_layers, graph['conv3_3'], 16, 'conv3_4')81graph['avgpool3'] = _avgpool(graph['conv3_4'])82graph['conv4_1'] = _conv2d_relu(vgg_layers, graph['avgpool3'], 19, 'conv4_1')83graph['conv4_2'] = _conv2d_relu(vgg_layers, graph['conv4_1'], 21, 'conv4_2')84graph['conv4_3'] = _conv2d_relu(vgg_layers, graph['conv4_2'], 23, 'conv4_3')85graph['conv4_4'] = _conv2d_relu(vgg_layers, graph['conv4_3'], 25, 'conv4_4')86graph['avgpool4'] = _avgpool(graph['conv4_4'])87graph['conv5_1'] = _conv2d_relu(vgg_layers, graph['avgpool4'], 28, 'conv5_1')88graph['conv5_2'] = _conv2d_relu(vgg_layers, graph['conv5_1'], 30, 'conv5_2')89graph['conv5_3'] = _conv2d_relu(vgg_layers, graph['conv5_2'], 32, 'conv5_3')90graph['conv5_4'] = _conv2d_relu(vgg_layers, graph['conv5_3'], 34, 'conv5_4')91graph['avgpool5'] = _avgpool(graph['conv5_4'])9293return graph9495