增强式学习:如何使用Q-Learning算法训练围棋机器人

上一节我们构造出如下结构的神经网络:


屏幕快照 2019-07-09 下午6.21.30.png

本节我们看看如何使用该网络训练围棋机器人。我们在标题中提到Q-Learning,它实际上是一种使用上面网络进行训练的算法流程。首先我们先定义执行Q-Learning算法的机器人对象:

class QAgent:
    def  __init(self, model, encoder): 
        #参数model就是我们构造的神经网络
        self.model = model
        self.encoder = encoder  #对棋盘的编码
        self.temperature = 0  #对应epsilong参数
    def  set_temperature(self, temperature):
        self.temperature = temperature  #该参数的值越大,机器人胆子就越大,就越多的进行随机落子
    def set_collector(self, collector):
        #collector包含了机器人对弈时的棋盘数据
        self.collector = collector 

在上面代码实现中,参数temperature对应上一章我们说过的epsilong参数,这个参数的值越大,QAgent的随机性就越强.同时代码中的collector根前几节一样,它收集了两个机器人对弈的大量棋盘数据,这些数据将用于执行Q-Learning算法。接着我们看看基于Q-Learning算法的围棋机器人如何选择落子策略:

def  select_move(self, game_state):
        board_tensor = self.encoder.encode(game_state) #对输入棋盘进行编码
        moves = []
        for move in game_state.legal_move():
            if not move.is_play:
                continue
            moves.append(self.encoder.encode_point(move.point)) #记录落子位置
            board_tensors.append(board_tensor) #将每个落子位置与当前棋盘对应起来
        if not moves:
            return goboard.Move.pass_turn()
        
        num_moves = len(moves)
        board_tensor = np.array(board_tensor)
        move_vectors = np.zeros((num_moves, self.encoder.num_points()))
        for i , move in enumerate(moves):
            move_vectors[i][move] = 1  #将落子位置转换为19*19的一维向量
        values = self.model.predict([board_tensors, move_vectors]) #让网络评判每个落子位置的优劣
        values = values.reshape(len(moves))  #转换为N*1二维矩阵,N是moves数组的长度
        ranked_moves = self.rank_moves_eps_greedy(values)  #将每一个落子位置按照网络给出的评分和相应策略进行调整
        for move_idx in ranked_moves:
            point = self.encoder.decode_point_index(moves[move_index])  #得到落子位置在二维棋盘上的对应位置
            if not is_point_an_eye(game_state.board, 
                                  point, game_state.next_player):
                if self.collector is not None:
                    #将当前棋盘与相应的落子方式记录下来
                    self.collector.record_decision(state = board_tensor,
                                                  action = moves[move_idx])
                return goboard.Move.play(point)
        return go_board.Move.pass_turn()
    def  rank_moves_eps_greedy(self, values):
        if np.random.random() < self.temperature:  #如果生成随机数小于epsilong,那么随机选择一种可行的落子位置
            values = np.random.random(values.shape)
        ranked_moves = np.argsort(values)  #将网络对每一步落子给出的评分进行升序排列
        return ranked_moves[::-1]  #返回评分最高的落子方式

select_moves用于机器人给出落子方式。机器人先获得当前棋盘和棋盘所有可能的落子位置,然后让网络对所有落子位置的好坏进行评分。按道理它应该选择评分最高的落子位置,但是在rank_move_eps_greedy函数中,我们要像上一节描述的那样引入随机性,先生成一个随机数,如果该随机数小于预先给定的数值,那么机器人就不按照评分来选择落子位置,而是从所有可能的落子位置中随机选择一种,要不然就老老实实按照每一步的评分,选择分数最高的那个落子位置。

接下来我们看看网络的训练方式:

    def  train(self, experience, lr = 0.1, batch_size = 128):
        opt = SGD(lr = lr)
        self.model.compile(loss = 'mse', optimizer = opt)
        n = experience.states.shape[0]
        num_moves = self.encoder.num_points()
        y = np.zeros((n, ))
        for i in range(n):
            action = experience.actions[i]  #获得给定棋盘时对应的落子位置
            reward = experience.rewards[i] #如果模拟对弈中赢了,reward的值是1,如果输了值是-1
            y[i] = reward
        #如果最终结果是胜利,那么我们希望网络对落子位置的评分尽可能趋近与1,如果输了,我们希望网络对落子位置的评分尽可能接近-1
        self.model.fit([experience.states, actions], y , batch_size = batch_size,
                      epochs = 1)

上面所给定的代码就是Q-Learning算法训练机器人的过程,这些代码主要用来表达设计逻辑,由于要运行上面代码需要强大的硬件支持,我们普通电脑根本运行不了上面代码,因此代码主要目的还是在于展现逻辑过程。

更详细的讲解和代码调试演示过程,请点击链接

新书上架,请诸位朋友多多支持:
WechatIMG1.jpeg
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355

推荐阅读更多精彩内容