播客参考 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()