构建新的云原生系统或是将遗留系统云原生化,如何少走弯路?点击查看 了解详情
写点什么

AWS DeepLens Lambda 函数与新 Model Optimizer 详解

  • 2019 年 10 月 30 日
  • 本文字数:4341 字

    阅读完需:约 14 分钟

AWS DeepLens Lambda 函数与新 Model Optimizer 详解

今天我们推出了面向 AWS DeepLens 的新 Model Optimizer,优化深度学习模型,只需一行 Python 代码即可在 DeepLens GPU 上高效运行。Model Optimizer 已在 AWS DeepLens 软件版本 1.2.0 中提供。


AWS DeepLens 使用深度神经网络计算库 (Cl-DNN) 来访问推断 GPU。模型必须转换为 Cl-DNN 格式后才能在 AWS DeepLens 上运行。根据具体模型的大小,只需输入如下一行代码,Model Optimizer 可在 2-10 秒内完成这一转换:


mo.optimize(model_name,input_width,input_height)
复制代码


将此代码行放入推断 Lambda 函数,即可访问 Model Optimizer。推断 Lambda 函数可让 AWS DeepLens 访问您刚刚部署的模型。在本贴中,我们演示了如何创建推断 Lambda 函数,并提供了一个模板,您可以根据自己的需要对此模板进行自定义。


推断 Lambda 函数执行三个关键功能:预处理、推断和后处理。


如要创建推断 Lambda 函数,请使用 AWS Lamda 控制台并执行如下步骤


  1. 选择创建函数。对此函数进行自定义,以运行深度学习模型的推断。

  2. 选择蓝图

  3. 搜索 greengrass-hello-world 蓝图。

  4. Lambda 函数名必须与模型名相同。

  5. 选择现有的 IAM 角色:AWSDeepLensLambdaRole。 此决策必须在注册过程中事先创建。

  6. 选择创建函数

  7. 函数代码中的句柄必须是 greengrassHelloWorld.function_handler

  8. 在 GreengrassHello 文件中,应清除所有代码。您将在此文件中写入推断 Lambda 函数的代码。


首先导入要求的文件包:


import osimport greengrasssdkimport awscamimport moimport cv2from threading import Thread
复制代码


导入 os 可让您访问 AWS DeepLens 的操作系统。导入 awscam 可让您访问 AWS DeepLens 推断 API。 mo 可让您访问 Model Optimizer。 cv2 可让您访问开放 CV 库,该库包含额图像预处理和导入的常用工具。 thread 可让您访问 Python 的多线程库。请使用单独的线程向 mplayer 发送推断结果,并可在那里查看模型的输出。


然后创建 Greengrass Core SDK 客户端,从而可以使用 MQTT 通过 AWS IoT 向云发送消息。Greengrass core SDK 已经加载到设备行,因此无需导入。


client = greengrasssdk.client('iot-data')
复制代码


然后为 Lambda 函数创建向其发送消息 AWS IoT 主题。您可以在 AWS IoT 控制台上访问此主题。


iot_topic = '$aws/things/{}/infer'.format(os.environ['AWS_IOT_THING_NAME'])
复制代码


如要启用通过 mplayer 在本地查看输出的功能,请声明一个全局变量,其中包含要输入到 FIFO 文件中的 jpeg 图像 results.mjpeg。此外,您还可以将 Write_To_FIFO 修改为 False,从而关闭指向 FIFO 文件的流。这将终止该线程,因此您将无法通过 mplayer 访问图像以查看输出。


jpeg = NoneWrite_To_FIFO = True
复制代码


然后创建一个在自有线程上运行的简单类,从而让您可以将输出图像发布到 FIFO 文件并使用 mplayer 查看。这是通过 mplayer 查看输出的标准代码,对所有推断 Lambda 函数通用。对于您自己的项目,您可以将此代码复制到自己的推断 Lambda 函数中。


class FIFO_Thread(Thread):    def __init__(self):        ''' Constructor. '''        Thread.__init__(self)
def run(self): fifo_path = "/tmp/results.mjpeg" if not os.path.exists(fifo_path): os.mkfifo(fifo_path) f = open(fifo_path,'w') client.publish(topic=iot_topic, payload="Opened Pipe") while Write_To_FIFO: try: f.write(jpeg.tobytes()) except IOError as e: continue
复制代码


然后在 Lambda 函数中定义推断类。 首先定义一个 Greengrass 推断函数。


def greengrass_infinite_infer_run():  input_width = 224  input_height = 224
复制代码


input_widthinput_height 参数定义了模型的输入参数。如要执行推断,模型要求帧的大小相同。对于您部署到 AWS DeepLens 的模型,您可以自定义这些参数。


在下一行定义模型名。模型名的前缀必须与经受训练的模型的 params 文件和 json 文件前缀一致。例如,如果 params 文件和 json 文件分别为 squeezenet_v1.1-0000.params 和 squeezenet_v1.1-symbol.json,则模型名的前缀必须为 squeezenet_v1.1。这一点十分重要。如果模型名的前缀与这两个文件不一致,推断将无法进行,将会发生错误。


model_name = 'squeezenet_v1.1'
复制代码


然后启动 Model Optimizer。这将把所部署的模型转换为 Cl-DNN 格式,从而可以在 AWS DeepLens GPU 中访问。这将返回指向优化后内容的路径。


error, model_path = mo.optimize(model_name,input_width,input_height)
复制代码


将模型加载到推断引擎中。这是您提供代码以访问 GPU 的地方。如要访问 CPU,只需输入代码 “GPU” = 0。但对于深度学习模型,我们建议您访问 GPU 以提高效率和速度。


model = awscam.Model(model_path, {"GPU": 1})
复制代码


您可以向 AWS IoT 发送一条消息,告诉它模型已经加载。


client.publish(topic=iot_topic, payload="Model loaded")
复制代码


然后定义您要运行的模型类型。例如,中性传输的模型类型为 segmentation,对象本地化的模型类型为 ssd (单次多重检测器)。对于图像分类,模型类型为 classification。由于您部署的是对图像进行分类的 squeezenet 模型,因此模型类型应定义为 classification


model_type = "classification"
复制代码


由于 squeezenet_v1.1 有多达 1,000 个分类符,编写 python 列表来定义数字标签与人类刻度标签的映射表是不实际的。为此我们将添加一个文本文件,按顺序列出索引和所代表的标签。您可以在此处找到有关此示例的文本文件。


如要为 Lambda 函数添加该文本文件:


  1. 在函数代码部分,选择文件。然后选择新建文件


  2. 将文本文件中的数据粘贴到您刚刚创建的新文件中

  3. 选择文件,然后选择保存

  4. 输入文件名 sysnet.txt,然后选择保存


含有相关索引和标签的文件将被添加到 Lambda 函数包中。


现在从左侧菜单中选择 greengrassHelloWorld.py,将返回您的 python 代码。下一步是打开我们刚刚添加的“sysnet.txt”。


with open('sysnet.txt', 'r') as f:  labels = [l.rstrip() for l in f]
复制代码


定义您希望在输出中看到的分类符数量。输入 5,输出结果将按降序返回概率最高的 5 个值。您可以指定模型支持的任何数量。


topk = 5
复制代码


现在启动 FIFO 线程,以使用 mplayer 在本地查看输出。


results_thread = FIFO_Thread()results_thread.start()
复制代码


Inference is starting 消息发布到 AWS IoT 控制台。在接下来的几行中,您将编写推断循环的代码。


client.publish(topic=iot_topic, payload="Inference is starting")
复制代码


以下代码可让 AWS DeepLens 访问 mjpeg 流的最新帧。这是来自 AWS DeepLens 摄像头的输入流。 awscam.getLastFrame 将捕获来自该流的最后一个或最新一个帧,以剖析和执行推断。 raise Exception 允许函数在未能从流中获取帧时生成异常。


while True:     ret, frame = awscam.getLastFrame()     if ret == False:             raise Exception("Failed to get frame from the stream")
frame_resize = cv2.resize(frame, (input_width, input_height))
复制代码


然后是图像的预处理。来自摄像头的输入帧不同于用于模型训练的输入维度。您之前已经定义了模型的输入参数。在这一步,调整来自摄像头的输入帧大小,使其与模型的输入维度相同。在本例中,您只需要降低帧的采样大小,使其与模型输入参数一致。根据您所训练的模型不同,您可能需要执行其他预处理步骤,例如图像正态化。


infer_output = model.doInference(frame_resize)
复制代码


现在经过预处理的帧已经可以用于推断。之前的代码会将模型的结果以词典的形式输出,词典名为最后一层的名称。输出数据不会被解析为人类刻度的格式。如果您照原样使用此输出,您必须执行自己的解析算法。AWS DeepLens 提供了为所支持模型类型解析网络输出的方便接口。 以下方法将返回作为其键的 model_type 词典以及作为其值的第二个词典。第二个词典的 labelprobability 键可让您检索非人类可读的标签以及相关概率。


parsed_results = model.parseResult(model_type, infer_output)
复制代码


您可以自定义该代码以仅显示输出中的前“n”个结果。在本例中,我们自定义该代码以显示前 5 个条目。条目按降序显示,概率最高的条目排在首位。


top_k = parsed_results[model_type][0:topk]
复制代码


现在您获得了结果,将其发送到云。请注意结果的格式为 json 格式,因此云上的其他 Lambda 函数可能会订阅此 IoT 主题,并在它们检测到感兴趣的具体事件时执行操作。例如,在 re:Invent 研讨会上,我们在云上部署了一个将在每次检测到热狗时发送短信的 Lambda 函数。此外还应注意您在进入将网络所输出标签转换为人类可读标签的循环前所创建标签列表的使用方式。


msg = "{"prob_num = 0 for obj in top_k:    if prob_num == topk-1:          msg += '"{}": {:.2f}'.format(labels[obj["label"]], obj["prob"])    else:         msg += '"{}": {:.2f},'.format(labels[obj["label"]], obj["prob"])    prob_num += 1msg += "}"
复制代码


现在消息是 json 格式的,通过 AWS IoT 将其发送到云。


client.publish(topic=iot_topic, payload=msg)
复制代码


现在数据已经在云中,对图像进行后处理以在 mplayer 中查看。在本例中,只需进行简单的后处理,使用 openCV向原始 400 万像素的图像添加标签。您可以根据自己的需求自定义此步骤。


cv2.putText(frame, labels[top_k[0]["label"]], (0,22), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 165, 20), 4)
复制代码


完成后处理后,更新 global jpeg 变量即可使用 mplayer 查看结果。


global jpegret,jpeg = cv2.imencode('.jpg', frame)
复制代码


此外也可添加一条代码,在发生错误时获取异常消息并将之发送到云。为此请使用如下代码。


except Exception as e:  msg = "Lambda failed: " + str(e)  client.publish(topic=iot_topic, payload=msg)
复制代码


现在运行函数并查看结果!


greengrass_infinite_infer_run()
复制代码


不要忘记保存并发布代码。如果忘记发布函数,您将无法在 AWS DeepLens 控制台查看推断 Lambda 函数。


恭喜您!您已经创建了一个 Lambda 函数,您可以使用进行 squeezenet 模型推断。并且您也使用了 Model Optimizer。


您可以在此处访问 squeezenet 模型。


如果您遇到任何问题或需要帮助,请参阅 AWS DeepLens 论坛


作者介绍:



Jyothi Nookula 是一名 AWS DeepLens 高级产品经理。她热爱创造客户满意的产品,在空余时间,她热爱绘画和主持自己作品的慈善义卖。



Eddie Calleja 是一名 AWS 深度学习软件开发工程师。他是 DeepLens 设备的开发人员之一。他以前是一名物理学家,他经常利用空闲时间思考如何运用人工智能技术来解决现代物理学问题。


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/dive-deep-into-aws-deeplens-lambda-functions-and-the-new-model-optimizer/


2019 年 10 月 30 日 08:00272

评论

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

半个多月时间4面阿里,已经成功拿下offer,分享一下个人面经

Java架构之路

Java 程序员 架构 面试 编程语言

拼多多五面面经(Java岗),全面涵盖Java基础到高并发级别

Java架构之路

Java 程序员 架构 面试 编程语言

【LeetCode】分割回文串 II Java题解

HQ数字卡

算法 LeetCode 28天写作

什么原因才是阻碍Linux桌面发展的罪魁祸首

守护石

Linux 程序人生 国产化 redhat

币管家量化交易软件开发|币管家量化交易APP系统开发

系统开发

Linux内核 设备树操作常用API

赖猫

Linux Linux内核

Python 中文编码

依旧廖凯

Python 28天写作 3月日更

如何招聘一名产品经理

马踏飞机747

互联网 产品经理 招聘 职场成长

JAVA已经呈饱和趋势了吗?

cdhqyj

Java 程序员 工作 IT

LDAP身份认证管理最佳实践

龙归科技

服务器 ldap 客户端

音视频之opengl渲染图片

赖猫

音视频

力扣(LeetCode)刷题,简单题(第19期)

不脱发的程序猿

程序员 LeetCode 28天写作 算法面经 3月日更

数据库定时备份linux篇

xiezhr

数据库 Linux Shell 数据备份 3月日更

区块链电子合同应用落地--区块链电子合同签约

13530558032

mongodb 源码实现系列 - Mongodb write写(增、删、改)模块设计与实现

杨亚洲(专注MongoDB及高性能中间件)

MySQL 数据库 mongodb 架构 分布式数据库mongodb

Java程序员福利!2021年最新17套完整版一线大厂面试真题

Java架构追梦

Java 架构 面试 金三银四

十四五,鹏城应作先锋看,山河同襄智能体

脑极体

智能炒币机器人软件开发|智能炒币机器人APP系统开发

系统开发

2021最新分享:阿里内部总监手码的“Redis学习手册”风靡全网

比伯

Java 编程 程序员 架构 面试

Kafka 架构中 ZooKeeper 以怎样的形式存在?

码农架构

Java 消息中间件

Linux/Centos Epoll 原理解析

赖猫

Linux 高并发 epoll

平安智慧社区建设方案,平安小区的系统功能

13530558032

职场里,对数据库要有敬畏之心!

Simon

MySQL 数据库

Alluxio 助力 Kubernetes,加速云端深度学习

阿里巴巴云原生

人工智能 大数据 容器 云原生 k8s

OCE等你加入

滴滴云

云计算 私有云 滴滴夜莺 Obsuite

WebRTC 音视频同步原理与实现

阿里云视频云

阿里云 音视频 WebRTC 流媒体 视频云

分布式事务与解决方案

一个大红包

28天写作 3月日更

SRS流媒体服务器源码分析--RTMP消息play

赖猫

音视频 流媒体 SRS 流媒体开发

不吹不黑聊中台

小谢同学

云计算 中台 企业架构

收藏!这些 IDE 使用技巧,你都知道吗

阿里巴巴云原生

Java ide 云原生 API 调度

深入理解Linux内核 RCU 机制

赖猫

Linux linux编程 Linux内核

AWS DeepLens Lambda 函数与新 Model Optimizer 详解_语言 & 开发_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章