tkinter製作強化學習可視化環境

原文地址

分類目錄——強化學習

分類目錄——tkinter

全部代碼

  • 先看一下環境效果

    tkinter環境
  • 強化學習用到的環境通常需要以下幾個功能函數

    1583854666466

  • _init_()

        def __init__(self):
            super(Maze, self).__init__()
            self.observatin_space = [(x, y) for x in range(1, 5) for y in range(1, 5)]
            self.action_space = range(4)
            self.n_actions = len(self.action_space)
            self.n_features = np.array(self.observatin_space).shape[-1]
            self.target = {(4, 2): 10}  # 安全/目標狀態
            self.danger = {(2, 2): -20, (3, 3): -20}  # 危險狀態
            self.state = None
            # 初始化窗口、畫布
            self.window = tk.Tk()
            self.canvas = tk.Canvas(self.window, bg='white', height=500, width=500)
    
  • reset()

    用來在每輪訓練前重置初始化狀態

        def reset(self, startstate=None):   # 重置初始狀態
            self.canvas.delete('all')       # 操作之前清空畫布,否則每步的狀態將都會堆在畫面上
            if startstate == None:          # 如果不指定起始狀態,隨機生成一個狀態
                self.state = self.observatin_space[np.random.choice(range(len(self.observatin_space)))]
            else:   # 如果指定了初始狀態,就初始化爲指定狀態
                self.state = startstate
            self.counts = 0
            return self.state
    
  • step()

    用來處理每一步的邏輯,獲得下一個狀態,回報以及判斷是否結束

        def step(self, action):
            self.canvas.delete('all')
            # self.canvas.delete(self.statepos)
            x, y = self.state
            if action == 0:  # 不動
                x = x
                y = y
            elif action == 1:  # 上
                x = x
                y = y + 1
            elif action == 2:  # 下
                x = x
                y = y - 1
            elif action == 3:  # 左
                x = x - 1
                y = y
            elif action == 4:  # 右
                x = x + 1
                y = y
    
            # 判斷下一個狀態是否屬於狀態空間,如果在狀態空間中更新當前狀態,如果不在狀態空間保持當前狀態
            next_state = (x, y)
            self.state = next_state if next_state in self.observatin_space else self.state
    
            self.counts += 1
    
            s = tuple(self.state)   # 爲了能用in操作
            if s in self.danger.keys():
                reward = self.danger[s]
                done = True
            elif s in self.target.keys():
                reward = self.target[s]
                done = True
            else:
                reward = -0.5   # 每多走一個,加個小的負反饋
                done = False
    
            return self.state, reward, done
    
  • render()

    完成可視化畫面搭建

        def render(self):
            # 注意tkinter的平面爲向下x軸正向,向右y軸正向
    
            # 格線
            for i in range(5):
                # 兩個頂點的四個座標
                self.canvas.create_line(50, 50 + 100 * i, 450, 50 + 100 * i)
                self.canvas.create_line(50 + 100 * i, 50, 50 + 100 * i, 450)
    
            # 繪製出口(安全狀態)
            for state in self.target:
                # 我自己把畫格的操作封裝了一個方法
                self.drawrectangle(state, fill='green')
    
            # 繪製危險區域
            for state in self.danger:
                self.drawrectangle(state, fill='red')
    
            # 繪製當前state的位置(圓)
            self.statepos = self.drawoval(self.state, fill='yellow')
    
            self.canvas.pack()
            self.window.update()
    	
        # 爲了方便的複用,將畫格點和畫圓另外進行了封裝
        def drawrectangle(self, point, **attrs):
            '''
            根據格點畫一個方格
            :param point: 格點座標(4,3)
            :param attrs: 其他參數,such as  fill='red'
            :return:
            '''
            size = 100
            self.canvas.create_rectangle(
                50 + (point[0] - 1) * size, 50 + (point[1] - 1) * size,
                50 + point[0] * size, 50 + point[1] * size,
                **attrs
            )
            # 向右爲x正方向,向下爲y軸正方向
            # 左上角座標和右下角座標
    
        # 畫橢圓
        def drawoval(self, point, **attrs):
            '''
            畫(橢)圓
            :param point: 格點座標(4,3)
            :param attrs: 其他參數,such as  fill='red'
            :return:
            '''
            size = 100
            self.canvas.create_oval(
                50 + (point[0] - 1) * size, 50 + (point[1] - 1) * size,
                50 + point[0] * size, 50 + point[1] * size,
                **attrs
            )
    
  • close()

        def close(self):
            if self.window:
                self.window.destroy()
    
  • 測試

    if __name__ == '__main__':
        env = Maze()
        for epoch in range(5):
            env.reset()
            print('Epoch', epoch + 1, ': ', end='')
            print(env.state, end='')
            env.render()  # 刷新畫面
            time.sleep(0.5)
            for i in range(5):
                env.step(np.random.choice(env.action_space))  # 隨機選擇一個動作執行
                print(' ->', env.state, end='')
                env.render()  # 刷新畫面
                time.sleep(0.5)
            print()
        env.close()
    

    測試效果如文首所示

  • 相關內容

    分類目錄——強化學習(更新中)

    什麼是gym

    gym自定義可視化環境繪製

    gym自定義可視化環境實例

    強化學習:gym環境解讀及使用

    從Q_Learning看強化學習

    一個Q_Learning強化學習自定義gym環境可視化實例

    Pytorch實現DQN

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章