智能体(agent):可以是一个简单的算法,通常输入为state,输出为policy(规则);
状态集(states):为智能体的输入;
动作集(actions):智能体的动作,比如左右移动;
奖励(rewards):环境根据智能体的动作,反馈回来的一个奖惩信号,可以为正奖励也可以为负奖励;
环境(environment):接收智能体的动作action,回馈reward和state。
Q-learning是强化学习中的一种算法,Q即为Q(steat,action)就是在某一时刻的s状态下(s∈S),采取动作action(action∈A)动作能够获得收益的期望,也就是行为值value。该算法的主要思想就是将State与Action构建成一张Q-table来存储Q值,然后根据Q值来选取能够获得最大的收益的动作。Q是一个列表,一般当矩阵看,当然实际中由于探索过程的发散,这个表将很大很大,因此需要将表做成神经网络来储存,也就是深度强化学习(DQN)。
新Q(s,a)=老Q+学习率*偏差
首先你是一个生活在一维平面内的婴儿,也就是智能体agent,你饿了,想吃东西。但你妈站在距离你6米远的地方,你必须找到你妈才能吃到东西(即寻宝过程)。
你只能左右上下移动(这里简化为左右移动),每次只能移动一米,你的移动就是动作action,而你妈刚好站在你右边6米。你所处的位置就是你的输入states。
这时候开始找你妈,往左边移动了一米即你发生了action, 但是与你妈更远了,你妈大喊:“乖宝宝,怎么还不过来呀,你走错啦,真笨”;当你往右移动一米,你妈说:“真聪明”,这时候“真笨”和“真聪明”这两个词恰好你听懂了,放进了心里,也就是reward负奖励和正奖励。
最终你通过不断左右左右移动,来到了你妈这里并吃上了热乎的食物,整个过程就是训练你的过程,也就是训练agent的过程。
# -u---T u是你的位置,T是你的最终目标 import pandas as pd import random import time #首先设置参数 want = 0.9 #设置你的渴望即贪婪率 efficiency = 0.1 #学习效率 reward_decrease = 0.8 #奖励递减值 # 定义你目前所处的状态(位置)和环境 states = range(6) #设置状态集0-6 即你距离你妈6个步长 actions = ['left','right'] #设置动作集,一维只有两个方向,即向左和向右 rewards = [0, 0, 0, 0, 0, 1] #设置奖励集, 即第6位时你爬到你妈那里时,才给你奖励 Q_table = pd.DataFrame(data=[[0 for _ in actions] for _ in states],index = states,columns = actions)# 创建一个表格 # DataFrame函数创建一个表格,index为行,这里用状态集赋值;columns为列,这里用动作集赋值;Q为某一时刻下状态state中采取动作action能获得收益的期望,即行为值 # 定义环境更新函数,实时更新且打印状态 def updata_environment(state): # global states #状态设为全局变量,可以整个环境内引用 environment = list('-----T') #环境设为一个6字符长的字符串 if state != states[-1]: #如果不在最后一个位置 environment[state] = 'u' #确定你所处的位置 print('\r{}'.format(''.join(environment)), end='')#打印 time.sleep(0.1)#调用线程推迟执行该函数0.1S #你动作之后,定义下一状态函数 def get_next_state(state, action): global states # left,right,none = -1,+1,0 if action == 'right' and state != states[-1]: #如果你不在最后一个位置,则向你妈移动一位 next_state = state +1 elif action == 'left' and state != states[0]: #如果你不在最开始的一个位置,则远离你妈移动一位(elif表示否则如果,如果if步骤执行成功,那么elif步骤就不会执行) next_state = state -1 #如果if和elif都判断失败,则执行else语句 else: next_state = state #否则+0,就是你没动的意思 return next_state #把下一状态值返回带出 #定义当前状态下合法的动作集合函数 def get_vaild_actions(state): global actions vaild_actions = set(actions) if state == states[-1]: # 如果你在最后一个位置 vaild_actions -= set(['right']) #则不能再向右了 if state == states[0]: #如果你在最初的位置 vaild_actions -= set(['left']) #则不能再向左了 return list(vaild_actions) #把当前状态值返回带出为一个列表格式 for i in range(13): #i在0-13内依次取值,这里的i是episode,即从action开始到结束的一个过程 current_state = 0 #设置Q估计表内的状态位置为0 # current_state = random.choice(states) updata_environment(current_state) #与绑定环境相关 total_steps = 0 while current_state != states[-1]:# 创建一个循环,直到你到达最后一个位置,这里是重复状态动作的执行 if (random.uniform(0,1) > want) or ((Q_table.loc[current_state] == 0).all()): #random.uniform(0,1)表示在0-1内随机生成一个随机数,loc通过行/列标签索引到状态矩阵,(iloc通过行/列号索引矩阵这里没用到),all()表示索引到的状态矩阵与0的比对结果再作一次与运算 current_action = random.choice(get_vaild_actions(current_state)) #random.choice可以从定义()里随机选取内容,并将选取结果放入赋值中返回 # 该if语句意思为:如果你的渴望(贪婪)小于这个随机数或者索引到的估计状态为0,则你目前探索到的状态是正确的行动 else: current_action = Q_table.loc[current_state].idxmax()#否则利用你的渴望逼近正确的行动,idmax()表示索引最大值 next_state = get_next_state(current_state,current_action) #调用你下一动作后的状态函数,与估计到的正确状态和动作绑定 next_state_Q_values = Q_table.loc[next_state,get_vaild_actions(next_state)] # 得到现实Q Q_table.loc[current_state, current_action] += efficiency*(rewards[next_state] + reward_decrease*next_state_Q_values.max() - Q_table.loc[current_state,current_action]) #根据贝尔曼方程更新Q,Q为某一时刻下状态state中采取动作action能获得收益的期望,Q_table.loc[current_state,current_action]为估计的Q current_state = next_state updata_environment(current_state) #更新环境 total_steps += 1 #总步骤加1 print('\rEpisode {}: total_steps = {}'.format(i, total_steps), end='') time.sleep(2) print('\r',end='') print('\nQ_table:') print(Q_table)