Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

📚 The CoCalc Library - books, templates and other resources

132928 views
License: OTHER
1
import os
2
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
3
import time
4
5
import numpy as np
6
import tensorflow as tf
7
8
import load_vgg_sol
9
import utils
10
11
def setup():
12
utils.safe_mkdir('checkpoints')
13
utils.safe_mkdir('outputs')
14
15
class StyleTransfer(object):
16
def __init__(self, content_img, style_img, img_width, img_height):
17
'''
18
img_width and img_height are the dimensions we expect from the generated image.
19
We will resize input content image and input style image to match this dimension.
20
Feel free to alter any hyperparameter here and see how it affects your training.
21
'''
22
self.img_width = img_width
23
self.img_height = img_height
24
self.content_img = utils.get_resized_image(content_img, img_width, img_height)
25
self.style_img = utils.get_resized_image(style_img, img_width, img_height)
26
self.initial_img = utils.generate_noise_image(self.content_img, img_width, img_height)
27
28
###############################
29
## TO DO
30
## create global step (gstep) and hyperparameters for the model
31
self.content_layer = 'conv4_2'
32
self.style_layers = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1']
33
self.content_w = 0.01
34
self.style_w = 1
35
self.style_layer_w = [0.5, 1.0, 1.5, 3.0, 4.0]
36
self.gstep = tf.Variable(0, dtype=tf.int32,
37
trainable=False, name='global_step')
38
self.lr = 2.0
39
###############################
40
41
def create_input(self):
42
'''
43
We will use one input_img as a placeholder for the content image,
44
style image, and generated image, because:
45
1. they have the same dimension
46
2. we have to extract the same set of features from them
47
We use a variable instead of a placeholder because we're, at the same time,
48
training the generated image to get the desirable result.
49
50
Note: image height corresponds to number of rows, not columns.
51
'''
52
with tf.variable_scope('input') as scope:
53
self.input_img = tf.get_variable('in_img',
54
shape=([1, self.img_height, self.img_width, 3]),
55
dtype=tf.float32,
56
initializer=tf.zeros_initializer())
57
def load_vgg(self):
58
'''
59
Load the saved model parameters of VGG-19, using the input_img
60
as the input to compute the output at each layer of vgg.
61
62
During training, VGG-19 mean-centered all images and found the mean pixels
63
to be [123.68, 116.779, 103.939] along RGB dimensions. We have to subtract
64
this mean from our images.
65
66
'''
67
self.vgg = load_vgg_sol.VGG(self.input_img)
68
self.vgg.load()
69
self.content_img -= self.vgg.mean_pixels
70
self.style_img -= self.vgg.mean_pixels
71
72
def _content_loss(self, P, F):
73
''' Calculate the loss between the feature representation of the
74
content image and the generated image.
75
76
Inputs:
77
P: content representation of the content image
78
F: content representation of the generated image
79
Read the assignment handout for more details
80
81
Note: Don't use the coefficient 0.5 as defined in the paper.
82
Use the coefficient defined in the assignment handout.
83
'''
84
# self.content_loss = None
85
###############################
86
## TO DO
87
self.content_loss = tf.reduce_sum((F - P) ** 2) / (4.0 * P.size)
88
###############################
89
90
def _gram_matrix(self, F, N, M):
91
""" Create and return the gram matrix for tensor F
92
Hint: you'll first have to reshape F
93
"""
94
###############################
95
## TO DO
96
F = tf.reshape(F, (M, N))
97
return tf.matmul(tf.transpose(F), F)
98
###############################
99
100
def _single_style_loss(self, a, g):
101
""" Calculate the style loss at a certain layer
102
Inputs:
103
a is the feature representation of the style image at that layer
104
g is the feature representation of the generated image at that layer
105
Output:
106
the style loss at a certain layer (which is E_l in the paper)
107
108
Hint: 1. you'll have to use the function _gram_matrix()
109
2. we'll use the same coefficient for style loss as in the paper
110
3. a and g are feature representation, not gram matrices
111
"""
112
###############################
113
## TO DO
114
N = a.shape[3] # number of filters
115
M = a.shape[1] * a.shape[2] # height times width of the feature map
116
A = self._gram_matrix(a, N, M)
117
G = self._gram_matrix(g, N, M)
118
return tf.reduce_sum((G - A) ** 2 / ((2 * N * M) ** 2))
119
###############################
120
121
def _style_loss(self, A):
122
""" Calculate the total style loss as a weighted sum
123
of style losses at all style layers
124
Hint: you'll have to use _single_style_loss()
125
"""
126
n_layers = len(A)
127
E = [self._single_style_loss(A[i], getattr(self.vgg, self.style_layers[i])) for i in range(n_layers)]
128
129
###############################
130
## TO DO
131
self.style_loss = sum([self.style_layer_w[i] * E[i] for i in range(n_layers)])
132
###############################
133
134
def losses(self):
135
with tf.variable_scope('losses') as scope:
136
with tf.Session() as sess:
137
# assign content image to the input variable
138
sess.run(self.input_img.assign(self.content_img))
139
gen_img_content = getattr(self.vgg, self.content_layer)
140
content_img_content = sess.run(gen_img_content)
141
self._content_loss(content_img_content, gen_img_content)
142
143
with tf.Session() as sess:
144
sess.run(self.input_img.assign(self.style_img))
145
style_layers = sess.run([getattr(self.vgg, layer) for layer in self.style_layers])
146
self._style_loss(style_layers)
147
148
##########################################
149
## TO DO: create total loss.
150
## Hint: don't forget the weights for the content loss and style loss
151
self.total_loss = self.content_w * self.content_loss + self.style_w * self.style_loss
152
##########################################
153
154
def optimize(self):
155
###############################
156
## TO DO: create optimizer
157
self.opt = tf.train.AdamOptimizer(self.lr).minimize(self.total_loss,
158
global_step=self.gstep)
159
###############################
160
161
def create_summary(self):
162
###############################
163
## TO DO: create summaries for all the losses
164
## Hint: don't forget to merge them
165
with tf.name_scope('summaries'):
166
tf.summary.scalar('content loss', self.content_loss)
167
tf.summary.scalar('style loss', self.style_loss)
168
tf.summary.scalar('total loss', self.total_loss)
169
self.summary_op = tf.summary.merge_all()
170
###############################
171
172
173
def build(self):
174
self.create_input()
175
self.load_vgg()
176
self.losses()
177
self.optimize()
178
self.create_summary()
179
180
def train(self, n_iters):
181
skip_step = 1
182
with tf.Session() as sess:
183
184
###############################
185
## TO DO:
186
## 1. initialize your variables
187
## 2. create writer to write your graph
188
sess.run(tf.global_variables_initializer())
189
writer = tf.summary.FileWriter('graphs/style_stranfer', sess.graph)
190
###############################
191
sess.run(self.input_img.assign(self.initial_img))
192
193
194
###############################
195
## TO DO:
196
## 1. create a saver object
197
## 2. check if a checkpoint exists, restore the variables
198
saver = tf.train.Saver()
199
ckpt = tf.train.get_checkpoint_state(os.path.dirname('checkpoints/style_transfer/checkpoint'))
200
if ckpt and ckpt.model_checkpoint_path:
201
saver.restore(sess, ckpt.model_checkpoint_path)
202
##############################
203
204
initial_step = self.gstep.eval()
205
206
start_time = time.time()
207
for index in range(initial_step, n_iters):
208
if index >= 5 and index < 20:
209
skip_step = 10
210
elif index >= 20:
211
skip_step = 20
212
213
sess.run(self.opt)
214
if (index + 1) % skip_step == 0:
215
###############################
216
## TO DO: obtain generated image, loss, and summary
217
gen_image, total_loss, summary = sess.run([self.input_img,
218
self.total_loss,
219
self.summary_op])
220
221
###############################
222
223
# add back the mean pixels we subtracted before
224
gen_image = gen_image + self.vgg.mean_pixels
225
writer.add_summary(summary, global_step=index)
226
print('Step {}\n Sum: {:5.1f}'.format(index + 1, np.sum(gen_image)))
227
print(' Loss: {:5.1f}'.format(total_loss))
228
print(' Took: {} seconds'.format(time.time() - start_time))
229
start_time = time.time()
230
231
filename = 'outputs/%d.png' % (index)
232
utils.save_image(filename, gen_image)
233
234
if (index + 1) % 20 == 0:
235
###############################
236
## TO DO: save the variables into a checkpoint
237
saver.save(sess, 'checkpoints/style_stranfer/style_transfer', index)
238
###############################
239
240
if __name__ == '__main__':
241
setup()
242
machine = StyleTransfer('content/deadpool.jpg', 'styles/guernica.jpg', 333, 250)
243
machine.build()
244
machine.train(300)
245