adamqqq's blog - 人工智能
type: channel
link: https://www.adamqqq.com/category/ai/
items: 击败DotA2顶级人类玩家，并不是AI的一次突破
items: Dota2 AI 简易开发教程（二）——英雄出装及其相关功能
items: Dota2 AI 简易开发教程（一）——选择阵容及技能使用
items: 人工智能首部诗集之小冰：是你的声音啊
items: Dota2 AI 简易开发教程

击败DotA2顶级人类玩家，并不是AI的一次突破
type: item
date: 2017-08-19T03:13:00+00:00
description: 文：Denny Britz（前谷歌大脑团队成员）来源：量子位 当我昨天看到OpenAI的人工智能，在一项奖金2400万美元的电子竞技赛事上，击败DotA2人类顶级高手时，整个人感觉超兴奋。 这是因为，一方面我是一个电子竞技的粉丝。尽管没玩过DotA 2，但我经常在Twitch上观看其他其他电竞赛事，高中时我还当过一阵半职业选手。 更重要是的，像DotA这类多人在线战术竞技游戏（MOBA），以及星际2这类实时策略游戏（RTS），通常被认为远超目前人工智能的驾驭能力。因为这两类游戏需要长期战略决策、多人合作，比国际象棋、围棋有着更复杂的状态和动作空间。 DeepMind已经在星际2上研究了一段时间，前不久刚刚发布了新的进展，但目前为止，相关研究还没有取得重大突破。大家普遍认为，距离人工智能在星际2上吊打人类顶级玩家，至少还有一两年的时间。 这就是OpenAI这个成果如此令人震惊的原因。这是怎么回事？最有有什么人工智能方面的突破是我没有注意到的么？于是我开始研究这个DotA 2人工智能到底干了什么，它是如何训练的，以及在什么样的游戏环境中运行。 我的结论是：这是一个令人印象深刻的成就。但不是一次AI上的突破。 通过这篇文章，我想提供一个关于此事的清醒解释。实际上，过度炒作人工智能的进步才是真正危险的事情。例如，下面这位在推特上的发言，才是真正的误导。 这是伊隆·马斯克的推特，这位硅谷钢铁侠不单创办了特斯拉，而且创办了OpenAI。上面这篇推特中，马斯克大意是说：OpenAI搞出了史上首个击败电子竞技顶级玩家的人工智能。这比搞国际象棋和围棋什么的复杂多了。 在第二条推特中，马斯克再次发表曾被AI届猛轰的观点：没人喜欢被管制，但对公众构成危险的一切（汽车、飞机、食品、药物等）都应该受到管制。AI也是一样。 当然，马斯克还发了一条，就不翻译了，贴图如下 首先要声明的是，我今天要谈及的炒作或者误导，并不是OpenAI研究人员的错误。OpenAI一直在研究方面都有诸多贡献。目前，OpenAI还没有公布他们解决方案的细节，所以外界很容易就会得出错误的结论。 现在开始切入正题。我们先来看看DotA 2的人工智能程序，到底解决了一个多困难的问题？尤其是与AlphaGo相比。1v1不能与5v5相提并论 在正常的DotA 2游戏中，两个对抗的队伍各由五名玩家组成。游戏过程中需要高级策略、团队沟通和协调，一局比赛通常要45分钟。 而这次人工智能击败人类的比赛，采用了1v1的模式，这种模式有太多限制。例如双方基本上只能沿着单线前进，并尝试击杀对方，游戏过程几分钟就结束了。 在1v1模式中，击败对手主要靠机械技能和短期策略，并不涉及长期规划和协调，而后者才是对当前AI技术来说最具挑战性的部分。 事实上，在这次的人机DotA 2对抗中，可以采用的有效动作数量，少于围棋人机大战；有效的状态空间（目前局面情况），如果以智能的方式表示，应该比围棋要小。AI可以获取更多信息 OpenAI的人工智能程序，极有可能是构建在DotA 2原有的机器人接口之上，可以获取更多人类玩家看不到的信息。即使OpenAI的研究人员限制了这些信息的获取，人工智能仍然能够得到比人类更精准的信息。 例如技能的施放，人类玩家必须紧盯屏幕，并且估算与对手之间的距离。而AI知道确切的距离，并且能立即决定是否施放技能。获得精准的数字信息是一个很大的优势。其实对战过程中你就能看到，AI有几次攻击都是在最大距离上展开。反应时间 AI可以立即作出反应，人类不行。再加上刚才说的信息优势，AI的优势进一步扩大了。比方，一旦对手逃离攻击范围，AI可以立刻取消攻击命令。使用单一英雄 DotA 2中有上百种不同的英雄角色，各具不同的能力和优势。而AI掌握的只是其中一个英雄：Shadow Fiend（影魔）。影魔通常会立刻展开攻击，而不是在一段时间内学习掌握更复杂的攻击技能，这更加有利于发挥AI在信息和反应方面的优势。 所以，鉴于1v1主要比拼机械技能，AI击败人类玩家并不奇怪。鉴于游戏环境被严格限制，造成一些列战术和策略也被限制，而且对战中几乎没有必要进行长期规划或协调。 再次重申我的结论：这次AI击败DotA玩家，比在围棋中击败人类冠军要容易得多。人类没有在AI领域突然取得突破。 这次在DotA对抗中之所以AI获胜，是因为研究人员聪明的设置了问题，使得AI可以绕过目前人工智能的技术限制。 据说这个OpenAI训练这个AI打DotA花了2周。与之相比，AlphaGo在Google的GPU集群上进行了数月的分布式大规模训练。两个程序之间的计算要求有着数量级的区别。 最后夸夸这个会玩DotA的AI，到底有何精彩之处？完全通过自学训练 AI不需要任何训练数据，也不会从人类的比赛中学习。整个学习过程随机开始，并且通过和自己对…

Dota2 AI 简易开发教程（二）——英雄出装及其相关功能
type: item
date: 2017-07-30T12:32:00+00:00
description: 距离上一篇教程也过去一个多月了，是时候写一篇新教程了。上一篇文章主要介绍了如何选择阵容和技能的使用，在这一篇文章中，我们将介绍如何配置英雄出装和其相关的一些模块。勘误首先先纠正一下上一篇文章中的一些错误，在选择阵容部分，下面的table.remove函数中出现了一个错误，bad argument #2 to 'remove' (number expected, got string)，就是第二个参数应该为数字而不是字符串。这个错误将导致已选择的英雄不能从英雄列表中移除，从而会选择出重复的英雄。function Think() for i,id in pairs(GetTeamPlayers(GetTeam())) do if(IsPlayerBot(id) and (GetSelectedHeroName(id)=="" or GetSelectedHeroName(id)==nil)) then local num=hero_pool_my[RandomInt(1, #hero_pool_my)] --取随机数 SelectHero( id, num ); --在保存英雄名称的表中，随机选择出AI的英雄 table.remove(hero_pool_my,num) --移除这个英雄 end end end所以中间几行应该修改为，这样从表中才能正确移除已经选择的英雄 local i=RandomInt(1, #hero_pool_my) --取随机数 local heroname=hero_pool_my[i] --获取英雄的名称 SelectHero( id, heroname ); --在保存英雄名称的表中，随机选择出AI的英雄 table.remove(hero_pool_my,i) --移除这个英雄出装系统简介在官方开发者维基中有着这样的说明：物品购买如果你只想重写在购买物品时的决策，你可以在文件名为item_purchase_generic.lua的文件中实现如下函数： ItemPurchaseThink() - 每帧被调用。负责物品购买。 你也可以仅重写某个特定英雄的物品购买逻辑，比如火女(Lina),写在文件名为item_purchase_lina.lua的文件中。在dota 2 beta\game\dota\scripts\vscripts\bots_example V社的示例文件中，我们可以找到item_purchase_lina.lua文件，这就是为火女配置出装的文件。打开这个文件，我们可以看到：--这个表用来记录AI出装的顺序 local tableItemsToBuy = { "item_tango", "item_tango", "item_clarity", "item_clarity", "item_branches", "item_branches", "item_magic_stick", "item_circlet", "item_boots", "item_energy_booster", "item_staff_of_wizardry", "item_ring_of_regen", "item_recipe_force_staff", "item_point_booster", "item_staff_of_wizardry", "item_ogre_axe", "item_blade_of_alacrity", "item_mystic_staff", "item_ultimate_orb", "item_void_stone", "item_staff_of_wizardry", "item_wind_lace", "item_void_stone", "item_recipe_cyclone", "item_cyclone", }; ------------------------------------------------------------------------------------------ --用来实现基本的物品购买函数 function ItemPurchaseThink() local npcBot = GetBot(); if ( #tableItemsToBuy == 0 ) then npcBot:SetNextItemPurchaseValue( 0 ); return; end local sNextItem = tableItemsToBuy[1]; npcBot:SetNextItemPurchaseValue( GetItemCost( sNextItem ) ); --用于默认AI的相关函数 if ( npcBot:GetGold() >…

Dota2 AI 简易开发教程（一）——选择阵容及技能使用
type: item
date: 2017-06-07T10:14:00+00:00
description: 在第一篇教程中，我们主要介绍了Dota2 AI的基本情况，在这篇文章中，我们将介绍如何为AI选择阵容和技能使用（以宙斯为例）。选择阵容在官方开发者维基中有着这样的说明：如果你想控制英雄选择和分路，你可以在文件名为hero_selection.lua的文件中实现如下函数：Think() - 每帧被调用。负责机器人选择英雄。 UpdateLaneAssignments() - 在游戏开始前的每一帧被调用。返回玩家ID-分路的值对。 GetBotNames() - 调用一次，返回一个包含玩家名称的表。 在dota 2 beta\game\dota\scripts\vscripts\bots_exampleV社的示例文件中，我们可以找到hero_selection.lua文件，这就是为AI选择阵容的脚本文件。如果我们要开始制作自己的AI，那么首先需要创建dota 2 beta\game\dota\scripts\vscripts\bots文件夹，之后建立hero_selection.lua文件，在其中编写选择阵容的部分，这样的话AI就会选择自定义阵容了。打开这个文件，我们可以看到如下内容 function Think() if ( GetTeam() == TEAM_RADIANT ) --处于天辉方时 then print( "selecting radiant" ); --在控制台输出调试信息 SelectHero( 0, "npc_dota_hero_antimage" ); --为0号玩家选择敌法师 SelectHero( 1, "npc_dota_hero_axe" ); SelectHero( 2, "npc_dota_hero_bane" ); SelectHero( 3, "npc_dota_hero_bloodseeker" ); SelectHero( 4, "npc_dota_hero_crystal_maiden" ); elseif ( GetTeam() == TEAM_DIRE ) then print( "selecting dire" ); SelectHero( 5, "npc_dota_hero_drow_ranger" ); SelectHero( 6, "npc_dota_hero_earthshaker" ); SelectHero( 7, "npc_dota_hero_juggernaut" ); SelectHero( 8, "npc_dota_hero_mirana" ); SelectHero( 9, "npc_dota_hero_nevermore" ); end end其中Think()是主函数，游戏选择阵容时就会调用这个函数，然后判断是天辉方还是夜魇方，之后分别选择各自的阵容。那么我们如何找到英雄对应的名字呢？在这里便可找到英雄的实际名称。例如宙斯的实际名称是"npc_dota_hero_zuus"，那么我们将夜魇方的SelectHero( 5, "npc_dota_hero_drow_ranger" );替换为SelectHero( 5, "npc_dota_hero_zuus" );，那么AI便会选择在5号玩家的位置上选择宙斯。需要注意的是，玩家的ID是会随着人类玩家的加入而发生改变的，将玩家ID硬编码是一种不好的做法，比较好的方法是通过循环遍历出玩家的ID，这样无论人类玩家有多少，AI都能正常选择阵容。下面便是能够自动适应玩家变化选择阵容的代码。function Think() for i,id in pairs(GetTeamPlayers(GetTeam())) --Lua语言自带的迭代器pairs，能够依次读取表中的值。 do if(IsPlayerBot(id)) --判断该玩家是否为电脑 then SelectHero( id, "npc_dota_hero_drow_ranger" ); --为id号玩家选择黑暗游侠 end end end如果我们要AI能够选择随机的阵容，而不是仅仅选择10个黑暗游侠，那该怎么办呢？很简单，通过Lua语言唯一的数据结构表(称作Table，可以用作数组)保存可以选择的英雄列表，然后随机出一个序号，选出表中的英雄。hero_pool_my= { 'npc_dota_hero_zuus', 'npc_dota_hero_skywrath_mage', 'npc_dota_hero_ogre_magi', 'npc_dota_hero_chaos_knight', 'npc_dota_hero_viper', "npc_dota_hero_lina", "npc_dota_hero_kunkka", "npc_dota_hero_li…

人工智能首部诗集之小冰：是你的声音啊
type: item
date: 2017-05-22T13:10:00+00:00
description: 微明的灯影里我知道她的可爱的土壤是我的心灵成为俘虏了我不在我的世界里街上没有一只灯儿舞了是最可爱的你睁开眼睛做起的梦是你的声音啊当然，这首诗不是我写的，而是人工智能创作的。原来从没想到人工智能能做出艺术性的创作，没想到今天也成为了现实。但是小冰所写的诗歌，还是有些稚 嫩，似乎并没有其个人的思想，只是映射出了中国现代诗的集体意识。为了测试小冰的创作水平，微软让小冰化名在报刊、豆瓣、贴吧和天涯等多个网络社区诗歌讨 论区中发布作品。其中用过的笔名有 23 个，我闲来无事，在豆瓣和简书上找到了小冰笔名为 “风的指尖 2017” 的主页。简书 豆瓣曾有人担心，当人工智能取代人类大部分的工作后，我们将何去何从？殊不知，一个行业的衰落总伴随着另一个行业的兴起，当机器人承担了那些枯燥重复的 工作时，就会有很大数量的人们从流水线上解放，那样我们便可以将更多的精力投入到创造性的工作上去。高晓松曾在微博发言忧虑，人工智能都能做出艺术创作 了，那我们人类又和机器有何区别？哈哈，当然有，因为是人创造出了人工智能。人工智能与人之间也许并不是竞争的关系，而是传承与创新。阳光失了玻璃窗微软小冰推出首部诗集：《阳光失了玻璃窗》

Dota2 AI 简易开发教程
type: item
date: 2017-05-18T13:04:00+00:00
description: 前言众所周知，v 社在 7.00 版本推出了自定义机器人功能，我也做了一个 ai 放到了创意工坊上。应广大玩家要求，也为了与大家交流 dota2 ai 的开发技术，我打算写一点浅显易懂的开发教程，希望无论是开发者还是普通玩家都能够理解。dota2 在刚推出时，新闻上就列举了很多 ai 的特性，那时候 ai 可以说是很强。但是由于 v 社天天度假，忽视了 ai 的开发，现在的 ai 还停留在远古版本。所以，为了更好度假！不不不，是为了提升 ai 的水平，便把 ai 开放给玩家制作。IceFrog：Dota2 新增血魔和船长，全新 AI 加入DOTA2 为适应各水平玩家 大幅优化 AI 智能浅谈 DOTA2 AI 打匹配的五大优点和三大缺点Dota2 ai 简介说了这么多，还是回归正题吧，Dota2 的 ai 到底是怎样制作的呢？dota2ai 是用 Lua 脚本语言实现的。Lua 是一种解释型编程语言，如果以前学过编程语言那就很好掌握，没学过也没关系，因为 Lua 语言的语法很简洁，即使是小白也能很快理解。当然，本文不会介绍 Lua 语言的基本语法，如果想进一步学习，可以参考 Lua 教程或者是《Lua 程序设计第二版》。那么，我们应该在什么环境下编写 Lua 脚本呢？很简单，我们没有什么 IDE（集成开发环境）。任何文本编辑器都可以拿来编写，就连记事本也可以！不过还是不推荐使用记事本，因为没有基本的语法高亮等功能，我使用的是 notepad++，一个很简洁的文本编辑器，当然如果你有更好的编辑器也可以直接使用。所有正在开发的 ai 脚本都存放于dota 2 beta\game\dota\scripts\vscripts\bots文件夹下，如果没有 bots 目录便需要自己创建一个。而当你上传你的脚本到工坊时，就会上传该目录下的内容。而下载的脚本则放在你 Steam 安装目录下自己的文件夹中。不出意外的话，你会找到bots_example文件夹，里面有 V 社原版 ai 的一部分。当然，原版 AI 并不是由 lua 编写的，而是由 C++ 编写，而完整的 AI 源码并没有公布。这一部分示例，是由 C++ 翻译为 Lua 的。目前，开发 ai 大致有两种路线，第一种是完全控制，这意味着你需要编写从游戏开始到游戏结束的所有 ai 代码。而第二种则是部分控制，这只需要你接手你想控制的部分，比如某个英雄的技能操作，游走的思路等。前一种工作量很大，需要完全重构 AI 系统。而后一种则比较简单的方法，本系列文章主要是讲解后一种。有的玩家经常反馈：为什么 ai 总是喜欢抱团一起推，一个个送。这也很好解释，因为目前创意工坊里的 ai 大部分都是属于后一种，继承了大部分默认 ai 的思路。至于如何开启一局社区原创机器人游戏，想必大家都已身经百战，不用我说了。不过我还是介绍一下。打开 dota2， 创建房间，选择本地主机，选择 “编辑”，在高级房间设置中，勾选 “机器人填满空位”，随后订阅并使用创意工坊的脚本。如果选择本地开发脚本，那么使用的便是我们在 bots 文件夹下编写的脚本。在接下来的文章中，我会为大家介绍如何开发编辑英雄出装加点，英雄的技能操作，喝神泉模式的实现等等。参考文档：Dota2 AI 开发 tutorial（一）AI 的 环境配置DOTA 机器人脚本 Wiki（英文版更全）Dota2 AI api 说明