Bootstrap

24/8/18算法笔记 目标导向强化学习

目标导向强化学习(Goal-Oriented Reinforcement Learning,简称GORL)是强化学习的一个分支,它关注于智能体如何通过与环境的交互来实现特定的目标或任务。与传统的强化学习不同,目标导向强化学习更加关注目标的设定和达成,而不是简单地最大化累积奖励。以下是目标导向强化学习的一些关键特点:

  1. 目标设定:在目标导向强化学习中,每个任务都有一个明确的目标,智能体需要学习如何达成这些目标。

  2. 目标表示:目标可以以不同的方式表示,例如状态向量、状态的子集、特定的状态标签或属性等。

  3. 策略学习:智能体需要学习一个策略,该策略能够根据当前状态和目标来选择最佳的动作。

  4. 探索与利用:智能体在学习过程中需要平衡探索(发现新的目标达成方式)和利用(使用已知的有效策略)。

  5. 多样性:目标导向强化学习鼓励智能体学习多种达成目标的方式,以适应不同的环境条件或初始状态。

  6. 泛化能力:智能体应该具备一定的泛化能力,能够在不同的目标或类似的任务中使用学到的知识。

  7. 奖励结构:奖励函数通常与目标紧密相关,智能体根据接近目标的程度来获得奖励。

  8. 学习效率:目标导向强化学习通常需要更少的探索,因为智能体可以专注于达成特定的目标,而不是在状态空间中随机游走。

  9. 应用领域:目标导向强化学习在机器人导航、自动驾驶、游戏AI等领域有广泛的应用。

  10. 算法实现:实现目标导向强化学习算法时,可以使用多种技术,如将目标作为额外的状态特征输入到策略网络中,或者使用目标引导的探索策略等。

#定义游戏环境
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())
;