如今,人工智能正在火速切入各個(gè)領(lǐng)域,比如電商、金融、交通、醫(yī)療、教育、安防,國(guó)內(nèi)外各大公司紛紛成立相關(guān)AI研究院,加速AI的發(fā)展速度。國(guó)務(wù)院印發(fā)《新一代人工智能發(fā)展規(guī)劃》(以下簡(jiǎn)稱《規(guī)劃》),提出了面向2030年我國(guó)新一代人工智能發(fā)展的指導(dǎo)思想、戰(zhàn)略目標(biāo)、重點(diǎn)任務(wù)和保障措施,部署構(gòu)筑我國(guó)人工智能發(fā)展的先發(fā)優(yōu)勢(shì),加快建設(shè)創(chuàng)新型國(guó)家和世界科技強(qiáng)國(guó)。其次也明確了我國(guó)新一代人工智能發(fā)展的戰(zhàn)略目標(biāo):到2020年,人工智能總體技術(shù)和應(yīng)用與世界先進(jìn)水平同步,人工智能產(chǎn)業(yè)成為新的重要經(jīng)濟(jì)增長(zhǎng)點(diǎn)。
對(duì)于和生活密不可分的游戲來(lái)說(shuō),也在AI領(lǐng)域上取得一步步發(fā)展。在廣義上說(shuō),大多數(shù)游戲都包含一些人工智能(AI)的運(yùn)用。例如,開發(fā)人員多年來(lái)都使用AI來(lái)給游戲中無(wú)數(shù)的人物以生命力,從經(jīng)典的街機(jī)游戲Pac Man的鬼魂到第一人稱射擊游戲中的機(jī)器人,還有很多其他游戲。各種各樣的游戲類型和游戲人物對(duì)什么是游戲AI給出了一個(gè)相當(dāng)廣泛的解釋。事實(shí)上,AI也在其他傳統(tǒng)的科學(xué)領(lǐng)域得到廣泛的運(yùn)用。
可以想象游戲AI應(yīng)用領(lǐng)域的廣泛程度,所以也就誕生這個(gè)項(xiàng)目,利用當(dāng)下最火之一的深度強(qiáng)化學(xué)習(xí)技術(shù),結(jié)合serpentai框架、以yolo算法為核心算法的游戲智能化項(xiàng)目。在游戲中,我們不一定對(duì)給參與游戲的機(jī)器方以人水平的智能感興趣。也許我們可通過(guò)寫代碼來(lái)控制非人類的生物,比如龍、機(jī)器人,甚至老鼠。另外,誰(shuí)說(shuō)我們必須賦予機(jī)器方智慧呢?不賦予機(jī)器方智慧以增加游戲內(nèi)容的多樣性和豐富性。雖然游戲AI經(jīng)常被呼吁解決相當(dāng)復(fù)雜的問(wèn)題,但我們可以利用AI去嘗試給機(jī)器方以個(gè)性模樣、不同的性格,或塑造情感和各種性情,如,害怕,焦慮,等等。
在我看來(lái),游戲AI目前還是比較傻的,至少還沒(méi)有想象中的“智能”,他是按照人給的定義,完成某種特定的行為,并且記憶這種行為,以至于實(shí)現(xiàn)最終的目標(biāo),也就是對(duì)高度定制化的智能游戲體驗(yàn),這也會(huì)是我們努力的方向。
1.由于darkflow實(shí)現(xiàn)了將darknet翻譯成tensorflow,這樣就可以用當(dāng)下流行的深度學(xué)習(xí)框架tensorflow來(lái)加載darknet訓(xùn)練好的模型,并使用tensorflow重新訓(xùn)練,輸出tensorflow graph模型。以下是在ubuntu環(huán)境下安裝配置darkflow。
2.需要安轉(zhuǎn)cython for python3,安裝命令為:sudo pip3 install Cython--install-option="--no-cython-compile"
3.下載darkflow:git clonehttps://github.com/thtrieu/darkflow,如圖2.1。

?4.cd darkflow進(jìn)入darkflow目錄,并安裝:python3 setup.py build_ext –inplace,如圖2.2。
5.pip3 install .

?(二)SerpentAI配置
1.由于整個(gè)框架需要在anaconda下進(jìn)行,所以要先安裝anaconda,Windows下安裝Anaconda3,這里安裝在I:\Anaconda3。一步步點(diǎn)擊下一步即可安裝成功。同時(shí)也把visual studip 2013安裝完成,如圖2.3。

2.打開anconda prompt為Serpent.AI 創(chuàng)建一個(gè)Conda虛擬環(huán)境,命令如下:conda create --name serpent python=3.6,如圖2.4。

3.為 SerpentAI 項(xiàng)目創(chuàng)建一個(gè)目錄,命令如下:mkdir SerpentAI && cd
SerpentAI
4.如圖2.5,啟動(dòng) Conda 虛擬環(huán)境,命令如下:activate serpent

5.開始安裝 Serpent.AI返回你原來(lái)為自己創(chuàng)建的Serpent.AI 項(xiàng)目目錄,
確保你在Conda 虛擬環(huán)境下。如圖2.6,運(yùn)行命令 pip install SerpentAI,等待系統(tǒng)自動(dòng)安裝完畢,出現(xiàn)setup success即說(shuō)明安裝成功。

三、Yolo算法設(shè)計(jì)與實(shí)現(xiàn)
近幾年來(lái),目標(biāo)檢測(cè)算法取得了很大的突破。比較流行的算法可以分為兩類,一類是基于Region Proposal的R-CNN系算法(R-CNN,F(xiàn)ast
R-CNN, Faster R-CNN),它們是two-stage的,需要先使用啟發(fā)式方法(selective search)或者CNN網(wǎng)絡(luò)(RPN)產(chǎn)生Region Proposal,然后再在Region Proposal上做分類與回歸。而另一類是Yolo,SSD這類one-stage算法,其僅僅使用一個(gè)CNN網(wǎng)絡(luò)直接預(yù)測(cè)不同目標(biāo)的類別與位置。第一類方法是準(zhǔn)確度高一些,但是速度慢,但是第二類算法是速度快,但是準(zhǔn)確性要低一些。
YOLO的速度非??欤舱怯捎谶@個(gè)特點(diǎn),我們團(tuán)隊(duì)一致決定基于yolo算法展開項(xiàng)目。因?yàn)樵谕嬗螒驎r(shí)候,每一幀的圖像都是不一樣的,背景也可能有較大差別,所以選擇yolo,可以快速識(shí)別出場(chǎng)景及人物,進(jìn)而完成規(guī)定的任務(wù)。還有就是與Fast R-CNN相比,YOLO在誤檢測(cè)(將背景檢測(cè)為物體)方面的錯(cuò)誤率能降低一半多。此次游戲是DNF(地下城與勇士),背景有時(shí)候會(huì)和人物比較接近,這時(shí)候yolo的優(yōu)勢(shì)又體現(xiàn)出來(lái)了。YOLO可以學(xué)到物體的generalizable representations,可以理解為泛化能力強(qiáng)。在DNF游戲中,要識(shí)別出第幾關(guān),以及有怪沒(méi)怪,來(lái)判斷英雄的行為,可謂是有點(diǎn)難度呢。
(二)yolo解析
接下來(lái),是從理論角度分析yolo本文介紹的是Yolo算法,其全稱是You Only Look Once: Unified, Real-Time Object Detection,其實(shí)個(gè)人覺(jué)得這個(gè)題目取得非常好,基本上把Yolo算法的特點(diǎn)概括全了:You Only Look Once說(shuō)的是只需要一次CNN運(yùn)算,Unified指的是這是一個(gè)統(tǒng)一的框架,提供end-to-end的預(yù)測(cè),而Real-Time體現(xiàn)是Yolo算法速度快。這里我們談的是Yolo-v1版本算法,其性能是差于后來(lái)的SSD算法的,但是Yolo后來(lái)也繼續(xù)進(jìn)行改進(jìn),產(chǎn)生了Yolo-9000算法。這里主要講述Yolo-v1算法的原理,特別是算法的訓(xùn)練與預(yù)測(cè)中詳細(xì)細(xì)節(jié),最后將給出如何使用TensorFlow實(shí)現(xiàn)Yolo算法。
YOLO檢測(cè)網(wǎng)絡(luò)包括24個(gè)卷積層和2個(gè)全連接層,如圖3.1所示。其中,卷積層用來(lái)提取圖像特征,全連接層用來(lái)預(yù)測(cè)圖像位置和類別概率值。YOLO網(wǎng)絡(luò)借鑒了GoogLeNet分類網(wǎng)絡(luò)結(jié)構(gòu)。不同的是,YOLO未使用inception module,而是 使用1x1卷積層(此處1x1卷積層的存在是為了跨通道信息整合)+3x3卷積層簡(jiǎn)單替代。

YOLO之前的物體檢測(cè)系統(tǒng)使用分類器來(lái)完成物體檢測(cè)任務(wù)。為了檢測(cè)一個(gè)物體,這些物體檢測(cè)系統(tǒng)要在一張測(cè)試圖的不同位置和不同尺寸的bounding box上使用該物體的分類器去評(píng)估是否有該物體。如DPM系統(tǒng),要使用一個(gè)滑窗(sliding window)在整張圖像上均勻滑動(dòng),用分類器評(píng)估是否有物體。在DPM之后提出的其他方法,如R-CNN方法使用region proposal來(lái)生成整張圖像中可能包含待檢測(cè)物體的potential bounding boxes,然后用分類器來(lái)評(píng)估這些boxes,接著通過(guò)post-processing來(lái)改善bounding boxes,消除重復(fù)的檢測(cè)目標(biāo),并基于整個(gè)場(chǎng)景中的其他物體重新對(duì)boxes進(jìn)行打分。整個(gè)流程執(zhí)行下來(lái)很慢,而且因?yàn)檫@些環(huán)節(jié)都是分開訓(xùn)練的,檢測(cè)性能很難進(jìn)行優(yōu)化。這里設(shè)計(jì)了YOLO(you only look once),將物體檢測(cè)任務(wù)當(dāng)做回歸問(wèn)題(regression problem)來(lái)處理,直接通過(guò)整張圖片的所有像素得到bounding
box的坐標(biāo)、box中包含物體的置信度和class
probabilities。通過(guò)YOLO,每張圖像只需要看一眼就能得出圖像中都有哪些物體和這些物體的位置。如圖3.2。

四、核心代碼設(shè)計(jì)與實(shí)現(xiàn)
(一)serpent_DNF_game的實(shí)現(xiàn)
from serpent.game import Game
from .api.api import DNFAPI
from serpent.utilities import Singleton
class SerpentDNFGame(Game, metaclass=Singleton):
??? def__init__(self, **kwargs):
???????kwargs["platform"] = "executable"
???????kwargs["window_name"] = "地下城與勇士"
??????? #kwargs["window_name"] = "地下城與勇士登錄程序"???????
???????kwargs["executable_path"] = "D:/DNF/TCLS/Client.exe"
(二)serpent_DNF_game_agent的實(shí)現(xiàn)
from serpent.game_agent import GameAgent
import offshoot
from serpent.input_controller import KeyboardKey
from serpent.input_controller import MouseButton
fromserpent.machine_learning.context_classification.context_classifiers.cnn_inception_v3_context_classifierimport \CNNInceptionV3ContextClassifier
from random import random, randrange
import csv
fromserpent.machine_learning.darkflow.darkflow.net.build import TFNet
import cv2
import skimage.transform
import skimage.util
import uuid
import skimage.io
import numpy as np
import time
class SerpentDNFGameAgent(GameAgent):
??? def__init__(self, **kwargs):
???????super().__init__(**kwargs)
???????self.frame_handlers["PLAY"] = self.handle_play
???????self.frame_handler_setups["PLAY"] = self.setup_play
???????self.analytics_client = None
???????self.has_paused = False
??????? #self.pre_contexts = []
???????self.pre_context = ''
???????plugin_path =offshoot.config["file_paths"]["plugins"]
???????self.options = {'model': "./cfg/yolo-voc-dnf-17-3.cfg",'load': -1, "threshold": 0.005}
???????self.before = ['sbd', 'ar', 'scbd', 'scbr', 'hm', 'gp', 'gps']
???????self.stages = ['m1w', 'm1wo', 'm2w', 'm2wo', 'm3w', 'm3wo', 'm4w','m4wo', 'm5w', 'm5wo', 'm6w', 'm6wo', 'm7w']
???????self.go_right = False
???????self.index = 0
???????self.labels = []
1.配置好 serpentai之后,將class SerpentDNFGame進(jìn)行一些參數(shù)的修改如圖5.1:
kwargs["platform"]= "executable"
kwargs["window_name"]
= "地下城與勇士"
# kwargs["window_name"]
= "地下城與勇士登錄程序"
kwargs["executable_path"]= "D:/DNF/TCLS/Client.exe"
#啟動(dòng)游戲程序的路徑

2.修改好serpent_DNF_game.py文件后,就可以在框架下啟動(dòng)游戲,啟動(dòng)命令提示符,啟動(dòng)虛擬環(huán)境,輸入 serpent launch DNF,就會(huì)出現(xiàn)如圖5.2界面,游戲啟動(dòng),且移動(dòng)到左上角位置。

?3.前面介紹了配置以及理論,接下來(lái)最重要的一部分便是對(duì)數(shù)據(jù)集的訓(xùn)練了,訓(xùn)練處model,以便于英雄自動(dòng)識(shí)別出當(dāng)前的狀態(tài),再寫腳本控制英雄做出相應(yīng)的行為。
執(zhí)行訓(xùn)練命令即可出現(xiàn)如圖5.3數(shù)據(jù)訓(xùn)練界面:
flow --modelcfg/yolo-tiny-dnf.cfg –load bin/yolo-tiny.weights

?4.將訓(xùn)練好的model,加載到程序書寫好的腳本中,如下圖5.4進(jìn)行的修改SerpentDNFGameAgent:
classSerpentDNFGameAgent(GameAgent):
? ??def__init__(self, **kwargs):
??????? super().__init__(**kwargs)
??????? self.frame_handlers["PLAY"] =self.handle_play
???????self.frame_handler_setups["PLAY"] = self.setup_play
??????? self.analytics_client = None
??????? self.has_paused = False
???? ???#self.pre_contexts = []
??????? self.pre_context = ''
??????? plugin_path =offshoot.config["file_paths"]["plugins"]
??????? self.options = {'model':"./cfg/yolo-voc-dnf-17-3.cfg", 'load': -1, "threshold":0.005}

5.啟動(dòng)游戲,輸入命令:serpent play DNF
SerpentPlayDNFGameAgent 便會(huì)出現(xiàn)如圖5.5游戲界面。

這個(gè)項(xiàng)目總的來(lái)說(shuō)是用serpentai游戲代理框架,結(jié)合yolo目標(biāo)檢測(cè)算法,以及深度強(qiáng)化學(xué)習(xí)的應(yīng)用技術(shù)而進(jìn)行的。