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

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

这里写图片描述
  如上图所示,假设我们有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

猜你喜欢

转载自blog.csdn.net/made_in_china_too/article/details/80171763
今日推荐