tensorflow 利用mnist数据集训练卷积网络

播客参考 https://blog.csdn.net/zyp199301/article/details/70247174 thanks a lot

本例子实现了net_model.py 和 train.py。

net_model.py中包括模型类,一些搭建cnn模型的基本函数,如cnn层,max_pooling,weights的生成,bias的生成,l2 regularization等

train.py 中包括训练数据的准备,训练,模型的保存等

net_model.py如下

# author guoyibo
# 影响神经网络模型性能的几个方面
# 1 网络结构:有多少层;多少卷积层,每次卷积核尺寸,卷积核数量;多少全连接层,每次全连接层神经元个数,rnn lstm
# 2 初始化权值和偏置方法
# 3 激活函数 1 sigmoid 2 thah 3 relu
# 4 优化方法 adam,sdg等
# 5 学习率及学习率递减方法
# 6 batch normalization
# 抑制过拟合方法 1 数据增强 2 dropout 3 正则化方法 l1 l2
# 抑制欠拟合的方法 1 选用更加复杂的模型
# 经典基础分类模型 alexnet,vgg,inception, resnet,等
# 经典检测算法 faster rcnn, ssd yolo等


import tensorflow as tf
from operator import mul
from functools import reduce


class Net_model():
    def __init__(self):
        pass

    def network(self):

        return net_work('2l_con_2l_fc_softmax')


def l2_regularizer(weight_decay=0.0001):
    # 下面函数会自动的地把计算的l2 loss 加入到key值为tf.GraphKeys.REGULARIZATION_LOSSES的collection
    # 使用的时候 l2_loss = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES) 得到的是一个列表
    # l2_loss = tf.add_n(l2_loss) 把列表内容求和
    return tf.contrib.layers.l2_regularizer(weight_decay)


def w_set(shape, name='weight'):
    return tf.get_variable(name,
                           shape=shape,
                           dtype=tf.float32,
                           initializer=tf.truncated_normal_initializer(stddev=0.01),
                           regularizer=l2_regularizer(),
                           trainable=True)


def bias_set(shape, name='bias'):
    return tf.get_variable(name,
                           shape=shape,
                           dtype=tf.float32,
                           initializer=tf.constant_initializer(0.01),
                           regularizer=None,
                           trainable=True)


def conv_layer(input,filter_h, filter_w, i_channel, o_channel,s_s,s_v,activate, name='conv_layer'):
    with tf.variable_scope(name):
        filter_shape = [filter_h, filter_w, i_channel, o_channel]
        filter_weight = w_set(filter_shape)
        bias = bias_set([o_channel])
        conv = tf.nn.conv2d(input,
                            filter_weight,
                            strides=[1,s_s,s_v,1],
                            padding='SAME')
        conv_bias = conv + bias
        # relu max(0,u) 0-->无穷
        if activate == 'relu':
            conv_bias = tf.nn.relu(conv_bias)
        # sigmoid 1/(1 + e^(-x))  [0,1]
        if activate == 'sigmoid':
            conv_bias = tf.nn.sigmoid(conv_bias)
        # tanh (e^(x) - e^(-x))/e^(x) + e^(-x)
        if activate == 'tanh':
            conv_bias = tf.nn.tanh(conv_bias)

        return conv_bias


def max_pool(input, name, ksize = [1,2,2,1], strides = [1,2,2,1],padding='SAME'):
    return tf.nn.max_pool(input,ksize,strides,padding, name=name)


def fc(input, hidden_size, name):
    with tf.variable_scope(name):
        shape = input.get_shape().as_list()
        # in_size = reduce(mul,shape[1:]) #   求列表元素的积
        fc_w = w_set([shape[-1], hidden_size])
        fc_bias = bias_set([hidden_size])
        fc_out = tf.matmul(input,fc_w) + fc_bias
        return fc_out


def dropout(input,keep_prob,name):
    return tf.nn.dropout(input,keep_prob,name=name)


def soft_max(input,name):
    return tf.nn.softmax(input,name=name)


# def batch_normalization(inputs):
#     return tf.layers.batch_normalization(inputs)


# 网络结构:con1-pool1-con2-pool2-fc1-fc2-softmax
def net_work(name):
    # 下面的语句意思是,利用tf.Graph()创建一个graph,并作为一个default graph,加入这一句的目的是要返回这张graph
    # 下面创建的
    with tf.Graph().as_default() as g:
        x = tf.placeholder(tf.float32, [None, 28, 28, 1])
        y_ = tf.placeholder(tf.float32, [None, 10])
        keep_prob = tf.placeholder(tf.float32)
        # con1-pool1-con2-pool2-fc1-fc2-softmax
        with tf.variable_scope(name):
            # conv1
            net = conv_layer(x,5,5,1,32,1,1,'relu',name='conv1_relu')
            # max pool1
            net = max_pool(net,name='max_pool1')

            # conv2
            net = conv_layer(net,5,5,32,64,1,1,'relu',name='conv2_relu')
            # max pool2
            net = max_pool(net,name='max_pool2')

            # data flatten
            net_shape = net.get_shape().as_list()
            node_num = net_shape[1] * net_shape[2] * net_shape[3]
            net = tf.reshape(net,[-1,node_num])
            # fc1
            net = fc(net,1024,name='fc1')

            # dropout
            net = dropout(net,keep_prob,name='dropout')

            # fc2
            net = fc(net,10,name='fc2')

            # softmax
            y_prediction = soft_max(net,name='softmax')

            feed_dict = {'x':x,'y_':y_,'keep_prob':keep_prob}

            return y_prediction, feed_dict, g

train.py

"""author guoyibo 
    reference: https://blog.csdn.net/zyp199301/article/details/70247174
    thanks a lot
"""

import os
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

from time import strftime, localtime

from nn_common.net_model import Net_model
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

DATA_FORMAT = 'NHWC'


def obtain_feed_dict(feed_dict, batch_x, batch_y, keep_prob):
    # print(feed_dict.keys())
    res_feed_dict = {feed_dict['x']:batch_x,
                     feed_dict['y_']:batch_y,
                     feed_dict['keep_prob']:keep_prob}
    return res_feed_dict


def main(_):
    mnist = input_data.read_data_sets('./MNIST_data', one_hot=True)

    # 获取模型
    net_model = Net_model()
    y_prediction, feed_dict, g = net_model.network()
    # 把返回的graph g 当做默认graph
    with g.as_default():
        # print(y_prediction.get_shape().as_list())

        # 设置全局步数
        global_step = tf.Variable(0, trainable=False,name='global_step')

        #
        variable_averages = tf.train.ExponentialMovingAverage(0.99,global_step)
        ave_vars = [variable_averages.average(var) for var in tf.trainable_variables()]
        variable_averages_op = variable_averages.apply(tf.trainable_variables())

        # loss
        cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.argmax(feed_dict['y_'],-1),
                                                                       logits=y_prediction)
        cross_entropy_mean = tf.reduce_mean(cross_entropy)

        # get l2 regularization loss
        regularization_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
        regularization_losses = tf.add_n(regularization_losses,name='regularization_losses')

        # total loss
        total_loss = cross_entropy_mean + regularization_losses

        # learning_rate
        learning_rate = tf.train.exponential_decay(0.0001,global_step,mnist.train.num_examples/32,0.99)

        # train_step
        train_step = tf.train.AdamOptimizer(learning_rate).minimize(total_loss,global_step=global_step)

        # correction accuracy
        correct_prediction = tf.equal(tf.argmax(y_prediction,1),tf.argmax(feed_dict['y_'],1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

        # 控制执行顺序
        with tf.control_dependencies([train_step, variable_averages_op]):
            train_op = tf.no_op(name='train')

        # 应用文件夹名字
        app_folder_name = strftime('%Y%m%d%H%M%S',localtime())

        save_root = './ckpt/%s/' % app_folder_name
        if not os.path.exists(save_root):
            os.makedirs(save_root)
        # for debug
        # 获取可以训练的变量
        # variables = tf.trainable_variables()
        # for var in variables:
        #     print(var)
        # print('*'*1000)

        # 获取所有的变量
        # global_variables = tf.global_variables()
        # for var in global_variables:
        #     print(var)

        # 保存模型
        saver = tf.train.Saver(max_to_keep=3)
        # for debug
        # with tf.Session() as sess:
        #     sess.run(tf.global_variables_initializer())
        #     batch_x, batch_y = mnist.train.next_batch(32)
        #     print(batch_y.shape)
        #     reshape_batch_x = np.reshape(batch_x, (32,28,28,1))
        #     keep_prob = 0.5
        #     feed_dict = obtain_feed_dict(feed_dict, reshape_batch_x,batch_y,keep_prob)
        #     a = sess.run(y_prediction,feed_dict=feed_dict)
        #     print(a.shape)
        # 在创建session()时如果参数graph=None,那么session会加载默认graph
        with tf.Session() as sess:
            # 对当前graph中的所有global_variables进行初始化
            sess.run(tf.global_variables_initializer())

            for i in range(1,20000):
                keep_prob = 0.5

                batch_x, batch_y = mnist.train.next_batch(32)
                reshape_batch_x = np.reshape(batch_x, (32,28,28,1))

                train_feed_dict = obtain_feed_dict(feed_dict, reshape_batch_x,batch_y,keep_prob)

                _, loss, step,lr = sess.run([train_op,total_loss,global_step,learning_rate],feed_dict=train_feed_dict)

                if i % 100 == 0 and i != 0:
                    saver.save(sess, save_root + 'model.ckpt',global_step=global_step)
                    test_x = mnist.test.images
                    reshape_test_x = np.reshape(test_x,[-1,28,28,1])
                    test_y = mnist.test.labels
                    keep_prob_test = 1.0
                    test_feed_dict = obtain_feed_dict(feed_dict,reshape_test_x,test_y,keep_prob_test)
                    accuracy_score = sess.run(accuracy,feed_dict=test_feed_dict)
                    print('step:%d, total loss:%.6f, test accuracy:%.6f, learning_rate:%.8f'
                          % (step, loss,accuracy_score, lr))


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

猜你喜欢

转载自blog.csdn.net/ruguowoshiyu/article/details/82875907