TensorFlow实战之CNN 发表于 2017-11-16 | 分类于 Deep Learning | 阅读次数 CNN 原理 Tensorflow实现CNNLeNet-5模型123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121import tensorflow as tfINPUT_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#全连接层节点数#输入参数def inference(input_tensor,train,regularizer): """ 第一层:卷积层 将28*28*1的原始图片像通过卷积核5*5卷积为28*28*32的矩阵,其中过滤器处理的矩阵深度为1,过滤器的深度为32 """ #为了便于变量管理,tf中通过变量名称获取变量的机制主要是通过tf.get_varibale和tf.varibale_scope函数来实现 with tf.variable_scope('layer1-conv1'): """ 第一个参数是name 第二个参数shape依次是卷积核高度,卷积核宽度,图像通道数(输入深度),卷积核个数(输出深度) 第三个参数是初始化权重参数的方式:采用截取的正态分布,标准差为0.1 """ conv1_weights=tf.get_variable( "weight",[CONV1_SIZE,CONV1_SIZE,NUM_CHANNELS,CONV1_DEEP], initializer=tf.truncated_normal_initializer(stddev=0.1)) """ 第二个参数是shape,偏差的维度是卷积后的深度(卷积核个数) 第三个参数是初始化偏差的方式,采用常量0.0来初始化 """ conv1_biases=tf.get_variable( "bias",[CONV1_DEEP], initializer=tf.constant_initializer(0.0)) """ 第一个参数:输入数据,shape为[batch,height,width,channels] 第二个参数:卷积核 第三个参数:步长,分别对应上面shape的每一个维度,即batch上步长为1,height上步长为1,width上步长为1,channels上步长为1 第四个参数:用全0补齐,这样的结果是,卷积前后矩阵的长宽不变 """ conv1=tf.nn.conv2d(input_tensor,conv1_weights,strides=[1,1,1,1],padding='SAME') """ 使用RELU函数作为激活函数 tf.nn.bias_add 将一维的偏差项加到conv1中 """ relu1=tf.nn.relu(tf.nn.bias_add(conv1,conv1_biases)) """ 第二层:池化层 池化层的目的是防止过拟合 将28*28*32的矩阵池化为14*14*32的矩阵 该池化层的参数说明如下: 第一个参数是输入矩阵 第二个参数是池化矩阵大小:对应着[batch,height,width,channels],即对一个batch的2*2*1池化 第三个参数是步长,与上面对应,每次移动一个batch的2个高,2个宽,深度为1的步长 第三个参数是使用全0填充 """ with tf.name_scope("layer2-pool1"): pool1=tf.nn.max_pool(relu1,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)) conv2=tf.nn.conv2d(pool1,conv2_weights,strides=[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(relu2,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME") pool_shape=pool2.get_shape().as_list()#获取shape并转为list nodes=pool_shape[1]*pool_shape[2]*pool_shape[3]#将矩阵(计算矩阵(7*7*64)的节点个数,用于全连接的输入节点,第一维为batch reshaped=tf.reshape(pool2,[pool_shape[0],nodes])#将pool2从[batch,7,7,64]变为[batch,7*7*64] """ 第五层:全连接层 输入节点为7*7*64 输出节点为512 """ 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 """ with tf.variable_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 训练程序123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596import tensorflow as tfimport chapter6.letNet_inference as letNet_inferenceimport numpy as npBATCH_SIZE=100#批量处理的大小LEARNING_RATE_BASE=0.01#学习率LEARNING_RATE_DECAY=0.99#REGULARIZATION_RATE=0.0001#正则化系数TRAINING_STEPS=6000#训练次数MOVING_AVERAGE_DECAY=0.99#衰减率def train(mnist): """ :param mnist: :return: """ """ 输入张量 第一个参数为值的类型 第二个参数为张量矩阵,shape表示:批量个数,原始图片像素长,原始图片像素宽,原始图片像素深度 第三个参数:变量名 """ x=tf.placeholder( tf.float32, [BATCH_SIZE,letNet_inference.IMAGE_SIZE,letNet_inference.IMAGE_SIZE,letNet_inference.NUM_CHANNELS], name='x-input') """ 输出张量 第一个参数为值类型 第二个参数为张量矩阵, """ y_=tf.placeholder( tf.float32, [None,letNet_inference.OUTPUT_NODE], name='y-input') regularizer=tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)#L2正则 y=letNet_inference.inference(x,False,regularizer) global_step=tf.Variable(0,trainable=False) variable_averages=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step) variable_averages_op=variable_averages.apply(tf.trainable_variables()) """ logits:其shape是[batch_size,num_classes],一般为神经网络的最后一层 labels:shape与logits相同,神经网络期望的输出 tf.argmax:表示对矩阵(y_)按行或列(0表示按列,1表示按行)计算最大值 这个函数的作用就是计算最后一层softmax层的cross entropy,然后将输出的结果和labels做交叉熵 返回的是一个向量,这里还需要将向量中的值全部求和取平均 关于这个函数说明参见:https://www.cnblogs.com/welhzh/p/6595032.html """ cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_,1)) cross_entropy_mean=tf.reduce_mean(cross_entropy)#求取平均值 loss=cross_entropy_mean+tf.add_n(tf.get_collection('losses'))#交叉熵和正则项作为损失函数 """ 指数衰减法 参数依次如下: 基础学习率, 当前迭代轮数, 迭代次数,(这里取得是训练完所有数据需要迭代的次数)【表示的是迭代该次数后,对基础学习率进行修正】 学习率衰减速度 """ learning_rate=tf.train.exponential_decay( LEARNING_RATE_BASE, global_step, mnist.train.num_examples/BATCH_SIZE, LEARNING_RATE_DECAY, staircase=True) """ 优化算法,以learning_rate的速率来最小化损失函数, """ train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step) """ """ with tf.control_dependencies([train_step,variable_averages_op]): train_op=tf.no_op(name='train') saver=tf.train.Saver() with tf.Session() as sess: tf.global_variables_initializer().run() for i in range(TRAINING_STEPS): xs,ys=mnist.train.next_batch(BATCH_SIZE) #将训练数据格式调整为一个二维矩阵 reshaped_xs = np.reshape(xs, ( BATCH_SIZE, letNet_inference.IMAGE_SIZE, letNet_inference.IMAGE_SIZE, letNet_inference.NUM_CHANNELS)) _, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: reshaped_xs, y_: ys}) if i % 1000 == 0: print("After %d training step(s), loss on training batch is %g." % (step, loss_value)) 如果觉得有帮助,给我打赏吧! 赏 微信打赏 支付宝打赏