卷积层运算实例

 

昨天晚上为了区分TensorFlow的tf.nn.conv2d 函数的中的参数取值问题,(padding='VALID’和 padding='SAME' ) 自己编写了一个非常简单的卷积层,但是出现了一些小问题,在这里做一下汇总。

 

import tensorflow as tf 
x0  = tf.constant([[1., 2., 3., 4., 5.],
                  [6., 7., 8., 9., 10.],
                  [11., 12., 13., 14., 15.],
                  [16., 17., 18., 19., 20.]])
print(x0.shape)
x = tf.reshape(x0,[-1,4,5,1])
print(x) 



fil0 = tf.constant([[2.,2.],
                   [3.,3.]])
print(fil0)
fil1 = tf.reshape(fil0,[2,2,1,1])
print(fil1)

这个是我自己定义的输入矩阵了卷积核矩阵,我将输入矩阵reshape为了[-1,4,5,1] 这样的维度,卷积核矩阵reshape为了[2,2,1,1] 这样的维度。 

下面这里,我们简要的看一下输出:

(4, 5)
Tensor("Reshape_38:0", shape=(1, 4, 5, 1), dtype=float32)
Tensor("Const_42:0", shape=(2, 2), dtype=float32)
Tensor("Reshape_39:0", shape=(2, 2, 1, 1), dtype=float32)

---------------------------------------------------

好的,现在我们开始卷积运算,

#  计算过程
res1 = tf.nn.conv2d(input=x, filter=fil1, strides=[1,1,1,1],padding='VALID')
res2 = tf.nn.conv2d(input=x, filter=fil1, strides=[1,1,1,1],padding='SAME')

print('------#  计算过程  #--------')
print(res1)
print(res2)
print('------#  计算过程  #--------')

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(res1))
    print('- - - - - - - - - -  --  - -- ')
    print(sess.run(res2))

我们观察一下输出的结果

------#  计算过程  #--------
Tensor("Conv2D_34:0", shape=(1, 3, 4, 1), dtype=float32)
Tensor("Conv2D_35:0", shape=(1, 4, 5, 1), dtype=float32)
------#  计算过程  #--------
[[[[ 45.]
   [ 55.]
   [ 65.]
   [ 75.]]

  [[ 95.]
   [105.]
   [115.]
   [125.]]

  [[145.]
   [155.]
   [165.]
   [175.]]]]
- - - - - - - - - -  --  - -- 
[[[[ 45.]
   [ 55.]
   [ 65.]
   [ 75.]
   [ 40.]]

  [[ 95.]
   [105.]
   [115.]
   [125.]
   [ 65.]]

  [[145.]
   [155.]
   [165.]
   [175.]
   [ 90.]]

  [[ 66.]
   [ 70.]
   [ 74.]
   [ 78.]
   [ 40.]]]]

想必大家之前对padding取值的不同对结果的影响都有了一个普遍的认识了,这里这是做一个小小的验证。

 

然而,我在这里发现了一个小小的意外

            我们定义的卷积核的大小是2x2的,而且使用constant来定义的 ,这也就意味着我们在reshape这个卷积核矩阵的时候有着很大的局限,具体的来说就是[ [2., 2., ],[ 3., 3.] ] 这样的矩阵可以reshape为我们例子中的[2,2,1,1], 这种卷积核矩阵的意思就是单输入,单输出,然而这样并没有什么天大的意义;如果我们将其reshape为[2,2,1,15]这样的维度,那么编译器就会给你报错 。相信大家都看过MNIST的例子,在MNIST中打一层卷积的输入为1,输出为32。

 

        其实解决这个问题并不困难,我们只需要更改定义的方式即可;譬如:::::

filter1 = tf.Variable(tf.random_normal([1,1,5,5]))
print(filter1)

或者说也可以:

fil1 = tf.truncated_normal(shape, stddev = 0.1)
#  正态分布

方法很多,但是我在网上看到用的最多的也就是这两种,这样更改完之后,我们就可以任意改变我们卷积层的输出维度了,这样也才能达到我们使用卷积层的真正目的了。。。。

# conv2d case 1
import tensorflow as tf

input1 = tf.Variable(tf.random_normal([1,3,3,5]))
print(input1)

filter1 = tf.Variable(tf.random_normal([1,1,5,5]))
print(filter1)

op1 = tf.nn.conv2d(input=input1,filter=filter1,strides=[1,1,1,1],padding='SAME')
print(op1)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(input1))
    print('- - - - - - - - - - - - - - - - - - - - - ')
    print(sess.run(filter1))
    print('- - - - - - - - - - - - - - - - - - - - - ')
    print(sess.run(op1))

结果:

<tf.Variable 'Variable_24:0' shape=(1, 3, 3, 5) dtype=float32_ref>
<tf.Variable 'Variable_25:0' shape=(1, 1, 5, 5) dtype=float32_ref>
Tensor("Conv2D_23:0", shape=(1, 3, 3, 5), dtype=float32)
[[[[ 1.0076689  -1.0429513   0.19840461 -1.4179145   0.21241538]
   [ 1.5745131   0.9061459  -0.8719591   0.9945474  -1.1337398 ]
   [ 0.03464183 -1.5947934   0.64049923 -0.07008466  1.6137193 ]]

  [[ 0.7869904  -0.6835375   0.69408005 -2.0935128   0.0372552 ]
   [ 0.1736713  -1.221272    0.665623    0.7544438  -0.36622164]
   [-0.31765813  0.9946766  -0.93498504 -0.20999084  1.073885  ]]

  [[-0.4125433  -0.5018808   0.5720211   1.429884    0.16586587]
   [ 0.5928908  -1.1014961   0.5609521   1.3232079   0.46690243]
   [ 3.1215336   1.450255   -0.94082916  0.8863312  -0.7052749 ]]]]
- - - - - - - - - - - - - - - - - - - - - 
[[[[-2.4539537  -0.5954268   0.6421796  -0.40367666  1.9257879 ]
   [-0.77819943 -1.9217943  -0.5275012   0.04040896 -0.4035784 ]
   [ 1.4318761   0.966928   -0.90433323 -0.520099   -1.5638638 ]
   [ 0.59773684 -0.6318572  -0.05836076 -0.84807736  0.32493162]
   [-1.8983399  -0.5072093  -0.1815751   0.988288    0.23245037]]]]
- - - - - - - - - - - - - - - - - - - - - 
[[[[-2.6278341e+00  2.3843687e+00  1.0620198e+00  8.6032176e-01
     1.6398423e+00]
   [-3.0707808e+00 -3.5754230e+00  1.4694850e+00 -2.1093874e+00
     4.0897241e+00]
   [-1.0321066e+00  2.8893447e+00 -4.6440363e-03  1.2427056e+00
     6.1020404e-02]]

  [[-1.7275658e+00  2.8200538e+00  3.5369077e-01  1.1059786e+00
     3.4402516e-02]
   [ 2.6234736e+00  2.5962846e+00  1.7627250e-01 -1.4674065e+00
    -5.3596362e-02]
   [-3.4974389e+00 -3.0384851e+00 -6.5884218e-02  1.8941059e+00
     6.3040936e-01]]

  [[ 2.7618134e+00  7.7564323e-01 -6.3104808e-01 -1.1999829e+00
    -9.8331565e-01]
   [ 1.1006153e-01  1.2333306e+00  2.9249403e-01 -1.2363458e+00
     1.2475530e+00]
   [-8.2671928e+00 -5.7577639e+00  2.1667304e+00 -2.1608548e+00
     7.0215044e+00]]]]

关于卷积的输出结果,可以参考https://blog.csdn.net/zuolixiangfisher/article/details/80528989  这位朋友的博客

 

 

 

到这里,其实我还有一个疑问。

那就是当padding的模式为SAME的时候,我们假设有一个5x5的矩阵,我们用3x3的核去做卷积,结果会是(4x4)还是(5x5)呢??????

我们来看代码

import tensorflow as tf

demo_input = tf.Variable(tf.truncated_normal([1,5,5,1],stddev=0.1))
filter_input = tf.Variable(tf.truncated_normal([3,3,1,1],stddev=0.1))

que_op = tf.nn.conv2d(input=demo_input, filter=filter_input,strides=[1,1,1,1], padding='SAME')
print(que_op.shape)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(que_op))
(1, 5, 5, 1)


[[[[-8.3898138e-03]
   [-2.1066532e-02]
   [-1.4402784e-03]
   [ 8.5802004e-03]
   [-1.4919336e-02]]

  [[ 1.6910087e-02]
   [ 3.8107365e-02]
   [-4.9511576e-03]
   [-8.5974624e-03]
   [ 1.6875543e-02]]

  [[-2.0971554e-03]
   [-1.3970275e-02]
   [-1.8095970e-02]
   [ 1.7300552e-02]
   [-4.7517763e-03]]

  [[ 2.8687459e-03]
   [ 2.7101874e-02]
   [-2.2895761e-02]
   [-1.7852791e-02]
   [-8.9415582e-05]]

  [[-2.4188370e-02]
   [-1.0250438e-02]
   [-1.1976613e-02]
   [ 2.2352396e-02]
   [ 4.6136477e-03]]]]

5X5,也无需在做更多的解释

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值