写点什么

游戏“外挂”?—— AI 生成游戏最强攻略

发布于: 7 小时前

作为一名快乐的肥宅,玩游戏是居家必备,无论是王者荣耀、吃鸡、原神这些大热游戏,还是跳一跳、合成大西瓜、2048、这些风靡一时得小游戏,咱都有涉及。但是为了成为一个“头号玩家”,我总是疯狂的去个各大社区、网站寻找各种攻略,跟着攻略成长,我时常在想,什么时候俺才能成为一代攻略大神啊,让大家学习我的技术,岂不是很刺激!


灵光一闪,毕竟我是个有点小技术的肥宅,曾经也痴迷过 deepmind,跑过 AlphaGo,这不得训练一个 AI 玩一玩。  


强化学习训练 2048 游戏,观察 AI 如何找到出口。



既然要练手,那就先从 2048 这种简单,不考验操作,纯策略的游戏入手吧。在网上搜罗了一番,果然让我找到了开源的 2048 游戏环境。


GitHub 地址:  https://github.com/rgal/gym-2048


下一步就是把这个算法和强化学习结合了。


算法部分很简单,目前我才用的是最传统的 DQN,10 分钟就可以达到一个还可以的模型效果。如果小伙伴们有想法,可以试试 RainBow,PPO,A2C,SAC 这类算法,相信会获得更佳的效果。


我开发这个模型,用的是来自华为云的 ModelArts(它是一个在线、开箱即用的 AI 平台,还有免费的 GPU 算力,每天不限次数使用,不要太爽!),所以代码是在 ipynb 中跑的。


整体步骤大概可以分为 3 步:


1.创建游戏环境

2.创建 DQN 算法


def learn(self, buffer):        # 当replaybuffer中存储的数据大于batchsize时,从中随机采样一个batch的数据学习        if buffer.size >=self.args.batch_size:            # 更新target_model的参数            if self.learn_step_counter %args.target_update_freq == 0:               self.target_model.load_state_dict(self.behaviour_model.state_dict())            self.learn_step_counter += 1             # 从replaybuffer中随机采样一个五元组(当前观测值,动作,下一个观测值,是否一局结束,奖励值)            s1, a, s2, done, r =buffer.get_sample(self.args.batch_size)            s1 =torch.FloatTensor(s1).to(device)            s2 = torch.FloatTensor(s2).to(device)            r = torch.FloatTensor(r).to(device)            a = torch.LongTensor(a).to(device)             if args.use_nature_dqn:                q =self.target_model(s2).detach()            else:                q = self.behaviour_model(s2)            # 每个动作的q值=r+gamma*(1-0或1)*q_max            target_q = r +torch.FloatTensor(args.gamma * (1 - done)).to(device) * q.max(1)[0]            target_q =target_q.view(args.batch_size, 1)            eval_q = self.behaviour_model(s1).gather(1,torch.reshape(a, shape=(a.size()[0], -1)))            # 计算损失函数            loss = self.criterion(eval_q,target_q)            self.optimizer.zero_grad()            loss.backward()            self.optimizer.step()     def get_action(self, state, explore=True):        # 判断是否探索,如果探索,则采用贪婪探索策略决定行为        if explore:            if np.random.uniform() >=args.epsilon:                action = randint(0,self.action_dim - 1)            else:                # Choose the best action accordingto the network.                q =self.behaviour_model(torch.FloatTensor(state).to(device))                m, index = torch.max(q, 1)                action =index.data.cpu().numpy()[0]        else:            q = self.behaviour_model(torch.FloatTensor(state).to(device))            m, index = torch.max(q, 1)            action =index.data.cpu().numpy()[0]         return action  classReplayBuffer:    def __init__(self, buffer_size, obs_space):        self.s1 = np.zeros(obs_space, dtype=np.float32)        self.s2 = np.zeros(obs_space,dtype=np.float32)        self.a = np.zeros(buffer_size,dtype=np.int32)        self.r = np.zeros(buffer_size,dtype=np.float32)        self.done = np.zeros(buffer_size,dtype=np.float32)         # replaybuffer大小        self.buffer_size = buffer_size        self.size = 0        self.pos = 0     # 不断将数据存储入buffer    def add_transition(self, s1, action, s2,done, reward):        self.s1[self.pos] = s1        self.a[self.pos] = action        if not done:            self.s2[self.pos] = s2        self.done[self.pos] = done        self.r[self.pos] = reward         self.pos = (self.pos + 1) %self.buffer_size        self.size = min(self.size + 1,self.buffer_size)     # 随机采样一个batchsize    def get_sample(self, sample_size): i = sample(range(0, self.size), sample_size)        return self.s1[i], self.a[i],self.s2[i], self.done[i], self.r[i]
复制代码


3.创建网络模型

此处我用的就是一个非常简单的三层卷积网络


classNet(nn.Module):    #obs是状态空间输入,available_actions_count为动作输出维度    def __init__(self, obs,available_actions_count):        super(Net, self).__init__()        self.conv1 = nn.Conv2d(obs, 128,kernel_size=2, stride=1)        self.conv2 = nn.Conv2d(128, 64,kernel_size=2, stride=1)        self.conv3 = nn.Conv2d(64, 16,kernel_size=2, stride=1)        self.fc1 = nn.Linear(16,available_actions_count)        self.relu = nn.ReLU(inplace=True)     def forward(self, x):        x = x.permute(0, 3, 1, 2)        x = self.relu(self.conv1(x))        x = self.relu(self.conv2(x))        x = self.relu(self.conv3(x))        x = self.fc1(x.view(x.shape[0], -1))        return x
复制代码


完成以上三步,就可以愉快的开始训练啦:


print('\ntraining...')begin_t= time.time()max_reward= 0fori_episode in range(args.epochs):    # 每局开始,重置环境    s = env.reset()    # 累计奖励值    ep_r = 0    while True:        # 计算动作        a = dqn.get_action(np.expand_dims(s,axis=0))        # 执行动作        s_, r, done, info = env.step(a)        # 存储信息        memory.add_transition(s, a, s_, done,r)        ep_r += r        # 学习优化过程        dqn.learn(memory)         if done:            print('Ep: ', i_episode,                  '| Ep_r: ', round(ep_r, 2))            if ep_r > max_reward:                max_reward = ep_r                print("current_max_reward{}".format(max_reward))                # 保存模型                torch.save(dqn.behaviour_model,"2048.pt")            break        s = s_print("finish!time cost is {}s".format(time.time() - begin_t))
复制代码


我只训练了 10 分钟,在这个不能错步的严格环境下,推理时可以达到 256 分,如果采用更先进算法,更长的训练时间,2048 不是梦。


详细代码获取方式:点此链接可直接在线运行,或者下载https://marketplace.huaweicloud.com/markets/aihub/notebook/detail/?id=3a11d09b-85f5-4ae4-b4a7-9b19be2b444d


这个技术来源是我在去年华为云 AI 全栈成长计划中接触到的,据说今年华为云又开始了新一轮【AI 实战营】,6 大分类实战营 Python、ModelArts、MindSpore AI 框架、深度、强化、机器学习,助我们成为“AI 王者”!短平快地学习全面 AI 知识的同时,还能拿到 Mate 30Pro、智能手表、无线耳机等惊喜豪礼!我已经扫描下面二维码报名啦~你还要等吗?



点击关注,第一时间了解华为云新鲜技术~

发布于: 7 小时前阅读数: 5
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
游戏“外挂”?—— AI生成游戏最强攻略