Принцип Q-обучения и его простой случай

обучение с подкреплением

утверждение

Студентам, заинтересованным в глубоком обучении с подкреплением, настоятельно рекомендуетсяВидеоуроки Ван Шусена! !

Это примечание относится кдругой блогиОткрытый курс обучения Baidu Paddle, Добро пожаловать в гости.

Первые впечатления от обучения с подкреплением

Обучение с подкреплением — это область машинного обучения, в которой особое внимание уделяется тому, как действовать в зависимости от среды, чтобы максимизировать предполагаемую выгоду.

смысл:агентсуществуетокружающая обстановкаобучения, согласносостояние окружающей среды(или наблюдение), выполнитьдействие действие, и в зависимости от окружениявознаграждение за обратную связь(награда), чтобы направлять лучшие ходы.

Классические алгоритмы обучения с подкреплением:Q-learning,Sarsa,DQN,Policy Gradient,A3C,DDPG,PPO

Классификация среды: сцена с дискретным управлением (управление счетным выходом), сцена непрерывного управления (действие с несчетным выходом).

Табличный метод решения RL

Sarsa

состояние-действие-награда-состояние Аббревиатура для «-действия». Цель состоит в том, чтобы узнать значение Q конкретного действия в конкретном состоянии и, наконец, установить и оптимизироватьФорма Q, с состоянием в виде строки и действием в виде столбца, обновите таблицу Q в соответствии с вознаграждением, полученным за взаимодействие с окружающей средой.Формула обновления:

image.pngгде α — скорость обучения, а γ — коэффициент снижения вознаграждения.

Q-learning

Q-обучение также использует таблицу Q для хранения значения Q (значение действия состояния).Часть принятия решений такая же, как и в Sarsa, а для расширения исследования используется ε-жадный метод.

Чем Q-обучение отличается от Sarsa, так это способом обновления Q-таблицы.

  • Sarsa — это метод обновления, основанный на политике: сначала выполняется действие, а затем выполняется обновление.
  • Q-обучение — метод обновления вне политики, при обновлении Learn() нет необходимости получать следующее действие, next_action, которое фактически выполняется на следующем шаге, и предполагается, что следующим действием является действие принимает максимальное значение Q.

Формула обновления Q-learning:

image.pngгде α — скорость обучения, а γ — коэффициент снижения вознаграждения.

Поток алгоритма Q-обучения

image.png

кейс

агент:

image.png

QL.py

import numpy as np
import pandas as pd

class QL:
    def __init__(self, actions, learning_rate=0.05, reward_decay=0.9, e_greedy=0.9):
        self.actions = actions      #初始化可以进行的各种行为,传入为列表
        self.lr = learning_rate     #学习率,用于更新Q_table的值
        self.gamma = reward_decay   #当没有到达终点时,下一环境对当前环境的影响
        self.epsilon = e_greedy     #随机选择几率为1-e_greedy,当处于e_greedy内时,不随机选择。
        self.q_table = pd.DataFrame(columns=self.actions, dtype=np.float64)     #生成q_table,列向量为columns

    def choose_action(self,observation):
        self.check_observation(observation)        #检测是否到达过这个点,如果没到达过,在Q表中增加这个节点
        action_list = self.q_table.loc[observation,:]           #取出当前observation所在的不同方向
        
        if(np.random.uniform() < self.epsilon):    #如果在epsilon几率内
            action = np.random.choice(action_list[action_list == np.max(action_list)].index)    #选出当前observation中Q值最大的方向
        else:
            action = np.random.choice(self.actions)      #如果不在epsilon内,则随机选择一个动作
        return action                                    #返回应当做的action

    def learn(self,observation_now,action,score,observation_after,done):
        self.check_observation(observation_after)        #检查是否存在下一环境对应的方向状态
        q_predict = self.q_table.loc[observation_now,action]        #获得当前状态下,当前所作动作所对应的预测得分
        if done:
            q_target = score     #如果完成了则q_target为下一个环境的实际情况得分,本例子中此时score为1
        else:
            q_target = score + self.gamma * self.q_table.loc[observation_after, :].max()  #如果未完成则取下一个环境若干个动作中的最大得分作为这个环境的价值传递给当前环境
        #根据所处的当前环境对各个动作的预测得分和下一步的环境的实际情况更新当前环境的q表
        self.q_table.loc[observation_now, action] += self.lr * (q_target - q_predict)  

    def check_observation(self,observation):
        if observation not in self.q_table.index:               #如果不存在 
            self.q_table = self.q_table.append(                 #则通过series函数生成新的一列
                pd.Series(
                    [0]*len(self.actions),
                    index=self.actions,
                    name=observation,)
            )

Envirnment

image.png

Env.py

import numpy as np
import pandas as pd
import time 

class Env:
    def __init__(self,column,maze_column):
        self.column = column                        #表示地图的长度
        self.maze_column = maze_column - 1          #宝藏所在的位置
        self.x = 0                                  #初始化x
        self.map = np.arange(column)                #给予每个地点一个标号
        self.count = 0                              #用于技术一共走了多少步
        

    def draw(self):
        a = []
        for j in range(self.column) :               #更新图画
            if j == self.x:
                a.append('o')
            elif j == self.maze_column:
                a.append('m')
            else:
                a.append('_')
        interaction = ''.join(a)
        print('\r{}'.format(interaction),end = '')
        

    def get_observation(self):
        return self.map[self.x]                     #返回现在在所


    def get_terminal(self):
        if self.x == self.maze_column:              #如果得到了宝藏,则返回已经完成
            done = True
        else:
            done = False
        return done


    def update_place(self,action):
        self.count += 1                              #更新的时候表示已经走了一步
        if action == 'right':                                  
            if self.x < self.column - 1:
                self.x += 1
        elif action == 'left':   #left
            if self.x > 0:
                self.x -= 1

    def get_target(self,action):
        if action == 'right':                        #获得下一步的环境的实际情况
            if self.x + 1 == self.maze_column:
                score = 1
                pre_done = True
            else:
                score = 0
                pre_done = False
            return self.map[self.x + 1],score,pre_done
        elif action == 'left':   #left
            if self.x - 1 == self.maze_column:
                score = 1
                pre_done = Ture
            else:
                score = 0
                pre_done = False
            return self.map[self.x - 1],score,pre_done
        
    def retry(self):            #初始化
        self.x = 0
        self.count = 0

Выполнить основную программу

run_this.py

from Env import Env
from QL import QL
import time

LONG = 6                    #总长度为6
MAZE_PLACE = 6              #宝藏在第六位
TIMES = 15                  #进行15次迭代

people = QL(['left','right'])       #生成QLearn主体的对象,包含left和right
site = Env(LONG,MAZE_PLACE)         #生成测试环境
for episode in range(TIMES):
    state = site.get_observation()  #观察初始环境
    site.draw()                     #生成图像
    time.sleep(0.3)                 #暂停
    while(1):
        done = site.get_terminal()  #判断当前环境是否到达最后
        if done:                    #如果到达,则初始化
            interaction = '\n第%s次世代,共使用步数:%s。'%(episode+1 ,site.count)
            print(interaction)
            # print(people.q_table)
            site.retry()
            time.sleep(2)
            break
        action = people.choose_action(state)                        #获得下一步方向
        state_after,score,pre_done = site.get_target(action)        #获得下一步的环境的实际情况
        people.learn(state,action,score,state_after,pre_done)       #根据所处的当前环境对各个动作的预测得分和下一步的环境的实际情况更新当前环境的q表
        site.update_place(action)                                   #更新位置
        state = state_after                                         #状态更新
        site.draw()                                                 #更新画布
        time.sleep(0.3)
    

print(people.q_table)