TF-搞不懂的TF矩阵加法

本文深入解析了在TensorFlow中卷积神经网络的卷积层后加偏置量的操作,通过具体代码示例和测试,解释了不同维度的张量如何进行加法运算,揭示了张量广播机制在卷积神经网络中的应用。

看谷歌的demo mnist,卷积后加偏执量的代码

h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

其中的x_image的维数是[-1, 28, 28, 1],W_conv1的维数是[5, 5, 1, 32], b的维数是[32]

conv2d对x_image和W_conv1进行卷积,结果为[-1, 28, 28, 32],结果就是:

[-1, 28, 28, 32]和[32]的加法。

完全搞不清为什么[-1, 28, 28, 32]和[32]两个完全不同维数可以做加法?而且加出的结果还是[-1, 28, 28, 32]?

于是做了下面的测试:

sess = tf.InteractiveSession()
test1 = tf.ones([1,2,2,3],tf.float32)
b1 = tf.ones([3])
re1 = test1 + b1
print("shap3={},eval=\n{}".format(b1.shape, b1.eval()))
print("shap4={},eval=\n{}".format(test1.shape, test1.eval()))
print("shap5={},eval=\n{}".format(re1.shape, re1.eval()))

test1 = tf.ones([1,2,2,3],tf.float32)
b1 = tf.ones([1,1,1,1])
re1 = test1 + b1
print("shap6={},eval=\n{}".format(b1.shape, b1.eval()))
print("shap7={},eval=\n{}".format(test1.shape, test1.eval()))
print("shap8={},eval=\n{}".format(re1.shape, re1.eval()))

test1 = tf.ones([1,2,2,3],tf.float32)
b1 = tf.ones([1,1,1,3])
re1 = test1 + b1
print("shap9 ={},eval=\n{}".format(b1.shape, b1.eval()))
print("shap10={},eval=\n{}".format(test1.shape, test1.eval()))
print("shap11={},eval=\n{}".format(re1.shape, re1.eval()))

test1 = tf.ones([1,2,2,3],tf.float32)
b1 = tf.ones([1])
re1 = test1 + b1
print("shap12={},eval=\n{}".format(b1.shape, b1.eval()))
print("shap13={},eval=\n{}".format(test1.shape, test1.eval()))
print("shap14={},eval=\n{}".format(re1.shape, re1.eval()))

test1 = tf.ones([1,2,2,3],tf.float32)
alist = [[[[ 1, 1, 1.],
[ 0, 0, 0.]],
[[ 1, 1, 1.],
[ 0, 0, 0.]]]]
b1 = tf.constant(alist)
re1 = test1 + b1
print("shap15={},eval=\n{}".format(b1.shape, b1.eval()))
print("shap16={},eval=\n{}".format(test1.shape, test1.eval()))
print("shap17={},eval=\n{}".format(re1.shape, re1.eval()))

结果为

shap3=(3,),eval=
[ 1.  1.  1.]
shap4=(1, 2, 2, 3),eval=
[[[[ 1.  1.  1.]
   [ 1.  1.  1.]]

  [[ 1.  1.  1.]
   [ 1.  1.  1.]]]]
shap5=(1, 2, 2, 3),eval=
[[[[ 2.  2.  2.]
   [ 2.  2.  2.]]

  [[ 2.  2.  2.]
   [ 2.  2.  2.]]]]
shap6=(1, 1, 1, 1),eval=
[[[[ 1.]]]]
shap7=(1, 2, 2, 3),eval=
[[[[ 1.  1.  1.]
   [ 1.  1.  1.]]

  [[ 1.  1.  1.]
   [ 1.  1.  1.]]]]
shap8=(1, 2, 2, 3),eval=
[[[[ 2.  2.  2.]
   [ 2.  2.  2.]]

  [[ 2.  2.  2.]
   [ 2.  2.  2.]]]]
shap9 =(1, 1, 1, 3),eval=
[[[[ 1.  1.  1.]]]]
shap10=(1, 2, 2, 3),eval=
[[[[ 1.  1.  1.]
   [ 1.  1.  1.]]

  [[ 1.  1.  1.]
   [ 1.  1.  1.]]]]
shap11=(1, 2, 2, 3),eval=
[[[[ 2.  2.  2.]
   [ 2.  2.  2.]]

  [[ 2.  2.  2.]
   [ 2.  2.  2.]]]]
shap12=(1,),eval=
[ 1.]
shap13=(1, 2, 2, 3),eval=
[[[[ 1.  1.  1.]
   [ 1.  1.  1.]]

  [[ 1.  1.  1.]
   [ 1.  1.  1.]]]]
shap14=(1, 2, 2, 3),eval=
[[[[ 2.  2.  2.]
   [ 2.  2.  2.]]

  [[ 2.  2.  2.]
   [ 2.  2.  2.]]]]

shap15=(1, 2, 2, 3),eval=
[[[[ 1. 1. 1.]
[ 0. 0. 0.]]

[[ 1. 1. 1.]
[ 0. 0. 0.]]]]
shap16=(1, 2, 2, 3),eval=
[[[[ 1. 1. 1.]
[ 1. 1. 1.]]

[[ 1. 1. 1.]
[ 1. 1. 1.]]]]
shap17=(1, 2, 2, 3),eval=
[[[[ 2. 2. 2.]
[ 1. 1. 1.]]

[[ 2. 2. 2.]
[ 1. 1. 1.]]]]

这个结果说明了什么呢?说明张量加法时,维数不等时会自动扩充,用存在的数字填充。

比如下面这个[4, 3, 2, 3]的矩阵A,

我们把A加上[1, 2, 3]结果为

[[[[1 2 3]
[2 3 4]]

[[3 4 5]
[4 5 6]]

[[5 6 7]
[6 7 8]]]


[[[1 2 3]
[2 3 4]]

[[3 4 5]
[4 5 6]]

[[5 6 7]
[6 7 8]]]


[[[1 2 3]
[2 3 4]]

[[3 4 5]
[4 5 6]]

[[5 6 7]
[6 7 8]]]


[[[1 2 3]
[2 3 4]]

[[3 4 5]
[4 5 6]]

[[5 6 7]
[6 7 8]]]]

转载于:https://www.cnblogs.com/qggg/p/6849719.html

<think>嗯,用户问的是TensorFlow中Tensor之间的加法是怎么进行的。首先,我需要回忆一下TensorFlow的基本操作。记得在TensorFlow中,张量之间的运算通常是通过运算符重载或者使用tf.add函数来实现的。加法的话,可能有两种方式:用+运算符或者调用tf.add函数。 然后,我需要确认这两种方法是否真的等效。比如,当两个张量的形状相同的时候,直接相加应该没问题。但如果形状不同,但满足广播机制的条件,比如一个张量是标量或者可以扩展的维度,这时候加法应该也能自动处理。例如,一个形状是(2,3),另一个是(1,3),这时候会广播成(2,3)再相加。 接下来,得考虑数据类型的问题。如果两个张量的数据类型不同,比如一个是float32,另一个是int32,这时候会不会自动转换?或者会抛出错误?可能需要用户显式转换类型,或者TensorFlow会自动进行类型提升。比如,int32和float32相加,结果可能是float32。 另外,用户可能想知道如何执行元素级别的加法,这其实和数学中的逐元素相加一致,而矩阵乘法则是用tf.matmul。需要明确说明加法是逐元素的,而乘法运算符*在TensorFlow中也是逐元素的,矩阵乘法用@或者tf.matmul。 然后,我需要给出具体的代码示例,比如创建两个张量,用+和tf.add两种方式演示加法操作。还要展示一个广播的例子,比如形状不同的张量相加,说明广播机制的应用。还要注意可能出现的错误情况,比如形状不兼容或者数据类型不匹配。这时候应该提醒用户如何处理这些异常,例如使用tf.cast进行类型转换,或者调整张量的形状。 最后,总结一下加法操作的两种方法,强调它们的结果是相同的,并指出适用的情况,比如动态图下的便捷性。同时,在相关问题部分,可以扩展到其他运算符、广播机制、类型处理以及更复杂的运算如矩阵乘法,这样用户能有一个全面的了解。</think>之间的加法在TensorFlow中可以通过`+`运算符或`tf.add()`函数实现,两种方式都会执行元素级别的加法运算。具体实现方式如下: ```python import tensorflow as tf # 创建两个相同形状的Tensor a = tf.constant([[1, 2], [3, 4]]) b = tf.constant([[5, 6], [7, 8]]) # 方法1:使用运算符 c = a + b # [[6, 8], [10, 12]] # 方法2:使用tf.add() d = tf.add(a, b) # [[6, 8], [10, 12]] # 广播机制示例 e = tf.constant([10, 20]) f = a + e # [[11, 22], [13, 24]] ``` **解释**: 1. **元素级别运算**:加法在两个Tensor的每个对应元素之间进行 2. **广播机制**:当Tensor形状不同但满足广播规则时(如最后一个示例中形状(2,2)和(2,)的相加),Tensor会自动扩展维度进行运算 3. **类型要求**:参与运算的Tensor必须具有兼容的数据类型(如都是float32或int32),否则需要显式转换 **常见错误处理**: ```python # 类型不匹配解决方案 a_float = tf.cast(a, tf.float32) b_int = tf.constant([[5, 6], [7, 8]], dtype=tf.int32) correct_sum = a_float + tf.cast(b_int, tf.float32) # 形状不匹配解决方案 try: invalid = a + tf.constant([1,2,3]) # 会抛出InvalidArgumentError except tf.errors.InvalidArgumentError as e: print("形状不兼容错误:", e) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值