Style Loss:
- def compute_style_loss(style_features_t, style_layers,net):
- style_loss = 0
- for style_gram, layer in zip(style_features_t, style_layers):
- generated_images, _ = tf.split(0, 2, net[layer])
- size = tf.size(generated_images)
- for style_image in style_gram:
- style_loss += tf.nn.l2_loss(tf.reduce_sum(gram(generated_images) - style_image, 0)) / tf.to_float(size)
- style_loss = style_loss / len(style_layers)
- return style_loss
gram:
- def gram(layer):
- shape = tf.shape(layer)
- num_images = shape[0]
- num_filters = shape[3]
- size = tf.size(layer)
- filters = tf.reshape(layer, tf.pack([num_images, -1, num_filters]))
- grams = tf.batch_matmul(filters, filters, adj_x=True) / tf.to_float(size / FLAGS.BATCH_SIZE)
- return grams
在trainfast_neural_style.py main()中,net, = http://vgg.net(FLAGS.VGG_PATH, tf.concat(0, [generated, images]))这部分有点疑问,按我的想法来说应该分别把generated、images作为input给到http://vgg.net,然后在后面去计算与content image 和style的loss,但是这里是直接首先把generated和原来的content images先concat by axis=0(具体可以查下tf.concat)然后在输出进行tf.split得到对应网络的输出,这个很有意思,想想CNN在做卷积的时候某个位置的值只与周围相关,共享weight之后,该层彼此之间不相关(可能在generated和image之间就边缘地方有些许pixels的影响,基本可以忽略,我的解释可能就是这样,有其他更合理的解释的小伙伴,请在本文下方留言),这个技巧感觉挺有用的,以后写相关代码的时候可以采纳。
后记
代码图像生成效果不是很好,我怀疑是content和 style之间的weight大小的关系,还有就是可能是epoch数大小的问题,之后我会好好改下权重,看看能不能有点比较好的结果。
—试过好多不同的版本,fast neural style确实效果要差一点。