用 TensorFlow 追踪千年隼号

eachti21 6年前
   <p style="text-align: center;"><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/01614e6ba1d596f97abeee5c1573f0e8.gif"></p>    <p>TensorFlow 是个机器学习的开源库。这篇文章中作者将用 TensorFlow 来训练识别自定义模型,并给出了详细的过程(星战迷 = =|| )。</p>    <p>在写这篇博客时,许多大型技术公司(如 IBM,Google,Microsoft,Amazon)都有简单易用的视觉识别 API。一些小点的公司同样提供了类似的服务,比如 <a href="/misc/goto?guid=4959755503327734504" rel="nofollow,noindex">Clarifai </a>。但它们都没有提供对象识别。</p>    <p>下面的图片都使用了相同的 <a href="/misc/goto?guid=4959755503423640448" rel="nofollow,noindex">Watson 视觉识别 </a>默认分类器标签。第一个已经通过对象识别模型处理过了。</p>    <p><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/129407d553622b27bf0a04fe13735d5e.jpg"></p>    <p>对象识别可以远远超过视觉识别本身。但如果你想要对象识别,你就要亲自动手。</p>    <p>取决于你的用例,你或许不需要自定义对象识别模型。 <a href="/misc/goto?guid=4959741728361791712" rel="nofollow,noindex">TensorFlow </a>的对象识别 API 提供了几种不同速度和精度的模型,它们给予 <a href="/misc/goto?guid=4959755503535775392" rel="nofollow,noindex">COCO 数据集 </a>。</p>    <p>为了让你方便,我放上了一个 COCO 模型可以识别的完整对象列表:</p>    <p><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/48d77a5d760b12c553601cf2ec554515.jpg"></p>    <p>如果你想要识别一些标志或者不在上面这个表的东西,你需要构建自己的对象识别器。我想要可以识别千年隼号和一些钛战机。这显然是个极其重要的用例,因为你永远不知道……</p>    <p> </p>    <h2>给你的图片作注解</h2>    <p>训练自己的模型要大量工夫。现在,你可能会想,“哇,哇,哇!我不想要费大量工夫!”如果是这样,你可以看看我的关于使用现有模型的 <a href="/misc/goto?guid=4959755503619975603" rel="nofollow,noindex">其他文章 </a>。这是个更平滑的方向。</p>    <p>你需要收集大量的图片,并且写上注解。注解包括声明对象的坐标以及关联的标签。比如一张有两架钛战机的图片,注解看起来像这样;</p>    <pre>  <annotation>      <folder>images</folder>      <filename>image1.jpg</filename>      <size>          <width>1000</width>          <height>563</height>      </size>      <segmented>0</segmented>      <object>          <name>Tie Fighter</name>          <bndbox>              <xmin>112</xmin>              <ymin>281</ymin>              <xmax>122</xmax>              <ymax>291</ymax>          </bndbox>      </object>      <object>          <name>Tie Fighter</name>          <bndbox>              <xmin>87</xmin>              <ymin>260</ymin>              <xmax>95</xmax>              <ymax>268</ymax>          </bndbox>      </object>  </annotation></pre>    <p>像我的星战模型,我收集了 308 张图片,每张图片有两到三个对象。我建议每个对象找 200-300 个例子。</p>    <p>“哇”,你可能想,“我要收集成百上千张图片,而且每张都要写上一堆 XML?”</p>    <p>当然不!有各种各样的注解工具,比如 <a href="/misc/goto?guid=4959755503710895454" rel="nofollow,noindex">labelImg </a>和 <a href="/misc/goto?guid=4959755503795000019" rel="nofollow,noindex">RectLabel </a>。我使用 RectLabel,但它只支持 macOS。还要费很多工夫,相信我。我用了三到四个小时不间断的工作才把整个数据集注解完。</p>    <p>如果你有钱,你可以让别人来做,比如实习生。你可以用像 <a href="/misc/goto?guid=4959755503872848891" rel="nofollow,noindex">Mechanical Turk </a>这样的资源。如果你是个穷大学生像我这样的,或者,以单调的工作为乐子的人,你还得自己来。</p>    <p>当创造注解时,如果你不想写自己的转换脚本,确保它们导出为 PASCAL VOC 格式。这是我和许多其他人用的格式,你可以“偷”我上面的脚本(其实是从别人那偷的)。</p>    <p>在开始运行为 TensorFlow 准备数据的脚本之前,我们需要做一些设置。</p>    <p> </p>    <h2>克隆仓库</h2>    <p>从克隆我的 <a href="/misc/goto?guid=4959755503957966119" rel="nofollow,noindex">仓库 </a>开始。</p>    <p>目录结构看起来是这样的:</p>    <pre>  models  |-- annotations  |   |-- label_map.pbtxt  |   |-- trainval.txt  |   `-- xmls  |       |-- 1.xml  |       |-- 2.xml  |       |-- 3.xml  |       `-- ...  |-- images  |   |-- 1.jpg  |   |-- 2.jpg  |   |-- 3.jpg  |   `-- ...  |-- object_detection  |   `-- ...  `-- ...</pre>    <p>我加上了自己的训练数据,这样你就可以开箱即用。但如果你想要用自己的数据创造一个模型,你需要把你的训练图片放到 images 目录下,把 XML 注解放到 annotations/xmls 下,更新 trainval.txt 以及 label_map.pbtxt。</p>    <p>trainval.txt 是一个文件名列表,让我们可以找到以及关联 JPG 和 XML 文件。下面的 trainval.txt 列表可以让我们找到 <code>abc.jpg</code> , <code>abc.xml</code> , <code>123.jpg</code> , <code>123.xml</code> , <code>xyz.jpg</code> 和 <code>xyz.xml</code> :</p>    <pre>  abc  123  xyz</pre>    <p><strong>提示</strong> :确保去掉扩展名后,你的 JPG 和 XML 文件名匹配。</p>    <p>label_map.pbtxt 是我们尝试识别的对象列表。看起来像这样:</p>    <pre>  item {    id: 1    name: 'Millennium Falcon'  }  item {    id: 2    name: 'Tie Fighter'  }</pre>    <p> </p>    <h2>运行脚本</h2>    <p>首先,安装 Python 和 pip,安装脚本需求:</p>    <pre>  pip install -r requirements.txt</pre>    <p>把 models 和 models/slim 添加到你的 PYTHONPATH:</p>    <pre>  export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim</pre>    <p><strong>重要提示</strong> :如果不想每次打开终端都运行上面的命令,你需要把它添加到 ~/.bashrc 文件。</p>    <p>运行脚本:</p>    <pre>  python object_detection/create_tf_record.py</pre>    <p>一旦脚本运行完成,你会得到 train.record 和 val.record 文件。这是我们用来训练模型要用的文件。</p>    <p> </p>    <h2>下载基础模型</h2>    <p>从头开始训练对象识别器甚至使用多个 <a href="/misc/goto?guid=4959755504044193110" rel="nofollow,noindex">GPU </a>也要花好几天。为了加快训练速度,我们会采取一个通过不同的数据集训练过的对象识别器,并重用它的一些参数来初始化我们的新模型。</p>    <p>你可以从 <a href="/misc/goto?guid=4959755504132440640" rel="nofollow,noindex">model zoo </a>下载一个模型。每个模型都有不同的精确值和速度。我使用的是 faster_rcnn_resnet101_coco。</p>    <p>提取并把所有的 model.ckpt 文件移动到我们库的根目录。</p>    <p>你应该会看到一个 faster_rcnn_resnet101.config 文件。它和 faster_rcnn_resnet101_coco 模型一起工作。如果你使用其他模型,你可以从 <a href="/misc/goto?guid=4959755504222593407" rel="nofollow,noindex">这里 </a>找到对应的配置文件。</p>    <p> </p>    <h2>准备训练</h2>    <p>运行下面的脚本,然后就能开始训练了!</p>    <pre>  python object_detection/train.py \          --logtostderr \          --train_dir=train \          --pipeline_config_path=faster_rcnn_resnet101.config</pre>    <p><strong>提示</strong> :将 pipeline_config_path 替换成你的配置文件的本地路径</p>    <pre>  global step 1:  global step 2:  global step 3:  global step 4:  ...</pre>    <p>耶!开始训练了!</p>    <p>10 分钟后:</p>    <pre>  global step 41:  global step 42:  global step 43:  global step 44:  ...</pre>    <p>电脑开始抽烟:</p>    <pre>  global step 71:  global step 72:  global step 73:  global step 74:  ...</pre>    <p>这玩意儿要跑多久?</p>    <p>我在视频中使用的模型运行大概要运行 22,000 步。</p>    <p>等等,什么?!</p>    <p>我用的是 MacBook Pro,如果你运行的设备和我的差不多,我假设每一步你大约需要花 15 秒,那么得到一个像样的模型需要不间断的运行三到四天。</p>    <p>好吧,这太傻了。我没有这么多时间做这个:dizzy_face:</p>    <p><a href="/misc/goto?guid=4959755504302767801" rel="nofollow,noindex">PowerAI </a>来救场了!</p>    <p> </p>    <h2>PowerAI</h2>    <p>PowerAI 让我们在 IBM Power System 中用 P100 GPUs 快速地训练我们的模型!</p>    <p>训练 10,000 步只需要大约一个小时。但是,这仅仅用了一个 GPU。PowerAI 中真正的力量来源于分布式地使用几百个 GPU 进行深度学习的能力,效率可以达到 95%。</p>    <p>有了 PowerAI 的帮助,IBM 创造了一项图片识别纪录:在 7 小时内识别准确率达到 33.8%。超过了之前 Microsoft 的纪录 —— 10 天 29.9 %的准确率。</p>    <p>超快快快!</p>    <p>因为我没有训练几百万张图片,我当然不需要这种资源。一个 GPU 够了。</p>    <p> </p>    <h2>创建 Nimbix 账户</h2>    <p>Nimbix 给开发者提供了一个 10 小时免费体验 PowerAI 平台的体验账户。你可以在 <a href="/misc/goto?guid=4959755504382870245" rel="nofollow,noindex">这里 </a>注册。</p>    <p><strong>提示</strong> :这个过程不是自动的,审核通过要 24 小时。</p>    <p>一旦审核通过,你就会收到一个创建账户的确认邮件。它会要你提供促销代码,留空白就行了。</p>    <p>你现在可以在 <a href="/misc/goto?guid=4959755504467755064" rel="nofollow,noindex">这里登录 </a>了。</p>    <p> </p>    <h2>部署 PowerAI 笔记本应用</h2>    <p>从搜索 PowerAI Notebooks 开始:</p>    <p><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/95fcadc64c002f92ab8e01ff3dcbebc7.jpg"></p>    <p>点中它,然后选择 TensorFlow。</p>    <p><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/3608fdda28ad67af4896430ac078fde9.jpg"></p>    <p>选择机器类型为:32 线程 POWER8,128G RAM, 1 * P100 GPU w/NVLink(np8g1)。</p>    <p><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/3fb1d0fe17434c15eb67a0b7e9dfd661.jpg"></p>    <p>开始后,下面的工作台就会出现。当服务器状态变成运行时,服务器就准备好了。</p>    <p><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/188cd7a6b83be6c182b186e9074ca215.jpg"></p>    <p>点击 click to show 得到密码。然后点击 click here to connect 启动笔记本。</p>    <p>登录使用 nimbix 的账户和密码。</p>    <p> </p>    <p><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/09a73590de2d2f084209bdc2bcf841c8.jpg"></p>    <p><strong>开始训练</strong></p>    <p>通过点击 New 下拉菜单,选择 Terminal 打开一个新的终端。</p>    <p><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/fadb71d54e164a0f8ecaec8df3d38c19.jpg"></p>    <p>你应该熟悉这个界面了:</p>    <p><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/ec9add9750b20305281c89ffcf7a38ec.jpg"></p>    <p>提示:终端在 Safari 上可能有问题。</p>    <p>训练的步骤和我们在本地运行的时候相同。如果你使用我的训练数据,你可以克隆我的仓库:</p>    <pre>  git clone https://github.com/bourdakos1/Custom-Object-Detection.git</pre>    <p>然后去到这个目录:</p>    <pre>  cd Custom-Object-Detection</pre>    <p>运行下面的片段,下载 faster_rcnn_resnet101_coco 模型:</p>    <pre>  wget http://storage.googleapis.com/download.tensorflow.org/models/object_detection/faster_rcnn_resnet101_coco_11_06_2017.tar.gz  tar -xvf faster_rcnn_resnet101_coco_11_06_2017.tar.gz  mv faster_rcnn_resnet101_coco_11_06_2017/model.ckpt.* .</pre>    <p>然后,我们需要再次更新 PYTHONPATH,因为使用了新的终端:</p>    <pre>  export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim</pre>    <p>最后在运行下面的命令开始训练:</p>    <pre>  python object_detection/train.py \          --logtostderr \          --train_dir=train \          --pipeline_config_path=faster_rcnn_resnet101.config</pre>    <p> </p>    <h2>下载你的模型</h2>    <p>什么时候我的模型才能弄好?这取决于你的训练数据。越多数据,你需要越多步数。我的模型在接近 4500 步时趋于稳定。在 20,000 步时达到顶峰。我甚至让它训练到了 200,000 步,但是没有任何增加。</p>    <p>我建议在每 5000 步左右下载你的模型,评估一下它,要确保你在正确的道路上。</p>    <p>点击左上角的 Jupyter 标志,然后,去到 Custom-Object-Detection/train。</p>    <p>下载所有的带有最大数字的 model.ckpt 文件。</p>    <ul>     <li><code>model.ckpt-STEP_NUMBER.data-00000-of-00001</code></li>     <li><code>model.ckpt-STEP_NUMBER.index</code></li>     <li><code>model.ckpt-STEP_NUMBER.meta</code></li>    </ul>    <p>提示: 你一次只能下载一个。</p>    <p><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/892ee1b8805b47c11a7a9652b6836da9.jpg"></p>    <p>提示:确保在完成后点击红色电源按钮,否则计时将不会停止。</p>    <p> </p>    <h2>导出推理图</h2>    <p>想要在我们的代码中使用模型,我们需要把检查点文件(model.ckpt-STEP_NUMBER.*)转换成冻结 <a href="/misc/goto?guid=4959755504555539173" rel="nofollow,noindex">推理图 </a>。</p>    <p>把刚刚下载的检查点文件移动到之前我们使用的库的根目录。</p>    <p>然后运行命令:</p>    <pre>  python object_detection/export_inference_graph.py \          --input_type image_tensor \          --pipeline_config_path faster_rcnn_resnet101.config \          --trained_checkpoint_prefix model.ckpt-STEP_NUMBER \          --output_directory output_inference_graph</pre>    <p>记得 <em>export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim</em></p>    <p>你应该会看到一个新的 output_inference_graph 目录,里面有一个 frozen_inference_graph.pb 文件,这是我们要用的。</p>    <p> </p>    <p><strong>测试模型</strong></p>    <p>现在,运行下面的命令:</p>    <pre>  python object_detection/object_detection_runner.py</pre>    <p>它会找到 output_inference_graph/frozen_inference_graph.pb 文件,用你的对象识别模型去识别 test_images 目录下的所有图片,然后把结果输出到 output/test_images 目录。</p>    <p> </p>    <h2>结果</h2>    <p>以下是我们在“星球大战:原力觉醒”这个片段中的所有帧上运行模型时得到的结果。</p>    <p><a href="/misc/goto?guid=4959755504650466878" rel="nofollow,noindex"><img alt="用 TensorFlow 追踪千年隼号" src="https://simg.open-open.com/show/0453a06a5f80bddbdd3fc3301e4da688.jpg"></a></p>    <p><br> 推荐阅读:</p>    <ul>     <li><a href="/misc/goto?guid=4959755504730160643" rel="nofollow,noindex">最近 2 个月中我是如何开始学习 AI 的</a></li>    </ul>    <p> </p>    <p>来自:<a href="https://zhuanlan.zhihu.com/p/31247372?utm_source=tuicool&utm_medium=referral">https://zhuanlan.zhihu.com/p/31247372</a></p>