【TensorFlow】卷积神经网络的参数设置与例子

xiaoxiao2021-02-28  33

一、卷积操作参数的简要说明

  如上图所示,假设我们有32*32的RBG图片,也就是神经网络的 input 是 32*32*3,表示输入是一个有3个图层的32*32的图片。   假设现在有一个 5*5的 filter处理一个32*32的图层,那么处理后的输出就是一个28*28的图层。现在总共有3个图层,filter需要覆盖这三个图层,因此对于32*32*3的input,filter需要设置为 5*5*3,表示是一个深度为3,长和宽都为5的卷积核。   需要注意的是,使用1个5*5*3的filter处理1个32*32*3的input,输出还是 28*28*1的大小(表示大小为28*28,深度为1的图层)。   在实验中,一个filter对应用来提取 1 种特征,因此一般需要设置多个卷积核提取多个特征。比如上图的第一个CONV层 就是 6 个 5*5*3 的卷积核 ,用于提取 6 种特征。上文已经说过,使用1个filter,则output是一个深度为1的图层。那么这里使用6个filter,则output是一个深度为6的图层。   因此对应上图的第一个CONV层,Input是32*32*3,使用6个5*5*3的filter,output是 28*28*6。


二、TensorFlow的函数conv2d的参数设置

tf.nn.conv2d(input, w, strides, padding)

1. input

  input是一个4为tensor =[batch, height, width, channels]= [样本数量,样本长,样本宽,样本深度(对应图片通道数)],RGB图像通道数为3,黑白图像通道数为1

2. strides

  strides=[ batch 维度上的滑动步长,样本height方向的滑动步长,样本width方向的滑动步长, channels 维度上的滑动步长 ]   一种常用的经典设置是 strides[0]=strides[3]=1。   strides[0] = 1,也即在 batch 维度上的移动为 1,也就是不跳过任何一个样本,否则当初也不该把它们作为输入(input)   strides[3] = 1,也即在 channels 维度上的移动为 1,也就是不跳过任何一个颜色通道;

3.padding

  padding=’SAME’,卷积操作后样本的长和宽不发生改变。   padding=’VALID’,卷积操作后,将样本中不能进行卷积的部分丢掉:

4. w

  w=[filter的长,filter的宽,input的深度,output的深度]。上文已经介绍,output的深度等于filter的个数。


三、Input层 - CONV层 - CONV层的W参数设置例子

  假设我们使用k*k大小的卷积核对1个n*m的图像运算,在tensorflow里面,我们并不用设置计算图片卷积后的输出大小。我们只需要设置上一层的卷积核个数,及对应下一层的卷积核个数。 1. Input层   例如,我们将一张32*32的RBG图像作为输入,则input = [ 1,32,32,3 ],第一个1表示图片的数量。 2. 第一个CONV层   接受input的第一个卷积层的filter设置为 w=[filter的长,filter的宽,input的深度,output的深度] = [ 3,3,3,32 ],其中input的深度就是图片的图层数(RBG图片有3层)。output的深度为32(等于卷积核的个数)。 3. 第二个CONV层   上一个的CONV层的output的深度作为第二层的input深度。假设第二层的卷积核的大小是3*3,output的深度为64,则w=[ 3,3,32,64 ]


四、CNN识别Mnist数据集

  (卷积层 - 池化层) - (卷积层 - 池化层) - (卷积层 - 池化层) - 全连接层 - 输出层

''' 这里,我们首先读取数据MNIST,并分别得到训练集的图片和标记的矩阵,以及测试集的图片和标记的矩阵。代码如下: ''' import tensorflow as tf import numpy as np from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) trX, trY, teX, teY = mnist.train.images, mnist.train.labels, mnist.test.images,mnist.test.labels ''' 接着,需要处理输入的数据,把上述 trX 和 teX 的形状变为[-1,28,28,1],-1 表示不格虑输入图片 的数量,28×28 是图片的长和宽的像素数,1 是通道(channel)数量,因为 MNIST 的图片是黑白的,所以 通道是 1,如果是 RGB 彩色图像,通道是 3。 ''' trX = trX.reshape(-1, 28, 28, 1) # 28x28x1 input img teX = teX.reshape(-1, 28, 28, 1) # 28x28x1 input img X = tf.placeholder("float", [None, 28, 28, 1]) Y = tf.placeholder("float", [None, 10]) '''' 这里,我们将要构建一个拥有 3 个卷积层和 3 个池化层,随后接 1 个全连接层和 1 个输出层的卷积神经网络。 ''' # 首先定义初始化权重的函数: def init_weights(shape): return tf.Variable(tf.random_normal(shape, stddev=0.01)) ''' 初始化权重方法如下,我们设置卷积核的大小为 3×3: ''' # w,patch 大小为 3×3,输入维度为 1,输出维度为 32 w = init_weights([3, 3, 1, 32]) # w2,patch 大小为 3×3,输入维度为 32,输出维度为 64 w2 = init_weights([3, 3, 32, 64]) # w3,patch 大小为 3×3,输入维度为 64,输出维度为 128 w3 = init_weights([3, 3, 64, 128]) # w4,全连接层,输入维度为 128 × 4 × 4(是由上一层的三维输出数据`4*4*128`转变成一维),输出维度为 625 w4 = init_weights([128 * 4 * 4, 625]) # w_o,输出层,输入维度为 625, 输出维度为 10,代表 10 类(labels) w_o = init_weights([625, 10]) ''' 神经网络模型的构建函数,传入以下参数 X:输入数据 w:每一层的权重 p_keep_conv,p_keep_hidden:dropout 要保留的神经元比例 ''' def model(X, w, w2, w3, w4, w_o, p_keep_conv, p_keep_hidden): # 第一组卷积层及池化层,最后 dropout 一些神经元 l1a = tf.nn.relu(tf.nn.conv2d(X, w, strides=[1, 1, 1, 1], padding='SAME')) # l1a shape=(?, 28, 28, 32) l1 = tf.nn.max_pool(l1a, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # l1 shape=(?, 14, 14, 32) l1 = tf.nn.dropout(l1, p_keep_conv) # 第二组卷积层及池化层,最后 dropout 一些神经元 l2a = tf.nn.relu(tf.nn.conv2d(l1, w2, strides=[1, 1, 1, 1], padding='SAME')) # l2a shape=(?, 14, 14, 64) l2 = tf.nn.max_pool(l2a, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # l2 shape=(?, 7, 7, 64) l2 = tf.nn.dropout(l2, p_keep_conv) # 第三组卷积层及池化层,最后 dropout 一些神经元 l3a = tf.nn.relu(tf.nn.conv2d(l2, w3, strides=[1, 1, 1, 1], padding='SAME')) # l3a shape=(?, 7, 7, 128) l3 = tf.nn.max_pool(l3a, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # l3 shape=(?, 4, 4, 128) l3 = tf.reshape(l3, [-1, w4.get_shape().as_list()[0]]) # reshape to (?, 2048) l3 = tf.nn.dropout(l3, p_keep_conv) # 全连接层,最后 dropout 一些神经元 l4 = tf.nn.relu(tf.matmul(l3, w4)) l4 = tf.nn.dropout(l4, p_keep_hidden) # 输出层 pyx = tf.matmul(l4, w_o) return pyx #返回预测值 ''' 我们定义 dropout 的占位符 — keep_conv,它表示在一层中有多少比例的神经元被保留下 来。生成网格模型,得到预测值,如下: ''' p_keep_conv = tf.placeholder("float") p_keep_hidden = tf.placeholder("float") py_x = model(X, w, w2, w3, w4, w_o, p_keep_conv, p_keep_hidden) #得到预测值 ''' 接下来,定义损失函数,这里我们仍然采用 tf.nn.softmax_cross_entropy_with_logits 来比较 预测值和真实值的差异,并做均值处理;定义训练的操作(train_op),采用实现 RMSProp 算法 的优化器 tf.train.RMSPropOptimizer,学习率为 0.001,衰减值为 0.9,使损失最小;定义预测的 操作(predict_op)。具体如下: ''' cost = tf.reduce_mean(tf.nn. softmax_cross_entropy_with_logits_v2(logits=py_x, labels=Y)) train_op = tf.train.RMSPropOptimizer(0.001, 0.9).minimize(cost) ''' 最后输出的`py_x`是一个shape=(?,10)的评分矩阵。每一行对应一个图片属于10个的概率值,tf.argmax(py_x, 1) 就是取出每一行概率值最大的下标。 ''' predict_op = tf.argmax(py_x, 1) ''' 接下来训练模型和评估模型: ''' # 先定义训练时的批次大小和评估时的批次大小 batch_size = 128 test_size = 256 # 在一个会话中启动图,开始训练和评估 with tf.Session() as sess: # you need to initialize all variables tf. global_variables_initializer().run() for i in range(10): training_batch = zip(range(0, len(trX), batch_size), range(batch_size, len(trX)+1, batch_size)) for start, end in training_batch: sess.run(train_op, feed_dict={X: trX[start:end], Y: trY[start:end], p_keep_conv: 0.8, p_keep_hidden: 0.5}) test_indices = np.arange(len(teX)) # Get A Test Batch np.random.shuffle(test_indices) test_indices = test_indices[0:test_size] print(i, np.mean(np.argmax(teY[test_indices], axis=1) == sess.run(predict_op, feed_dict={X: teX[test_indices], p_keep_conv: 1.0, p_keep_hidden: 1.0})))

结果: 0 0.953125 1 0.98828125 2 0.9765625 3 0.9921875 4 0.98828125 5 0.99609375 6 0.98828125 7 0.9921875 8 0.9921875 9 0.98828125

转载请注明原文地址: https://www.6miu.com/read-2621304.html

最新回复(0)