Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

📚 The CoCalc Library - books, templates and other resources

132930 views
License: OTHER
1
""" An implementation of the paper "A Neural Algorithm of Artistic Style"
2
by Gatys et al. in TensorFlow.
3
4
Author: Chip Huyen ([email protected])
5
Prepared for the class CS 20SI: "TensorFlow for Deep Learning Research"
6
For more details, please read the assignment handout:
7
http://web.stanford.edu/class/cs20si/assignments/a2.pdf
8
"""
9
from __future__ import print_function
10
11
import os
12
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
13
import time
14
15
import numpy as np
16
import tensorflow as tf
17
18
import vgg_model
19
import utils
20
21
# parameters to manage experiments
22
STYLE = 'guernica'
23
CONTENT = 'deadpool'
24
STYLE_IMAGE = 'styles/' + STYLE + '.jpg'
25
CONTENT_IMAGE = 'content/' + CONTENT + '.jpg'
26
IMAGE_HEIGHT = 250
27
IMAGE_WIDTH = 333
28
NOISE_RATIO = 0.6 # percentage of weight of the noise for intermixing with the content image
29
30
# Layers used for style features. You can change this.
31
STYLE_LAYERS = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1']
32
W = [0.5, 1.0, 1.5, 3.0, 4.0] # give more weights to deeper layers.
33
34
# Layer used for content features. You can change this.
35
CONTENT_LAYER = 'conv4_2'
36
37
ITERS = 300
38
LR = 2.0
39
40
SAVE_EVERY = 20
41
42
MEAN_PIXELS = np.array([123.68, 116.779, 103.939]).reshape((1,1,1,3))
43
""" MEAN_PIXELS is defined according to description on their github:
44
https://gist.github.com/ksimonyan/211839e770f7b538e2d8
45
'In the paper, the model is denoted as the configuration D trained with scale jittering.
46
The input images should be zero-centered by mean pixel (rather than mean image) subtraction.
47
Namely, the following BGR values should be subtracted: [103.939, 116.779, 123.68].'
48
"""
49
50
# VGG-19 parameters file
51
VGG_DOWNLOAD_LINK = 'http://www.vlfeat.org/matconvnet/models/imagenet-vgg-verydeep-19.mat'
52
VGG_MODEL = 'imagenet-vgg-verydeep-19.mat'
53
EXPECTED_BYTES = 534904783
54
55
def _create_content_loss(p, f):
56
""" Calculate the loss between the feature representation of the
57
content image and the generated image.
58
59
Inputs:
60
p, f are just P, F in the paper
61
(read the assignment handout if you're confused)
62
Note: we won't use the coefficient 0.5 as defined in the paper
63
but the coefficient as defined in the assignment handout.
64
Output:
65
the content loss
66
67
"""
68
pass
69
70
def _gram_matrix(F, N, M):
71
""" Create and return the gram matrix for tensor F
72
Hint: you'll first have to reshape F
73
"""
74
pass
75
76
def _single_style_loss(a, g):
77
""" Calculate the style loss at a certain layer
78
Inputs:
79
a is the feature representation of the real image
80
g is the feature representation of the generated image
81
Output:
82
the style loss at a certain layer (which is E_l in the paper)
83
84
Hint: 1. you'll have to use the function _gram_matrix()
85
2. we'll use the same coefficient for style loss as in the paper
86
3. a and g are feature representation, not gram matrices
87
"""
88
pass
89
90
def _create_style_loss(A, model):
91
""" Return the total style loss
92
"""
93
n_layers = len(STYLE_LAYERS)
94
E = [_single_style_loss(A[i], model[STYLE_LAYERS[i]]) for i in range(n_layers)]
95
96
###############################
97
## TO DO: return total style loss
98
pass
99
###############################
100
101
def _create_losses(model, input_image, content_image, style_image):
102
with tf.variable_scope('loss') as scope:
103
with tf.Session() as sess:
104
sess.run(input_image.assign(content_image)) # assign content image to the input variable
105
p = sess.run(model[CONTENT_LAYER])
106
content_loss = _create_content_loss(p, model[CONTENT_LAYER])
107
108
with tf.Session() as sess:
109
sess.run(input_image.assign(style_image))
110
A = sess.run([model[layer_name] for layer_name in STYLE_LAYERS])
111
style_loss = _create_style_loss(A, model)
112
113
##########################################
114
## TO DO: create total loss.
115
## Hint: don't forget the content loss and style loss weights
116
117
##########################################
118
119
return content_loss, style_loss, total_loss
120
121
def _create_summary(model):
122
""" Create summary ops necessary
123
Hint: don't forget to merge them
124
"""
125
pass
126
127
def train(model, generated_image, initial_image):
128
""" Train your model.
129
Don't forget to create folders for checkpoints and outputs.
130
"""
131
skip_step = 1
132
with tf.Session() as sess:
133
saver = tf.train.Saver()
134
###############################
135
## TO DO:
136
## 1. initialize your variables
137
## 2. create writer to write your graph
138
###############################
139
sess.run(generated_image.assign(initial_image))
140
ckpt = tf.train.get_checkpoint_state(os.path.dirname('checkpoints/checkpoint'))
141
if ckpt and ckpt.model_checkpoint_path:
142
saver.restore(sess, ckpt.model_checkpoint_path)
143
initial_step = model['global_step'].eval()
144
145
start_time = time.time()
146
for index in range(initial_step, ITERS):
147
if index >= 5 and index < 20:
148
skip_step = 10
149
elif index >= 20:
150
skip_step = 20
151
152
sess.run(model['optimizer'])
153
if (index + 1) % skip_step == 0:
154
###############################
155
## TO DO: obtain generated image and loss
156
157
###############################
158
gen_image = gen_image + MEAN_PIXELS
159
writer.add_summary(summary, global_step=index)
160
print('Step {}\n Sum: {:5.1f}'.format(index + 1, np.sum(gen_image)))
161
print(' Loss: {:5.1f}'.format(total_loss))
162
print(' Time: {}'.format(time.time() - start_time))
163
start_time = time.time()
164
165
filename = 'outputs/%d.png' % (index)
166
utils.save_image(filename, gen_image)
167
168
if (index + 1) % SAVE_EVERY == 0:
169
saver.save(sess, 'checkpoints/style_transfer', index)
170
171
def main():
172
with tf.variable_scope('input') as scope:
173
# use variable instead of placeholder because we're training the intial image to make it
174
# look like both the content image and the style image
175
input_image = tf.Variable(np.zeros([1, IMAGE_HEIGHT, IMAGE_WIDTH, 3]), dtype=tf.float32)
176
177
utils.download(VGG_DOWNLOAD_LINK, VGG_MODEL, EXPECTED_BYTES)
178
utils.make_dir('checkpoints')
179
utils.make_dir('outputs')
180
model = vgg_model.load_vgg(VGG_MODEL, input_image)
181
model['global_step'] = tf.Variable(0, dtype=tf.int32, trainable=False, name='global_step')
182
183
content_image = utils.get_resized_image(CONTENT_IMAGE, IMAGE_HEIGHT, IMAGE_WIDTH)
184
content_image = content_image - MEAN_PIXELS
185
style_image = utils.get_resized_image(STYLE_IMAGE, IMAGE_HEIGHT, IMAGE_WIDTH)
186
style_image = style_image - MEAN_PIXELS
187
188
model['content_loss'], model['style_loss'], model['total_loss'] = _create_losses(model,
189
input_image, content_image, style_image)
190
###############################
191
## TO DO: create optimizer
192
## model['optimizer'] = ...
193
###############################
194
model['summary_op'] = _create_summary(model)
195
196
initial_image = utils.generate_noise_image(content_image, IMAGE_HEIGHT, IMAGE_WIDTH, NOISE_RATIO)
197
train(model, input_image, initial_image)
198
199
if __name__ == '__main__':
200
main()
201
202