Tensorflow tf.用于汇集错误结果的梯度?

Tensorflow tf.用于汇集错误结果的梯度?,tensorflow,Tensorflow,我在tensorflow中遇到了一个问题,tf.gradients应用于池: [编辑]:通过将等式更改为: gradpooltest, = tf.gradients((pooltest * pooltest)/2 , [x1]) 无论如何,我不知道为什么我必须这样做,下面回答的人似乎不理解我的问题 input x1: [[ 0. 0. 0. 0. 0. 0.] [ 0. 2. 2. 2. 0. 0.] [ 0. -2. 0. 0. 2. 1.] [ 0. 1

我在tensorflow中遇到了一个问题,tf.gradients应用于池:

[编辑]:通过将等式更改为:

gradpooltest, = tf.gradients((pooltest * pooltest)/2 , [x1])
无论如何,我不知道为什么我必须这样做,下面回答的人似乎不理解我的问题

input x1:
[[ 0.  0.  0.  0.  0.  0.]
 [ 0.  2.  2.  2.  0.  0.]
 [ 0. -2.  0.  0.  2.  1.]
 [ 0.  1.  0.  1.  2.  2.]
 [ 0.  1.  1.  2.  0.  1.]
 [ 0. -2.  2.  1. -1.  1.]]
pooling test forward:
[[ 2.  2.  0.]
 [ 1.  1.  2.]
 [ 1.  2.  1.]]
 tf.gradients pool test backward:
[[ 0.  0.  0.  0.  1.  0.]
 [ 0.  1.  1.  0.  0.  0.]
 [ 0.  0.  0.  0.  1.  0.]
 [ 0.  1.  0.  1.  0.  0.]
 [ 0.  1.  0.  1.  0.  1.]
 [ 0.  0.  0.  0.  0.  0.]]
but I expect actually this result by  tf.gradients pool test backward:
 0     0     0     0     0     0
 0     2     2     0     0     0
 0     0     0     0     2     0
 0     1     0     1     0     0
 0     1     0     0     0     1
 0     0     2     0     0     0
我不明白tf.gradients池测试的tf结果。(看起来tensorflow只返回位置的存储矩阵??)。知道tf为什么不返回实际的上采样结果吗

这是我的密码:

import numpy as np
import tensorflow as tf
sess = tf.Session()

#init input-----------------------------------------------------------
init1=np.array([ [0,0,0,0,0,0],
                 [0,2,2,2,0,0],
                 [0,-2,0,0,2,1],
                 [0,1,0,1,2,2],
                 [0,1,1,2,0,1],
                 [0,-2,2,1,-1,1] ],dtype="float32")           
init2 = init1.reshape(1,6,6,1)
x1 = tf.Variable(init2)               
#init weight-----------------------------------------------------------
init3 = np.array( [[[[3, 5], [2, -1]]]], dtype="float32")
init4 = init3.reshape(2,2,1,1)
w1 = tf.Variable(init4) 

#init model-----------------------------------------------------------
model = tf.initialize_all_variables()
sess.run(model)

#print values-----------------------------------------------------------
print('x1:')
#print sess.run(x6)
x1y = tf.reshape(x1, [6, 6])
print sess.run(x1y)

###################################
#ff: pooling
################################### 
#needs 4D volumes as inputs:
pooltest = tf.nn.max_pool(x1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
print('pooltest:')
#print sess.run(pooltest)
pooltesty = tf.reshape(pooltest, [3, 3])
print sess.run(pooltesty)

###################################
#bw: pooling 
################################### 
#needs 4D volumes as inputs:
gradpooltest, = tf.gradients(pooltest , [x1])
print('gradpooltest:')
#print sess.run(gradpooltest)
gradpooltesty = tf.reshape(gradpooltest, [6, 6])
print sess.run(gradpooltesty)

sess.close()

您正在计算maxpool操作的梯度,这是正确的-最大值为1,其他位置为0


请参阅以下页面:

想象一下您的最大池操作,内核大小为
2x2
,实现方式如下:

max(x1, x2, x3, x4)
其中,
x1,…,x4
是内核下输入图像中的位置

在向前传递中,提取最大值,例如:

max(x1, x2, x3, x4) = x2
这意味着对于这4个变量,在正向传递中,只有
x2
变量将通过网络传递

因此,在反向过程中,只有一个变量可以计算导数,其导数为
1


因此,您得到的输出是正确的,您期望的是不正确的。

查看@dm0的链接。max gate是一个路由器。也许你把relu和pooling混在一起了??唯一的方法是让梯度通过一个输入流,然后把它放到其他地方。让它保持不变的唯一方法是将梯度(来自计算图的以下节点)乘以1检查输入为0的位置。。。(4个零)右上角。tf显示1为梯度,这是错误的,您的答案一定是错误的。对不起,不,它是正确的。0和0之间的最大值是多少?tf作者决定选择第一个值,而不是返回一个未定义的值(因为在数学中max(x,x)=未定义)。因此,梯度将流经该输入位置的第一个单元格。我们是否同意0的梯度=0?最大值(0,0)=0?如果是这种情况,则只有0的渐变链接回右上角的2x2窗口。这是一个0.2从“添加”门路由,“最大”门路由它不变到它的一个输入,所以最大门的梯度所以“最大”门的梯度在最大位置是1,在其他位置是0。(抱歉单独评论,找不到编辑我以前评论的方法)是的,所以很明显你的答案是错误的。请参见红色2,路由到z仍然是2,因为“*2”节点才是2。如果没有“*2”节点,“z”的梯度为1。