1强化学习是机器学习的一个重要的分支,它主要研究如何在环境中做出合适的动作以最大化某些奖励
理解:在所处环境下,怎样达到目标的最优方法或者步骤
2强化学习中的几个核心概念
- 智能体(Agent)
- 环境(Environment)
- 动作(Action)
- 奖励(Reward)
智能体存在于环境中,并会在环境中作出一些动作,这些动作会使得智能体获得一些奖励,这些奖励有正有负。
强化学习的目标是学习一个策略,使得智能体可以在合适的时候作出合适的动作以获得最大的奖励。
就像我们要达成某个目标一步步的行动,比如英语考级,作出的行动对于目标 正的反馈和负的反馈
比如专注背单词 有助于 考英语等级 正反馈 荒废了一些时间 负反馈
强化学习就是要学习达成目标的最后策略
3还有一个重要的概念:状态
状态是描述了智能体和环境的状况,它和环境以及智能体都有关
智能体一般以当前的状态作为决策依据,作出决策后,智能体的行为又会引起状态的改变。
4图示
自己画的
状态就是指智能体+环境的状态
5例子:走迷宫
孩子在迷宫中要找到图中的宝藏
这里孩子只能上下左右一步一步的走
其中不同的位置代表不同的状态( s1,s2,s3....)
孩子采取的行动(Action)有四个上下左右:a1,a2,a3,a4。
在不同的位置(不同的状态下)采取不同的行动(Action)会得到不同的期望奖励(Reward)
6 Q函数
Q Learning算法的核心是Q(s,a)函数 ,其中s表示状态,a表示行为
Q函数可以看作一个“表格”,每一行代表一个状态,每一列代表一个行为。
Q(s,a)的值是在s状态执行了a行为后的期望奖励值
只要得到正确的函数Q函数,可以在没个状态做出合适的决策了
7 Q函数的学习策略
Q(state,action):表示在状态state下执行action后期望得到的奖励
实际上执行action后状态为state变成new_state 并得到了奖励reward
Q Learning算法用
数学公式上:
Q(s,a)←(1-α)Q(s,a)+α[R+γmaxQ(s',a)]
来更新Q函数 s’代表新的状态
代码上
Q Learning 算法用reward+GAMMA*Q[new_state,:].max() 来近似期望得到的奖励
8 用学习率ALPHA来代替公式中的GAMMA
GAMMA:
Q[new_state,:].max 表示新状态下的最大期望奖励 由于是下一个时间节点的值 因此要乘以一个衰减系数GAMMA
一般不直接使用reward+GAMMA*Q[new_state,:].max() 来更新Q函数
而是设置一个学习率ALPHA :
(1-ALPHA)*Q(state,action)+ALPHA*Q[new_state,:].max() 来更新Q函数
原因: 这样更新比较平缓 防止模型过早收敛到局部极小值
9ε-greedy策略
在Q learning的更新过程中 每一步都要根据当前状态一起Q函数确定一个合适的行动action
这里要考虑一个平衡经验和探索的问题
完全按照经验行动 : 每次都根据Q函数选择期望对应最大的action 我们可有可能会一直局限现有的经验之中,难以发现新的行为。
如果智能体只关注探索新的行为 :完全随机行为 ,而大多数行为是没有价值的 ,导致Q函数学习的速度很慢。
使用ε-greedy策略来选择合适的行动。
设置一个较小ε的值
以(1-ε)概率来凭借经验做出选择,得到Q(s,a)最大的期望。
以ε概率来随机进行探索
10Qlearning算法每次更新Q函数的步骤
- 使用ε-greedy策略或其他方法选出一个acion
- 智能体猜取动作action 得到奖励reward 和 新的状态 new_state
- 用(1-ALPHA)*Q(state,action)+ALPHA*Q[new_state,:].max() 来更新Q函数
代码
迷宫的环境
from __future__ import print_function
import copy
迷宫的地图
#迷宫地图
MAP = \
'''
.........
. .
. o .
. .
.........
'''
MAP = MAP.strip().split('\n')
MAP = [[c for c in line] for line in MAP]
现在MAP
MAP
[['.', '.', '.', '.', '.', '.', '.', '.', '.'],
['.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '.'],
['.', ' ', ' ', ' ', ' ', ' ', 'o', ' ', '.'],
['.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '.'],
['.', '.', '.', '.', '.', '.', '.', '.', '.']]
四个action
DX = [-1, 1, 0, 0]
DY = [0, 0, -1, 1]
#左右上下
环境类的定义:我的理解写在注释上面
#环境类
class Env(object):
#初始化
def __init__(self):
#迷宫
self.map = copy.deepcopy(MAP)
#智能体的初始位置1,1
self.x = 1
self.y = 1
self.step = 0
self.total_reward = 0
self.is_end = False
#在环境中做出行动
def interact(self, action):
assert self.is_end is False
new_x = self.x + DX[action]
new_y = self.y + DY[action]
new_pos_char = self.map[new_x][new_y]#计算新的坐标
self.step += 1#移动次数
#判断新的位置是什么样的?墙壁 or 无东西 or 宝藏 or 陷阱
if new_pos_char == '.':
reward = 0 # do not change position
elif new_pos_char == ' ':
self.x = new_x
self.y = new_y
reward = 0
elif new_pos_char == 'o':
self.x = new_x
self.y = new_y
self.map[new_x][new_y] = ' ' # update map
self.is_end = True # end #获得保障 结束游戏
reward = 100 #奖励值100 get
elif new_pos_char == 'x':
self.x = new_x
self.y = new_y
self.map[new_x][new_y] = ' ' # update map
reward = -5 #掉入陷阱 惩罚 :奖励值-5
self.total_reward += reward
return reward
@property
#总的状态数
def state_num(self):
rows = len(self.map)
cols = len(self.map[0])
return rows * cols#行×列 5×9 = 45
@property
#当前状态的编码
def present_state(self):
cols = len(self.map[0])
return self.x * cols + self.y#x坐标×cls数+y坐标
#打印智能体在迷宫上面的位置
def print_map(self):
printed_map = copy.deepcopy(self.map)
printed_map[self.x][self.y] = 'A'
print('\n'.join([''.join([c for c in line]) for line in printed_map]))
def print_map_with_reprint(self, output_list):
printed_map = copy.deepcopy(self.map)
printed_map[self.x][self.y] = 'A'
printed_list = [''.join([c for c in line]) for line in printed_map]
for i, line in enumerate(printed_list):
output_list[i] = line
Q Learning 算法
from __future__ import print_function
import numpy as np
import time
from env import Env
设置超参数
EPSILON = 0.1
ALPHA = 0.1
GAMMA = 0.9
MAX_STEP = 30
np.random.seed(0)
定义了epsilon_greedy策略函数
和Q Learning 算法的过程
def epsilon_greedy(Q, state):
#np.random.uniform()随机参数 大于 0.9时 采用 随机的探索的方式 来决定下一个action
#如果根据经验 来期望最大值action的期望值为0 采用随机探索方式
#np.random.uniform()随机参数 小于 0.9时 根据Q函数采取最大期望奖励的action
if (np.random.uniform() > 1 - EPSILON) or ((Q[state, :] == 0).all()):
action = np.random.randint(0, 4) # 0~3
else:
action = Q[state, :].argmax()
return action
#Q函数的定义
#这里一共有45个状态 每个状态有4个action Q函数就是这些状态对应不同的操作的期望奖励的值
#45×4
e = Env()
Q = np.zeros((e.state_num, 4))
for i in range(200):
e = Env()#迷宫环境
while (e.is_end is False) and (e.step < MAX_STEP):
action = epsilon_greedy(Q, e.present_state)#根据epsilon_greedy 确定接下来的action
state = e.present_state#当前的状态
reward = e.interact(action)#执行action 运行这个函数的时候 智能体的坐标改变 相当于更新了状态
new_state = e.present_state#更新state
#更新Q值 ALPHA = 0.1 GAMMA = 0.9
Q[state, action] = (1 - ALPHA) * Q[state, action] + \
ALPHA * (reward + GAMMA * Q[new_state, :].max())
#打印
e.print_map()
time.sleep(0.1)#迟调用线程的运行,可通过参数secs指秒数,表示进程挂起的时间
print('Episode:', i, 'Total Step:', e.step, 'Total Reward:', e.total_reward)
time.sleep(2)
其中一次游戏运行的过程
.........
. A .
. o .
. .
.........
.........
.A .
. o .
. .
.........
.........
. A .
. o .
. .
.........
.........
. A .
. o .
. .
.........
.........
. A .
. o .
. .
.........
.........
. A .
. o .
. .
.........
.........
. A .
. o .
. .
.........
.........
. .
. A .
. .
.........
源码分享:码云:https://gitee.com/MaLuBuShiWo/Q-Learning/tree/master