《深度学习:主流框架和编程实战》——2.3.5 实验结果及分析
2.3.5 实验结果及分析
1.实验运行
用户可以通过在终端输入python cifar10_main.py来执行该实例。训练以及测试的截图如图2-10~图2-14所示。
图2-10 开始训练ResNet
图2-11 ResNet训练第782步
图2-12 ResNet训练第9775步
图2-13 ResNet测试图片
图2-14 ResNet测试图片类别
2.测试误差(见图2-15)
图2-15 误差曲线
3.实验结果分析
本实验运行过程包括训练和验证两个部分。从图2-15的误差曲线可以看出,在网络ResNet-34初期,训练误差和测试误差都会很大。随着迭代次数的增加,训练误差和验证误差有着显著的降低,从开始训练误差0.898438、验证误差0.912、验证损失2.3543降低到第9775步的训练误差0.117188、验证误差0.1280、验证损失0.348188。在进行到1000步以上时,误差曲线在0.1附近收敛。随着ResNet网络层数的增加,网络在Cifar-10的测试误差确实有所降低,当层数达到110层时,网络的性能达到最优。当ResNet网络超过1000层时,该网络的优化就很难了,测试误差比ResNet-110高出1.5%,可能是训练网络产生了过拟合现象,而对于相对小的数据集,不必要设计如1202层那样深的网络。在数据集上,使用正则化,例如,Maxout和Dropout会得到更好的结果。但是,在本网络中,没有使用Maxout或是Dropout,只是简单地使用正则化设计网络架构。
最后关于测试图片分类效果,由图2-15可以看出ResNet-34网络在训练10000步之后,能够很好地得出测试图片的类别。证明了ResNet确实克服了优化困难,当增加了深度时,确实可以获得很好的精确度收益。
4.调整网络参数
若想要修改网络的结构,可在resnet.py和hyper_parameters.py中找到修改具体的参数的方法。
pooled_input = tf.nn.avg_pool(input_layer, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='VALID')(1)
语句(1)中可以修改网络中的池化层,包括池化层核大小、池化步长,以及有
效性。
conv1 = residual_block(layers[-1], 16)(2)
conv2 = residual_block(layers[-1], 32)(3)
conv3 = residual_block(layers[-1], 64)(4)
语句(2)、(3)、(4)中分别定义了卷积层1、2、3中不同残差构件大小。分别为16×16、32×32、64×64。
tf.app.flags.DEFINE_integer('train_steps’, 80000,
'''Total steps that you want to train''')(5)
语句(5)中定义了训练总步数为80000步,可以根据自己的需求进行修改。
tf.app.flags.DEFINE_float('lr_decay_factor’, 0.1,
''How much to decay the learning rate each time''')(6)
语句(6)中定义了每次学习率的衰减因子,学习率较大时,容易在搜索过程中发生震荡,因此需要通过学习率衰减因子来不断动态调整。在本网络中,在第40000步和第60000步分别有一次学习率衰减的发生。
tf.app.flags.DEFINE_integer('train_batch_size', 128, '''Train batch size''')(7)
tf.app.flags.DEFINE_integer('validation_batch_size', 250, )(8)
tf.app.flags.DEFINE_integer('test_batch_size', 125, '''Test batch size''')(9)
语句(7)、(8)、(9)分别定义了网络中训练批次大小、验证批次大小、测试批次大小,分别为128、250、125。对于Batch大小的选择,首先决定的是下降的方向,如果数据集比较小,完全可以采用全数据集学习(Full Batch Learning)的形式。对于大的数据集,随着数据集的海量增长和内存限制,一次性载入所有数据变得越来越不可行。如果数据集足够充分,那么用一半(甚至少得多)的数据训练算出来的梯度与用全部数据训练出来的梯度几乎是一样的。
- 点赞
- 收藏
- 关注作者
评论(0)