Tensorflow的安装
1.Tensorflow简介
Tensorflow是一个谷歌发布的人工智能开发工具,于2015年年底开源。在开源之前一直是在谷歌内部使用,维护性比较好,里面的很多工具也比较新。Tensorflow是采用C++和python写成的,给的接口也是C++和python,但是更支持python。下面是Tensorflow和其他几个深度学习或机器学习工具的比较:
谷歌称以后的学术文章也大都使用该工具,所以如果要跟进谷歌的学术进展,可能要对这个工作做一定了解的。
Tensorflow安装
Tensorflow目前只能在Linux或者Mac下使用,其安装还是比较简单的,它提供了CPU版本和GPU版本。如果电脑中有GPU,可以尝试使用GPU版本,这个略微复杂。如果您并不想跑太过于复杂的程序,或您的电脑GPU也并不是很好,推荐CPU版本,安装简单。下面是在Ubuntu14.04下一个GPU版本的安装方法。安装过程中请联网(fanqiang):
一.在安装Tensorflow之前先安装CUDA和CUDNN.
1.安装cuda
在https://developer.nvidia.com/cuda-downloads中,选择和自己系统相对应的且合适的CUDA版本。我的选择依次是:Linux—x86_64—ubuntu—14.04—deb(local).选择好后开始下载。下载好后进入下载的目录中在命令行输入如下命令:
sudo dpkg -i cuda-repo-ubuntu1404-7-5-local_7.5-18_amd64.deb
sudo apt-get update
sudo apt-get install cuda
2.安装cudnn
https://developer.nvidia.com/rdp/cudnn-download安装cudnn,需要首先注册,随便填填就好,之后选择cuDNN v5.1 Library for Linux 下载后,cd至下载目录,在命令行中输入如下命令:
tar xvzf cudnn-7.5-linux-x64-v5.1-ga.tgz
sudo cp cuda/include/cudnn.h /usr/local/cuda/include
sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64
sudo chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib64/libcudnn*
安装好后,在home 路径下的.profile中添加路径:
export CUDA_HOME=/usr/local/cuda
export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:$CUDA_HOME/lib"
export PATH="$CUDA_HOME/bin:$PATH"
安装完成后,可以用编译cuda-sample中的案例来时一下:
$ cp -r /usr/local/cuda/samples ~/cuda-samples
$ pushd ~/cuda-samples
$ make
$ popd
$ ~/cuda-samples/bin/x86_64/darwin/release/deviceQuery
最终会显示您的GPU的配置等一些信息。编译过程比较缓慢。
最后,在安装tensorflow的根目录下,使用./configure命令来确认配置。
会出现这样的画面,除了一些地方需要输入y或cuda和cudnn的型号来确认外,一路enter。
但是实际上我并没有得到上面的那些setting up,而是绿色的IFNO标志,后面是一些download命令,我在谷歌上搜索了一些,这样也是表示正常的意思,至于为什么显示的不统一,我猜测应该是和CUDA,或者tensorflow的版本有关。当显示configuration finished后,说明GPU已经设置好的。
二.安装virtualenv并下载tensorflow文件
推荐在virtualenv下安装tensorflow,这样tensorflow就对其他python环境没有影响,想删掉就直接删除这个文件夹就行。
1.首先安装virtualenv
sudo pip install virtualenv
接着安装virtualenvwrapper,这是一个virtualenv的管理工具,可以方便得管理多个virtualenv环境,并可以将它们放在一个文件夹下面。
Sudo pip install virtualenvwrapper
环境配置:
export WORKON_HOME='~/.virtualenvs'
source /usr/local/bin/virtualenvwrapper.sh
建立一个tensorflow虚拟环境:
mkmkvirtualenv tensorflow
可以看见命令行的最开头变化了。
之后下载tensorflow的源码:git clone https://github.com/tensorflow/tensorflow。下载后可能在Home目录下,我一般习惯将其拷贝到.virtualenv/tensorflow/bin/python2.7/dist-package目录下。
三.安装Bazel编译器
因为我们tensorflow源码编译(不知道为什么,tensorflow的二进制安装方法安装后的tensorflow,功能比源码编译的少,这也是我在实践中发现的),所以首先安装这个编译器。
1.如果电脑的系统是Ubuntu14.04或以下,需要安装Oracle JDK 8。
sudo add-apt-repository ppa:webupd8team/java
最后会出现这个,中间的没有找到任何绝对信任的密钥不用管。
接着sudo apt-get update
接着sudo apt-get install oracle-java8-installer
这一步需要下载文件,所以需要等一会。
最后在sudo apt-get update一下。
2.安装必要的包:sudo apt-get install pkg-config zip g++ zlib1g-dev unzip
3.bazel:https://github.com/bazelbuild/bazel/releases。bazel-0.3.1-installer-linux-x86_64.sh。下载后在下载的目录中于命令行输入:
chmod +x bazel-version-installer-os.sh
/bazel-version-installer-os.sh --user
完成后记得添加路径,按照命令行中的说明在在home目录下的.bashrc中添加路径。
至此bazel安装完毕
四.tensorflow编译
下面的命令推荐在下载的tensorflow文件的根目录下执行(即第二步下载的tensorflow文件夹中)
1.首先安装其他依赖:sudo apt-get install python-numpy swig python-dev。
2.安装完毕后对tensorflow源码的pip包进行编译和安装。
bazel build -c opt //tensorflow/tools/pip_package:build_pip_package
这个比较慢,大概需要20分钟左右。如果您有GPU,推荐让GPU参与编译这一步(如下),可以提高编译的速度,大概需要600s左右。
bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
之后执行:
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
sudo pip install /tmp/tensorflow_pkg/tensorflow-0.10.0-py2-none-any.whl
3.按照教程,下面是一个为开发而进行的设置,目的似乎是设置路径(我也没看懂),总之按照这个设置。
bazel build -c opt //tensorflow/tools/pip_package:build_pip_package
# To build with GPU support:
bazel build -c opt
--config=cuda //tensorflow/tools/pip_package:build_pip_package
mkdir _python_build
cd _python_build
下面的命令有可能需要root权限。
ln-s ../bazel-bin/tensorflow/tools/pip_package/build_pip_package.runfiles/org_tensorflow/* .
ln -s ../tensorflow/tools/pip_package/* .
python setup.py develop
五.测试
这样tensorflow就安装和设置完毕了。下面是用minist数据集来进行测试。
cd tensorflow/models/image/mnist
python convolutional.py
会在命令行出现如下,如果开启了GPU,还会在这之前有一段GPU成功启动的说明:
Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.
Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.
Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.
Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.
Extracting data/train-images-idx3-ubyte.gz
Extracting data/train-labels-idx1-ubyte.gz
Extracting data/t10k-images-idx3-ubyte.gz
Extracting data/t10k-labels-idx1-ubyte.gz
Initialized!
Epoch 0.00
Minibatch loss: 12.054, learning rate: 0.010000
Minibatch error: 90.6%
Validation error: 84.6%
Epoch 0.12
Minibatch loss: 3.285, learning rate: 0.010000
Minibatch error: 6.2%
Validation error: 7.0%
……
六.问题说明
我在这过程中遇到过很多问题,其中的很多解决方法已经写在安装的过程中了,下面是几个不是很常见的问题:
1.当有这样的问题时:
ImportError: libcudart.so.7.0: cannot open shared object file: No such file or directory:
请在.profile文件中中添加如下:
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64"
export CUDA_HOME=/usr/local/cuda
2.在进行minist出现如下问题:
__new__ if not newclass.is_abstract(): AttributeError: type object 'NewBase' has no attribute 'is_abstract'
请执行如下的命令,好像是重新安装python的six模块。
sudo pip install six --upgrade --target="/usr/lib/python2.7/dist-packages"
利用Tensorflow训练图像分类的模型
我在刚进行训练模型的时候,是想靠自己拆开一个模型,之后再进行训练的方法。后来发现在我不彻底弄清模型的原理并搞到模型的源码之前我是不可能去训练的。后来发现tensorflow就提供了这样一个工具,它虽然没有公开深度学习网络的模型源码,却给出了保存好的模型和训练的代码。这样就直接可以拿来训练了。
这个模型是谷歌的Inceptionv3(http://arxiv.org/abs/1512.00567)。在2012年的imageNet上进行训练,并在2012ImageNet上取得了3.4%的top-5准确率(人类的只有5%)
这么一个复杂的网络若是直接自己训练,起码需要几天甚至十几天的时间。所以这里我采用迁移学习的方法。即前面的层的参数都不变,而只训练最后一层的方法。最后一层是一个softmax分类器,这个分类器在原来的网络上是1000个输出节点(ImageNet有1000个类),所以需要删除网络的最后的一层,变为所需要的输出节点数量,然后再进行训练。
Tensorflow中采用的方法是这样的:将自己的训练集中的每张图像输入网络,最后在瓶颈层(bottleneck),就是倒数第二层,会生成一个2048维度的特征向量,将这个特征保存在一个txt文件中,再用这个特征来训练softmax分类器。
具体的方法如下:
1.编译和预处理
在tensorflow的根目录下的命令行中输入编译retrian的命令:
bazel buildtensorflow/examples/image_retraining:retrain。如果您的电脑比较新,建议用这个命令来编译:
bazel build -c opt --copt=-mavx tensorflow/examples/image_retraining:retrain。
这两种方法我都试过,后面一种在提取bottleneck特征的时候比前面的一种快了10倍左右。
编译完成后,实际上就可以使用了,就是这么简单。但是建议还是改动一下tensorflow/examples/image_retraining目录下的retrain的python脚本,因为里面的默认路径是/tmp,这个文件夹一旦电脑关机所有数据都会清除。建议把里面所有的这个路径都改为另外的路径。之后在该路径下将自己的训练数据集放好。
训练数据集是有格式要求的:
a.数据集应该这样设置,训练集文件夹下放置多个子文件夹,每个子文件夹就是一个类,里面包含该类的所有图像。
b.图像应该是jpg或者jpeg格式。
2.训练
在设置好数据集后,运行
bazel-bin/tensorflow/examples/image_retraining/retrain --image_dir ~/XXX
image_dir ~/XXX是训练数据集的路径XXX是数据集的名称。
这时就开始训练了。训练过程中会首先下载原来的Inception网络,保存在ImageNet的文件夹下。
第一个文件是网络的图结构,第二个文件是一个测试图像,第三个一个映射,从最后1000个节点中的而每一个映射到一个编码,第四个也是一个映射,是从编码映射到人能够识别的名词,例如:节点的表示是第234个节点,而这个节点映射到的编码是nb20003,这个编码映射到的名词是熊猫(仅举例,数字和编码以及名词是随意假设的)。这些映射关系和编码是在ImageNet 2012测试集中定义的。
下载后开始提取每张训练图像的bottleneck特征。这个过程大概1s提取5张图像。在提取完成后就开始训练。训练过程比较快。下面是我的训练结果,我训练了8000(可以在retrain.py中设置)次,一开始很奇怪为什么不需要设置softmax的输出节点数目,后来看了代码才知道它是根据训练集中的类别数量来自动设置的。
下面是我的训练结果:
最后的测试结果是93.2%。这个成绩好么?其实并不好,这说明这个模型的15个类的Top5的准确率比ImageNet的1000个类的Top5准确率还低。但是鉴于没有那么多的训练数据集和那么多的时间来从头训练整个网络,这个结果已经算是还不错。
这时候如果打开image_dir路径,可以在下面发现多处了两个文件,分别是output.pb和output.txt。第一个文件是训练后的图结构,第二个是从节点到名词的映射,这里不会给出中间的编码映射——除非您自己定义一个映射关系。
接下来怎么利用训练好的模型来进行训练呢?首先还是回到下载下来的ImageNet文件夹中,这时候如果运行tensorflow/model/ImageNet中的classify.py,会发现命令行中出现如下:
这是对文件夹中的测试图像进性预测的结果。
这时,我们将训练出的output_graph文件放到该文件夹下,替换掉原有的图文件(可以把output_graph文件重命名为原来的图文件名,这样就不需要改动代码了)。再运行classfy.py文件就可以用自己的模型来对图像进行分类了。给出的结果是Top5对应的节点数以及相应的概率。如果需要输出名词,需要自己定义映射关系。
但是这样还是只会对一张图像进行分类,我改动了classify_image的脚本,让它可以对多个文件分类。如果您想自己尝试改写脚本让它可以对多个文件分类,那可能您会遇到这样的情况:大概在预测10几个文件后,突然报错,说图的结构不能大于2G,这是因为每训练一个图,就会在图中增加一个点,当增加到一个程度,图的结构就会超过2G。这需要在每训练一个图片后重置图,在我改写的脚本中已经克服了这个问题,但是这也使得分类的速度变慢,大概1.5s一张图像。这个脚本会输出top-2的准确率,如下:
分别是文件名,top1结果,top1置信度,top2结果,top2置信度。
我改动后的,可以支持多图像输入的classify_image可以在: http://pan.baidu.com/s/1qYq3yck中获得。
总结
这是我近十天来摸索tensorflow的心得(前面时间摸索Overfeat了)。Tensorflow的上手还是比较难得,它的一些思想理念(图和张量)还是很难理解的。比较重要的心得是Don’t be a hero。有问题不要闭门造车,如果尝试了下没解决就第一时间找人交流,如果别人也没有解决方法,再想办法从网上搜,再实在没办法再去看源码和问题提示自己找问题所在。此外,还了解一些包括linux还有python的工具,相信这会对我后面的学术和工程都有帮助。
但是还是感觉走了很多的弯路,中间浪费了太多现在看起来可以避免浪费的时间,我想这就是因为我没有跟他人交流很多的原因吧。
补充:额。。。好久没上博客了,我最近一年多都是在研究弱监督学习问题了,所以对深度学习没怎么继续做下去了。这个博客不知怎么图片被吞了,想要完整的可以从http://pan.baidu.com/s/1i4FhNwh下载。