0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

讨论游戏Emoji Scavenger Hunt的内部运作方式

Tensorflowers 来源:未知 作者:李倩 2018-10-13 10:41 次阅读

在这篇文章中,我们将讨论游戏 Emoji Scavenger Hunt 的内部运作方式。我们将向您展示如何使用 TensorFlow 训练用于对象识别的自定义模型以及如何在 Web 前端使用 TensorFlow.js 使用该模型。在使用浏览器 API 进行摄像头访问和文本到语音的转换时,我们还将介绍一些挑战和解决方法。这个游戏的所有代码都是开源的,可以在 Github 上找到(https://github.com/google/emoji-scavenger-hunt)。

介绍游戏 Emoji Scavenger Hunt

Emoji Scavenger Hunt 是一个有趣的游戏,你会看到一个表情符合,并在秒数之内找到真实世界的等效物体。当你在现实世界中发现表情符号时,随后的表情符号显示难度增加。从你可能拥有的物品开始,比如鞋子,书本或者你自己的手以及像香蕉,蜡烛甚至踏板车这样的东西。

我们的目标是以有趣,互动的方式展示机器学习技术。

训练对象识别模型

Emoji Scavenger Hunt 游戏的核心功能是识别您的相机所看到的物体,并将其与游戏要求您找到的物体(表情符号)相匹配。但相机如何知道它看到了什么?我们需要一个可以帮助识别物体的模型。最初我们开始使用名为 MobileNet 的预训练模型。这个模型是轻量级的,并针对移动设备进行了优化,但其中的对象太具体,不适合我们的游戏。例如,确定了像 “金毛猎犬” 这样的犬种,但没有 “狗” 的通用对象类。我们逐渐意识到需要训练自定义的图像识别模型。

这是转移学习可以派上用场的地方。转移学习是一种技术,它通过将其用于另一个目标任务来重用针对特定任务而训练的机器学习模型。我们通过使用此教程中描述的过程重新训练基于 MobileNet 的模型来构建我们自己的自定义模型。我们添加了一个全连接层,它将默认输出 logits 映射到我们想要的表情符号对象,如 “手” 和 “键盘” 等。我们列出了大约400个对象用于物体识别并收集 100-1000 个图像作为每个对象的训练数据。添加的全连接层通过组合来自 MobileNet 输出层的 1000 个信号来推断这 400 个对象。

注:教程 链接

https://www.tensorflow.org/hub/tutorials/image_retraining

训练脚本可在 TensorFlow Github 存储库中找到(https://github.com/tensorflow/hub/blob/master/examples/image_retraining/retrain.py)。我们将训练过程编译为 Dockerfile,以便您可以通过指向自己的图像数据集来训练自己的模型

我们运行脚本将训练图像数据提供给模型。为了简化我们的训练流程,我们在 Google Cloud Platform 上构建了整个管道。所有的训练数据都将存储在 Google Cloud 存储桶中。通过在 Google Functions 设置云存储触发器,一旦在存储桶中检测到任何变化,就会启动计算引擎上的 GPU 实例。GPU 实例以 TensorFlow SavedModel 格式输出再训练模型,并将其保存在云存储上的另一个存储桶中。

模型培训的数据管道

我们如何与 TensorFlow.js 集成

完成上述模型训练中的步骤后,我们最终得到了一个用于对象识别的 TensorFlow SavedModel。为了通过 TensorFlow.js 在浏览器中访问和使用此模型,我们使用 TensorFlow.js 转换器将此 SavedModel 转换为 TensorFlow.js 可以加载的格式。

识别对象的行为可以分为两个子任务。首先,从相机中抓取像素,然后将图像数据发送到 TensorFlow.js,以根据我们之前训练过的模型预测它的想法。

相机和模型设置

在我们开始预测对象之前,我们需要确保相机(通过 MediaDevices.getUserMedia)准备好显示内容,并且我们的机器学习模型已加载并准备好开始预测。在我们开始预测之前,我们使用以下代码段来启动这两个代码并执行一些任务设置。

1Promise.all([

2this.emojiScavengerMobileNet.load().then(() => this.warmUpModel()),

3camera.setupCamera().then((value: CameraDimentions) => {

4camera.setupVideoDimensions(value[0], value[1]);

5}),

6]).then(values => {

7// Both the camera and model are loaded, we can start predicting

8this.predict();

9}).catch(error => {

10// Some errors occurred and we need to handle them

11});

一旦成功完成,相机设置和模型加载都将以 Promise 解析。您会注意到,一旦加载了模型,我们就会调用 this.warmUpModel()。这个函数只是做一个预测调用来编译程序并将权重上传到 GPU,这样当我们想要传递真实数据进行预测时,模型就会准备就绪。

将图像数据发送到 TensorFlow.js

以下代码片段(已删除注释)是我们的预测函数调用,它从相机中获取数据,将其解析为正确的图像大小,将其发送到我们的 TensorFlow.js 并使用生成的识别对象来查看我们是否找到了表情符号。

1async predict() {

2if (this.isRunning) {

3const result = tfc.tidy(() => {

4

5const pixels = tfc.fromPixels(camera.videoElement);

6const centerHeight = pixels.shape[0] / 2;

7const beginHeight = centerHeight - (VIDEO_PIXELS / 2);

8const centerWidth = pixels.shape[1] / 2;

9const beginWidth = centerWidth - (VIDEO_PIXELS / 2);

10const pixelsCropped =

11pixels.slice([beginHeight, beginWidth, 0],

12[VIDEO_PIXELS, VIDEO_PIXELS, 3]);

13

14return this.emojiScavengerMobileNet.predict(pixelsCropped);

15});

16

17const topK =

18await this.emojiScavengerMobileNet.getTopKClasses(result, 10);

19

20this.checkEmojiMatch(topK[0].label, topK[1].label);

21}

22requestAnimationFrame(() => this.predict());

21}

让我们更详细地看一下这个片段。我们将整个预测代码逻辑包装在 requestAnimationFrame 调用中,以确保浏览器在进行屏幕绘制更新时以最有效的方式执行此逻辑。如果游戏处于运行状态,我们只执行预测逻辑。通过这种方式,我们可以确保在执行屏幕动画(如结束和赢取屏幕)时,我们不会运行任何 GPU 密集型预测代码。

另一个小而重要的性能改进是将 TensorFlow.js 逻辑包装在对 tf.tidy() 的调用中。这将确保在执行该逻辑期间创建的所有 TensorFlow.js 张量都将在之后得到清理,从而确保更好的长期运行性能。请参阅https://js.tensorflow.org/api/latest/#tidy

我们预测逻辑的核心与从相机中提取图像以发送到 TensorFlow.js 有关。我们不是简单地拍摄整个相机图像并将其发送出去,而是从相机中心切出一部分屏幕并将其发送到 TensorFlow.js。在我们的游戏中,我们使用 224 像素x 224 像素的参考图像训练我们的模型。将与我们的参考训练数据具有相同尺寸的图像发送到 TensorFlow.js,从而确保更好的预测性能。我们的相机元素(它只是一个 HTML 视频元素)不是 224 像素的原因是因为我们想要确保用户的全屏体验,这意味着使用 CSS 将相机元素扩展到 100% 的屏幕。

以下参考图像显示左上角的切片,该切片将发送到 TensorFlow.js。

然后,模型使用该图像数据生成前 10 个最可能项目的列表。您会注意到我们获取前 2 个值并将其传递给 checkEmojiMatch 以确定我们是否找到了匹配项。我们选择使用前 2 个匹配而不是最顶级的项目,因为它使游戏更有趣,并允许我们根据模型在匹配中留有一些余地。拥有一个过于准确和严格的模型会导致用户在无法识别对象时感到沮丧。

在上面的图像示例中,您可以看到我们目前的任务是找到 “键盘” 表情符号。在此示例中,我们还显示了一些调试信息,因此您可以根据输入图像查看模型预测的所有 10 个可能项目。这里的前两个匹配是 “键盘” 和 “手”,它们都在图像中,而 “手” 具有稍大的可能性。虽然 “键盘” 在第二个检测到的位置,但游戏在这里检测到匹配,因为我们使用前两个匹配进行检查。

为我们的模型提供文本到语音的转换

作为游戏的一个有趣的补充,我们实施了 SpeechSynthesis API。从而当你在寻找表情符号的时候,大声朗读出模型预测。在 Android 上的 Chrome 中,通过以下代码实现这一点非常简单:

1speak(msg: string) {

2if (this.topItemGuess) {

3if ('speechSynthesis' in window) {

4let msgSpeak = new SpeechSynthesisUtterance();

5msgSpeak.voice = this.sleuthVoice['activeVoice'];

6

7msgSpeak.text = msg;

8speechSynthesis.speak(msgSpeak);

9}

10}

11}

此 API 在 Android 上即时运行,但 iOS 将任何 SpeechSynthesis 调用限制为直接与用户操作相关的调用(例如点击事件),因此我们需要为该平台找到替代解决方案。我们已经熟悉 iOS 将音频播放事件绑定到用户操作的要求,我们通过启动用户最初单击 “播放” 按钮时播放的所有音频文件来处理我们游戏中的其他声音,然后立即暂停所有这些音频文件。最后,我们最终制作了一个音频精灵,其中包含了所有 “成功” 的语音线(例如,“嘿,你找到了啤酒”)。这种方法的缺点是这个音频精灵文件变得非常大,对话需要更多。

我们尝试过的一种方法是将音频精灵分解为前缀(“嘿,你找到了”,“是那个”)和后缀(“啤酒”,“香蕉” 等),但我们发现 iOS 在播放一个音频文件的片段,暂停,移动播放头,然后播放同一文件的另一个片段之间增加了不可避免的一秒延迟。前缀和后缀之间的差距很长,以至于感觉很刺耳,我们经常发现语音会远远落后于实际的游戏玩法。我们仍在调查 iOS 上语音改进的其他选项。

下面是我们播放音频文件的函数,其中包含通过开始和停止时间戳处理播放音频精灵片段的附加代码:

1playAudio(audio: string, loop = false, startTime = 0,

2endTime:number = undefined) {

3let audioElement = this.audioSources[audio];

4if (loop) {

5audioElement.loop = true;

6}

7if (!this.audioIsPlaying(audio)) {

8audioElement.currentTime = startTime;

9let playPromise = audioElement.play();

10if (endTime !== undefined) {

11const timeUpdate = (e: Event) => {

12if (audioElement.currentTime >= endTime) {

13audioElement.pause();

14audioElement.removeEventListener('timeupdate', timeUpdate);

15}

16};

17audioElement.addEventListener('timeupdate', timeUpdate);

18}

19if (playPromise !== undefined) {

20playPromise.catch(error => {

21console.log('Error in playAudio: ' + error);

22});

23}

24}

25}

通过 getUserMedia 进行相机访问时可能存在的风险

Emoji Scavenger Hunt 在很大程度上依赖于能够通过浏览器中的 Javascript 访问相机。我们在浏览器中使用 MediaDevices.getUserMedia API 来访问摄像头。并非所有浏览器都支持此 API,但大多数主流浏览器的最新版本都有很好的支持。

要通过此 API 访问相机,我们使用以下代码段:

1if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {

2const stream = await navigator.mediaDevices.getUserMedia({

3'audio': false,

4'video': {facingMode: 'environment'}

5});

6(window).stream = stream;

7this.videoElement.srcObject = stream;

8}

此 API 提供了一种通过传入配置对象并指定 facingMode 来访问前置和后置摄像头的方法。

无法通过 UIWebViews 访问

在测试期间,我们意识到 Apple 不支持任何基于 webkit 浏览器的 UIWebView 使用 getUserMedia API,这意味着 iOS 上任何实现自己浏览器的应用程序,如第三方 Twitter 客户端或 iOS 上的 Chrome,都无法访问摄像头。

为解决此问题,我们会检测到相机初始化失败,并提示用户在本机 Safari 浏览器中打开体验。

致谢

通过这个实验,我们想要创建一个有趣和愉快的游戏,利用当今浏览器中提供的惊人的机器学习技术。这只是一个开始,我们希望您能使用 TensorFlow.js 和 TensorFlow.js 转换器实现您所有的想法。如上所述,我们的代码可以在 Github 上找到(https://github.com/google/emoji-scavenger-hunt),所以请用它来开始你自己的想法。

在构建这个实验的过程中,我们要感谢 Takashi Kawashima,Daniel Smilkov,Nikhil Thorat 和 Ping Yu 的帮助。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 图像
    +关注

    关注

    2

    文章

    1063

    浏览量

    40037
  • 机器学习
    +关注

    关注

    66

    文章

    8116

    浏览量

    130546
  • tensorflow
    +关注

    关注

    13

    文章

    313

    浏览量

    60242

原文标题:让我们看看,如何使用 TensorFlow.js 构建 Emoji Scavenger Hunt

文章出处:【微信号:tensorflowers,微信公众号:Tensorflowers】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    游戏融网:结婚的正确打开方式

    游戏的正确打开方式是什么呢?是众筹!发行商只有提前调研、预售,才能知道玩家的心理;玩家也只有在游戏成型前提出意见、给予支持,才能得到自己真正喜欢的游戏。林心如与霍建华非常聪明地运用了正
    发表于 07-15 14:27

    我用这种方式停止程序运行为啥导致循环里面都不运作

    我用这种方式停止程序运行为啥导致循环里面都不运作,我把这个停止的结构删除程序就可以正常运转了
    发表于 09-12 15:09

    MySql支持Emoji表情?

    MySql支持Emoji表情
    发表于 05-15 13:54

    Linux-Mysql插入emoji表情问题怎么回事

    Linux-Mysql插入emoji表情问题
    发表于 06-15 06:55

    超高速电机控制方式讨论

    超高速10万转电机(1对极)控制方式讨论
    发表于 08-27 08:22

    ADC内部模数转换查询方式实验

    ADC内部模数转换查询方式实验
    发表于 12-16 21:48 0次下载

    北约29国已经内部讨论有关华为5G问题

    3月15日下午消息,据外媒报道,北约29国已经在“内部讨论”有关华为5G问题。
    的头像 发表于 03-16 10:07 2602次阅读

    三星电子继苹果之后也宣布推出迪士尼AR Emoji角色

    在苹果宣布了新一批 Animoji 角色和多样的 Memojis 之后,三星也宣布为自家 AR Emoji 家族引入了两个全新的迪士尼动画角色黛丝鸭(Daisy Duck)和高飞犬(Goofy
    发表于 06-22 09:01 2537次阅读

    基于一种完善运作的跨平台卡牌游戏Nova Blitz介绍

    Nova Blitz 是一种完善运作的跨平台卡牌游戏,是第一个使用 Nova Token 的卡牌游戏。它已经拥有超过 300 种卡牌,每月可能推出超过 50 种新卡。
    发表于 08-21 11:39 366次阅读

    黑鲨游戏手机3 Pro的操控方式曝光

    下个月黑鲨游戏手机3 Pro就要发布了,在此之前黑鲨产品中心部长 @黑鲨关二爷 继续曝光该机的信息,今天他放出的是黑鲨游戏手机3 Pro的操控方式
    的头像 发表于 02-29 15:02 2384次阅读

    云计算正在改变业务的运作方式

    在2021年消费电子展会举办期间,行业专家针对组织领导者应该了解有关云计算的当前状态以及未来的发展前景进行了探讨。来自IBM、微软、埃森哲等知名公司的行业专家参加了会议,他们分析了云计算正在改变业务的运作方式以及云计算架构对软件开发的意义。
    的头像 发表于 02-03 14:03 2013次阅读

    open-source-emoji WordPress的emoji表情插件

    ./oschina_soft/open-source-emoji.zip
    发表于 05-18 14:28 3次下载
    open-source-<b class='flag-5'>emoji</b> WordPress的<b class='flag-5'>emoji</b>表情插件

    Kawaii Emoji Messenger多平台的Facebook客户端

    ./oschina_soft/kawaii-emoji-messenger.zip
    发表于 05-27 10:30 1次下载
    Kawaii <b class='flag-5'>Emoji</b> Messenger多平台的Facebook客户端

    现在Android平台也能顺利使用Emoji

    在移动互联网如此发达的今天,Emoji 已无处不在,并成为我们日常交流中不可或缺的一部分。据统计,Emoji 的使用率在过去 10 年内不断攀升,2021 年更是达到了历史新高,每天有超过五分之一
    的头像 发表于 06-02 15:08 2621次阅读
    现在Android平台也能顺利使用<b class='flag-5'>Emoji</b>了

    微软Windows 11新增支持Emoji表情符号

    据Windows Developer官方账号发布的信息显示,用户可在Windows Terminal应用中使用命令提示符输入各类Emoji,以实现更具个性和趣味性的命令输入体验。
    的头像 发表于 04-11 11:26 102次阅读