Tensorflow:初试Tensorflow,理解卷积神经网络输出形状

Tensorflow:理解Tensorflow中的sess.run原理机制,理解卷积神经网络输出形状shape

我们通过运行tensorflow中的程序,理解卷积和全连接操作的输出形状,并清楚为什么会是这个形状?

一、理解Tensorflow中的sess.run原理机制

首先,Tensorflow是google的开源深度学习框架,目前全球最流行的框架。其sess.run的运行原理可以简单地由下图来看。

在这里插入图片描述

其中ops是一个操作节点,Tensor可以理解成可以通过ops进行计算变换的矩阵。通过这种方式可以组成非常复杂的结构图(graph)来模拟人脑的神经元工作。

Tensorflow的图需要建立,图建立后需要在session中运行,也就是sess.run()。下面模拟了一个图,一个常量经过卷积操作后,输出。

import tensorflow as tf
import numpy as np

#建立Graph
inputs = tf.constant(np.random.rand(4,3,3,2))#创建4*3*3*2的随机张量
conv1 = tf.layers.conv2d(inputs, 5, (3, 3),padding = "same")#二维卷积操作
conv2 = tf.layers.conv2d(inputs, 5, (3, 3),padding = "valid")#二维卷积操作

#运行
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    [_conv1] = sess.run([conv1])
    [_conv2] = sess.run([conv2])
    print("当padding=same时:输出形状为:",_conv1.shape)
    print("当padding=valid时:输出形状为:",_conv2.shape)

在上述代码中,sess.run()一共执行了两次,也就是图中的数据一共流动了两次。但是如果我们用下面的代码执行:

import tensorflow as tf
import numpy as np

#建立Graph
inputs = tf.constant(np.random.rand(4,3,3,2))#创建4*3*3*2的随机张量
conv1 = tf.layers.conv2d(inputs, 5, (3, 3),padding = "same")#二维卷积操作
conv2 = tf.layers.conv2d(inputs, 5, (3, 3),padding = "valid")#二维卷积操作

#运行
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    [_conv1, _conv2] = sess.run([conv1, conv2])
    print("当padding=same时:输出形状为:",_conv1.shape)
    print("当padding=valid时:输出形状为:",_conv2.shape)

这样sess.run()只执行了一次,也就是图中的数据只流动了一次。

通过这两种方式的区别我们可以清楚Tensorflow的数据流动机制,以以上例子,用图来理解。

在这里插入图片描述

现在的输入是一个常量,看不出来什么,如果真实的训练,就有差距了,比如我要看同一批输入,同时输出的conv1和conv2是什么,用两次sess.run()就不合理。因为这样输入已经变了,而且涉及到训练的时候可能已经反向传播了一次,参数w和b也变了。

sess.run()一次,数据只会流动一次,Tensorflow就会去分析图的构成。一个tensor可以流向两个地方的,就只用一个tensor就行。

通俗一点理解就是:如果两次卷积在一个sess.run()同时流动的话,输入是一样的,方便比较两次卷积的结果;如果两次卷积在两个sess.run()分别流动的话,两次卷积分别的输入值就不一样了。但因为例子里面是个常量,所以看着是一样的,实际是不一样的。

所以理解为什么叫Tensorflow了吗?我们run一次,Tensor就flow一次!

二、理解卷积的输出形状shape

理解了上述机制后,再继续看代码。

import tensorflow as tf
import numpy as np

#建立Graph
inputs = tf.constant(np.random.rand(4,3,3,2))#创建4*3*3*2的随机张量
conv1 = tf.layers.conv2d(inputs, 5, (3, 3),padding = "same")#二维卷积操作
conv2 = tf.layers.conv2d(inputs, 5, (3, 3),padding = "valid")#二维卷积操作

#运行
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    [_conv1, _conv2] = sess.run([conv1, conv2])
    print("当padding=same时:输出形状为:",_conv1.shape)
    print("当padding=valid时:输出形状为:",_conv2.shape)

我们调用Tensorflow中自带的conv包,对输入数据进行卷积操作。其中conv2d代表的是二维卷积操作,同样的conv3d就是三位卷积操作。在卷积过程中,tf.layers.conv2d()中的参数分别是输入数据、卷积核数目、卷积核形状和padding。padding通常去两个值,分别是“same”和“valid”,两种方式的输出结果区别如下:
在这里插入图片描述

接下来我们来着重理解一下,为什么输出的结果不同。

当padding=“same”时,会对原有的矩阵外圈进行均匀补零,见下图:

在这里插入图片描述

当padding=“valid”时,不会对原有矩阵进行扩充,将直接对原矩阵进行卷积操作,见下图:
在这里插入图片描述

三、理解全连接的输出形状shape

理解了上述的卷积的输出形状后,我们在此基础上,再加一个全连接层dense,输出结果的形状shape,并清楚为什么会是这个形状。

以卷积过程padding="same"为例。

import tensorflow as tf
import numpy as np

#建立Graph
inputs = tf.constant(np.random.rand(4,3,3,2))#创建4*3*3*2的随机张量
conv1 = tf.layers.conv2d(inputs, 5, (3, 3),padding = "same")#二维卷积操作
f_conv1 = tf.layers.flatten(conv1)#输出矩阵拉伸运算
dense = tf.layers.dense(f_conv1, 1024)#设置神经元个数为1024

#运行
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    [dense] = sess.run([dense])
    print("全连接后的输出形状为:", dense.shape)

输出形状结果为:
在这里插入图片描述
以某一张图为输入层为例,从下图方便理解:
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力不秃头的小仙主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值