我想推荐这篇清晰的文章:CS231n Convolutional Neural Networks for Visual Recognition,让我将(简化的)香草网络与(简化的)残差网络进行比较,如下所示。
这是我从该页面借来的图表:
其中线条上方的绿色数字表示正向传递,红色数字表示反向传递(初始梯度为 1)。
让我们通过在某处添加一个残差来做一点改变来得到这个:
其中线条上方的蓝色数字表示正向传递,线条下方的红色数字表示反向传递(初始梯度为 1)。
这是最后一个示例的代码:
# use tensorflow 1.12
x = tf.Variable(3, name='x', dtype=tf.float32)
y = tf.Variable(-4, name='y', dtype=tf.float32)
z = tf.Variable(2, name='z', dtype=tf.float32)
w = tf.Variable(-1, name='w', dtype=tf.float32)
x_multiply_y = tf.math.multiply(x, y, name="x_multiply_y")
z_max_w = tf.math.maximum(z, w, name="z_max_w")
xy_plus_zw = tf.math.add(z_max_w, x_multiply_y, name="xy_plus_zw")
residual_op = tf.math.add(x_multiply_y, xy_plus_zw, name="residual_op")
multiply_2 = tf.math.multiply(residual_op, 2, name="multiply_2")
# to make sure that the last gradient is 1 we make the cost 1
cost = multiply_2 + 45
optimizer = tf.train.AdamOptimizer()
variables = tf.trainable_variables()
all_ops = variables + [x_multiply_y, z_max_w, xy_plus_zw, residual_op, multiply_2]
gradients = optimizer.compute_gradients(cost, all_ops)
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
variables = [g[1] for g in gradients]
gradients = [g[0] for g in gradients]
gradients = sess.run(gradients)
for var, gdt in zip(variables, gradients):
print(var.name, "\t", gdt)
# the results are here:
# x:0 -16.0
# y:0 12.0
# z:0 2.0
# w:0 0.0
# x_multiply_y:0 4.0
# z_max_w:0 2.0
# xy_plus_zw:0 2.0
# residual_op:0 2.0
# multiply_2:0 1.0
我们可以看到梯度是从不同来源累积的。
HTH。