Tensorflow中级教程——用于Mnist的CNN

来源:互联网 发布:mac更改登录用户名 编辑:程序博客网 时间:2024/05/18 02:32

教程来自人工智能社区

主要包括10节内容,实现简单卷积神经网络对MNIST数据集进行分类:conv2d + activation + pool + fc

#第1节:简单卷积神经网络的计算图设计(上)#第2节:简单卷积神经网络的计算图设计(下)#调用写好的函数构造计算图,并把计算图写入事件文件,在TensorBoard里面查看#写好的函数:WeightsVariable、BiasesVariable、Conv2d、Activation、Pool2d、FullyConnected
#第3节:简单卷积神经网络的训练和评估会话
#加入了csv文件收集训练过程的数据#通用的评估函数,用来评估模型在给定的数据集上的损失和准确率,为了防止内存爆炸,将数据集切片
#第4节:卷积滤波器核的数量与网络性能之间的关系#研究卷积层中的卷积核个数K与在训练集和验证集上损失曲线、正确率曲线的关系#在excise3_1_2的基础上添加了一个变量conv1_kernels_num(卷积核个数K)
具体分析结果:点击打开链接#第5节:用Excel绘制网络性能曲线#输出结果保存在logs/excise313/evaluate_results.csv,将文件另存为.xlsx的Excel表格形式,绘制曲线#第6节:改变网络激活函数观察网络性能的变化##非线性激活层with tf.name_scope('Activate')##全连接层activate(wx+b)的封装 def FullyConnected(x, W, b, activate=tf.nn.relu, act_name='relu')#不同的激活函数适用于这两处,详见点击打开链接#保持卷积层(全连接层)的激活函数不变,不断改变全连接层(卷积层)的激活函数,观察网络性能的变化
#3.7 学习率与权重初始化对网络性能的影响分析#学习率越大曲线抖动越大,网络越不稳定,受初始条件的影响大#学习率对网络的训练过程有着至关重要的影响:#1.学习率比较小时,网络的损失曲线下降的比较慢,但是损失曲线的形态在不同的随机起始状态下比较一致,波纹比较小#2.学习率比较大时,网络的损失曲线下降的比较快,但是损失曲线的形态在不同的随机起始状态下差别比较大,波纹比较大#所以,学习率的设置应该遵循“稳中求进”的基本原则#池化层变化对网络性能的影响分析(最大池化与平均池化),小网络中并没有多少影响#权重初始化对网络性能的影响分析,默认情况下取stddev=0.1,不能取特别小的值
详情见点击打开链接

#3.8 使用10种不同的优化器训练模型,观察性能曲线
# 定义优化训练层(train layer)(studyai.com)with tf.name_scope('Train'):    learning_rate = tf.placeholder(tf.float32)    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)    global_step = tf.Variable(0,name='global_step', trainable=False, dtype=tf.int64)    #optimizer = tf.train.AdagradDAOptimizer(learning_rate=learning_rate, global_step=global_step)    #optimizer = tf.train.AdadeltaOptimizer(learning_rate=learning_rate)    #optimizer = tf.train.AdagradOptimizer(learning_rate=learning_rate)    #optimizer = tf.train.ProximalGradientDescentOptimizer(learning_rate=learning_rate)    #optimizer = tf.train.ProximalAdagradOptimizer(learning_rate=learning_rate)    #RMSPropOptimizer这个优化器比较好,对学习率不太敏感,都能收敛    #optimizer = tf.train.RMSPropOptimizer(learning_rate=learning_rate)    #GradientDescentOptimizer这是最早的优化器,对学习率比较敏感    #optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)    #optimizer = tf.train.MomentumOptimizer(learning_rate=learning_rate, momentum=0.9)    #optimizer = tf.train.FtrlOptimizer(learning_rate=learning_rate)    trainer = optimizer.minimize(cross_entropy_loss,global_step=global_step)

#3.9 增加一个非线性全连接层并观察过拟合现象#增加非线性全连接层with tf.name_scope('FC_ReLU')#不断全连接层的神经元个数,观察其对网络过拟合的影响

        # 第一个全连接层(fully connected layer)        with tf.name_scope('FC_ReLU'):            fcl_units_num = 100            weights = WeightsVariable(shape=[12 * 12 * conv1_kernels_num, fcl_units_num], name_str='weights')            biases = BiasesVariable(shape=[fcl_units_num], name_str='biases')            fc_out = FullyConnected(features, weights, biases,                                            activate=tf.nn.relu, act_name='relu')        # 第二个全连接层(fully connected layer)        with tf.name_scope('FC_Linear'):            weights = WeightsVariable(shape=[fcl_units_num, n_classes], name_str='weights')            biases = BiasesVariable(shape=[n_classes], name_str='biases')            Ypred_logits = FullyConnected(fc_out, weights, biases,                                          activate=tf.identity, act_name='identity')



#3.10 为非线性全连接层添加正则化损失
#为了防止过拟合,增加正则化技术#方法一:为非线性全连接层的权重输出添加dropout正则化,即在FC_ReLU层后添加dropout层#随机失活的神经元比例keep_prob,取值0-1,不能取0#值越大,保留的越多,随机失活(使其输出为0)的神经元越少,即丢弃的越少,正则化强度越弱
设置超参数:keep_prob_init = 0.5
        #dropout层,正则化技术        with tf.name_scope('Dropout'):            keep_prob = tf.placeholder(tf.float32)            fc_dropout = tf.nn.dropout(fcl_out, keep_prob)
                # 运行优化器训练节点 (backprop)                sess.run(trainer, feed_dict={X_origin: batch_x,                                             Y_true: batch_y,                                             learning_rate: learning_rate_init,                                             keep_prob: keep_prob_init})

#方法二:为非线性全连接层的权重添加L2正则化# 即在FC_ReLU层中添加权重的L2损失,并将其与交叉熵损失相加得到总体损失#正则化强度系数wd,取值0-1#值越大,正则化强度越强,取0.1,0.01,0.001,0.0001
#保存l2loss的输出结果
        # 第一个全连接层(fully connected layer)        with tf.name_scope('FC_ReLU'):            fcl_units_num = 100            weights = WeightsVariable(shape=[12 * 12 * conv1_kernels_num, fcl_units_num], name_str='weights')            biases = BiasesVariable(shape=[fcl_units_num], name_str='biases')            fc_out = FullyConnected(features, weights, biases,                                            activate=tf.nn.relu, act_name='relu')            #为非线性全连接层添加L2正则化损失            with tf.name_scope('L2_Loss'):                weights_loss = tf.nn.l2_loss(weights)
    # 定义损失层(loss layer)    with tf.name_scope('Loss'):        wd = 0.00001        with tf.name_scope('XEntroyLoss'):            cross_entropy_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(                labels=Y_true, logits=Ypred_logits))        with tf.name_scope('TotalLoss'):            weights_loss = wd * weights_loss            #总体的损失 = 经验损失 + 正则化损失            total_loss = cross_entropy_loss + weights_loss
                    # 计算当前模型的正则化损失,用以保存到.csv文件                    l2loss = sess.run(weights_loss)                    # 将评估结果保存到文件                    results_list.append([training_step, train_loss, validation_loss,l2loss,                                         training_step, train_acc, validation_acc])