美文网首页程序员
TensorFlow实现Lenet在cifar10数据集运行

TensorFlow实现Lenet在cifar10数据集运行

作者: 续袁 | 来源:发表于2018-12-05 22:31 被阅读33次

1. 数据集简介

2. Lenet 简介

3. 代码实现

3.1 cifar10.py

代码链接

3.2 cifar10_input.py

代码链接

3.3 LeNet_inference.py

# _*_ coding: utf-8 _*_
import tensorflow as tf

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

IMAGE_SIZE = 24  # cifar数据集裁剪后的图像尺寸为24
NUM_CHANNELS = 3   #原值是1
NUM_LABELS = 10

# 第一个卷积层的尺寸和深度
CONV1_DEEP = 64  # 32     原:6
CONV1_SIZE = 5
# 第二个卷积层的尺寸和深度
CONV2_DEEP = 64   #64    原:16
CONV2_SIZE = 5
# 全连接层的节点个数
FC_SIZE = 120
FC_SIZE_2 = 84
FC_SIZE_3 = 10
# 使用正太分布初始化权重并添加L2正则化,使用w1控制L2损失的大小
def variable_with_weight_loss(shape, stddev, w1):
    # 从截断的(2个标准差以内)正态分布中输出随机值
    var = tf.Variable(tf.truncated_normal(shape, stddev=stddev))
    if w1 is not None:
        # l2_loss(var)*w1
        weight_loss = tf.multiply(tf.nn.l2_loss(var), w1, name='weight_loss')
        # 使用默认图
        tf.add_to_collection('losses', weight_loss)
    return var
# 定义卷积神经网络的前向传播过程。这里添加了一个新的参数train,用于区别训练过程和测试过程。在这个程序中将用到dropout方法
# dropout可以进一步提升模型可靠性并防止过拟合(dropout过程只在训练时使用)
def inference(input_tensor, train, regularizer):
    with tf.variable_scope('layer1-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))
        conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')
        relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))

    with tf.name_scope('layer2-pool1'):
        pool1 = tf.nn.max_pool(relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
    # 使用LRN对结果进行处理-Local Response Normalization-本地响应标准化
    # 增强大的抑制小的,增强泛化能力
    norm1 = tf.nn.lrn(pool1, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75)
    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))
        conv2 = tf.nn.conv2d(norm1,conv2_weights, strides=[1, 1, 1, 1], padding='SAME')
        relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))

    with tf.name_scope('layer4-pool2'):
        pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

    # 全连接层
    # 将样本变成一维向量
    reshaped = tf.reshape(pool2, [batch_size, -1])
    # 数据扁平化后的长度
    dim = reshaped.get_shape()[1].value
    with tf.variable_scope('layer5-fc1'):
        fc1_weights = tf.get_variable('weight', [dim, 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.0))
        fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases)
        #if train:
          #  fc1 = tf.nn.dropout(fc1, 0.5)

    with tf.variable_scope('layer6-fc2'):
        fc2_weights = tf.get_variable('weight', [FC_SIZE, FC_SIZE_2],
                                      initializer=tf.truncated_normal_initializer(stddev=0.04))
        if regularizer != None:
            tf.add_to_collection('losses', regularizer(fc2_weights))
        fc2_biases = tf.get_variable('bias', [FC_SIZE_2],
                                     initializer=tf.constant_initializer(0.1))
        fc2 = tf.nn.relu(tf.matmul(fc1, fc2_weights) + fc2_biases)
    with tf.variable_scope('layer7-fc3'):
        fc3_weights = tf.get_variable('weight', [FC_SIZE_2, FC_SIZE_3],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer != None:
            tf.add_to_collection('losses', regularizer(fc3_weights))
        fc3_biases = tf.get_variable('bias', [FC_SIZE_3],
                                     initializer=tf.constant_initializer(0.0))
        fc3 = tf.nn.softmax(tf.matmul(fc2, fc3_weights) + fc3_biases)
    return fc3

3.4 LeNet_train.py

# _*_ coding: utf-8 _*_
import os
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data

# 加载mnist_inference.py中定义的常量和前向传播的函数
import myLenet.LeNet_inference as LeNet_inference
import myLenet.cifar10  as cifar10
import myLenet.cifar10_input as cifar10_input
# 配置神经网络的参数
BATCH_SIZE = 128
batch_size = 128
LEARNING_RATE_BASE = 0.01   #0.8   #
LEARNING_RATE_DECAY =   0.0005     # 0.99
REGULARAZTION_RATE = 0.0001
TRAIN_STEPS = 30000    #3000
MOVING_AVERAGE_DECAY = 0.99

MODEL_SAVE_PATH = "./model/"
MODEL_NAME = "model3.ckpt"
# 下载DIFAR-10数据的默认路径 
data_dir = 'C:/Users/xpb/PycharmProjects/MachineVison3/cifar10_data/cifar-10-batches-bin'
def train():

    # 从Alex的网站下载并解压到默认位置,需要到cifar10.py修改文件下载的位置
    #cifar10.maybe_download_and_extract()
    # 使用Reader操作构造CIFAR训练需要的数据(特征及其对应的label)
    # 并对数据进行了数据增强(水平翻转/随机对比度亮度/随机裁剪)以及数据的标准化
    print("数据读取开始!")
    images_train, labels_train = cifar10_input.distorted_inputs(data_dir=data_dir, batch_size=batch_size)
    # 使用Reader操作构建CIFAR评估的输入(裁剪图像中间24*24大小的块并进行数据标准化)
    images_test, labels_test = cifar10_input.inputs(eval_data=True, data_dir=data_dir, batch_size=batch_size)
    onehot_labels = tf.one_hot(labels_train, depth=10, axis=-1)
    print("数据读取完成!")
    # 输入图像占位符(24*24 3通道)
    image_holder = tf.placeholder(tf.float32, [batch_size, 24, 24, 3], name='image_holder')
    # 输入标签占位符
    label_holder = tf.placeholder(tf.int32, [batch_size], name='y-input')
    #label_holder = tf.placeholder(tf.int32, [batch_size, LeNet_inference.OUTPUT_NODE], name='y-input')

    regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE)

    y = LeNet_inference.inference(image_holder, train, regularizer)
    # 假如需要保存y,以便在预测时使用
    tf.add_to_collection('network-output', y)

    global_steps = tf.Variable(0, trainable=False)
    #
    variable_average = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_steps)
    variable_average_op = variable_average.apply(
        tf.trainable_variables())
    #cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.argmax(label_holder, 1), logits=y)
    labels = tf.cast(label_holder, tf.int64)
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=labels)
    cross_entropy_mean = tf.reduce_mean(cross_entropy)

    loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses'))
    # 将logits节点label_holder和传入loss函数获得最终的loss

    #学习率(learning rate)控制着参数的更新速度:此处为指数衰减法
    learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE,
                                               global_step=global_steps, decay_steps=(50000) / BATCH_SIZE,
                                               decay_rate=LEARNING_RATE_DECAY)
    #优化器:梯度下降   minimize()函数处理了梯度计算和参数更新两个操作  AdamOptimize
    #train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss, global_step=global_steps)
    train_step = tf.train.AdamOptimizer(1e-3).minimize(loss, global_step=global_steps)
  
    with tf.control_dependencies([train_step, variable_average_op]):
        # with tf.control_dependencies([train_step]):
        train_op = tf.no_op(name='train')

    saver = tf.train.Saver()
    # 创建默认的session()
    sess = tf.InteractiveSession()
    #with tf.Session() as sess:
    tf.global_variables_initializer().run()
        # 启动图片数据增强的线程队列
    tf.train.start_queue_runners()
    print("开始处理!")
    for i in range(TRAIN_STEPS):
            image_batch, label_batch = sess.run([images_train, labels_train])
            _, loss_value, step,yy = sess.run([train_op, loss, global_steps,y],
                                           feed_dict={image_holder: image_batch, label_holder:label_batch})

            if i % 10 == 0:
                np.set_printoptions(threshold=np.nan)
                print("---------预测结果---------")
                y_test = np.argmax(yy, 1)
                print(y_test[:10])
                d = np.argwhere(label_batch != y_test)
                print("预测错误数:",len(d))
                print("After %d training steps, loss on training"
                      "batch is %f" % (i, loss_value))
                saver.save(sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=global_steps)

def main(argv=None):
    train()

if __name__ == '__main__':
    tf.app.run()

3.5 LeNet_test.py

from tensorflow.contrib.keras.api.keras.models import load_model
import tensorflow as tf
import numpy as np
import myLenet.cifar10_input as cifar10_input
import myLenet.LeNet_inference as LeNet_inference
data_dir = 'C:/Users/xpb/PycharmProjects/MachineVison3/cifar10_data/cifar-10-batches-bin'
# 训练轮数
max_steps = 3000
batch_size = 128

if __name__ == '__main__':
    np.set_printoptions(threshold=np.nan)
    # 使用Reader操作构建CIFAR评估的输入(裁剪图像中间24*24大小的块并进行数据标准化)
    # 获取测试集的数据
    images_test, labels_test = cifar10_input.inputs(eval_data=False, data_dir=data_dir, batch_size=batch_size)
    #images_test, labels_test = cifar10_input.distorted_inputs(data_dir=data_dir, batch_size=batch_size)

    onehot_labels = tf.one_hot(labels_test, depth=10, axis=-1)
    print(type(images_test))
 
    num_examples = 10000
    import math

    num_iter = int(math.ceil(num_examples / batch_size))
    true_count = 0
    total_sample_count = num_iter * batch_size
    step = 0
    # 创建默认的session()
    sess = tf.InteractiveSession()
    tf.train.start_queue_runners()
    #with tf.Session() as sess:
        # 载入训练好的模型
    saver = tf.train.import_meta_graph('model/model3.ckpt-13691.meta')
    saver.restore(sess, tf.train.latest_checkpoint("model/"))

    while step < num_iter:
            pred = tf.get_collection('network-output')[0]
            image_batch, label_batch = sess.run([images_test, labels_test])
            onehot_labels_1 = sess.run([onehot_labels])
            print(type(image_batch))
            graph = tf.get_default_graph()
            x = graph.get_operation_by_name('image_holder').outputs[0]
            y_ = graph.get_operation_by_name('y-input').outputs[0]
            y = sess.run(pred, feed_dict={x: image_batch, y_: label_batch })
            step += 1
            print("---------真实值---------")
            print(label_batch[:10])
            print("---------预测结果---------")
            y_test = np.argmax(y, 1)
            print(y_test[:10])
            # print(y_lable)
            d = np.argwhere(label_batch != y_test)
            print("预测错误数:", len(d))
            true_count = true_count +(batch_size-len(d))
    # 统计预测正确的图片的数目
    precision = true_count / total_sample_count
    print('precision @ 1 = %.3f' % precision)

3.6 运行结果

image.png

参考资料

[0][CIFAR-10数据集连接 包含获取数据集的代码
[1] Tensorflow深度学习之二十:CIFAR-10数据集介绍
[2] 浅入浅出TensorFlow 4 - 训练CIFAR数据
[3] 在tensorflow上训练cifar10数据集
[4] cifar官网
[5] TensorFlow学习--卷积神经网络训练CIFAR-10数据集很好,训练加测试

[6] TensorFlow入门:第一个机器学习Demo
[7] tensorflow 从入门到上天教程一
[8] TensorFlow学习笔记-实现经典LeNet5模型
[9] # 深度学习(五)基于tensorflow实现简单卷积神经网络Lenet5
[10] Tensorflow深度学习之二十一:LeNet的实现(CIFAR-10数据集)
[11] Tensorflow实例:(卷积神经网络)LeNet-5模型 很详细,很好
[12] 深度学习 CNN卷积神经网络 LeNet-5详解

相关文章

网友评论

    本文标题:TensorFlow实现Lenet在cifar10数据集运行

    本文链接:https://www.haomeiwen.com/subject/rgrucqtx.html