这篇文章是对TensorFlow官方例子:CIFAR-10数据集分类的理解记录。
对CIFAR-10 数据集的分类是机器学习中一个公开的基准测试问题,其任务是对一组大小为32x32的RGB图像进行分类,这些图像涵盖了10个类别:
飞机, 汽车, 鸟, 猫, 鹿, 狗, 青蛙, 马, 船以及卡车。
这里主要介绍cifar10_input.py
、caifar10.py
、caifar_train.py
和cifar10_eval.py
模型输入
cifar10_input.py
文件,从二进制文件cifar-10-binary.tar.gz
中提取数据
1 | def distorted_inputs(data_dir, batch_size): |
主要函数有两个,inputs
和distorted_inputs
,这里贴出来的是distorted_inputs
。两个方法都是从训练/测试 数据集文件中读取数据,后者针对测试集,裁剪图像、提取变换成相应的格式,前者针对训练集,在变化成需要格式前,还要进行图像的处理,如翻转,亮度变换、随机替换等等来增加数据集。返回的是构建生成的数据样本和标签。
模型构建
使用CNN模型,包括两级卷基层、两级全连接层和最后的softmax激励函数输出。
模型
1 | def inference(images): |
训练阶段
loss
1 | def loss(logits, labels): |
train
训练阶段就是通过训练算法迭代优化,最小化损失函数的过程。
1 | #接受参数:总损失def train(total_loss, global_step): |
测试阶段
1 | # 测试一次的函数,saver是操作模型参数文件checkpoints的对象;top_k_op计算准确率def eval_once(saver, summary_writer, top_k_op, summary_op): |
其他
关于tf.train.shuffle_batch 中的参数 shuffle、min_after_dequeue
shuffle的作用在于指定是否需要随机打乱样本的顺序,一般作用于训练阶段,提高鲁棒性。
- 当shuffle = false时,每次dequeue是从队列中按顺序取数据,遵从先入先出的原则
- 当shuffle = true时,每次从队列中dequeue取数据时,不再按顺序,而是随机的,所以打乱了样本的原有顺序。
shuffle还要配合参数min_after_dequeue使用才能发挥作用。这个参数min_after_dequeue的意思是队列中,做dequeue(取数据)的操作后,queue runner线程要保证队列中至少剩下min_after_dequeue个数据。如果min_after_dequeue设置的过少,则即使shuffle为true,也达不到好的混合效果。
因为我们的目的肯定是想尽最大可能的混合数据,因此设置min_after_dequeue,可以保证每次dequeue后都有足够量的数据填充尽队列,保证下次dequeue时可以很充分的混合数据。
但是min_after_dequeue也不能设置的太大,这样会导致队列填充的时间变长,尤其是在最初的装载阶段,会花费比较长的时间。
关于训练与测试
在以前的教程中,都是将训练和评估放在一个程序中运行,而在这个教程中,训练和评估是分开在两个独立的程序中进行的,之所以这样做,是因为评估过程不会直接使用训练学习到的模型参数(trainable variable的值),而是要使用的是变量的滑动平均(shadow variable)来代替原有变量进行评估。
具体的实现方法是,在训练过程中,为每个trainable variable 添加 指数滑动平均变量,然后每训练1000步就将模型训练到的变量值保存在checkpoint中,评估过程运行时,从最新存储的checkpoint中取出模型的shadow variable,赋值给对应的变量,然后进行评估