【问题标题】:How do backpropagation works in tensorflow反向传播如何在张量流中工作
【发布时间】:2019-08-30 23:40:13
【问题描述】:

在 tensorflow 中,整个反向传播算法似乎是通过优化器在某个成本函数上的单次运行来执行的,该成本函数是一些 MLP 或 CNN 的输出。

我不完全明白 tensorflow 如何从成本中知道它确实是某个 NN 的输出?可以为任何模型定义成本函数。我应该如何“告诉”它某个成本函数源自 NN?

【问题讨论】:

  • 您应该了解 DL 库的工作原理,特别是图计算。 tldr:成本函数是图上的一个节点,边(权重)来自网络的最后一层。

标签: tensorflow


【解决方案1】:

问题

我应该如何“告诉” tf 某个成本函数源自 NN?

(简短)回答

这可以通过简单地配置优化器来最小化(或最大化)张量来完成。例如,如果我有这样的损失函数

loss = tf.reduce_sum( tf.square( y0 - y_out ) )

其中 y0 是 ground truth(或期望的输出),y_out 是计算的输出,然后我可以通过像这样定义我的训练函数来最小化损失

train = tf.train.GradientDescentOptimizer(1.0).minimize(loss)

这告诉Tensorflow,在计算train时,是对loss应用梯度下降来最小化它,而loss是使用y0和y_out计算的,所以梯度下降也会影响那些(如果它们是可训练的变量)等等。

变量 y0y_outlosstrain 不是标准的 Python 变量,而是描述计算图。 Tensorflow 在应用梯度下降时使用有关该计算图的信息来展开它。

具体如何做到这一点超出了这个答案的范围。 Herehere 是了解更多细节的两个很好的起点。

代码示例

让我们来看一个代码示例。首先是代码。

### imports
import tensorflow as tf

### constant data
x  = [[0.,0.],[1.,1.],[1.,0.],[0.,1.]]
y_ = [[0.],[0.],[1.],[1.]]

### induction
# 1x2 input -> 2x3 hidden sigmoid -> 3x1 sigmoid output

# Layer 0 = the x2 inputs
x0 = tf.constant( x  , dtype=tf.float32 )
y0 = tf.constant( y_ , dtype=tf.float32 )

# Layer 1 = the 2x3 hidden sigmoid
m1 = tf.Variable( tf.random_uniform( [2,3] , minval=0.1 , maxval=0.9 , dtype=tf.float32  ))
b1 = tf.Variable( tf.random_uniform( [3]   , minval=0.1 , maxval=0.9 , dtype=tf.float32  ))
h1 = tf.sigmoid( tf.matmul( x0,m1 ) + b1 )

# Layer 2 = the 3x1 sigmoid output
m2 = tf.Variable( tf.random_uniform( [3,1] , minval=0.1 , maxval=0.9 , dtype=tf.float32  ))
b2 = tf.Variable( tf.random_uniform( [1]   , minval=0.1 , maxval=0.9 , dtype=tf.float32  ))
y_out = tf.sigmoid( tf.matmul( h1,m2 ) + b2 )


### loss
# loss : sum of the squares of y0 - y_out
loss = tf.reduce_sum( tf.square( y0 - y_out ) )

# training step : gradient decent (1.0) to minimize loss
train = tf.train.GradientDescentOptimizer(1.0).minimize(loss)


### training
# run 500 times using all the X and Y
# print out the loss and any other interesting info
with tf.Session() as sess:
  sess.run( tf.global_variables_initializer() )
  for step in range(500) :
    sess.run(train)

  results = sess.run([m1,b1,m2,b2,y_out,loss])
  labels  = "m1,b1,m2,b2,y_out,loss".split(",")
  for label,result in zip(*(labels,results)) :
    print ""
    print label
    print result

print ""

让我们来看看它,但是以相反的顺序开始

sess.run(train)

这告诉 tensorflow 查找由 train 定义的图节点并计算它。 火车定义为

train = tf.train.GradientDescentOptimizer(1.0).minimize(loss)

要计算这个张量流必须计算loss自动微分,这意味着走图。 损失定义为

loss = tf.reduce_sum( tf.square( y0 - y_out ) )

真正的 tensorflow 应用 自动微分 首先展开 tf.reduce_sum,然后是 tf.square,然后是 y0 - y_out ,这导致必须同时遍历 y0 和 y_out 的图形。

y0 = tf.constant( y_ , dtype=tf.float32 )

y0 是一个常数,不会被更新。

y_out = tf.sigmoid( tf.matmul( h1,m2 ) + b2 )

y_out会像loss一样被处理,首先tf.sigmoid会被处理,以此类推……

总而言之,每个操作(例如 tf.sigmoid、tf.square )不仅定义了前向操作(应用 sigmoid 或 square ),还定义了自动微分所需的信息。这与标准 python 数学不同,例如

x = 7 + 9

上面的等式除了如何更新 x 之外什么都不编码,其中为

z = y0 - y_out

对从 y0 减去 y_out 的图形进行编码,并将前向运算和足以在 z

中进行自动微分的操作存储起来

【讨论】:

  • 这很有帮助!非常感谢。我在其他网站上找不到此类信息。他们只是用指令来演示代码,而不解释它背后发生了什么。你能在网站上推荐我对 TF 有更深入的解释吗?这个地方也解释了这种独特的编程范式背后的合理性。
  • 很遗憾没有。我没有读过任何东西。我如何更好地理解是,我为自己做了一个小型学习课程,然后做了。这是链接:github.com/panchishin/learn-to-tensorflow 我实际上做了我在自述文件中写的。在没有作弊的情况下,每天大约需要一个小时才能达到 Level 4 - Solo 的所有挑战。当我达到 Level 4 - Solo 后,即使我只是通过一些小例子工作,Tensorflow 也感觉非常自然。
【解决方案2】:

backpropagation 由 Rumelhart 和 Hinton 等人创建,并于 1986 年发布on Nature

正如deeplearning book6.5: Back-Propagation and Other DifferentiationAlgorithms 部分所述,通过计算图反向传播梯度有两种类型的方法:符号到数字的微分和符号到符号的导数。如本文所述,与 Tensorflow 更相关的一个:A Tour of TensorFlow 是后者,可以使用此图说明:

来源:A Tour of TensorFlow 的第二部分 D 部分

在上图 7 的左侧,w 表示 Tensorflow 中的权重(或变量),x 和 y 是两个中间操作(或节点,w、x、y 和 z 都是操作)来得到标量损失 z。

Tensorflow 将为每个节点添加一个节点(如果我们在某个检查点打印变量的名称,我们可以看到这些节点的一些额外变量,如果我们将模型冻结到协议缓冲区文件以进行部署,它们将被消除)在右侧图 (b) 中可以看到的梯度图中:dz/dy、dy/dx、dx/dw。

在每个节点的反向传播的遍历过程中,我们将其梯度与前一个节点的梯度相乘,最后得到一个符号句柄,用于整体目标导数 dz/dw = dz/dy * dy/dx * dx/dw ,这完全适用于链式法则。计算出梯度后,w 可以使用学习率进行自我更新。

更多详细信息请阅读本文:TensorFlow: Large-Scale Machine Learning on Heterogeneous Distributed Systems

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 2017-10-31
    • 2017-09-19
    相关资源
    最近更新 更多