AI自动化测试:技术原理、平台搭建与工程实践
上QQ阅读APP看书,第一时间看更新

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网络得到每个类别的概率,然后根据游戏的不同,执行最大概率的动作或按概率随机采样的动作。一般飞车类和酷跑类游戏是执行概率最大的动作,而枪战类和动作类游戏是执行按概率随机采样的动作。