从零使用强化学习训练AI玩儿游戏(9)——使用DQN(Keras+CNN)

做了这么。。。。。终于到达这一步了。

GitHub上源代码

上一篇我们用简单的全连接神经网络实现了DQN玩儿了一个简单的游戏,今天我们要用一个复杂的神经网络来玩儿一个复杂的游戏,SpaceInvaders-v0,就玩这个游戏吧,看起来很棒的样子,随便选的。

在这个游戏中observaction是一个屏幕RGB的图片,shape是(210,160,3) = 100800个数据正好试一下卷积神经网络,action 6个中4是发送子弹 2、3分别是左右,reward就是你打没打死那个外星人所得到的奖励,就是图片上的分数,reward分别是5,10,15,20,25,30,每往上增加一层的外星人加5分,然后时不时的有一个紫色的外星人出现,打中他加200分,这里可以考虑做不做归一化处理,我这里先不做归一化处理直接使用它的reward。然后我看国外的论文中也有用opencv先做一个图像处理的,我这里也先不做了就用原图。

看来我还是太小看这个神经网络的训练,还有太高估我渣渣电脑的能力了,居然还想不做图像预处理直接跑。。。。。。根本跑不动啊。。。。我还是老老实实加opencv预处理吧,还有opencv比较熟悉。

所以使用这个教程安装opencv,在这个教程中我没有进入Windows的终端,而是进入anaconda prompt进行安装的,要不然找不到pip命令。

做灰度化处理后的效果:

加了opencv处理后还是很慢,但是比之前好多了

接下来还需要继续优化神经网络,让训练的速度变快。

真正遇到大数据做机器学习的时候就知道自己的电脑有多差了。。。。。。。可优化后的学习速度都需要1.1s左右,导致整个游戏完全没法看,所以我开了一个线程来控制是否学习,也就是说关闭学习的时候能从游戏界面中看出学习的成果,但还是太慢了。。。。。。。所以接下来可能在网上租一个服务器,或者去实验室用实验室的服务器来跑一跑看看效果。

接下来看看我搭的神经网络是什么样的,看起来很大的样子,其实说到底也就是四层,前两层是卷积神经网络,配备了pooling减少数据损失,然后加上两层全连接网络,本来这个地方是要放LSTM的,但是我的电脑更跑不动了。。。。。。所以先用全连接。等我找到好的服务器再修改。

       

这个是搭建两个神经网络的代码,Keras搭建的,真的超级方便。(详见注释)

    def _build_net(self):
        # ------------------ 建造估计层 ------------------
        # 因为神经网络在这个地方只是用来输出不同动作对应的Q值,最后的决策是用Q表的选择来做的
        # 所以其实这里的神经网络可以看做是一个线性的,也就是通过不同的输入有不同的输出,而不是确定类别的几个输出
        # 这里我们先按照上一个例子造一个两层每层单个神经元的神经网络
        self.model_eval = Sequential([
            # 输入第一层是一个二维卷积层(100, 80, 1)
            Convolution2D(                              # 就是Conv2D层
                batch_input_shape=(None, self.observation_shape[0], self.observation_shape[1],
                                   self.observation_shape[2]),
                filters=15,                             # 多少个滤波器 卷积核的数目(即输出的维度)
                kernel_size=5,                          # 卷积核的宽度和长度。如为单个整数,则表示在各个空间维度的相同长度。
                strides=1,                              # 每次滑动大小
                padding='same',                         # Padding 的方法也就是过滤后数据xy大小是否和之前的一样
                data_format='channels_last',           # 表示图像通道维的位置,这里rgb图像是最后一维表示通道
            ),
            Activation('relu'),
            # 输出(100, 80, 15)
            # Pooling layer 1 (max pooling) output shape (50, 40, 15)
            MaxPooling2D(
                pool_size=2,                            # 池化窗口大小
                strides=2,                              # 下采样因子
                padding='same',                         # Padding method
                data_format='channels_last',
            ),
            # output(50, 40, 30)
            Convolution2D(30, 5, strides=1, padding='same', data_format='channels_last'),
            Activation('relu'),
            # (10, 8, 30)
            MaxPooling2D(5, 5, 'same', data_format='channels_first'),
            # (10, 8, 30)
            Flatten(),
            # LSTM(
            #     units=1024,
            #     return_sequences=True,  # True: output at all steps. False: output as last step.
            #     stateful=True,          # True: the final state of batch1 is feed into the initial state of batch2
            # ),
            Dense(512),
            Activation('relu'),
            Dense(self.n_actions),
        ])
        # 选择rms优化器,输入学习率参数
        rmsprop = RMSprop(lr=self.lr, rho=0.9, epsilon=1e-08, decay=0.0)
        self.model_eval.compile(loss='mse',
                            optimizer=rmsprop,
                            metrics=['accuracy'])

        # ------------------ 构建目标神经网络 ------------------
        # 目标神经网络的架构必须和估计神经网络一样,但是不需要计算损失函数
        self.model_target = Sequential([
            Convolution2D(  # 就是Conv2D层
                batch_input_shape=(None, self.observation_shape[0], self.observation_shape[1],
                                   self.observation_shape[2]),
                filters=15,  # 多少个滤波器 卷积核的数目(即输出的维度)
                kernel_size=5,  # 卷积核的宽度和长度。如为单个整数,则表示在各个空间维度的相同长度。
                strides=1,  # 每次滑动大小
                padding='same',  # Padding 的方法也就是过滤后数据xy大小是否和之前的一样
                data_format='channels_last',  # 表示图像通道维的位置,这里rgb图像是最后一维表示通道
            ),
            Activation('relu'),
            # 输出(210, 160, 30)
            # Pooling layer 1 (max pooling) output shape (105, 80, 30)
            MaxPooling2D(
                pool_size=2,  # 池化窗口大小
                strides=2,  # 下采样因子
                padding='same',  # Padding method
                data_format='channels_last',
            ),
            # output(105, 80, 60)
            Convolution2D(30, 5, strides=1, padding='same', data_format='channels_last'),
            Activation('relu'),
            # (21, 16, 60)
            MaxPooling2D(5, 5, 'same', data_format='channels_first'),
            # 21 * 16 * 60 = 20160
            Flatten(),
            # LSTM(
            #     units=1024,
            #     return_sequences=True,  # True: output at all steps. False: output as last step.
            #     stateful=True,          # True: the final state of batch1 is feed into the initial state of batch2
            # ),
            Dense(512),
            Activation('relu'),
            Dense(self.n_actions),
        ])

我准备用一下午时间跑一跑,看看会不会有效果。

GitHub上源代码

训练了20个小时后的reward结果,由于随机性的问题肯定会有一些浮动,但是整体的趋势还是看的出来是在上升的。

我们就按波谷点来看,可以看出一个上升趋势。

跑了这么久,有点怀疑是不是神经网络架构有问题,所以拜读了一下deepmind玩这个游戏的文章Playing Atari with Deep Reinforcement Learning,发现其实我们的架构是相同的,所以应该是我的硬件太差了迟迟没有特别好的效果出来。

惹不起,原来他训练了1千万的数据,我算了一下 如果我训练一千万个数据大概需要十一天。。。。。。所以我们大概看看结果就好了吧。。。。。。。

下面这幅图是deepmind训练各种游戏后得到的平均分和最高分,可以看到DQN其实在我们选的这款游戏S.invders上达到500多分已经算得上他的平均了。其实这款游戏对神经网络来说算是有点难的了,因为他的策略要求更高。The games Q*bert, Seaquest, Space Invaders, on which we are far from human performance, are more challenging
because they require the network to find a strategy that extends over long time scales.

所以我想应该是要加入LSTM会有更好的效果,但是实在是找不到跑这么大数据量的啊。。。。。。哎~~~穷

————————————————————————分割线——————————————————————————————

最近刚刚入职百度无人车,抽空用公司电脑跑了一下这个算法,效果还是不错,果然用gpu跑比我那个渣电脑跑效果好多了,跑了两三个小时已经有明显效果了,直接上图

这么短的时间已经出现能把外星人打没了的情况了,公司电脑私人gpu 1080Ti

 

  • 6
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值