简介
本文介绍为什么代码能够实现风格迁移的功能,重点在优化对象.
地址
我的重点
- tensorflow中,怎么定制自己的求导函数,而不是使用优化器的minimize
- tf.train.Optimizer.minimize的minimize包含了什么
- opt.compute_gradients(loss, list_of_variables])
- opt.apply_gradients(grads_and_vars, global_step=global_step,
name=name)
解析
- 由于tf.train.Optimizer.minimize会自动求导并将导数*学习率应用到网络的所有权重上
这与A Neural Algorithm of Artistic Style的目的不合
因此作者不使用minimize函数,而是自己求导数,并且自己将导数只应用到自己想要的地方,也就是最终的生成图 - 由于 minimize其实包含了
compute_gradients
(求结果相对于某数的导数)与apply_gradients
(将导数应用到某数上),
因此只需要更改这两个函数即可. - 作者首先计算loss函数,也就是
α
∗
L
c
o
n
t
e
n
t
+
β
∗
L
s
t
y
l
e
\alpha*L_{content}+\beta*L_{style}
α∗Lcontent+β∗Lstyle.
然后使用tf.gradient(total_loss, cfg['init_image'])
计算loss对于初始化图像的导数,
最后将导数以及学习率应用到初始化的图像上,用来不断改变初始化的图像,使其更加接近目标
使用的函数为opt.apply_gradients([(grads, init_image)])
,将导数应用到初始化图像上. - 计算梯度使用
tf.gradient
函数
def compute_grads(cfg):
with tf.GradientTape() as tape:
all_loss = compute_loss(**cfg)
# Compute gradients wrt input image
total_loss = all_loss[0]
return tape.gradient(total_loss, cfg['init_image']), all_loss
- 应用梯度使用
opt.apply_gradients
函数
opt.apply_gradients([(grads, init_image)])
clipped = tf.clip_by_value(init_image, min_vals, max_vals)
init_image.assign(clipped)
拓展
tf.gradients(loss, tf.variables)
函数与computer_gradients(loss, val_list)
函数相似,只是后者会返回这个时候被求导数的那个变量此时的值.- 例子
import tensorflow as tf
with tf.Graph().as_default():
x = tf.Variable(initial_value=3., dtype='float32')
w = tf.Variable(initial_value=4., dtype='float32')
y = w*x
grads = tf.gradients(y, [w])
opt = tf.train.GradientDescentOptimizer(0.1)
grads_vals = opt.compute_gradients(y, [w])
sess=tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(grads))
print(sess.run(grads_vals))
- 结果为
>> [3.0]
[(3.0, 4.0)]