另一个 TensorFlow 图片分类例子

第二次能 “出点结果” 了。仍然是一个 Demo。

这次的目的是使用 TfRecord 这个文件格式来存储数据集(上次 是用 txt,用到图片就现读取)。

所以,第一步,我们要写一个将数据集转换成 TfRecord 的脚本。

将数据集转换成 TfRecord 格式

我们依然使用 flower 这个数据集。5 个文件夹是图片的类别,每个文件夹下一大堆图片。

在这里,由于 TensorFlow 还用不好,所以使用比较熟悉的 ScikitImage 来读入和转换图片。读入图片后,将其序列化为 Example 这个 “名字很奇怪” 的类型,然后保存到磁盘上。代码见这里:

使用数据集

使用 tf.contrib.data.TFRecordDataset 创建数据集。然后对每一条记录进行反解析,得到图片、标签,最后将数据送入网络。

想使用一些比较高级的 API,例如 tf.estimator 等。虽然手动控制 Session 很方便,但是这些高级 API 还是能用就用吧,毕竟可以自动加入 TensorBoard、自动 Load 之前的状态等等。

这里没用 Slim 来定义网络。Slim 定义网络确实方便,但是感觉 tf.layers 定义网络也不怎么复杂。所以呢,各有所爱吧。

自己写网络

下一步就是把网络给换掉了。这里使用 Tiny Yolo 试试:

这是一个我一直垂涎的小网络。只需要把上面的相应函数替换掉,类别改成 5,然后重新制作数据集,图片大小改为 224×224×3 即可。

运行看看效果吧~

TensorBoard TinyYolo 训练截图

后记

数据集转换代码几乎都是自己写的。

网络代码大部分参考了 官方 Models 的代码

我是这样进行调试的: 现在已知官方 mnist 分类代码是可以正常工作的,那么如果我做出来的数据集也能正常工作,那么就说明我的代码没问题。所以,县写一个数据集转换的代码,一点一点进行调试,直到生成的数据集能让官方 mnist 分类代码可以正常工作为止。然后再根据需要,同步修改两边的代码。

本来数据集转换那里想使用 TensorFlow 的 image 包里面的东西,但是实在控制不好。例如,读入图片之后,直接 decode_image 出来的图片没有 channel 信息,用 decode_jpeg 出来的图不能 resize,提示「没有 size」。各种乱了一整天之后,最终决定使用 Scikit-Image 来进行读入和图片简单预处理。但我发现,使用 TensorFlow 处理图片速度可达 400 张 / s,但使用 Scikit-Image 处理图片就只有 160 张 / s。大概是 TensorFlow 使用了多线程的缘故?

这次 GPU 使用率可以达到 50% 左右了。不知道为什么还是赶不上官方 Mnist 分类代码的 GPU 使用率(80~90%)。

而且,也不知道为什么,训练精度可以达到 99.99%,但是测试精度爬升到 50% 左右就开始下降了。下降是因为过拟合了,这个在 TensorBoard 上可以看出来(大概是在 5k 次迭代左右过拟合的),但是为什么测试精度最高只有 50% ?这是我想不通的地方。希望能看到这篇文章的大佬不惜赐教。

TensorBoard 训练截图

另外吐槽:TensorFlow 各种例子看着很乱。比如,Mnist 例子在下面几个位置都可以找到:

  1. tensorflow/examples/tutorials/mnist
  2. models/tutorials/image/mnist
  3. models/offcial/mnist
  4. models/offcial/research/slim/datasets/mnist
  5. ...

参考资料

  1. models/offcial/mnist
  2. Importing Data

《另一个 TensorFlow 图片分类例子》上有2条评论

    1. 这个……目测应该没有什么问题的呀。看一下是不是自己的标签打错了?

      这个代码比较早了,已经记不清楚了,目前已转坑 PyTorch。

      见谅

发表评论

电子邮件地址不会被公开。 必填项已用*标注