当前位置: 时代头条 > 正文

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

小编的话:前几天刚读完入门介绍的第一部分,是否仍意犹未尽?我们不妨再想点有趣的事:还记得海明威的小说吗?你上一次玩《超级马里奥兄弟》是几年前?这些和机器学习有什么关系呢?往下阅读吧!

原文地址://t.cn/RGEnqbL

作者:Adam Geitgey

编译:糖糖糖

校对:苏尚君

我们在第一部中曾提及:机器学习使用通用算法从数据中获取相应信息,而在此过程中,你无需编写任何只能处理某一特定问题的程序代码。(如果你尚未读过第一部,请先将其读完!)。

这次,我们要用一种通用算法来做一件很酷的事 —— 创建看上去像人工设计的电子游戏关卡。我们将搭建一个神经网络,用现有的超级马里奥关卡作为训练材料,实现全新关卡的生成!

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

我们的算法所创建的诸多关卡中的一个

和第一部一样,这篇指南的目标人群是任何对机器学习感兴趣、但总觉得无从下手的人。我希望所有人都可以从此指南中获益,而且能把所学所得应用于更广阔的范围。当然了,不必在一开始将眼光放得这么远。倘若本文使人对机器学习的兴趣愈发高涨,那我的目的自然也就达成了。

## 建模:如果是非线性问题呢?

在第一部中,我们创建了一个可以根据某一房屋的各项特征值来估算房价的简单算法。我们从如下的房屋初始数据开始:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

最后得到这样一个简单的预估函数:

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood): price = 0 # a little pinch of this price += num_of_bedrooms * 0.123 # and a big pinch of that price += sqft * 0.41 # maybe a handful of this price += neighborhood * 0.57 return price

换句话说,我们预估房价的方法是先将其每一个特征值乘以相应的权重值,然后把这些数字全部相加从而得到房价的估值。

我们用简图替代程序代码来展现上面这个函数:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

图中箭头标记函数中的权重值

然而这样的算法只对输入和输出值存在线性关系的简单问题奏效。如果隐藏在房价之后的真相并不简单呢?例如,也许所在社区对于大型和小型房屋的房价影响甚巨,但对中型尺寸的房屋没有任何影响。面对这种情况,我们如何才能抓住房价估值模型中相关的复杂细节呢?

一种更为聪明的办法是多次运行我们的算法,每次都使用不同的权重值,其中包括模拟不同的边界情况:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

尝试用四种不同路径来解决问题

现在我们有四个不同的价格估值,将它们组合起来形成一个最终估价。此时我们还是再次运行同样的算法(但使用另一组权重值)!

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

这全新的最佳答案合并了之前针对问题的四次不同尝试所得估价值。如此一来,相比原先的简单模型,这个新模型能与更多的案例数据拟合。

## 神经网络:是什么?

我们把上面的猜测估值四次尝试整合到一张大的图例中:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

这就是一个神经网络!每一个节点都知道如何接收一组输入值,套用权重值,之后再计算一个输出值。这样的节点一旦被大量地拼接串联在一起就能搭建实现复杂函数功能的模型。

为了保持简略,我在这里省去了很多内容(包括特征缩放激活函数),但最为重要的部分是如下两条基本思路:

  • 创建一个简单的估值函数,它能够接收一组输入值,之后通过与相应权重值相乘得到一个输出值。这样的简单函数被称为神经元

  • 简单的神经元被大量地拼接串联在一起之后就能搭建实现复杂函数功能的模型,这种模型的复杂程度是单一神经元无法达到的。

这就像是乐高玩具!我们无法单单用一块乐高玩具积木完成建模,但如果有足够多的积木基本单位进行拼搭,我们就可以做出任何种类的模型:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

塑料动物玩具的未来堪忧?只有时间能说明一切吧

## 状态组件:赋予神经网络记忆

在以上介绍的神经网络中,当你向其输入同样的值时,它也总是回复给你同样的答案。它并没有记忆。用编程的术语来说,这是一种无状态算法

对于很多案例而言(例如房价估值),这样的情况恰恰是符合需求的。但是此类模型无法做到的一件事是随着时间的推移对数据模式作出不同反应

试想我递给你一个键盘工具并要求你写个故事。但是在你开始工作之前,我所要做的是猜一猜你将敲击输入的第一个字母。我该猜哪一个字母呢?

我可以使用自己掌握的英语知识来增加猜中目标字母的成功率。例如,你键入的第一个字母可能是最常见的英语单词首字母。如果我曾读过你在以前写的书,那我或许可以根据你在书中惯常书写的第一个字母来将范围进一步缩小。一旦我获得以上所有数据,就能用它们搭建一个神经网络模型,可以估算你输入任何一个字母作为整个故事开头字母的可能性。

我们的模型可能是这样的:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

我们再让问题变得更难一些。假设我需要猜测你在写故事的过程中任何时间点所要键入的下一个字母。这下问题变得有趣多了。

拿 Ernest Hemingway(欧内斯特 海明威)的著作《太阳照常升起》中开头的几个字词作为例子:

Robert Cohn was once middleweight boxi

下一个出现的字母是什么呢?

你可能猜到是字母「n」 ——相应的完整单词则会是 boxing(拳击)。我们是根据句子中已知的字母以及英语中关于常用词的知识作出的判断。同时,「middleweight」(中量级)一词也提供了指向拳击活动的额外线索。

换句话说,猜测下一个字母并不难,只要考虑到猜测目标对象之前的字母排序,并且加上英语规则知识。

用神经网络解决这个问题需要向模型中加入状态组件。每一次用神经网络求解时,我们要存储当前任务中的一组中间计算结果,并在下次的任务中将其作为整个输入值的额外部分再次被使用。如此一来,模型就可以根据其最近的输入值处理记录来调整预测值。

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

通过状态组件的跟踪功能,我们的模型不只能够预测所写故事中最可能出现的第一个字母,而且能够预测给定任意已知字母串时下一个最可能出现的字母

以上就是递归神经网络的基本思路。每次使用该网络的时候都将其更新一次,于是每个预测值也就随着前次的记录而得到更新。只要我们赋予其足够强的记忆能力,那么该网络甚至能够对实时变动的模式进行建模。

## 预测单个字母:AI 写作第一步

预测所书写的故事中的下一个字母看上去并没有什么用处。那到底有没有用呢?

一个可能显得酷酷的用处是移动手机输入键盘的自动预测功能:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

下一个出现可能性最高的字母是「t」。

但如果我们将问题推至极端呢?如果我们希望模型预测下一个最可能出现的字符,然后是再下一个 —— 一直这样持续预测下去呢?这样一来,实际上是这个模型为我们写了一个完整的故事啊!

## 写一个故事吧!

我们已经知道如何猜测海明威文中句子的下一个字母。接下来就试着按照海明威式的写作风格编写一个完整的故事吧。

我们将使用安德烈·卡帕西(Andrej Karpathy)所写的递归神经网络操作步骤。安德烈在斯坦福大学工作进行深度学习领域的研究,他撰写了一份极佳的入门攻略介绍如何使用递归神经网络生成文本材料,你可以在 GitHub 上看到该模型的所有代码。

我们创建模型所使用的材料是整部《太阳照常升起》的文本 ———总长 362,239 字,共有 84 种不同字符(包括标点符号、大写字母、小写字母等等)。这个数据集实际上比真实世界中的典型应用所需材料要小的多。如果要创建一个具备海明威风格的优秀模型,则需要数倍于现有文本材料的样本数量。但是,如此少的材料数量对于一个简单示例而言已经足够了。

由于我们是从头开始训练递归神经网络,此时该模型的字母预测功能颇为不佳。以下是模型经过 100 次循环训练之后的生成结果:

hjCTCnhoofeoxelif edElobe negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.

Ddelnss.eelaishaner” cot AAfhB ht ltny

ehbih a”on bhnte ectrsnae abeahngy

amo k ns aeo?cdse nh a taei.rairrhelardr er deffijha

你可以看到,模型已经发现在某些时候字与字之间存在着空白间隔,然而此刻模型也就只能做到这样。

经过 1000 次循环训练之后,结果变得更加像模像样了:

hing soor ither. And the caraos, and the crowebel for figttier and ale the room of me? Streat was not to him Bill-stook of the momansbed mig out ust on the bull, out here. I been soms

inick stalling that aid.

“Hon’t me and acrained on .Hw’s don’t you for the roed,” In’s pair.”

“Alough marith him.”

模型已经开始辨认基础句子结构的模式。句号被添加至句末,而且还引用了对话。虽然一些词可以被识别出来,但大部分仍是无意义的。

然而在几千次训练交互之后,结果变得相当不错:

He went over to the gate of the café. It was like a country bed.

“Do you know it’s been me.”

“Damned us,” Bill said.

“I was dangerous,” I said. “You were she did it and think I would a fine cape you,” I said.

“I can’t look strange in the cab.”

“You know I was this is though,” Brett said.

“It’s a fights no matter?”

“It makes to do it.”

“You make it?”

“Sit down,” I said. “I wish I wasn’t do a little with the man.”

“You found it.”

“I don’t know.”

“You see, I’m sorry of chatches,” Bill said. “You think it’s a friend off back and make you really drunk.”

此时此刻,算法已经抓住了海明威所写对话的一种基本模式,短小而直接。有一些句子甚至不再毫无意义。

来比较一下原书中的一段文字:

There were a few people inside at the bar, and outside, alone, sat Harvey Stone. He had a pile of saucers in front of him, and he needed a shave.

“Sit down,” said Harvey, “I’ve been looking for you.”

“What’s the matter?”

“Nothing. Just looking for you.”

“Been out to the races?”

“No. Not since Sunday.”

“What do you hear from the States?”

“Nothing. Absolutely nothing.”

“What’s the matter?”

如果每次只考量一个角色的一句话,算法所生成的文本行文也是显得有板有眼,且格式正确无误。这种表现实在令人惊叹!

文本的编写当然不必完全来自缺乏逻辑的东拼西凑。我们可以在算法中设定一部分先置字母为种子,然后让其生成一些后续字母。

我们再来做件有趣的事,为模拟出来的书制作一个封面,上面有杜撰出来的全新作者名和书名,先后使用「Er」、「He」和「The S」作为文本生成的种子:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

左侧是原书,而右侧是蠢萌计算机编写的无意义之书

相当不错!

真正令人兴奋不已的是我们的这个算法能够在任何数据序列中发现某些模式。此算法可以轻而易取地生成看似像模像样的菜谱或奥巴马演讲模拟稿。然而又为何要自我局限于人类语言的应用呢?我们可以将同样的思路用在各类任何蕴含某种模式的数据序列上。

## 制造马里奥,不走寻常路

2015 年,任天堂在 Wii U 平台上发布了游戏超级马里奥制造™

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

每一个孩子的梦想!

这款游戏让玩家在游戏手柄上创建自己的《超级马里奥兄弟》关卡,再上传至互联网与朋友互享游戏。你可以把马里奥原生游戏中所有经典道具和敌人加入自己的关卡。这就像是一套虚拟的乐高玩具组,其内容是伴随很多人成长的《超级马里奥兄弟》。

生成海明威拟作的那个模型是否能够用来生成非人工创建的《超级马里奥兄弟》游戏关卡呢?

首先,我们需要一个数据集来训练模型。我们将 1985 年发售的《超级马里奥兄弟》原生版本中的所有室外场景关卡提取出来:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

最棒的圣诞夜。感谢我的父母!

这个游戏有 32 个关卡,其中的 70% 都是属于同一套室外场景格局,下文将聚焦于这些关卡。

为了获得每一个关卡的设计信息,我拿来游戏的备份,之后编写一个程序把关卡设计元素从游戏程序中剥离开来。《超级马里奥兄弟》游戏的历史已经有 30 年,网络上存在着大量能够帮助你理解关卡信息如何被存储在游戏程序中的资源。而从一款老电子游戏中提取关卡相关的数据是一次有趣的编程实践经历,你在闲暇时也应该试试。

这是游戏中的第一个关卡(如果你曾玩过此游戏,也许能想起来):

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

《超级马里奥兄弟》游戏中的关卡 1–1

如果放大观察,不难发现关卡是由很多对象所组成的简单网格结构:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

这个网格结构可以被轻而易举地表征为一组字符序列,其中每一种对象都由特定字符来表征:

-------------------------- -------------------------- -------------------------- #??#---------------------- -------------------------- -------------------------- -------------------------- -##------=--=----------==- --------==--==--------===- -------===--===------====- ------====--====----=====- =========================-

把关卡中的每种对象用一个字符表征如下:

  • 「-」是一个空白

  • 「=」是一个实心砖块

  • 「#」是一个可破坏的砖块

  • 「?」是一个道具砖块

……诸如此类等等都是用不同字符表征不同种类的对象。

于是我得到了下图所示的文本文件来表征关卡:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

当一行一行依次观察时,你会在文本文件中发现马里奥游戏关卡看上去并没有什么模式可循:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

当你一行一行观察时,并不会找到什么实实在在的模式。大量的纵向字符串完全就是空白。

可是当你把关卡视为横向字符序列的组合,其模式就涌现出来了:

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

当观察角度变为一列一列,实实在在的模式出现了。例如几乎每一列都以「=」结尾。

所以为了让算法能够找出我们手上数据中存在的模式,数据需要以一列一列的形式进行输入。确定输入数据最为有效的表征方式(被称为特征选择是善加利用机器学习算法的关键之一

为了训练我们的模型,需要把文本文件 90 度转向,由此确保输入模型中的字符所含模式可以更为轻易地识别出来:

-----------= -------#---= -------#---= -------?---= -------#---= -----------= -----------= ----------@= ----------@= -----------= -----------= -----------= ---------PP= ---------PP= ----------== ---------=== --------==== -------===== ------====== -----======= ---========= ---=========

## 迭代:做出真实可用的关卡!

正如之前的海明威写作模型那样,模型随着训练而不断进步。

在数次训练之后,我们的模型生成的还是垃圾:

-------------------------- LL+<&=------P------------- -------- ---------------------T--#-- ----- -=--=-=------------=-&--T-------------- -------------------- --=------$-=#-=-_ --------------=----=<---- -------b -

看样子模型此时只是认为「-」和「=」元素应该会有很多,仅此而已。具体的模式仍未被找到。

在数千次的迭代训练之后,结果开始出现眉目:

-- -----------= ----------= --------PP= --------PP= -----------= -----------= -----------= -------?---= -----------= -----------=

模型已经发现每一行的长度应该是相等的,甚至开始察觉马里奥游戏的一些逻辑:游戏中的水管总是两个格子的宽度,同时其高度至少为两个格子,于是数据中的「P」应该 以2x2 的块状呈现。这很酷吧!

继续经过更为大量的训练,模型达到了生成完美有效数据的标准:

--------PP= --------PP= ----------= ----------= ----------= ---PPP=---= ---PPP=---= ----------=

从模型创建的结果中取出一个完整关卡并将其转回水平方向如下:

这可是一个完整的关卡!由我们的模型所创建!

这数据看起来棒极了! 有几个非常赞的要点需要注意:

  • 一个快乐云 (Lakitu,一种骑在云朵上的怪物) 在关卡一开始就被放上了天空 —— 看上去和人工创建的马里奥关卡很像。

  • 模型知道位于半空的水管应该放在实心砖块之上,而不是直接往半空中一放了之。

  • 模型把敌人放在了符合游戏逻辑的位置。

  • 模型不会放置任何不合理的东西使得玩家根本无法向前通过。

  • 模型感觉上就像是一个真人创建的《超级马里奥兄弟一代》关卡,因为它是基于该游戏的原生关卡风格。

最后,把这个设计数据放回《超级马里奥制造》中创建出关卡:

我们的关卡数据在《超级马里奥制造》中的具体呈现

你自己也去玩一下吧!

如果你有《超级马里奥制造》这款游戏,就可以网上收藏后进行本关卡的游戏,也可以通过关卡代码4AC9–0000–0157-F3C3 找到游戏(网址://t.cn/RGEu9ws )。

## 玩具 vs. 真实世界中的应用

我们在上文中用来训练模型的递归神经网络算法与真实世界中众多企业所使用的是同一类,它们被用于解决诸如语音监测换语言翻译之类的难题。使得我们的模型沦为「玩具」而非尖端产品的原因是:我们用于建模的训练数据仍太少。《超级马里奥兄弟》原生游戏中的关卡数量远远不足以为搭建一个高质量模型提供足够数据。

如果能从任天堂公司取用成千上万《超级马里奥制造》玩家的自制关卡数据,那么我们就可以搭建一个极其棒的模型。可是我们不能 —— 因为任天堂不会允许我们取用数据。大公司可不会白白将他们的数据拱手送人。

随着机器学习在越来越多的行业中日趋重要,一个程序的优良差距将取决于模型训练数据的数量多寡。这就是为什么像谷歌(Google)和脸谱(Facebook)这样的公司对你的数据需求甚巨!

例如,谷歌最近将 TensorFlow 开源,这是进行大规模机器学习应用的软件工具。谷歌把如此重要而实用的技术免费公开的确是一件大事。它同样也是谷歌翻译这款产品的支持工具。

如果你没有像谷歌那样在每一种语言中进行大型的数据挖掘,那你就无法制作出能与谷歌翻译匹敌的产品。正是训练数据赋予谷歌无与伦比的优势。下次打开谷歌地图定位记录脸谱定位记录时你可以注意看一下自己呆过的所有地点是否被一一记录。

## 机器学习:我的胃口尚未满足

在机器学习领域中,解决某一问题永远都不会只有单一的方法可行。在决定如何对数据进行预处理时,又或在挑拣可用的算法时,会有无数选项供你取舍。相较仅使用任何单一方法方法而言,结合多种方法往往会为你带来更佳的结果。

有读者发送给我如下链接地址,都是展现如何使用其它有趣的方法来创建超级马里奥的关卡:

  • 艾米·胡佛(Amy K. Hoover)的团队使用了一种方法将每种关卡对象(水管、地面、平台等等)像编排一整部交响乐一样整合在一起。他们的系统通过被称为功能支架的过程添加任意种类的对象单位,从而能够拉长关卡。例如,你可以草拟出一个关卡的基本形状,系统则负责添加水管和任务道具单位等,帮助你完成设计。

  • 史蒂夫·达尔斯科格(Steve Dahlskog)的团队发现,通过将每一列的关卡数据建模为一系列 n-gram 算法的「字词」单位,游戏关卡可以由一种比递归神经网络简单很多的算法来创建。

如果你想联系我

如果你喜欢这篇文章,可以在推特上关注我,@ageitgey( https://twitter.com/ageitgey )。你也可以访问我的个人站点( //adamgeitgey.com/ ),邮件( ageitgey@gmail.com )联系我,又或者通过linkedin找到我( https://www.linkedin.com/in/ageitgey )。

相关阅读

机器学习入门介绍第一部:谁说机器学习遥不可及,史上最易懂的入门介绍来了!| 机器学习

谁说机器学习遥不可及,你也可以用它写小说玩游戏 | 机器学习

最新文章

取消
扫码支持 支付码