人工智能(AI)库TensorFlow 踩坑日记之一

 上次写完粗浅的BP算法 介绍html

原本应该继续把 卷积神经网络算法写一下的python

可是最近一直在踩 TensorFlow的坑。因此就先跳过算法介绍直接来应用场景,原谅我吧。git

 

TensorFlow 介绍github

TF是google开源出来的人工智能库,由python语言写的算法

官网地址:http://www.tensorflow.org/   请用***访问编程

中文地址:http://www.tensorfly.cn/ windows

固然还有其余AI库,不过大多数都是由python 写的数组

.net 的AI库叫 Accord.net (由于我本职是.net的,so……)有兴趣的同窗能够去看看,有不少机器学习的工具类,不过惋惜当时我在研究的时候只有BP算法,尚未卷积算法的相关。网络

写这篇博文的时候,据说微软又开放了一个AI库,可是tensorflow比较早。因此仍是继续搞tensorFlowsession

TensorFlow 在支持GPU 并行运算上作的挺多。这个库的入手程度相对其余AI库稍容易点。并且有不少教程代码,包括卷积,对抗网络,循环网络算法。

声明一下踩坑日志系列主要是针对卷积。

阿尔法狗的核心部分就是用的TensorFlow,真佩服google说开源就开源。

好了,废话不说,开始

 

安装方法推荐

由于我用的是windows机

因此我推荐的安装环境是 python 3.5.2  +PyCharm

这篇博文写时,最新的python是3.6  

尝试过安装3.6跟tensorFlow有不兼容问题,后来换了3.5.2 就能够了。

我安装的版本是tensorFlow1.1

不排除以后的版本已经修复这个问题。

tensorFlow1.2已经修复此问题

 

我推荐的安装方法超简单,可是网上有不少很是复杂的安装,在此踩一下。

十几个字搞定:

安装好python 以后设置好环境变量,而后安装PyCharm 打开=》setting =》project Interpreter 选择刚才安装好的3.5.2 

点下面的绿色+ 号 搜索 tensorFolw ,install package! 完成。

 

 

教程代码介绍

关于教程部分我建议先看一下极客学院的翻译教程文档。

传送门在此 http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/overview.html

另外下载一下 github上的源码

https://github.com/tensorflow/tensorflow

 

最简单的教程是 

MNIST

这个教程相关内容在上面的极客学院的文档有详细的介绍,这里我摘取一点

 

 

官网例子上有一个坑,由于训练数据会从外网连接上下载,我刚入门那个时候这个连接是404。因此只能另外找这个包,如今这个问题虽然已经修复了,可是我担忧那个网站也不是很靠谱。有须要的能够留下邮箱,很少人的话我直接发给大家。

这里我讲一下tensorFlow几个比较晦涩的概念,请结合那个教程一块儿看

张量 tensor :张量是TF最基本的元素,基本上全部的接口都是须要张量做为输入。

张量实际上是对基本类型的一层包装,就是说tensor能够包装是int string array 各类类型。最重要的用途是用来描述多维数组

好比 这个方法生成的tensor 

tf.zeros([100,100]) 就是表明正式运行的时候会生成一个二维数组,第一维有100个索引,每一个里面有100个0 
tf.random_normal([784, 200], stddev=0.35) 表明随机生成一个二维数组 ,784是一维,每一个里面有200个元素。总共就是784*100个随机数。 sttddev是这个正态分布的误差值,我以为能够理解为平均的差值。用来调整数值分布的密度。

生成一个tensor的方式有不少,也能够用

tf.constant() 直接输入常量

这里你们确定已经很奇怪了,数组就数组,string 就string,干吗还要包装起来成了tensor

其实这个tensor除了常量tensor以外,其余比方说随机数组,在调用的时候里面都没有值的,只是声明说要生成这么一堆数据,可是实际上要等到 session.run 的时候数据才会生成。

因此其实tensorFlow 编程就是用这些方法声明要构建一个怎么样的算法,这个过程叫作构建图。而后再N次的session.run 这个算法来训练。因此调试的时候很麻烦的地方是,经常是构建图的时候没问题,可是这个算法图正式跑的时候各类出错,可是很难定位是因为哪一个数据进行到什么地方出错的。幸亏有 tfdbg的模块能够调试,我下面会讲一下在tfdbg上踩的坑。

 

checkpoint :至关于保存点,就是用来训练到一半的时候保存当时全部张量的值,而后下次能够经过一个saver的鬼东西读取checkpoint的全部环境,继续训练。

这个很是有用,由于数据量特大的时候可能要跑好几天,这样就能够分段进行的,也不怕中途死机。(别问我为啥会死机,说多了都是泪)

 

MNSIT 这个教程代码是比较简易的卷积算法,训练集很小。

稍大一点的教程是:cifar10 

cifar10 的算法比较全面一点

这是这个算法过程的简要描述

 

由2层 (卷积层+最大池化+归一层)+2层全链接层。不知道全链接层是什么东西的,请参考我上一篇关于BP算法,全链接层就是BP算法的典型结构。
卷积层我这里简单说一下,就是由一个k*k 的数据矩阵(),去跟图像作卷积运算。卷积过程参考下图卷积核
 
 
这个过程的做用主要是提取图像特征,不一样的卷积核对图像的处理效果是不一样的。
好比模糊效果,锐化效果,黑白效果,轮廓效果。都是能够直接设定不一样卷积核来达到。
卷积这个词是指这个过程当中执行的实际数学过程,不过这个过程在图像领域能够称之为“提取特征”或者叫“滤镜”你们更能明白一点,就是由于不一样值的卷积核表明不一样的特征提取器。

上面还提到一个名词叫“池化”就是降维,提取特征出来的图片数据量很是大,池化效果好比3*3范围内取一个最大值。那么本来90*90的图片就变成 30*30了。
这就是最大池化。Maxpool
归一化的算法也挺多,可是通俗一点讲,比方说作完卷积以后数据多是这样 [255,244,266,7777,433] 太大了很差计算,也增长计算压力。归一化一种最简单的办法就是 取个最大值,对每一个数作一次 除法
 
[255/7777,244/7777,266/7777,7777/7777,433/7777]
 

 这样得出来的值就都在 0-1 之间了。这就是传说中归“一”化。

卷积层+最大池化+归一层最终得出一张图片的各类特征数组,而后传给全连接层,根据偏差值调整网络里的全部参数,最终达到跟真实值一致。而后跑一下测试集评估结果。
卷积我这里就不细说了。
(我后来写的算法综述中有介绍CNN卷积神经网络的一些内容,补充性的看一下吧 传送门:点我点我
 

cifar10+imagenet 改代码

 

固然cifar10 仍是不能拿来用的。毕竟是教程代码

那么如今若是要投入实用,其实有2个问题要解决

1,扩大训练集

2,由于评估代码用的一打图片打包成一个.bin 文件 因此得改为接收1张jpg图片而后输出结果。

第一个问题

先下载imagenet 训练集 ILSVRC2012

这个朋友有地址 http://www.cnblogs.com/zjutzz/p/6083201.html

1000种分类,每一种分类有1000张图片 就是一百万张图片 压缩包140G。下载大半天,解压又是大半天。推荐用7z解压。神速。

可是没有中文分类的名字

因此还得看这里 中文对照表 http://blog.csdn.net/u010165147/article/details/72848497

下载好以后再说一个坑。里面有部分图片是出错格式的。大概有几百张吧。其实量也很小。若是大家找到没问题数据包的就不要我这个了。

不过由于代码读取的时候会出错,因此可能训练到几十万步的时候忽然来那么一下,前功尽弃,还很难锁定是哪张出错了。

后来我疯了,由于能够看到出错图片的字节数,因此根据字节数查看文件,而后删了它,而后再跑几十万步以后,又出错,又删了它。

 

 可是几百张图可能出错。- -!哈哈哈哈哈(此处苦笑)。。让我死吧。

而后我就用tfdbg 或者 tensorbroad 来查出那些出错的图片路径。可是……我把图片路径装到一个tf队列里,tfdbg不能显示队列内容。F!

tensorbroad 开启后一直显示没找到监控数据,然而数据文件一直存在的。F!(这个问题在下文有找到缘由)

找了不少办法,花了不少时间以后宣告放弃。另觅良方。

干了一阵子傻事以后,我忽然受到上天的启发,感受真神上身。“为啥我不用try catch呢!”

由于这个方法在第一天的时候被我否认了,由于读图的方法

 decode_jpeg 一直是这里报错,可是我直接try catch 这一段代码是无效的。由于正如我上面说的,这里只是构建图,构建了想要解码图片的算法而已,并无真正解码,因此图片格式错误不会被catch到。

可是。。。。。。

我能够在session.run 的时候try catch啊!!!!

我能够在session.run 的时候try catch啊!!!!

我能够在session.run 的时候try catch啊!!!!

结果绕了一大圈,仍是最开始的办法最靠谱。“师傅,把那块砖头往我这里砸,对,就是这里,脑门上,用力”。 

(结果是try catch也不太行,仍是会有一些错误致使session报错,而后程序中止。

最后的办法是用一个图片批量处理工具,把全部图过一遍,去掉那些不可读的图片。)

 

OK,前戏完结。

cifar10 的详细源码解析这里就不讲了,你们自行搜索。

大体讲一下我对cifar10的修改,用来装载这100万张图片

首先

cifar10_input.py 代码里
distorted_inputs 方法主要是用来加载

 

这六个bin文件

每一个文件里是一堆图片跟标签的打包。

再看

read_cifar10()方法里

FixedLength 读取器会根据固定长度的一段段的读取文件。因此这个bin文件里面一张图的长度就是 32*32*3(RGB3个通道的意思)+label的长度。

如今imagenet解压出来的格式是

这里明显不一样了,怎么办?

不干了!删代码!卸载系统!

说笑了,默默的打开IDE。

仍是 

cifar10_input.py文件
主要改这个方法

这个方法主要是从bin文件里读取了固定长度的,而后把label切出来放到 result.label  把本来图片数据转换成3维数组tersor(reshape)。而后稍微把数组的维度转换一下。就是最后  transpone 改成了[1,2,0] 就是本来depth*height*width 改成 height*width*depth*depth这里是指颜色通道,红绿蓝3种。

 

 

这里我换成
WholeFileReader 读取整个文件。而后
resize_images 成32*32
由于label 是分类名称,也是图片所在文件夹的名称,因此我在外面把图片文件夹名称都丢到一个label的string队列里,而后里面作出队 depuqeue。

核心部分就完了。
剩下一个问题就是读取单张图片而后跑一下评估代码
cifar10_eval.py
得出结果。而后就能够投入实用了。

cifar10_eval.py代码还须要改一下

新增这个方法,图片必须改为32*32大小的,这个能够用其余本身熟悉的代码处理,把图片读取成数组,而后按照bin文件的格式打包成一个。剩下就是按照eval原有的代码,只改一下读取bin文件的路径就能够。

最后run以后把 

predictions输出就能够了
这里就能拿到label了,而后根据上面的中文对照表得出分类名称。大功告成。
然而。。。。。。
这篇文章叫作踩坑日志,因此最大的坑在最后。
不知道为啥,训练了100W步以后每次去测试跑结果,都是

有毒啊!!!

未完待续。

国际惯例 原文地址http://www.cnblogs.com/7rhythm/p/7091624.html

 

转载请注明出处。PS:文中代码都是用图片,由于只是摘取部分核心代码,并不能直接运行,因此诸君不用复制去调试了,理解要紧。

传送门:踩坑日记之二

相关文章
相关标签/搜索