📚 The CoCalc Library - books, templates and other resources
cocalc-examples / stanford-tensorflow-tutorials / 2017 / assignments / style_transfer_starter / style_transfer.py
132930 viewsLicense: OTHER
""" An implementation of the paper "A Neural Algorithm of Artistic Style"1by 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"""8from __future__ import print_function910import os11os.environ['TF_CPP_MIN_LOG_LEVEL']='2'12import time1314import numpy as np15import tensorflow as tf1617import vgg_model18import utils1920# parameters to manage experiments21STYLE = 'guernica'22CONTENT = 'deadpool'23STYLE_IMAGE = 'styles/' + STYLE + '.jpg'24CONTENT_IMAGE = 'content/' + CONTENT + '.jpg'25IMAGE_HEIGHT = 25026IMAGE_WIDTH = 33327NOISE_RATIO = 0.6 # percentage of weight of the noise for intermixing with the content image2829# Layers used for style features. You can change this.30STYLE_LAYERS = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1']31W = [0.5, 1.0, 1.5, 3.0, 4.0] # give more weights to deeper layers.3233# Layer used for content features. You can change this.34CONTENT_LAYER = 'conv4_2'3536ITERS = 30037LR = 2.03839SAVE_EVERY = 204041MEAN_PIXELS = np.array([123.68, 116.779, 103.939]).reshape((1,1,1,3))42""" MEAN_PIXELS is defined according to description on their github:43https://gist.github.com/ksimonyan/211839e770f7b538e2d844'In the paper, the model is denoted as the configuration D trained with scale jittering.45The input images should be zero-centered by mean pixel (rather than mean image) subtraction.46Namely, the following BGR values should be subtracted: [103.939, 116.779, 123.68].'47"""4849# VGG-19 parameters file50VGG_DOWNLOAD_LINK = 'http://www.vlfeat.org/matconvnet/models/imagenet-vgg-verydeep-19.mat'51VGG_MODEL = 'imagenet-vgg-verydeep-19.mat'52EXPECTED_BYTES = 5349047835354def _create_content_loss(p, f):55""" Calculate the loss between the feature representation of the56content image and the generated image.5758Inputs:59p, f are just P, F in the paper60(read the assignment handout if you're confused)61Note: we won't use the coefficient 0.5 as defined in the paper62but the coefficient as defined in the assignment handout.63Output:64the content loss6566"""67pass6869def _gram_matrix(F, N, M):70""" Create and return the gram matrix for tensor F71Hint: you'll first have to reshape F72"""73pass7475def _single_style_loss(a, g):76""" Calculate the style loss at a certain layer77Inputs:78a is the feature representation of the real image79g is the feature representation of the generated image80Output:81the style loss at a certain layer (which is E_l in the paper)8283Hint: 1. you'll have to use the function _gram_matrix()842. we'll use the same coefficient for style loss as in the paper853. a and g are feature representation, not gram matrices86"""87pass8889def _create_style_loss(A, model):90""" Return the total style loss91"""92n_layers = len(STYLE_LAYERS)93E = [_single_style_loss(A[i], model[STYLE_LAYERS[i]]) for i in range(n_layers)]9495###############################96## TO DO: return total style loss97pass98###############################99100def _create_losses(model, input_image, content_image, style_image):101with tf.variable_scope('loss') as scope:102with tf.Session() as sess:103sess.run(input_image.assign(content_image)) # assign content image to the input variable104p = sess.run(model[CONTENT_LAYER])105content_loss = _create_content_loss(p, model[CONTENT_LAYER])106107with tf.Session() as sess:108sess.run(input_image.assign(style_image))109A = sess.run([model[layer_name] for layer_name in STYLE_LAYERS])110style_loss = _create_style_loss(A, model)111112##########################################113## TO DO: create total loss.114## Hint: don't forget the content loss and style loss weights115116##########################################117118return content_loss, style_loss, total_loss119120def _create_summary(model):121""" Create summary ops necessary122Hint: don't forget to merge them123"""124pass125126def train(model, generated_image, initial_image):127""" Train your model.128Don't forget to create folders for checkpoints and outputs.129"""130skip_step = 1131with tf.Session() as sess:132saver = tf.train.Saver()133###############################134## TO DO:135## 1. initialize your variables136## 2. create writer to write your graph137###############################138sess.run(generated_image.assign(initial_image))139ckpt = tf.train.get_checkpoint_state(os.path.dirname('checkpoints/checkpoint'))140if ckpt and ckpt.model_checkpoint_path:141saver.restore(sess, ckpt.model_checkpoint_path)142initial_step = model['global_step'].eval()143144start_time = time.time()145for index in range(initial_step, ITERS):146if index >= 5 and index < 20:147skip_step = 10148elif index >= 20:149skip_step = 20150151sess.run(model['optimizer'])152if (index + 1) % skip_step == 0:153###############################154## TO DO: obtain generated image and loss155156###############################157gen_image = gen_image + MEAN_PIXELS158writer.add_summary(summary, global_step=index)159print('Step {}\n Sum: {:5.1f}'.format(index + 1, np.sum(gen_image)))160print(' Loss: {:5.1f}'.format(total_loss))161print(' Time: {}'.format(time.time() - start_time))162start_time = time.time()163164filename = 'outputs/%d.png' % (index)165utils.save_image(filename, gen_image)166167if (index + 1) % SAVE_EVERY == 0:168saver.save(sess, 'checkpoints/style_transfer', index)169170def main():171with tf.variable_scope('input') as scope:172# use variable instead of placeholder because we're training the intial image to make it173# look like both the content image and the style image174input_image = tf.Variable(np.zeros([1, IMAGE_HEIGHT, IMAGE_WIDTH, 3]), dtype=tf.float32)175176utils.download(VGG_DOWNLOAD_LINK, VGG_MODEL, EXPECTED_BYTES)177utils.make_dir('checkpoints')178utils.make_dir('outputs')179model = vgg_model.load_vgg(VGG_MODEL, input_image)180model['global_step'] = tf.Variable(0, dtype=tf.int32, trainable=False, name='global_step')181182content_image = utils.get_resized_image(CONTENT_IMAGE, IMAGE_HEIGHT, IMAGE_WIDTH)183content_image = content_image - MEAN_PIXELS184style_image = utils.get_resized_image(STYLE_IMAGE, IMAGE_HEIGHT, IMAGE_WIDTH)185style_image = style_image - MEAN_PIXELS186187model['content_loss'], model['style_loss'], model['total_loss'] = _create_losses(model,188input_image, content_image, style_image)189###############################190## TO DO: create optimizer191## model['optimizer'] = ...192###############################193model['summary_op'] = _create_summary(model)194195initial_image = utils.generate_noise_image(content_image, IMAGE_HEIGHT, IMAGE_WIDTH, NOISE_RATIO)196train(model, input_image, initial_image)197198if __name__ == '__main__':199main()200201202