- AI自動化測試:技術原理、平臺搭建與工程實踐
- 騰訊TuringLab團隊
- 1828字
- 2020-08-13 13:47:08
4.3 模仿學習在自動化測試中的運用
逆強化學習和生成對抗模仿學習都需要與游戲環境進行交互,而市面上大多數游戲沒有提供內部接口,無法對游戲進行加速,因此,與游戲環境交互需要耗費大量時間。為了快速訓練游戲AI,我們采用行為克隆方案,并增加一系列策略來彌補行為克隆的缺陷。訓練流程如圖4-1所示。
圖4-1 訓練流程
首先,人工錄制半小時左右特定場景的游戲樣本,保留游戲過程中的圖像和對應的游戲動作。隨后,提取圖像中對動作執行影響較大的區域,去除干擾。錄制過程中,我們會對不同動作的樣本進行重新采樣,確保每類動作對應的樣本數量超過一個閾值,該閾值通常根據經驗進行設置。最后,將調整過的樣本輸入深度網絡進行訓練。
通過人工錄制游戲的方式收集半小時左右的游戲樣本。采用的游戲頻率為1秒10幀,采用的游戲按鈕根據游戲自行設定,比如針對飛車游戲,采用左移、右移和漂移;針對天天酷跑,采用下蹲和跳躍;針對槍戰游戲,采用上移、下移、左移和右移;針對動作游戲,采用左移、右移、攻擊、閃避和必殺。游戲圖像和按鈕示例如圖4-2所示,紅色框內為對應的游戲按鈕。
圖4-2 游戲按鈕示例
我們可以對游戲按鈕進行組合,比如在飛車游戲的錄制過程中,如果玩家同時按下左移和漂移,將這種行為定義為左漂移;如果同時按下右移和漂移,則定義為右漂移。錄制過程中,如果沒有按壓任何游戲按鈕,則定義為沒有動作。
游戲圖像中往往存在一些更具動作判別力的區域,提取這些區域可以減小模型訓練的難度,更能讓深度網絡學會如何提取關鍵的抽象特征。比如在飛車和槍戰類游戲中,雷達地圖是非常重要的區域,與執行的動作相關度較高,因此,對于這類含有小地圖的游戲,我們往往是提取其中的小地圖,將其作為深度網絡的輸入,而對于沒有小地圖的游戲,則選擇對動作影響較大的矩形區域。區域提取的示例如圖4-3所示。
圖4-3 區域提取示例
由于在游戲錄制過程中,不同動作類別的數量差異較大,比如在飛車類游戲中,一共設計了5個動作:左移、右移、左漂移、右漂移和沒有動作。其中,沒有動作對應的樣本數量遠超其他動作對應的樣本數量,如果不對動作進行重新采樣,那訓練出來的游戲將會傾向于做一個動作。為此,我們對游戲樣本進行重新采樣,保證每一類動作的樣本數量超過總樣本數量的20%,這里20%是一個經驗值。
對樣本進行重新采樣后,選取80%的樣本訓練網絡,余下的樣本用于模型的驗證。為了減少計算量,圖像統一縮放至150×150像素。由于游戲的畫面變化一般較為劇烈,通過簡單的深度網絡難以提取具備判別力的抽象特征,所以我們設計了一種輕量化的殘差網絡,其能在CPU下達到1秒10幀以上的速度,耗費的內存和計算資源較小。殘差網絡結構如圖4-4所示,通過與之前的特征融合,網絡能防止梯度衰減,提升網絡的收斂速度。網絡結構由兩個子模塊構成,子模塊的結構如圖4-5所示,而輕量化模型結構如圖4-6所示。在訓練輕量化殘差網絡的過程中,我們將交叉熵損失作為模型的目標函數,通過梯度后向傳遞的方式迭代更新網絡參數。
圖4-4 殘差網絡結構
圖4-5 子模塊結構
輕量化模型是基于Keras編寫的,網絡的定義代碼如下。
圖4-6 輕量化模型架構
import keras
from keras import regularizers
import keras.backend as K
from keras.layers import Input, Activation, BatchNormalization, Flatten, Conv2D
from keras.applications.resnet50 import conv_block, identity_block
from keras.layers import Convolution2D, ZeroPadding2D
from keras.layers import MaxPooling2D, Dense, GlobalAveragePooling2D, PReLU, LSTM
def Keras_Model(imageSize, imageSize, imageChannel,actionSpace):
input_shape = (imageSize, imageSize, imageChannel)
img_input = Input(shape=input_shape)
bn_axis = 3
x = ZeroPadding2D((3, 3))(img_input)
x = Convolution2D(8, 7, 7, subsample=(2, 2), name='conv1')(x)
x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x)
x = Activation('relu')(x)
x = MaxPooling2D((3, 3), strides=(2, 2))(x)
x = conv_block(x, 3, [8, 8, 16],stage=2, block='a', strides=(1, 1))
x = identity_block(x, 3, [8, 8, 16], stage=2, block='b')
x = identity_block(x, 3, [8, 8, 16], stage=2, block='c')
x = conv_block(x, 3, [16, 16, 32], stage=3, block='a')
x = identity_block(x, 3, [16, 16, 32], stage=3, block='b')
x = identity_block(x, 3, [16, 16, 32], stage=3, block='c')
x = identity_block(x, 3, [16, 16, 32], stage=3, block='d')
x = conv_block(x, 3, [32, 32, 64], stage=4, block='a')
x = identity_block(x, 3, [32, 32, 64], stage=4, block='b')
x = identity_block(x, 3, [32, 32, 64], stage=4, block='c')
x = identity_block(x, 3, [32, 32, 64], stage=4, block='d')
x = identity_block(x, 3, [32, 32, 64], stage=4, block='e')
x = identity_block(x, 3, [32, 32, 64], stage=4, block='f')
x = conv_block(x, 3, [64, 64, 128], stage=5, block='a')
x = identity_block(x, 3, [64, 64, 128], stage=5, block='b')
x = identity_block(x, 3, [64, 64, 128], stage=5, block='c')
x = conv_block(x, 3, [64, 64, 256], stage=6, block='a')
x = identity_block(x, 3, [64, 64, 256], stage=6, block='b')
x = identity_block(x, 3, [64, 64, 256], stage=6, block='c')
x = GlobalAveragePooling2D()(x)
x = Dense(200, name='fc_feature')(x)
x = PReLU()(x)
x = Dense(actionSpace, activation='softmax', name='fc_action')(x)
model = Model(img_input, x)
return model
為了提取游戲過程中的時序特征,我們提出了一種基于LSTM的網絡結構。為了加快收斂速度,LSTM的輸入特征為5幀連續圖像的輕量化網絡的全連接特征,輸出的特征維度為100,隨后通過一個全連接層輸出每個動作的概率。LSTM網絡結構如圖4-7所示。通過20輪迭代優化,得到優化后的LSTM結構的深度網絡模型。
圖4-7 LSTM網絡結構
LSTM網絡的代碼如下:
def Keras_Model_LSTM(timeStep, actionSpace):
model = Sequential()
model.add(LSTM(100, input_dim=200, input_length=timeStep))
model.add(Dropout(0.6))
model.add(Dense(actionSpace, activation='softmax'))
return model
在測試階段,首先從游戲圖像中提取重要區域,隨后輸入輕量化網絡提取抽象特征,將5幀連續圖像的全連接特征輸入LSTM網絡得到每個類別的概率,然后根據游戲的不同,執行最大概率的動作或按概率隨機采樣的動作。一般飛車類和酷跑類游戲是執行概率最大的動作,而槍戰類和動作類游戲是執行按概率隨機采樣的動作。