反向传播如何在tensorflow中工作
在tensorflow中,整个反向传播算法似乎是由一个优化器在某个代价函数上运行一次来执行的,该代价函数是某个MLP或CNN的输出 我不完全理解tensorflow如何从成本中知道它确实是某个NN的输出?可以为任何模型定义成本函数。我应该如何“告诉”它某个成本函数来自NN?问题 我应该如何“告诉”tf某个成本函数来自NN (简短)回答 这可以通过简单地配置优化器来最小化(或最大化)张量来实现。例如,如果我有这样一个损失函数反向传播如何在tensorflow中工作,tensorflow,Tensorflow,在tensorflow中,整个反向传播算法似乎是由一个优化器在某个代价函数上运行一次来执行的,该代价函数是某个MLP或CNN的输出 我不完全理解tensorflow如何从成本中知道它确实是某个NN的输出?可以为任何模型定义成本函数。我应该如何“告诉”它某个成本函数来自NN?问题 我应该如何“告诉”tf某个成本函数来自NN (简短)回答 这可以通过简单地配置优化器来最小化(或最大化)张量来实现。例如,如果我有这样一个损失函数 loss = tf.reduce_sum( tf.square( y0
loss = tf.reduce_sum( tf.square( y0 - y_out ) )
train = tf.train.GradientDescentOptimizer(1.0).minimize(loss)
如果y0是基本事实(或期望输出),y_out是计算输出,那么我可以通过这样定义我的训练函数来最小化损失
loss = tf.reduce_sum( tf.square( y0 - y_out ) )
train = tf.train.GradientDescentOptimizer(1.0).minimize(loss)
这告诉Tensorflow,当计算train时,将对损失应用梯度下降以使其最小化,并使用y0和y_out计算损失,因此梯度下降也将影响这些(如果它们是可训练变量),依此类推
变量y0、y_out、loss和train不是标准python变量,而是计算图的描述。Tensorflow在应用梯度下降时使用有关该计算图的信息展开它
具体来说,它是如何做到这一点的,超出了本答案的范围。这是关于更多细节的更多信息的两个很好的起点
代码示例
让我们浏览一个代码示例。首先是代码
### 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 = tf.reduce_sum( tf.square( y0 - y_out ) )
要计算此tensorflow,必须计算损失的自动微分,这意味着在图形中行走损失定义为
train = tf.train.GradientDescentOptimizer(1.0).minimize(loss)
loss = tf.reduce_sum( tf.square( y0 - y_out ) )
这是真正的tensorflow应用自动微分首先展开tf。减少,然后tf.square,然后y0-y u,这导致必须遍历y0和y 0的图形
y0 = tf.constant( y_ , dtype=tf.float32 )
y0是一个常量,不会被更新
y_out = tf.sigmoid( tf.matmul( h1,m2 ) + b2 )
y\u out的处理方法与loss类似,首先tf。乙状结肠将被处理,等等
总之,每个操作(如tf.sigmoid、tf.square)不仅定义正向操作(应用sigmoid或square),还定义自动微分所需的信息。这与标准python数学不同,例如
x = 7 + 9
上面的等式除了如何更新x之外,没有任何编码,其中
z = y0 - y_out
对从y0中减去y_的图形进行编码,并将正向操作和足够的数据存储在z中。该图由Rumelhart和Hinton等人创建,并于1986年出版
如第节所述,有两种通过计算图实现反向传播梯度的方法:符号到数字的微分和符号到符号的导数。如本文所述,与Tensorflow更相关的是后者,可使用此图进行说明:
资料来源:报告第二节D部分
在上面图7的左侧,w表示Tensorflow中的权重(或变量),x和y是获得标量损失z的两个中间操作(或节点,w、x、y和z都是操作)
Tensorflow将向每个节点添加一个节点(如果我们在某个检查点中打印变量名称,我们可以看到这些节点的一些附加变量,如果我们将模型冻结到协议缓冲区文件中进行部署,这些变量将被消除),在图中的梯度可以在右侧的图(b)中看到:dz/dy,dy/dx,dx/dw
在每个节点的反向传播遍历过程中,我们将其梯度与前一个节点的梯度相乘,最后得到整体目标导数dz/dw=dz/dy*dy/dx*dx/dw的符号句柄,它完全适用于链规则。一旦计算出梯度,w就可以用学习率来更新自己
有关更多详细信息,请阅读本文:您应该了解DL库的工作原理,特别是图形计算。tldr:代价函数是图上的一个节点,边(权重)来自网络的最后一层。这非常有用!谢谢。我在其他网站上找不到这种信息。他们只是用指令演示代码,而没有解释代码背后的情况。你能在网站上推荐我对TF有更深入的解释吗?这也解释了这种独特的编程范式背后的合理性。不幸的是,不是。我没有读到任何东西。我是如何更好地理解的是,我为自己做了一个小的学习课程,然后就做了。这里是链接:我实际上做了我在自述中写的事情。几周来,每天大约要花一个小时的时间才能达到4级——在没有作弊的情况下独自应对所有挑战。当我达到4级独奏时,Tensorflow感觉非常自然,尽管我只做了一些小例子。