Neural Style
Neural Style
April 9, 2019
1
1.2 Features
1.2.1 Preprocessing and Postprocessing
In [4]: rgb_mean = nd.array([0.485, 0.456, 0.406])
rgb_std = nd.array([0.229, 0.224, 0.225])
def postprocess(img):
img = img[0].as_in_context(rgb_std.context)
return (img.transpose((1, 2, 0)) * rgb_std + rgb_mean).clip(0, 1)
net = nn.Sequential()
for i in range(max(content_layers + style_layers) + 1):
net.add(pretrained_net.features[i])
2
styles = []
for i in range(len(net)):
X = net[i](X)
if i in style_layers:
styles.append(X)
if i in content_layers:
contents.append(X)
return contents, styles
3
def compute_loss(X, contents_Y_hat, styles_Y_hat, contents_Y, styles_Y_gram):
contents_l = [content_loss(Y_hat, Y) * content_weight for Y_hat, Y in zip(
contents_Y_hat, contents_Y)]
styles_l = [style_loss(Y_hat, Y) * style_weight for Y_hat, Y in zip(
styles_Y_hat, styles_Y_gram)]
tv_l = tv_loss(X) * tv_weight
l = nd.add_n(*styles_l) + nd.add_n(*contents_l) + tv_l
return contents_l, styles_l, tv_l, l
def forward(self):
return self.weight.data()
1.4.1 Initialize
In [13]: def get_inits(X, ctx, lr, styles_Y):
gen_img = GeneratedImage(X.shape)
gen_img.initialize(init.Constant(X), ctx=ctx, force_reinit=True)
trainer = gluon.Trainer(gen_img.collect_params(), 'sgd',
{'learning_rate': lr})
styles_Y_gram = [gram(Y) for Y in styles_Y]
return gen_img(), styles_Y_gram, trainer
1.5 Train
In [14]: def train(X, contents_Y, styles_Y, ctx, lr, max_epochs, lr_decay_epoch):
X, styles_Y_gram, trainer = get_inits(X, ctx, lr, styles_Y)
for i in range(max_epochs):
start = time.time()
with autograd.record():
contents_Y_hat, styles_Y_hat = extract_features(
X, content_layers, style_layers)
contents_l, styles_l, tv_l, l = compute_loss(
X, contents_Y_hat, styles_Y_hat, contents_Y, styles_Y_gram)
l.backward()
trainer.step(1)
nd.waitall()
if i % 50 == 0 and i != 0:
print('epoch %3d, content loss %.2f, style loss %.2f, '
'TV loss %.2f, %.2f sec'
% (i, nd.add_n(*contents_l).asscalar(),
nd.add_n(*styles_l).asscalar(), tv_l.asscalar(),
4
time.time() - start))
if i % lr_decay_epoch == 0 and i != 0:
trainer.set_learning_rate(trainer.learning_rate * 0.1)
print('change lr to %.1e' % trainer.learning_rate)
return X
epoch 50, content loss 7.12, style loss 14.02, TV loss 3.26, 0.05 sec
epoch 100, content loss 5.50, style loss 9.55, TV loss 3.41, 0.05 sec
epoch 150, content loss 5.04, style loss 7.49, TV loss 3.49, 0.05 sec
epoch 200, content loss 4.69, style loss 6.57, TV loss 3.54, 0.05 sec
change lr to 5.0e-01
epoch 250, content loss 4.47, style loss 6.40, TV loss 3.54, 0.05 sec
epoch 300, content loss 4.43, style loss 6.32, TV loss 3.54, 0.05 sec
epoch 350, content loss 4.40, style loss 6.25, TV loss 3.54, 0.05 sec
epoch 400, content loss 4.37, style loss 6.19, TV loss 3.54, 0.05 sec
change lr to 5.0e-02
epoch 450, content loss 4.36, style loss 6.18, TV loss 3.54, 0.05 sec
5
1.5.2 Visualize
epoch 50, content loss 20.51, style loss 43.77, TV loss 0.74, 0.93 sec
epoch 100, content loss 17.54, style loss 31.44, TV loss 0.77, 1.00 sec
change lr to 1.0e-01
epoch 150, content loss 17.29, style loss 30.58, TV loss 0.77, 1.16 sec
epoch 200, content loss 17.09, style loss 29.90, TV loss 0.77, 0.95 sec
change lr to 1.0e-02
epoch 250, content loss 17.07, style loss 29.83, TV loss 0.78, 1.00 sec