使用Tensorflow训练神经网络
应用场景
当前主流的大数据、AI训练和推理等应用(如Tensorflow、Caffe)均采用容器化方式运行,并需要大量GPU、高性能网络和存储等硬件加速能力,并且都是任务型计算,需要快速申请大量资源,计算任务完成后快速释放。本文将演示在云容器实例中创建GPU类型的负载,以tensorflow的图像分类为示例,演示在容器中直接使用GPU训练一个简单的神经网络。
优势
使用容器化的方式做此类人工智能训练与推理有如下优势:
- 容器化消除环境差异,不需要自己安装各种软件和配套版本,如python,tensorflow,cuda toolkit等软件。
- GPU驱动免安装。
- 低成本,按秒计费。
- serverless带来的免VM运维。
镜像制作
tensorflow社区有tensoflow的基础镜像,已经装好了基础的tensorflow库,它分支持GPU和支持CPU两个版本,在镜像中心即可下载。
- GPU版本地址为 tensorflow/tensorflow:1.15.0-gpu
- CPU版本地址为 tensorflow/tensorflow:1.13.0
本文采用tensorflow官网中一个已经训练好的模型,对图片进行分类,模型名称Inception-v3。Inception-v3是在2012年ImageNet视觉识别挑战赛上训练出的模型,它将一个非常大的图片集进行了1000个种类的图片分类。Github有使用Inception-v3进行图片分类的代码。
训练模型的代码,均在工程https://gpu-demo.obs.cn-north-1.myhuaweicloud.com/gpu-demo.zip中,您需要将代码下载解压,并将代码工程打入镜像中。下面附上制作镜像的Dockerfile文件内容:
FROM tensorflow/tensorflow:1.15.0-gpu ADD gpu-demo /home/project/gpu-demo
其中ADD将gpu-demo工程拷贝到镜像的/home/project目录下,可以根据自己需要修改。
执行docker build -t tensorflow/tensorflow:v1 . 命令制作镜像(.表示当前目录,即Dockerfile文件所在目录)。
镜像制作好后需要上传到容器镜像服务,具体步骤请参见https://support.huaweicloud.com/usermanual-swr/swr_01_0009.html。
创建Tensorflow负载
- 登录云容器实例管理控制台。
- 创建GPU型命名空间,填写命名空间名称,设置好VPC和子网网段后,单击“创建”。
图1 GPU型命名空间
- 左侧导航栏中选择“工作负载 > 无状态(Deployment)”,在右侧页面中单击“镜像创建”。
- 配置负载信息。
- 填写基本信息,选择2创建的命名空间,Pod数量选择为“1”,选择Pod规格为“GPU加速型”,显卡的驱动版本选择“418.126”,如下所示。
GPU Pod的详细规格和显卡驱动的说明请参见Pod规格。图2 选择GPU容器规格
- 选择需要的容器镜像,这里选择的上传到镜像容器仓库的tensorflow镜像。
- 在容器设置下面的高级设置中,挂载一个NFS类型的文件存储卷,用于保存训练后的数据。
图3 挂载NFS存储
- 在启动命令中输出执行命令和参数。
- 可执行命令:/bin/bash
- 参数1:-c
- 参数2:python /home/project/gpu-demo/cifar10/cifar10_multi_gpu_train.py --num_gpus=1 --data_dir=/home/project/gpu-demo/cifar10/data --max_steps=10000 --train_dir=/tmp/sfs0/train_data; while true; do sleep 10; done
此处 --train_dir 表示训练结果存储路径,其前缀 /tmp/sfs0 需要与4.c中设置的NFS“容器内挂载路径”路径保持一致,否则训练结果无法写入NFS中。
--max_steps表示训练迭代的次数,这里指定了10000次迭代,完成模型训练大概耗时3分钟,如果不指定,默认是1000000次迭代,耗时会比较长。max_steps数值越大,训练时间越久,结果越精确。
该命令是训练图片分类模型,然后单击“下一步”。
图4 设置容器启动命令
- 配置负载访问信息。
- 单击“提交”,然后单击“返回工作负载列表”。
- 填写基本信息,选择2创建的命名空间,Pod数量选择为“1”,选择Pod规格为“GPU加速型”,显卡的驱动版本选择“418.126”,如下所示。
使用已有模型分类图片
- 单击负载名称,进入负载详情界面,选择“Pod列表>终端”Tab页。当黑色区域文本框中出现#号时,说明已登录。
图5 Pod终端访问
- 进入到工程所在目录,执行python classify_image.py --model_dir=model命令,可以看到分类结果。
# cd /home/project/gpu-demo # ls -l total 96 -rw-r--r-- 1 root root 6874 Aug 30 08:09 airplane.jpg drwxr-xr-x 3 root root 4096 Sep 4 07:54 cifar10 drwxr-xr-x 3 root root 4096 Aug 30 08:09 cifar10_estimator -rw-r--r-- 1 root root 30836 Aug 30 08:09 dog.jpg -rw-r--r-- 1 root root 43675 Aug 30 08:09 flower.jpg drwxr-xr-x 4 root root 4096 Sep 4 02:14 inception # cd inception # python classify_image.py --model_dir=model --image_file=/home/project/gpu-demo/airplane.jpg … 2019-01-02 08:05:24.891201: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1084] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 15131 MB memory) -> physical GPU (device: 0, name: Tesla P100-PCIE-16GiB, pci bus id: 0000:00:0a.0, compute capability: 6.0) airliner (score = 0.84250) wing (score = 0.03228) space shuttle (score = 0.02524) warplane, military plane (score = 0.00691) airship, dirigible (score = 0.00664)
这里通过--image_file指定了要分类的图片,图片如下。执行结果最后几行是分类的label和对应的打分,其中有一行显示airliner(score = 0.84250),分数越高越准确,可见模型认为这个图片是一架客机。图6 airliner
也可以不指定要分类的图片,默认将使用下面这张图片分类。图7 熊猫
执行命令python classify_image.py ––model_dir=mode# python classify_image.py --model_dir=model … 2019-01-02 08:02:33.271527: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1084] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 15131 MB memory) -> physical GPU (device: 0, name: Tesla P100-PCIE-16GiB, pci bus id: 0000:00:0a.0, compute capability: 6.0) giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca (score = 0.89107) indri, indris, Indri indri, Indri brevicaudatus (score = 0.00779) lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens (score = 0.00296) custard apple (score = 0.00147) earthstar (score = 0.00117)
执行结果显示模型认为这是一只大熊猫。
使用训练的图片分类模型
tensorflow官网中给了一个深度卷积网络的模型代码和训练数据:CIFAR-10。这是个简化的图片分类模型,将图片分成以下10类:airplane, automobile, bird, cat, deer, dog, frog, horse, ship和truck。当然给模型的图,也就是训练数据,也是这10种类型的图片。
- 单击负载名称,进入负载详情界面,选择“Pod列表>终端”Tab页,使用代码中提供的cifar10_eval.py校验模型的准确性,这里的checkpoint_dir指定使用刚刚训练出来的模型进行准确性校验。
# cd /home/project/gpu-demo/cifar10 # python cifar10_eval.py --data_dir=data --checkpoint_dir=/tmp/sfs0/train_data --run_once … 2019-01-02 08:25:43.914186: precision @1 = 0.817
- 继续使用上面的飞机图片进行测试,这里的checkpoint_dir指定使用刚刚训练出来的模型进行图片分类,test_file指定用哪张图片测试。
# python label_image.py --checkpoint_dir=/tmp/sfs0/train_data --test_file=/home/project/gpu-demo/airplane.jpg … 2019-01-02 08:36:42.149700: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1084] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 15131 MB memory) -> physical GPU (device: 0, name: Tesla P100-PCIE-16GiB, pci bus id: 0000:00:0a.0, compute capability: 6.0) airplane (score = 4.28143) ship (score = 1.92319) cat (score = 0.03095)
可见它准确识别出图中是架飞机。label_image.py是使用刚刚训练的模型来进行图片分类的代码。
同时,在“Pod列表>监控”Tab页中,可以看到各种资源的使用率。