写点什么

MXNet API 入门 —第 4 篇

  • 2017-07-16
  • 本文字数:3009 字

    阅读完需:约 10 分钟

第3 篇文章中,我们构建并训练了第一个神经网络,接下来可以处理一些更复杂的样本了。

最顶尖的深度学习模型通常都复杂到让人难以置信。其中可能包含数百层,就算用不了数周,往往也要数天时间来使用海量数据进行训练。这类模型的构建和优化需要大量经验。

好在这些模型的使用还是很简单的,通常只需要编写几行代码。本文将使用一个名为 Inception v3的预训练模型进行图片分类。

Inception v3

诞生于 2015 年 12 月的 Inception v3 GoogleNet 模型(曾赢得 2014 年度 ImageNet 挑战赛)的改进版。本文不准备深入介绍该模型的研究论文,不过打算强调一下论文的结论:相比当时最棒的模型,Inception v3 的准确度高出了15%–25%,同时计算的经济性方面低六倍,并且至少将参数的数量减少了五倍(例如使用该模型对内存的要求更低)。

简直就是神器!那么我们该如何使用?

MXNet model zoo

Model zoo 提供了一系列可直接使用的预训练模型,并且通常还会提供模型定义模型参数(例如神经元权重),(也许还会提供)使用说明。

首先来下载定义和参数(你也许需要更改文件名)。第一个文件可以直接打开:其中包含了每一层的定义。第二个文件是一个二进制文件,请不要打开 ;)

复制代码
$ wget http://data.dmlc.ml/models/imagenet/inception-bn/Inception-BN-symbol.json
$ wget http://data.dmlc.ml/models/imagenet/inception-bn/Inception-BN-0126.params
$ mv Inception-BN-0126.params Inception-BN-0000.params

该模型已通过 ImageNet 数据集进行了训练,因此我们还需要下载对应的图片分类清单(共有 1000 个分类)。

复制代码
$ wget http://data.dmlc.ml/models/imagenet/synset.txt
$ wc -l synset.txt
1000 synset.txt
$ head -5 synset.txt
n01440764 tench, Tinca tinca
n01443537 goldfish, Carassius auratus
n01484850 great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias
n01491361 tiger shark, Galeocerdo cuvieri
n01494475 hammerhead, hammerhead shark

搞定,开始实战。

加载模型

我们需要:

  • 加载处于保存状态的模型:MXNet 将其称之为检查点 (Checkpoint)。随后即可得到输入的 Symbol 和模型参数。 ```

    import mxnet as mx

    sym, arg_params, aux_params = mx.model.load_checkpoint(‘Inception-BN’, 0)

复制代码
- 新建一个 Module 并为其指派输入 Symbol。我们还可以使用一个 Context 参数决定要在哪里运行该模型:默认值为 cpu(0),但也可改为 gpu(0) 以便通过 GPU 运行。 ```
mod = mx.mod.Module(symbol=sym)
  • 将输入 Symbol 绑定至输入数据。将其称之为“数据”是因为在网络的输入层中就使用了这样的名称(可以从 JSON 文件的前几行代码中看到)。
  • 将“数据”的形态 (Shape)定义为 1x3x224x224。别慌 ;),“224x224”是图片的分辨率,模型就是这样训练出来的。“3”是通道数量:红绿蓝(严格按照这样的顺序),“1”是批大小:我们将一次预测一张图片。
复制代码
mod.bind(for_training=False, data_shapes=[('data', (1,3,224,224))])
  • 设置模型参数。 ```

    mod.set_params(arg_params, aux_params)

复制代码
这样就可以了。只需要四行代码!随后可以放入一些数据看看会发生什么。嗯……先别急。
## 准备数据
数据准备:从七十年代以来,这一直是个痛苦的过程……从关系型数据库到机器学习,再到深度学习,这方面没有任何改进。虽然乏味但很必要。开始吧。
还记得吗,这个模型需要通过四维 NDArray 来保存一张 224x224 分辨率图片的红、绿、蓝通道数据。我们将使用流行的 [OpenCV](http://www.opencv.org/) 库从输入图片中构建这样的 NDArray。如果还没安装 OpenCV,考虑到本例的要求,直接运行 pip install opencv-python 就够了 :)。
随后的步骤如下:
- ** 读取 ** 图片:将返回一个 Numpy 数组,其形态为(图片高度, 图片宽度, 3),按顺序代表 **BGR**(蓝、绿、红)三个通道。 ```
img = cv2.imread(filename)
{1}
  • 将图片转换为 RGB。 ```

    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

复制代码
- 将图片 ** 调整大小 ** 至 **224x224**。 ```
img = cv2.resize(img, (224, 224,))
  • 重塑数组的形态,从(图片高度, 图片宽度, 3)重塑为(3, 图片高度, 图片宽度)。 ```

    img = np.swapaxes(img, 0, 2)
    img = np.swapaxes(img, 1, 2)

复制代码
- 添加一个 ** 第四维度 ** 并构建 NDArray ```
img = img[np.newaxis, :]
array = mx.nd.array(img)
>>> print array.shape
(1L, 3L, 224L, 224L)

晕了?一起用个例子看看吧。输入下列这张图片:

输入 448x336 的图片(来源:metaltraveller.com)

处理完毕后,该图会被缩小尺寸并拆分为 RGB 通道,存储在 array[0] 中(生成下文图片的代码可参阅这里)。

array[0][0]:224x224,红色通道

array 0 :224x224,绿色通道

array 0 :224x224,蓝色通道

如果批大小大于 1,那么可以通过 array 1 指定第二张图片,使用 array 2 指定第三张图片,以此类推。

无论这个过程是乏味还是有趣,接下来我们开始预测吧!

开始预测

你可能还记得第 3 篇文章中提到,Module 对象必须以为单位向模型提供数据:最常见的做法是使用数据迭代器(因此我们使用了 NDArrayIter 对象)。

在这里我们想要预测一张图片,因此尽管可以使用数据迭代器,不过也没啥必要。但我们可以创建一个名为 Batch 的具名元组 (Named tuple), 它可以充当假的迭代器,在引用数据属性时返回输入的 NDArray。

复制代码
from collections import namedtuple
Batch = namedtuple('Batch', ['data'])

随后即可将这个“Batch”传递给模型开始预测。

复制代码
mod.forward(Batch([array]))

这个模型会输出一个包含1000 个可能性的 NDArray,每个可能性对应一个分类。由于批大小等于 1,因此只需要一行代码。

复制代码
prob = mod.get_outputs()[0].asnumpy()
>>> prob.shape
(1, 1000)

使用 squeeze() 将其转换为数组,随后使用 argsort() 创建第二个数组,其中保存了这些可能性按照降序排列的指数

复制代码
prob = np.squeeze(prob)
>>> prob.shape
(1000,)
>> prob
[ 4.14978594e-08 1.31608676e-05 2.51907986e-05 2.24045834e-05
2.30327873e-06 3.40798979e-05 7.41563645e-06 3.04062659e-08 etc.
sortedprob = np.argsort(prob)[::-1]
>> sortedprob.shape
(1000,)

根据模型的计算,这张图片最可能的分类是#546,可能性为58%

复制代码
>> sortedprob
[546 819 862 818 542 402 650 420 983 632 733 644 513 875 776 917 795
etc.
>> prob[546]
0.58039135

这个分类叫什么名字呢?我们可以使用 synset.txt 文件构建分类清单,并找出 546 号的名称。

复制代码
synsetfile = open('synset.txt', 'r')
categorylist = []
for line in synsetfile:
categorylist.append(line.rstrip())
>>> categorylist[546]
'n03272010 electric guitar'

可能性第二大的分类是什么?

复制代码
>>> prob[819]
0.27168664
>>> categorylist[819]
'n04296562 stage

挺棒的,你说呢?

就是这样,我们已经了解了如何使用预训练的顶尖模型进行图片分类。而这一切只需要4 行代码……除此之外只要准备好数据就够了。

完整代码如下,请自行尝试并继续保持关注 ??

代码已发布至 GitHub: mxnet_example2.py

后续内容:

  • 第 5 篇:进一步了解预训练模型(VGG16 和 ResNet-152)
  • 第 6 篇:通过树莓派进行实时物体检测(并让它讲话!)

作者 Julien Simon 阅读英文原文 An introduction to the MXNet API?—?part 4


感谢杜小芳对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-07-16 17:037347
用户头像

发布了 283 篇内容, 共 107.0 次阅读, 收获喜欢 62 次。

关注

评论

发布
暂无评论
发现更多内容

报表分析工具免费试用:瓴羊Quick BI带你快速解析数据

夜雨微澜

专家老师带教!现场答疑!阿里云实时计算 Flink 版线下训练营北京站来啦!

Apache Flink

大数据 flink 实时计算

Apache 官方限定社区周边,Community Over Code 亚洲大会参会礼包抢鲜看!

Apache IoTDB

对线面试官 - TCP 经典面试题

派大星

Java 面试题

TDengine 3.1.0.0 版本成功发布,涉及五大板块功能更新!

TDengine

tdengine 时序数据库

如何落地复杂系统的架构治理?

码猿外

架构设计 软件架构治理

【Python】一键查询依赖生成文件 requirements.txt

ReturnTmp

商业智能工具 bi工具是什么,瓴羊Quick BI能给企业主带来哪些优势?

对不起该用户已成仙‖

【学习课程送福利!】InfoQ最新Java开发课程喊你来领奖品!100%中奖!

SoFlu软件机器人

【名师代练】带你玩转 RocketMQ,角逐「RocketMQ 首席评测官」

阿里巴巴云原生

阿里云 云原生 Apahce RocketMQ

免费物联网平台好用吗?物联网平台卷蒙圈了,集体不要钱,白嫖的到底能不能用?

Geek_a6511e

物联网平台 物联网 物联网低代码平台 物联网平台选型

什么是主数据管理?企业主数据管理方法论

优秀

主数据管理 主数据

一个好用的低代码平台应具有哪些素养?

树上有只程序猿

低代码 零代码 应用开发

什么是业务敏捷,如何实现业务敏捷?

CODING DevOps

敏捷开发

提速 40%,融云基于 QUIC 深度优化通信协议

融云 RongCloud

网络 协议 融云 QUIC 通讯

【数据库原理 | MySQL】一文打通 DDL语句 - ARTS 打卡第 一 周

计算机魔术师

如何唤醒潜在用户?选择智能化推送系统的重要性

MobTech袤博科技

前端 前端开发 APP开发 前端开发工具

Apache Dubbo 云原生可观测性的探索与实践

阿里巴巴云原生

Apache 阿里云 云原生 dubbo

智能标签系统如何助力智能推送服务

MobTech袤博科技

前端开发 消息推送 APP开发 前端开发工具

低代码平台技术分享官丨工作流应用场景之动态驳回

inBuilder低代码平台

ARTS 打卡第 6 天

自由

LeetCode题解:617. 合并二叉树,JavaScript,详细注释

Lee Chen

JavaScript LeetCode

火热的低代码和无代码赛道

互联网工科生

软件开发 低代码 无代码 应用开发

ASR 语音识别接口封装和分析

非晓为骁

AI 语音识别 ASR AIGC

文心一言 VS 讯飞星火 VS chatgpt (76)-- 算法导论7.3 1题

福大大架构师每日一题

福大大架构师每日一题

融云出海:两极分化的网红大户「拉美」如何出海制胜

融云 RongCloud

互联网 泛娱乐 出海 社交娱乐 社媒

融云:以对话为场景本质,AIGC 将如何改变游戏规则

融云 RongCloud

人工智能 AI 算法 AIGC 通讯

QT使用QML实现地图绘制虚线

梦笔生花

“这对我个人能力的认可意义重大”!数据库“小白”到 Apache IoTDB committer 的心路历程!

Apache IoTDB

云原生 AI 工程化实践之 FasterTransformer 加速 LLM 推理

阿里巴巴云原生

阿里云 AI 容器 云原生

解决并发冲突:Java实现MySQL数据锁定策略

高端章鱼哥

Java MySQL 数据库

MXNet API入门 —第4篇_语言 & 开发_Julien Simon_InfoQ精选文章