本文将按照以下顺序进行内容安排:
一.Q_learning 简单示例
二.示例的逻辑思路和代码
三.Q_learning应用拓展
第一部分:Q_learning 简单示例——寻找目标
T表示目标位置
o表示人物位置
人物随机出生在一个地点,人物不知道T的位置,但每次可以向左或向右走一步,走到T位置则完成任务。
第二部分:简单示例的逻辑代码思路:
整体思路分为3步:
1.创建状态表 Q_table,用于保存奖励
2.根据每次移动获得的奖励(反馈)更新Q_table
每次人物移动都有两个要素:当前人物位置position,人物下一步动作action;
人物下一步动作action根据position从状态表中选择奖励最大的action,假若在起点位置,action=left的奖励为0,action=right的 奖励为0.6,则人物下一步的action为right
如果人物下一步动作把人物从position带到目标位置T,则给与奖励1,任务结束;如果人物下一步动作把人物带到了其他位 置,则给予奖励0,同时更新人物position=position_next=go_next(position,action)和状态表Q_table[position,action]
3.多次训练
经过多次执行任务后,状态表Q_table的值会趋于稳定。如图为经过50次训练后的目标位置T=4的状态表:
示例全部代码:
"""
qqy
Q_learning
20181007
"""
import numpy as np;
import pandas as pd;
import time
N_LENS=8;#标尺长度
T_POSITION=4;#目标位置
GAMMA=0.9;#理想模式下,奖励的传递效率
ALPHA=0.1;#误差传递效率(学习率)
ACTIONS=['left','right']
N=50;#迭代总循环次数
FRESH_TIME=0.3;
"""
初始化一个状态表,用0填充,表头为ACTIONS,长度为N_LENS
"""
def init_Q_table():
Q_table=pd.DataFrame(np.zeros((N_LENS,len(ACTIONS))),columns=ACTIONS)
return Q_table;
"""
获取起点位置,起点位置属于[0,N_lens)
"""
def get_begin_position():
return np.random.randint(0,N_LENS);
"""
根据Q表的值,选择最佳动作
如果两个动作都没有权重,则随机选择一个动作
如果随机数>0.9 也随机选择一个动作,目的是给予一定的概率尝试不同的路线
"""
def choose_action(position,Q_table):
return np.random.choice(ACTIONS) if Q_table.loc[position,:].max()==0.0 or np.random.rand()>0.9 else Q_table.loc[position,:].idxmax()
"""
根据Q_table获取该动作的真实奖励
"""
def get_real_reward(position,action,Q_table):
return Q_table.loc[position,action];
"""
获取下一个动作的位置
position属于[0,N_LENS)
"""
def get_position_next(position,action):
if position==N_LENS-1 and action=='right':
return position
elif position==0 and action=='left':
return position
else:
return position+1 if action=='right' else position-1;
"""
获取理想情况中的奖励=GAMMA*下一个位置的position的最大权重
"""
def get_dream_reward(position_next,Q_table):
return GAMMA*Q_table.loc[position_next,:].max() if position_next!=T_POSITION else 1
"""
更新环境
"""
def update_env(state,episode,step_counter):
env_list=['_']*(N_LENS)
env_list[T_POSITION]='T';
if state==T_POSITION:
interaction='Episode %s: total_steps= %s'%(episode+1,step_counter)
print('\r{}'.format(interaction),end='')
time.sleep(2)
print('\r ',end='')
else:
env_list[state]='o'
interaction=''.join(env_list)
print('\r{}'.format(interaction),end='')
time.sleep(FRESH_TIME)
"""
创建迭代的主循环
0.初始化Q_table
1.循环N次
2.每次更新起点位置:get_begin_position
3.创建循环,直到到达目标位置位置while not is_target:
4.根据当前位置选择一个动作:choose_action(position)
5.计算该动作的真实奖励:get_real_reward(position,action)=Q_table[position,action]
6.计算该动作的理想奖励:get_dream_reward(position_next)=下个position位置中的最大奖励*奖励传递效率
7.更新Q_table[postion,action]+=ALPHA*(理想奖励-真实奖励)
8.postion更新为position_next
9.如果position_next=目标,则退出当前while循环
"""
def rl():
Q_table=init_Q_table();
for episode in range(N):
position=get_begin_position();
is_target=False;
step_counter=0
update_env(position,episode,step_counter)
while not is_target:
action=choose_action(position,Q_table)
real_reward=get_real_reward(position,action,Q_table)
position_next=get_position_next(position,action)
dream_reward=get_dream_reward(position_next,Q_table)
#更新Q_table
Q_table.loc[position,action]+=ALPHA*(dream_reward-real_reward)
position=position_next
is_target=True if position==T_POSITION else False
update_env(position,episode,step_counter+1)
step_counter+=1
return Q_table
if __name__=='__main__':
q=rl();
print('run end')
print(q)
第三部分:Q_learning的小拓展:
Q_learning 可以解决迷宫问题,寻径问题等。如下例子,可以思考下:
一个人需要从某个房间走到房子外面
就可以抽象成如下模型,然后用Q_learning 解决。当图上增加节点,变得更加复杂时候Q_learning也依然有效: