我正在按照Tensorflow MNIST教程进行学习。
在阅读理论/直觉部分时,我理解输入x
是一个列矩阵。
事实上,在描述softmax
时,x
被展示为一个列矩阵:
然而,在tensorflow
中,x的声明如下:
x = tf.placeholder(tf.float32, [None, 784])
我理解这表示x
是一个可变长度的数组(None),其中每个元素都是一个大小为784的列矩阵。
尽管x
被声明为列矩阵的数组,但在使用时却像是单个列矩阵:
y = tf.nn.softmax(tf.matmul(x, W) + b)
在示例中,W
和b
的声明符合直觉,分别是形状为[784, 10]
和[10]
的变量,这也是合理的。
我的问题是:
-
Tensorflow是否会自动对x中的每个列矩阵执行softmax操作?
-
我假设[None, value]意味着一个可变大小的数组,每个元素都是大小为value的数组,这种理解正确吗?还是[None, value]也可能仅仅表示一个大小为value的数组(不包含在容器数组中)?
-
如何正确地将理论描述中x作为列向量的部分与实现中x作为列矩阵数组的部分联系起来?
感谢您的帮助!
回答:
直觉上是针对单个输入样本的(这就是为什么你看到一个列向量)。然而,实际操作中,训练是使用mini-batch进行的,这包含了多个输入样本(取决于batch_size
)。
x = tf.placeholder(tf.float32, [None, 784])
这一行创建了一个维度为? x 784
的矩阵,其中?
表示批次大小。从某种意义上说,列向量变成了这个新矩阵的行。
由于我们将列向量转换成了行,我们交换了x
和W
的乘法顺序。这就是为什么你的W
的维度是784 x 10
,而b
的维度是10
,它将应用于所有元素。第一次乘法后,x*W
的维度为? x 10
。相同的元素b
被添加到x*W
的每一行中。所以如果我的x*W
的第一行为[1,2,3,4,5,6,7,8,9,0]
,而b
为[1,1,1,1,1,1,1,1,1,1]
,结果的第一行将是[2,3,4,5,6,7,8,9,10,1]
。如果你觉得这很难理解,尝试取W*x
的转置。
关于你的问题,
Tensorflow是否会自动对x中的每个列矩阵执行softmax操作?
是的,在你的上下文中。TensorFlow对维度1
的所有元素(以上我解释的所有行)应用softmax
。所以你的softmax
结果也将具有维度? x 10
。
我假设[None, value]意味着一个可变大小的数组,每个元素都是大小为value的数组,这种理解正确吗?还是[None, value]也可能仅仅表示一个大小为value的数组(不包含在容器数组中)?
是的,前者是正确的解释。还请参考我上面的?
矩阵类比。
如何正确地将理论描述中x作为列向量的部分与实现中x作为列矩阵数组的部分联系起来?
我个人将此解释为W*x
的转置。详细来说,假设x
是一组列向量,[x1 x2 x3 x4 x5 ...]
,维度为784 x ?
,其中?
是批次大小。假设W
的维度为10 x 784
。如果你对每个列应用W
,你将得到[W*x1 W*x2 W*x3...]
或是一组维度为10
的列向量,总矩阵维度为10 x ?
。
将整个操作转置,trans(W*x) = trans(x)*trans(W)
,这些就是你代码中的x
和W
。