目标导向强化学习(Goal-Oriented Reinforcement Learning,简称GORL)是强化学习的一个分支,它关注于智能体如何通过与环境的交互来实现特定的目标或任务。与传统的强化学习不同,目标导向强化学习更加关注目标的设定和达成,而不是简单地最大化累积奖励。以下是目标导向强化学习的一些关键特点:
-
目标设定:在目标导向强化学习中,每个任务都有一个明确的目标,智能体需要学习如何达成这些目标。
-
目标表示:目标可以以不同的方式表示,例如状态向量、状态的子集、特定的状态标签或属性等。
-
策略学习:智能体需要学习一个策略,该策略能够根据当前状态和目标来选择最佳的动作。
-
探索与利用:智能体在学习过程中需要平衡探索(发现新的目标达成方式)和利用(使用已知的有效策略)。
-
多样性:目标导向强化学习鼓励智能体学习多种达成目标的方式,以适应不同的环境条件或初始状态。
-
泛化能力:智能体应该具备一定的泛化能力,能够在不同的目标或类似的任务中使用学到的知识。
-
奖励结构:奖励函数通常与目标紧密相关,智能体根据接近目标的程度来获得奖励。
-
学习效率:目标导向强化学习通常需要更少的探索,因为智能体可以专注于达成特定的目标,而不是在状态空间中随机游走。
-
应用领域:目标导向强化学习在机器人导航、自动驾驶、游戏AI等领域有广泛的应用。
-
算法实现:实现目标导向强化学习算法时,可以使用多种技术,如将目标作为额外的状态特征输入到策略网络中,或者使用目标引导的探索策略等。
#定义游戏环境
import torch
import random
import numpy as np
random.seed(0)
torch.manual_seed(0)
#创建一个游戏环境
class Env:
def reset(self):
#前两个数是起点,后两个数是终点
self.state = torch.zeros(4)
self.state[2] = random.uniform(3.5,4.5)
self.state[3] = random.uniform(3.5,4.5)
self.count = 0
return self.state.tolist()
def step(self,action):
action = torch.FloatTensor(action).reshape(2)
#裁剪动作范围
action = torch.clamp(action,min=-1,max = 1)
#执行动作
self.state[:2] +=action
#规范状态空间
self.state[:2] = torch.clamp(self.state[:2],min = 0,max = 5)
self.count+=1
#求二范数,求两向量相减之后的向量的模长
#两向量相减的几何意义是两个向量的尾部相连,再连接两个头部形成的新向量
#mod = ((self.state - self.goal)**2).sum()**0.5
mod = (self.state[:2] - self.state[2:]).norm(p=2).item()
reward = -1.0
over = False
if mod <=0.15:
reward = 0.0
over =True
if self.count>=50:
over =True
return self.state.tolist(),reward,over
env = Env()
print(env.reset())
env.step([0.1,0.2])
定义DDPG模型,代码省略http://t.csdnimg.cn/2wml3
#初始化DDPG模型
ddpg = DDPG()
ddpg.train(
torch.randn(200,4),
troch.randn(200,2),
troch.randn(200,1),
troch.randn(200,4),
troch.zeros(200,1).long(),
)
ddpg.get_action([1,2,3,4])
定义data update函数
class Data():
def __init__(self):
self.datas = []
def __len__(self):
return len(self.datas)
def update(self):
state = env.reset()
pvere =False
data = {
'state' : [],
'action':[],
'reward' :[],
'next_state':[],
'over':[],
}
while not over:
action = ddpg.get_action(state)
next_state,reward,over = env.step(action)
data['state'].append(state)
data['action'].append(action)
data['reward'].append(reward)
data['next_state'].append(next_state)
data['over'].append(over)
state = next_state
self.datas.append(data)
#Data采样函数
def get_sample(self):
#采样结果
sample = {
'state' : [],
'action':[],
'reward' :[],
'next_state':[],
'over':[],
}
#采样N个数据
for _ in range(256):
#随机一局游戏
data = random.sample(self.datas,1)[0]
#随机游戏中的一步,这里除了最后一步
step = random.randint(0,len(data['action'])-2)
#提取数据
state = data['state'][step]
next_state = date['next_state'][step]
action = data['action'][step]
reward = data['reward'][step]
over = data['over'][step]
#设置fake goal
if random.random()<=0.8:
#随机选择step后面的某一步
step = random.randin(step+1,len(date['action'])-1)
#以后面某个步的状态为一个伪的终点,也就是希望先走到这里再说
fake_goal = data['state'][step][:2]
#求二范数
mod = [
next_state[0]-fake_goal[0],next_state[1]-fake_goal[1]
]
mod = torch.FloatTensor(mod).norm(p=2).item()
#再自己重新计算reward和over
reward = -1.0
over =False
if mod <=0.15:
reward = 0.0
over = True
#以伪终点构建新的state
state[2] = fake_goal[0]
state[3] = fake_goal[1]
next_state[2] = fake_goal[0]
next_state[2] = fake_goal[1]
sample['state'].append(state)
sample['action'].append(action)
sample['reward'].append(reward)
sample['next_state'].append(next_state)
sample['over'].append(over)
sample['state'] = torch.FloatTensor(sample['state']).reshape(-1,4)
sample['action'] = torch.FloatTensor(sample['action']).reshape(-1,2)
sample['reward'] = torch.FloatTensor(sample['reward']).reshape(-1,1)
sample['next_state'] = torch.FloatTensor(sample['next_state']).reshape(-1,4)
sample['over'] = torch.FloatTensor(sample['over']).reshape(-1,1)
return sample
#计算最后10个数据reward_sum的值
def get_last_reward_mean(self):
reward_sum = []
for data in self.datas[-10:]:
reward_sum.append(sum(data['reward']))
return sum(reward_sum)/len(reward_sum)
初始化Data对象
data = Data()
#初始化数据
for _ in range(200):
data.update()
data.get_sample(),data.get_last_reward_mean()
训练
for i in range(1800):
data.update()
for _ in range(20):
ddpg.train(**data.get_sample())
if i% 100==0:
print(i,len(data,data.get_last_reward_mean())