首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >长假慢学,用TensorFlow做了个AI游戏

长假慢学,用TensorFlow做了个AI游戏

作者头像
花叔
发布2020-07-24 10:54:26
1.3K0
发布2020-07-24 10:54:26
举报
文章被收录于专栏:花叔的专栏花叔的专栏

这些天,想必大家最不缺的是假期....

正好可以趁这段时间学习学习,于是我还是沉下心搞了一下技术研究,接下来就说说从年前宅到现在折腾的东西吧。

一言蔽之:学习了tensorflow

年末给自己定了一个“研究人工智能”的目标,为什么呢?毕竟现在说自己会写代码的人很多,但会人工智能编程的人却不多吧,学习人工智能,这完全符合我的“信息不对称”论。

那么,为什么是tensorflow(以下简称为tf)呢?因为它简单呀!(后来发现其实也挺难),而且它有js版本,会做网页开发的前端同学基本看看demo就能知道它在干嘛,也能马上做出一两个相关demo。

注.以下是tensorflow.js的官方定义:

Tensorflow.js 是一个基于 deeplearn.js 构建的库,可直接在浏览器环境中创建深度学习模型。使用它可以在浏览器上创建 CNNs,RNNs 等,并使用客户端的 GPU 处理能力训练这些模型。 Google,公众号:TensorFlowTensorFlow.js 入门指南

于是,拧起袖子,说干就干。但问题来了,干什么呢?每次要创造或者学习什么东西,我都习惯给自己定一个简单直接的场景,并具象化成一个载体。

做点没人做过的事:把tf用在小游戏上,做个手绘识别游戏。

老规矩,先上实例,依然搞了个游戏,不过这次做的是跨平台版本。

微信小游戏版(待发布,要体验可以单独联系):

字节小游戏版:

可能是小游戏中鲜有的、用了tensorflow的游戏?

其实,google早在普通小程序上给过tf的应用方案,但在小游戏上却没怎么提及过,何不给小游戏一个tf案例呢?于是,作为一个完全没接触过tf开发的程序员,我开始找demo去研究代码。后来,在网上发现一个外国牛人对google开源手绘数据集的应用:

https://medium.com/tensorflow/train-on-google-colab-and-run-on-the-browser-a-case-study-8a45f9b1474e

里面阐述的内容大概是关于怎么利用手绘数据集,然后通过tf去训练模型的,与此同时,大牛还提供了一个web版的手绘识别demo。

结合文章,我发现其实把这个demo移植到微信小游戏中,应该是不难的,但因为我要做的是游戏,所以一般会用上游戏引擎,于是我试着用cocos creator(以下简称为ccc)去呈现这个demo。

其实还是有点麻烦的,最终花了一些时间去实现了一个可运行的网页版:

当我喜出望外,觉得这是一件简单的事情时,马上就晴天霹雳了,我在ccc中以微信小游戏发布,

然后在手机上试着运行,发现是报错的。

构造一个小游戏可用的tfjs

这是为什么呢?经过一定时间的摸索,发现官方的tf用了一个叫Fetch的方法,该方法在微信小游戏中并不兼容。

注.关于fetch的定义如下:

Fetch API 已经作为现代浏览器中异步网络请求的标准方法,其使用 Promise 作为基本构造要素。 公众号:前端大全认识 Fetch API

Fetch的作用说白了就是要简化请求,那么兼容方案就不难了,甚至也不用我主动去写兼容代码,因为google给普通小程序提供的Fetch兼容代码是适用于小游戏的:

https://cdn.jsdelivr.net/npm/fetch-wechat@0.0.3/dist/fetch_wechat.js

于是通过终端中执行命令行,可得到最新版的tfjs:

npm install @tensorflow/tfjs

在上述最右侧目录中找到tf.js,然后结合上述的Fetch兼容代码,我们就可以做出一份能在小游戏中适用的tfjs。

https://github.com/minijoe/tfjsForMinigame/blob/master/tf.js

主要兼容的代码包括以下两部分:

  1. 把原tfjs中的self和this换成小游戏的全局变量GameGlobal
  1. 底部加上Fetch代码

这样,我们就得到了一个可用的tfjs,需要提醒的是,字节小游戏中的webgl版本跟tfjs貌似是不兼容的,这时候可以试试把backend调整成cpu模式(当然会慢一点了)。

使用google手绘数据集构建模型数据

很早之前Google就开源了一个非常棒的数据集---涂鸦数据集,其中涉及300多种物体, 包含5000 万张矢量画数据,这些数据全部开源给开发者,数量量极其庞大:

https://github.com/googlecreativelab/quickdraw-dataset

借助于这个数据集,可用 Keras 框架在谷歌 Colab 免费提供的 GPU 上训练模型(Google云盘上的Colab Notebooks可运行脚本)。

具体可以参考这个帖子:

https://medium.com/tensorflow/train-on-google-colab-and-run-on-the-browser-a-case-study-8a45f9b1474e

实际上,关键是要生成model.json和group1-shard1of1,这是tf.loadLayerModel所需要的模型数据。

tf要实现“某个图片在已有模型数据中的匹配度”目的,所遵循的逻辑有以下3步:

1.利用tf.loadLayersModel加载训练好的模型数据

tf.loadLayersModel('http://xxx/model.json').then(model => {
    model.predict(tf.zeros([1, 28, 28, 1]))
    cc.game.model=model
})

2.读取并整理传进来的图片数据

function preprocess(imgData) {
    //注意,1.5.2的tf不能直接传入图片数据,要整理一下
    var data={
        width:imgData.width,
        height:imgData.height,
        data:new Uint8Array(imgData.data)
    }
    return tf.tidy(() => {
        var tensor = tf.browser.fromPixels(data, 1)
        const resized = tf.image.resizeBilinear(tensor, [28, 28]).toFloat()
        const offset = tf.scalar(255.0);
        const normalized = tf.scalar(1.0).sub(resized.div(offset));
        const batched = normalized.expandDims(0)
        return batched
    })
}

3.计算匹配度

const pred = cc.game.tfModel.predict(preprocess(imgData)).dataSync()

这句代码会得到传进来的图片数据在模型数据中的匹配排序,只要取出前几名就能判断出传进来的图片跟什么物体相似。

基于这个,就能做出只能识别手绘图的游戏逻辑了。

评估游戏主逻辑可行性后,我切换到灵魂画师的角色,理一下逻辑,游戏交互和视觉就出来了:

利用ipad的Procreate App,用apple pencil手绘一下logo和弹框、按钮之类的素材。

在ccc中嵌套视觉素材。

再补充关卡相关的页面和数据,调整一下难度,一个游戏的开发就完成了。

最后,个人对于字节互动的小游戏有点好奇,于是顺带就移植了一个版本,最终给微信和字节都做了版本。

结项~

这年春节很不平常,但对于想要学习和创作的我来说,其实是更多时间去折腾了。

本文只是基于应用层面简单的挂靠了一下AI概念,但愿还是能给想要在小游戏领域做AI的同学一点启发。

讲完了。

ps.最近一直在想能不能用技术去帮忙抗疫,昨晚就跟另一个朋友在聊,能不能用tf去做个智能识别口罩,然后推送真假货建议或使用建议信息的小程序,但模型训练难度太高,于是被否了。

现在还一直在想怎么做点跟疫情相关的技术研究,有想法的同学可以留言建议咯。

最后,

病毒无情,人间有情,愿我们在彼此隔离间迈过这道坎~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 MinProgram 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档