TensorFlow卷积神经网络
1、反向传播
几个人站成一排第一个人看一幅画(输入数据),描述给第二个人(隐层)……依此类推,到最后一个人(输出)的时候,画出来的画肯定不能看了(误差较大)。
反向传播就是,把画拿给最后一个人看(求取误差),然后最后一个人就会告诉前面的人下次描述时需要注意哪里(权值修正)
2、什么是卷积
1.已有运算:加减乘除,幂运算指数运算
卷积:卷积是一种运算
2.卷积运算
卷积操作是使用一个二维的卷积核在一个批处理的图片上进行不断扫描。具体操作是将一个卷积核在每张图片上按照一个合适的尺寸在每个通道上面进行扫描
3.卷积过程
如下图所示,用一个33的卷积核在55的图像上做卷积的过程
4.在三通道图像上的卷积过程
如下:
5.卷积函数
3、卷积函数 tf.nn.conv2d
参数一:input
input就是需要做卷积的图像(这里要求用Tensor来表示输入图像,并且Tensor(一个4维的Tensor,要求类型为float32)的shape为[batch, in_height, in_width, in_channels]具体含义[训练时一个batch图像的数量,图像高度,图像宽度, 图像通道数])
参数二:filter
filter就是卷积核(这里要求用Tensor来表示卷积核,并且Tensor(一个4维的Tensor,要求类型与input相同)的shape为[filter_height, filter_width, in_channels, out_channels]具体含义[卷积核高度,卷积核宽度,图像通道数,卷积核个数],这里的图片通道数也就input中的图像通道数,二者相同。)
参数三:strides
strides就是卷积操作时在图像每一维的步长,strides是一个长度为4的一维向量
参数四:padding
padding是一个string类型的变量,只能是 “SAME” 或者 “VALID”,决定了两种不同的卷积方式。下面我们来介绍 “SAME” 和 “VALID” 的卷积方式,如下图我们使用单通道的图像,图像大小为5 * 5,卷积核用3 * 3
方式一:VALID
具体卷积操作如下图,我们考虑卷积核中心点(这里卷积核大小是3*3,)走过的位置,
如图所示,红色#表示卷积核中心点在图像上的滑动过程。最后得到3 * 3的图像大小
方式二:SAME
对于上图,图像的每一个点都作为卷积核的中心。最后得到5 * 5的结果,如下图:
通俗的来说:首先在原图外层补一圈0,将原图的第一点作为卷积核中心,若一圈0不够,继续补一圈0
参数五:use_cudnn_on_gpu
参数六:data_format
data_format就是input的Tensor格式,一般默认就可以了。都采用NHWC
NHWC:[batch, height, width, channels]
参数七:name
name: A name for the operation (optional).
就是用以指定该操作的name,仅此而已
4、卷积构造方法
1.激活函数
在神经网络中,激活函数的作用是能够给神经网络加入一些非线性因素,使得神经网络可以更好地解决较为复杂的问题
在神经网络中,我们有很多的非线性函数来作为激活函数,比如连续的平滑非线性函数(sigmoid,tanh和softplus),连续但不平滑的非线性函数(relu,relu6和relu_x)和随机正则化函数(dropout)
所有的激活函数都是单独应用在每个元素上面的,并且输出张量的维度和输入张量的维度一样
- tf.nn.relu(features, name = None):这个函数的作用是计算激活函数relu,即max(features, 0)
- tf.nn.relu6(features, name = None):这个函数的作用是计算激活函数relu6,即min(max(features, 0), 6)
- tf.nn.softplus(features, name = None):这个函数的作用是计算激活函数softplus,即log( exp( features ) + 1)
- tf.sigmoid(x, name = None):这个函数的作用是计算 x 的 sigmoid 函数。具体计算公式为 y = 1 / (1 + exp(-x))
- tf.tanh(x, name = None):这个函数的作用是计算 x 的 tanh 函数。具体计算公式为
( exp(x) - exp(-x) ) / ( exp(x) + exp(-x) )
2.Dropout
当训练数据量比较小时,可能会出现因为追求最小差值导致训练出来的模型极度符合训练集,但是缺乏普适性,不能表达训练数据之外的数据。应用于解决过拟合
解决方案:
tf.nn.dropout(x, keep_prob, noise_shape = None, seed = None, name = None)
这个函数的作用是计算神经网络层的dropout。
一个神经元将以概率keep_prob决定是否放电,如果不放电,那么该神经元的输出将是0,如果该神经元放电,那么该神经元的输出值将被放大到原来的1/keep_prob倍。这里的放大操作是为了保持神经元输出总个数不变。比如,神经元的值为[1, 2],keep_prob的值是0.5,并且是第一个神经元是放电的,第二个神经元不放电,那么神经元输出的结果是[2, 0],也就是相当于,第一个神经元被当做了1/keep_prob个输出,即2个。这样保证了总和2个神经元保持不变
tf.nn.dropout是TensorFlow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层。
Dropout就是在不同的训练过程中随机扔掉一部分神经元。也就是让某个神经元的激活值以一定的概率p,让其停止工作,这次训练过程中不更新权值,也不参加神经网络的计算。但是它的权重得保留下来(只是暂时不更新而已),因为下次样本输入时它可能又得工作了
例:
import tensorflow as tf
a = tf.constant([[[[-1.0, 2.0, 3.0, 4.0,5.0,2]]],[[[2,2,2,3,3,4]]]])
print(a.shape)
with tf.Session() as sess:
b = tf.nn.dropout(a, 0.5)
print(sess.run(b))
b = tf.nn.dropout(a, 0.5)
print(sess.run(b))
输出:
[[[[-2. 0. 6. 0. 0. 4.]]]
[[[ 0. 0. 4. 0. 0. 8.]]]]
[[[[-0. 4. 0. 8. 0. 4.]]]
[[[ 4. 0. 0. 0. 0. 8.]]]]
图示:
3.卷积层
卷积操作是使用一个二维的卷积核在一个批处理的图片上进行不断扫描。具体操作是将一个卷积核在每张图片上按照一个合适的尺寸在每个通道上面进行扫描
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)
这个函数的作用是对一个四维的输入数据 input 和四维的卷积核 filter 进行操作,然后对输入数据进行一个二维的卷积操作,最后得到卷积之后的结果
tf.nn.bias_add(value, bias, name = None):这个函数的作用是将偏差项 bias 加到 value 上面
这个操作你可以看做是 tf.add 的一个特例,其中 bias 必须是一维的。该API支持广播形式,因此 value 可以有任何维度。但是,该API又不像 tf.add ,可以让 bias 的维度和 value 的最后一维不同
例:
import tensorflow as tf
a = tf.constant([[1.0, 2.0],[1.0, 2.0],[1.0, 2.0]])
b = tf.constant([2.0,1.0])
c = tf.constant([1.0])
sess = tf.Session()
print(sess.run(tf.nn.bias_add(a, b)))
# !!! 因为 a 最后一维的维度是 2 ,但是 c 的维度是 1,所以以下语句将发生错误
# print(sess.run(tf.nn.bias_add(a, c)))
# 但是 tf.add() 可以正确运行
print(sess.run(tf.add(a, c)))
4.池化层
池化操作是利用一个矩阵窗口在输入张量上进行扫描,并且将每个矩阵窗口中的值通过取最大值,平均值或者XXXX来减少元素个数
Maxpooling 就是在这个区域内选出最能代表边缘的值,然后丢掉那些没多大用的信息
为什么要这么做
举个例子
有四个美女,如果非要你选,你娶谁
你肯定会选最漂亮的(最符合的特征)
tf.nn.max_pool(value, ksize, strides, padding, name=None):
这个函数的作用是计算池化区域中元素的最大值
图示:
来源:CSDN
作者:一人白
链接:https://blog.csdn.net/qq_43576343/article/details/103482998