价值学习(Value-based Reinforcement Learning)
2026/4/27 21:26:51 网站建设 项目流程

文章目录

  • 前言
  • 一、价值学习(Value-based Reinforcement Learning)
    • 1.1 Q-learning算法
    • 1.2 Deep Q-Network(DQN)
    • 1.3 训练DQN使用的算法
    • 1.4 TD learning
  • 二、TD Learning algorithms
    • 2.1 Sarsa算法
  • 2.2 Multi-step TD Target
  • 2.3 用于Sarsa算法的One-step TD Target和Multi-step TD Target
  • 2.4 用于Q-learning算法的One-step TD Target和Multi-step TD Target
  • 三、价值学习代码示例
  • 3.1 Q-learning/DQN-离线学习代码
  • 3.2 Sarsa在线学习代码
  • 总结

前言

讲完强化学习的基本概念,来介绍一下价值学习算法;


一、价值学习(Value-based Reinforcement Learning)

Notes:Q-learning与DQN都是使用TD算法,原理上Q-learning与DQN没区别只是DQN用神经网络去近似最优动作价值函数;

1.1 Q-learning算法

1)Q-learing算法的表格形式:
每次观测到一个四元组(st,at,rt,st+1);
然后计算TD target yt;Q*(st+1,a)的计算是通过查表格,找到状态st+1那一行,找出最大的元素,最大的元素就是Q*(st+1,a);
最后把Qπ(st,at)写回表格对应的位置,更新了表格里的值;

2)Q-learing算法的神经网络形式:
跟表格形式的Q-learing算法类似,不再赘述;
3)总结:

Q-learning的目标是学习最优动作价值函数Q*;表格形式的Q适用的条件是状态和动作数量有限,Q-learning算法每次更新表格中的一个元素;Q-learning算法的神经网络的形式是通过q(s,a;w)近似Q,Q-learning算法每次更新参数w;

1.2 Deep Q-Network(DQN)

核心就是用神经网络去近似Q*(s,a)函数;我们把这个神经网络记为Q是Q(s,a;w),神经网络的参数是w,输入是状态s,输出是很多数值,这些数值是每一个动作对应的分数,通过奖励reward学习神经网络,使神经网络打分越来越准;

(以打游戏为例,强化学习的目标是在游戏结束的时候,获得的奖励最大;当有Q*(s,a)函数时,就可以告诉我们每个动作的平均回报,从而做平均回报最高的动作)

问题是我们并不知道Q*(s,a)函数,价值学习的想法就是学习一个函数来近似Q*(s,a)函数;

例子:应用DQN来打游戏

观测到当前的状态st,DQN把st作为输入,给所有的动作打分,选出分数最高的动作作为at;

agent执行动作at后,环境会改变状态,用状态转移函数p随机抽一个新的状态st+1,环境同时也告诉我们这一步的奖励rt;(奖励就是强化学习中的监督信号,DQN靠这些奖励来训练)

同理,观测到当前的状态st+1,DQN把st+1作为输入,给所有的动作打分,选出分数最高的动作作为at+1;

agent执行动作at+1后,环境改变状态,用状态转移函数p随机抽一个新的状态st+2,环境同时也告诉我们这一步的奖励rt+1

一直重复这个过程,一直到游戏结束;

1.3 训练DQN使用的算法

Temporal Difference Learning(TD算法);

TD算法例子理解Td算法:假设现在要开车从纽约到亚特兰大,模型Q(W)可以估计开车的时间,估计Q(W)估计开车要花1000分钟;

更新模型参数的过程:

首先估计开车要花多长时间;

到达亚特兰大后,看一下开车所花的真实时间;

计算预测时间与真实时间的差距;(也就是计算损失函数)

求损失函数对模型参数w的梯度;

梯度梯度下降更新模型的参数,使得估计的时间与真实时间越来越接近;

问题:如果我想在到达亚特兰大之前就更新模型的参数w呢?

这时候就需要用TD算法了;(从纽约到亚特兰大要经过DC(华盛顿),我们可以到华盛顿后,估计华盛顿到亚特兰大的时间,假设纽约到亚特兰大要300分钟)

模型估计从纽约到亚特兰大要花1000分钟;

(到华盛顿后发现用了300分钟;(300分钟是真实的观测),模型估计从华盛顿到亚特兰大要花600分钟;)根据模型新的预测,总的时间应该为900分钟,新的估计900分钟叫做TD target,虽然TD target也是估计值,但比原来的1000分钟更可靠,因为里面有事实的成分,300分钟就是真实值,因此当越接近亚特兰大时,TD target越准确;因此到达华盛顿就可以更新模型参数了!

损失函数就是最初的估计与TDtarget的差距的平方,这个差距叫做TD error,然后再做梯度下降更新模型的参数就行了;

TD算法的优点:即使不完成整个旅途,也能更新模型的参数,改进模型;

1.4 TD learning

应用TD算法到DQN的上个例子要用的公式:

整个旅途的时间和第二段时间都是模型的估计,而第一段时间是真实的时间;

TD算法必须等式左边有一项,右边有两项,也右边的两项必须有一项是真实观测到的;

在深度强化学习中,我们要应用的公式为:

简要证明:

应用TD算法到DQN上:

t时刻,DQN输出的值Q(st,at;w)是对Ut作出的估计;
t+1时刻,DQN输出的值Q(st+1,at+1;w)是对Ut+1作出的估计;

Q(st,at;w)类似于出发之前预计的时间,Q(st+1,at+1;w)类似于到达华盛顿后预计的到亚特兰大的时间;

整个过程:

二、TD Learning algorithms

Notes:Sarsa和Q-Learning都是TD算法,但是解决的问题不同:
Sarsa用来训练学习动作价值函数Qπ(s,a);
Q-learning用来训练最优动作价值函数Q*(s,a);
Q-learning的TD target和Sarsa的TD target如下图所示:
Q-learning对Q*(s,a)求最大化,而Sarsa没有最大化;

2.1 Sarsa算法

首先来回顾一下TD算法:Ut = Rt + r * U(t+1) ;Qπ(st,at)是在状态st和动作at下,Ut的期望;
1)表格形式的Sarsa算法:我们的目标是学习Qπ(s,a);如果状态和动作的数量是有限的,那么我们可以画一张表格,表中的一行对应一个状态,一列对应一个动作,表中的每个元素对应一个动作价值,我们要做的就是用Sarsa算法来更新表格,每次更新一个元素;

每次观测到一个四元组(st,at,rt,st+1);
用策略函数π来计算下一个动作,把下一个动作记为at+1;
然后计算TD target yt;这里的Qπ(st+1,at+1)就是在表格中找到st+1,
再找到动作at+1,把那个元素取出来,该元素就是Qπ(st+1,at+1);Qπ(st,at)同理;最后把Qπ(st,at)写回表格对应的位置,更新了表格里的值;
算法每次用五元组(st,at,rt,st+1,at+1)来更新动作价值函数Qπ,该五元组首字母缩写就是Sarsa;

2)神经网络形式的Sarsa算法:我们的目标就是用神经网络q(s,a;w)近似Qπ(s,a);
跟表格形式的Sarsa算法类似,不再赘述;
3)总结:

Sarsa算法的目标就是学习动作价值函数Qπ(s,a);表格形式的Sarsa算法直接学习Qπ(s,a);条件是状态和动作数量有限;
神经网络形式的Sarsa算法通过神经网络q(s,a;w)近似Qπ(s,a),每次通过五元组来更新神经网络的参数w;

2.2 Multi-step TD Target

1)

One-step 只用一个轨迹去计算TD Target,并且来更新动作价值;一个轨迹包括(st,at,rt,st+1),其中只有一个奖励rt,算出的TD Target叫做One-step TD Target;下一次用另一个轨迹去更新动作价值;一直重复下去;Multi-step TD Target使用多个奖励计算TD Target,然后对动作价值进行更新,比如同时使用两个奖励;

这样得到的TD Target叫做Multi-step TD Target;然后再用后面两个奖励再对动作价值进行更新;

这样做的效果比One-step TD Target效果要好;

2)Multi-Step Return

我们可以让汇报包含两个奖励rt和rt+1,还可以包含三个奖励rt和rt+1以及rt+2,然后可以递归下去,还可以包含m个奖励;这个公式叫做Multi-Step Return即多步汇报;

2.3 用于Sarsa算法的One-step TD Target和Multi-step TD Target


用多个奖励值能够把Qπ训练的更好,m=1就变成了标准的TD Target;

2.4 用于Q-learning算法的One-step TD Target和Multi-step TD Target


m是一个超参数,m大小合适的话,多步 TD Target会比一步 TD Target效果更好;

三、价值学习代码示例

3.1 Q-learning/DQN-离线学习代码

importnumpyasnpimportrandomimporttorchimporttorch.nnasnnimporttorch.optimasoptimimportgymfromcollectionsimportdeque# 定义Q网络classQNetwork(nn.Module):def__init__(self,state_dim,action_dim,hidden_dim=128):super(QNetwork,self).__init__()self.fc1=nn.Linear(state_dim,hidden_dim)self.fc2=nn.Linear(hidden_dim,hidden_dim)self.fc3=nn.Linear(hidden_dim,action_dim)defforward(self,x):x=torch.relu(self.fc1(x))x=torch.relu(self.fc2(x))x=self.fc3(x)returnx# 经验回放池classReplayBuffer:def__init__(self,capacity):self.buffer=deque(maxlen=capacity)defpush(self,state,action,reward,next_state,done):self.buffer.append((state,action,reward,next_state,done))defsample(self,batch_size):batch=random.sample(self.buffer,batch_size)state,action,reward,next_state,done=map(np.stack,zip(*batch))returnstate,action,reward,next_state,donedef__len__(self):returnlen(self.buffer)# 实现Q-learning算法(使用深度Q网络,即DQN)defdqn(env_name,learning_rate=0.001,gamma=0.99,num_episodes=1000,batch_size=64,buffer_capacity=10000):env=gym.make(env_name)state_dim=env.observation_space.shape[0]action_dim=env.action_space.n q_net=QNetwork(state_dim,action_dim)target_net=QNetwork(state_dim,action_dim)target_net.load_state_dict(q_net.state_dict())optimizer=optim.Adam(q_net.parameters(),lr=learning_rate)buffer=ReplayBuffer(buffer_capacity)epsilon=1.0epsilon_min=0.01epsilon_decay=0.995forepisodeinrange(num_episodes):state=env.reset()total_reward=0done=Falsewhilenotdone:# ε-贪婪策略选择动作ifrandom.random()<epsilon:action=env.action_space.sample()else:state_tensor=torch.FloatTensor(state)q_values=q_net(state_tensor)action=q_values.argmax().item()next_state,reward,done,_=env.step(action)total_reward+=rewardbuffer.push(state,action,reward,next_state,done)state=next_state# 当缓冲区有足够数据时,开始采样更新iflen(buffer)>=batch_size:states,actions,rewards,next_states,dones=buffer.sample(batch_size)states=torch.FloatTensor(states)actions=torch.LongTensor(actions)rewards=torch.FloatTensor(rewards)next_states=torch.FloatTensor(next_states)dones=torch.BoolTensor(dones)# 计算当前Q值# 假设:# q_net(states) 形状: [batch_size, action_dim]# actions 形状: [batch_size]# actions.unsqueeze(1) 形状: [batch_size, 1]# gather(1, actions.unsqueeze(1)) 选择每个样本对应的动作的Q值# 结果形状: [batch_size, 1]# squeeze(1) 形状: [batch_size]current_q_values=q_net(states).gather(1,actions.unsqueeze(1)).squeeze(1)# 计算目标Q值# target_net(states) 形状: [batch_size, action_dim]# target_net(next_states) 的输出可能是:# tensor([[ 1.2, -0.5], # 状态1: 左动作Q=1.2, 右动作Q=-0.5# [-0.1, 2.3], # 状态2: 左动作Q=-0.1, 右动作Q=2.3# [ 0.8, 0.6], # 状态3: 左动作Q=0.8, 右动作Q=0.6# [ 1.5, 1.4]]) # 状态4: 左动作Q=1.5, 右动作Q=1.4# .max(1) 的结果:# values = tensor([1.2, 2.3, 0.8, 1.5]) # 每个状态的最大Q值# indices = tensor([0, 1, 0, 0]) # 对应最大Q值的动作索引# [0] 取 values# next_q_values = tensor([1.2, 2.3, 0.8, 1.5])next_q_values=target_net(next_states).max(1)[0]target_q_values=rewards+gamma*next_q_values*(~dones)loss=nn.MSELoss()(current_q_values,target_q_values.detach())optimizer.zero_grad()loss.backward()optimizer.step()# 更新目标网络ifepisode%10==0:target_net.load_state_dict(q_net.state_dict())# 衰减εepsilon=max(epsilon_min,epsilon*epsilon_decay)ifepisode%100==0:print(f"Episode{episode}, Total Reward:{total_reward}, Epsilon:{epsilon}")env.close()# 运行DQN# dqn('CartPole-v1')

3.2 Sarsa在线学习代码

defsarsa(env_name,learning_rate=0.001,gamma=0.99,num_episodes=1000):env=gym.make(env_name)state_dim=env.observation_space.shape[0]action_dim=env.action_space.n q_net=QNetwork(state_dim,action_dim)optimizer=optim.Adam(q_net.parameters(),lr=learning_rate)epsilon=1.0epsilon_min=0.01epsilon_decay=0.995forepisodeinrange(num_episodes):state=env.reset()# 根据当前Q网络和ε-贪婪策略选择初始动作state_tensor=torch.FloatTensor(state)ifrandom.random()<epsilon:action=env.action_space.sample()else:q_values=q_net(state_tensor)action=q_values.argmax().item()total_reward=0done=Falsewhilenotdone:next_state,reward,done,_=env.step(action)total_reward+=reward# 选择下一个动作next_state_tensor=torch.FloatTensor(next_state)ifrandom.random()<epsilon:next_action=env.action_space.sample()else:next_q_values=q_net(next_state_tensor)next_action=next_q_values.argmax().item()# 计算当前Q值和目标Q值# 与DQN算法唯一的区别就是计算下一个q值是不是选择Q值最大的动作,别的和DQN差别不大current_q=q_net(state_tensor)[action]next_q=q_net(next_state_tensor)[next_action]target_q=reward+gamma*next_q*(notdone)loss=nn.MSELoss()(current_q,target_q.detach())optimizer.zero_grad()loss.backward()optimizer.step()state=next_state action=next_action state_tensor=next_state_tensor# 衰减εepsilon=max(epsilon_min,epsilon*epsilon_decay)ifepisode%100==0:print(f"Episode{episode}, Total Reward:{total_reward}, Epsilon:{epsilon}")env.close()# 运行SARSA# sarsa('CartPole-v1')

总结

以上就是今天要讲的内容,本文简单介绍了价值学习。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询