基于Tensorflow+MNIST的LeNet-5神经网络

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_36835368/article/details/82459266
"""#!coding:utf8
#调整输入数据placeholder的格式,输入为一个四维矩阵
x = tf.placeholder(tf.float32,[
                   BATCH_SIZE,     #第一维表一个batch中样例的个数
                   mnist_inference.IMAGE_SIZE,       #第二维和第三维表图片尺寸
                   mnist_inference.IMAGE_SIZE, 
                   mnist_inference.NUM_CHANNELS],   #第四维表图片深度,RGB格式深度为5
                   name='x-input')

#类似地将输入的训练数据格式调整为一个四维矩阵,并将这个调整后的数据传入sess.run过程
reshaped_xs = np.reshape(xs, (BATCH_SIZE,
                              mnist_inference.IMAGE_SIZE,
                              mnist_inference.IMAGE_SIZE,
                              mnist_inference.CHANNELS))
#在调整完输入格式之后,只需要在下述mnist_inference.py程序中实现类似LeNet-5模型结构的前向传播过程即可
"""

#!coding:utf8
import tensorflow as tf

#配置神经网络的参数
INPUT_NODE = 784
OUTPUT_NODE = 10

IMAGE_SIZE = 28
NUM_CHANNELS = 1
NUM_LABELS = 10

#第一层卷积层的尺寸和深度
CONV1_DEEP = 32
CONV1_SIZE = 5
#第二层卷积层的尺寸和深度
CONV2_DEEP = 64
CONV2_SIZE = 5
#全连接层的节点个数
FC_SIZE = 512

#定义卷积神经网络的前向传播过程.添加新的参数train,用于区分训练过程和测试过程.程序将用到dropout方法,可以进一步提升模型可靠性并防止过拟合,dropout过程只在训练时使用
def inference(input_tensor,train,regularizer):
    #定义卷积层输入为28*28*1的原始mnist图片像素,因为卷积层使用全0填充,输出28*28*32的矩阵
    with tf.variable_scope('layer-conv1'):
        conv1_weights = tf.get_variable(
            "weight",[CONV1_SIZE, CONV1_SIZE, NUM_CHANNELS, CONV1_DEEP],
            initializer = tf.truncated_normal_initializer(stddev=0.1))
        conv1_biases = tf.get_variable(
            "bias", [CONV1_DEEP],initializer = tf.constant_initializer(0.0))

        #使用变长为5,深度为32的过滤器,过滤器移动步长为1,且使用全0填充
        conv1 = tf.nn.conv2d(
              input_tensor, conv1_weights, striders=[1,1,1,1], padding = 'SAME')
        relu1 = tf.nn.relu(tf.nn.bias_add(conv1,conv1_biases))

    #第二层池化层前向传播过程.选用最大池化层,滤波器边长为2,使用全0填充且移动步长为2,输入28*28*32的矩阵,输出14*14*32的矩阵
    with tf.name_scope('layer2-pool1'):
        pool1 = tf.nn.max_pool(relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding = 'SAME')

    #第三层卷积层,输入14*14*32的矩阵,输出14*14*64的矩阵
    with tf.variable_scope('layer3-conv2'):
        conv2_weights = tf.get_variable(
            "weight",[CONV2_SIZE, CONV2_SIZE, CONV1_DEEP, CONV2_DEEP],
            initializer = tf.truncated_normal_initializer(stddev=0.1))
        conv2_biases = tf.get_variable(
            "bias", [CONV2_DEEP],initializer = tf.constant_initializer(0.0))

        #使用变长为5,深度为64的过滤器,过滤器移动步长为1,且使用全0填充
        conv2 = tf.nn.conv2d(
              input_tensor, conv1_weights, striders=[1,1,1,1], padding = 'SAME')
        relu2 = tf.nn.relu(tf.nn.bias_add(conv2,conv2_biases))

    #第四层池化层,输入14*14*64,输出7*7*64的矩阵
    with tf.name_scope('layer4-pool2'):
        pool2 = tf.nn.max_pool(relu, ksize=[1,2,2,1], strides=[1,2,2,1], padding = 'SAME')


    #第五层全连接层,输入7*7*64的矩阵.全连接层输入格式为向量,使用pool2.get_shape函数将第四层输出拉直成一个向量.注每一层神经网络的输入输出都为一个batch的矩阵,所以这里得到的维度也包含一个batch中数据的个数.
    pool_shape = pool2.get_shape().as_list()
    #计算将矩阵拉直成向量之后的长度,这个长度时矩阵长宽及深度的乘积.
    #注pool+shape[0]为一个batch中数据的个数
    nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]

    #通过将tf.reshape函数将第四层的输出变成一个batch的向量
    reshaped = tf.reshape(pool2, [pool_shape[0], nodes])

    #声明第五层全连接层的变量并实现前向传播过程.这一层的输入是拉直之后的一组向量,向量长度为3136,输出是一组长度为512的向量.dropout在训练时会随机将部分节点的输出改为0.dropout可以避免过拟合问题,从而使得模型在测试数据上的效果更好,dropout一般只在全连接层而不是卷积层或者池化层使用.

    with tf.variable_scope('layer5-fc1'):
        fc1_weights = tf.get_variable(
                      "weight", [nodes, FC_SIZE],
                       initializer = tf.truncated_normal_initializer(stddev=0.1))
        #只有全连接层的权重需要加入正则化
        if regularizer != None:
            tf.add_to_collection('losses', regularizer(fc1_weights))
        fc1_biases = tf.get_variable(
                     "bias", [FC_SIZE], initializer = tf.constant_initializer(0.1))

        fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases)
        if train: fc1 = tf.nn.dropout(fc1, 0.5)


    #声明第六层全连接层的变量并实现前向传播过程.这一层的输入为一组长度为512的向量,输出为一组长度为10的向量.这一层的输出通过softmax之后就得到了最后的分类结果.
    with tf.variables_scope('layer6-fc2'):
        fc2_weights = tf.get_variable(
                      "weight", [FC_SIZE, NUM_LABELS],
                       initializer = tf.truncated_normal_initializer(stddev=0.1))
        if regularizer != None:
            tf.add_to_collection('losses', regularizer(fc2_weights))
        fc2_biases = tf.get_variable(
                     "bias",[NUM_LABELS],
                     initializer= tf.constant_initializer(0.1))
        logit = tf.matmul(fc1, fc2_weights) + fc2_biases

    #返回六层的输出
    return logit
        

猜你喜欢

转载自blog.csdn.net/weixin_36835368/article/details/82459266
今日推荐