[转载]Reinforcement Learning:Sarsa和Q-learning

Sarsa算法

Sarsa的算法如下: 

[转载]Reinforcement Learning:Sarsa和Q-learning_第1张图片
 
Sarsa算法是on-policy方法,其原始策略和更新策略是一致的,而其更新策略和MC不一样的是其策略更新不需要采样一个完整的轨迹,在执行完一个动作后就可以更新其值函数。

Q-learning算法

[转载]Reinforcement Learning:Sarsa和Q-learning_第2张图片

Q-learning算法则是一个off-policy的方法,其原始策略和值函数更新策略不一致,同样的也不需要进行采样一个轨迹进行策略更新,和Sarsa算法不一样的是,Q-learning在更新值函数的时候使用的是贪心策略,而不是ϵϵ-greedy策略。

两者的区别

Q-learning完成一次状态转移的过程为:

  • 使用 epsilon-greedy 的方法,选择当前状态的 action
  • 使用 greedy 法选择使 next_state 最大的动作 next_action
  • 使用 Q[next_state][next_acion] 更新 Q[state][action]
  • 然后 state = next_state,动作再重新选择,next_acion 值仅用于更新 Q值

Sarsa则不同:

  • 使用 epsilon-greedy 的方法,选择当前状态的 action
  • 使用 epsilon-greedy 的方法,选择 next_state 的 next_action
  • 用 Q[next_state][next_acion]来更新Q[state][action]
  • ,更新的时候:state=next_state, action=next_action 

从中就可以看出两个算法的区别,Sarsa是一种on-policy算法,Q-learning是一种off-policy算法。
Sarsa选取的是一种保守的策略,他在更新Q值的时候已经为未来规划好了动作,对错误和死亡比较敏感。而Q-learning每次在更新的时候选取的是最大化Q的方向,而当下一个状态时,再重新选择动作,Q-learning是一种鲁莽、大胆、贪婪的算法,对于死亡和错误并不在乎。
在实际中,如果你比较在乎机器的损害就用一种保守的算法,在训练时,可以减少机器损害的次数。此处参考这篇博客

为了比较Sarsa算法和Q-learning算法的不同,我们使用一个具体的问题进行展示。问题描述如下:


[转载]Reinforcement Learning:Sarsa和Q-learning_第3张图片

如上图所示,有一个12*4的格子,从左下角开始走,走的方向可以是上下左右(不能超过方格),走到右下角为终点,游戏结束,其中在最下面的一行有10个被标记了的区域,一旦走到这个区域,将会回到原点并继续游戏。


游戏分析: 
1. 用户走到被标记区域的reward值为-100,其余的区域reward值为-1 
2. 游戏的状态为用户的两个坐标x,y

由此可以规划这个游戏的场景Environment:以开始点S建立坐标,开始点设置为(0,0),x轴坐标向右,y轴坐标向上。代码构建如下:

class CliffEnvironment(object):

    def __init__(self):
        self.width=12
        self.height=4
        self.move=[[0,1],[0,-1],[-1,0],[1,0]] #up,down,left,right
        self.nA=4
        self._reset()

    def _reset(self):
        self.x=0
        self.y=0
        self.end_x=11
        self.end_y=0
        self.done=False

    def observation(self):
        return tuple((self.x,self.y)),self.done
    def clip(self,x,y):
        x = max(x,0)
        x = min(x,self.width-1)
        y = max(y,0)
        y = min(y,self.height-1)
        return x,y
    def _step(self,action):
        self.done = False
        self.x+=self.move[action][0]
        self.y+=self.move[action][1]
        self.x,self.y=self.clip(self.x,self.y)

        if self.x>=1 and self.x<=10 and self.y==0:
            reward=-100
            self._reset()
        elif self.x==self.width-1 and self.y==0:
            reward=0
            self.is_destination=True
            self.done=True
        else:
            reward=-1
        return tuple((self.x,self.y)),reward,self.done

其中_step表示的是根据action走一步,_reset是还原开始的布局,observation返回当前的状态。

Sarsa算法

使用Sarsa算法来更新策略的代码如下:

def sarsa(env,episode_nums,discount_factor=1.0, alpha=0.5,epsilon=0.1):

    env = CliffEnvironment()
    Q = defaultdict(lambda:np.zeros(env.nA))
    rewards=[]

    for i_episode in range(1,1+episode_nums):

        if i_episode % 1000 == 0:
            print("\rEpisode {}/{}.".format(i_episode, episode_nums))
            sys.stdout.flush()

        env._reset()
        state,done = env.observation()
        A= epsilon_greedy_policy(Q,state,env.nA)
        probs = A
        action = np.random.choice(np.arange(env.nA),p=probs)
        sum_reward=0.0

        while not done:
            new_state,reward,done = env._step(action)

            if done:
                Q[state][action]=Q[state][action]+alpha*(reward+discount_factor*0.0-Q[state][action])
                break
            else:
                new_A =  epsilon_greedy_policy(Q,new_state,env.nA)
                probs = new_A
                new_action = np.random.choice(np.arange(env.nA),p=probs)
                Q[state][action]=Q[state][action]+alpha*(reward+discount_factor*Q[new_state][new_action]-Q[state][action])
                state = new_state
                action=new_action
            sum_reward+=reward
        rewards.append(sum_reward)
    return Q,rewards


其中原始策略和Q[state][action]更新策略都使用的是ϵϵ-greedy算法,在迭代1000次之后,我们得到的更新策略是:

right right right right right right right right right right right down  
up    up    up    up    up    up    right up    up    right right down  
up    left  up    up    right up    up    up    left  up    right down  
up    up    up    up    up    up    up    up    up    up    up    up    

其中up表示向上,down表示向下走,left和right分别表示左右,可以看出来的是Sarsa算法得到的策略是一条最安全的路,也就是最开始的图中的“safe path”,我们迭代10次Sarsa算法,每次Sarsa算法使用1000个episode,对10次迭代的每个episode的reward取均值,并按照每隔10个episode采样值然后绘制其reward图: 

[转载]Reinforcement Learning:Sarsa和Q-learning_第4张图片


Q-learning算法

使用Q-learning更新算法的代码如下:

def Q_learning(env,episode_nums,discount_factor=1.0, alpha=0.5,epsilon=0.1):

    env = CliffEnvironment()
    Q = defaultdict(lambda:np.zeros(env.nA))
    rewards=[]

    for i_episode in range(1,1+episode_nums):

        if i_episode % 1000 == 0:
            print("\rEpisode {}/{}.".format(i_episode, episode_nums))
            sys.stdout.flush()

        env._reset()
        state,done = env.observation()

        sum_reward=0.0

        while not done:

            A= epsilon_greedy_policy(Q,state,env.nA)
            probs = A
            action = np.random.choice(np.arange(env.nA),p=probs)
            new_state,reward,done = env._step(action)

            if done:
                Q[state][action]=Q[state][action]+alpha*(reward+discount_factor*0.0-Q[state][action])
                break
            else:
                new_action = greedy_policy(Q,new_state)
                Q[state][action]=Q[state][action]+alpha*(reward+discount_factor*Q[new_state][new_action]-Q[state][action])
                state = new_state
            sum_reward+=reward
        rewards.append(sum_reward)
    return Q,rewards


可以看出,Q-learning原始策略是ϵϵ-greedy策略,而更新值函数中使用的是贪心策略,显然Q-learning是一个off-policy算法。和Sarsa算法一样,我们迭代1000个episode后得到其策略:

up    right right right right right right right down  right down  down  
down  right right right right down  right down  right right right down  
right right right right right right right right right right right down  
up    up    up    up    up    up    up    up    up    up    up    up    

得到的策略和最开始的图中的“optimal path”一致,也就是说Q-learning偏向选择最优的策略,但是有时候Q-learning会陷入到被标记的区域中,这个可以从Q-leanring的返回reward值看出,绘制图的方法和Sarsa算法中保持一致,得到的图是: 

[转载]Reinforcement Learning:Sarsa和Q-learning_第5张图片


从图中可以看出的是,Q-learning的reward值相比sarsa算法是偏低的,原因是Q-learning在选择最优策略的时候偶尔会陷入陷阱得到-100的reward值(由于原始策略存在ϵϵ-greedy方法)。

尽管Q-learning实际上是在学习最优策略的价值,但它的在线表现要比学习迂回策略的Sarsa差。当然如果ϵϵ逐渐变小的话,两种方法都能最后收敛到最优策略。

本文所有代码可以在这里找到


————————————————
版权声明:本文为CSDN博主「luchi007」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010223750/article/details/78955807

你可能感兴趣的:(强化学习)