[PyTorch][chapter 61][强化学习-免模型学习 off-policy]

news2024/7/4 4:55:42

前言:

    蒙特卡罗的学习基本流程:

     Policy Evaluation :          生成动作-状态轨迹,完成价值函数的估计。

     Policy Improvement:       通过价值函数估计来优化policy。

       同策略(one-policy):产生 采样轨迹的策略 \pi^{'} 和要改善的策略 \pi 相同。

       Policy Evaluation :    通过\epsilon-贪心策略(\pi^{'}),产生(状态-动作-奖赏)轨迹。

       Policy Improvement:  原始策略也是 \epsilon-贪心策略(\pi^{'}), 通过价值函数优化, \epsilon-贪心策略(\pi^{'})

      异策略(off-policy):产生采样轨迹的  策略 \pi^{'} 和要改善的策略 \pi 不同。

      Policy Evaluation :   通过\epsilon-贪心策略(\pi^{'}),产生采样轨迹(状态-动作-奖赏)。

      Policy Improvement:  改进原始策略\pi

    两个优势:

    1: 原始策略不容易采样

    2: 降低方差

易策略常用的方案为 IR(importance sample) 重要性采样

Importance sampling is a Monte Carlo method for evaluating properties of a particular distribution, while only having samples generated from a different distribution than the distribution of interest. Its introduction in statistics is generally attributed to a paper by Teun Kloek and Herman K. van Dijk in 1978,[1] but its precursors can be found in statistical physics as early as 1949.[2][3] Importance sampling is also related to umbrella sampling in computational physics. Depending on the application, the term may refer to the process of sampling from this alternative distribution, the process of inference, or both.


一  importance-samling

    1.1 原理

     原始问题:

      u_f=\int_x p(z)f(z)dx

     如果采样N次,得到z_1,z_2,...z_N

       u_f \approx \frac{1}{N}\sum_{z_i \sim p(z)}f(z_i)

    问题: p(z) 很难采样(采样空间很大,很多时候只能采样到一部分)

   引入 q(x) 重要性分布(这也是一个分布,容易被采样)

  w(x)=\frac{p(x)}{q(x)}: 称为importance weight

            u_f =\int q(x)\frac{p(x)}{q(x)}f(x)dx

             \approx \frac{1}{N}\sum_i w(x_i)f(x_i)(大数定理)

 下面例子,我们需要对w(x_i),做归一化处理,更清楚的看出来占比

   下面代码进行了归一化处理,方案如下:

     w(x_i)=log p(x_i)-log q(x_i)

     w^1(x_i)=\frac{e^{w(x_i)}}{\sum_j e^{w(x_i)}}

     w^2(x_i)=w(x_i)-log\sum_j(e^{w(x_j)})

      

# -*- coding: utf-8 -*-
"""
Created on Wed Nov  8 16:38:34 2023

@author: chengxf2
"""

import numpy as np
import matplotlib.pyplot as plt
from scipy.special import logsumexp

class pdf:
    
    def __call__(self,x):
        pass
    def sample(self,n):
        
        pass
    
#正太分布的概率密度
class Norm(pdf):
    #返回一组符合高斯分布的概率密度随机数。
    def __init__(self, mu=0, sigma=1):
        
        self.mu = mu
        self.sigma = sigma
        
    def __call__(self, x):
        #log p 功能,去掉前面常数项
         logp = (x-self.mu)**2/(2*self.sigma**2)
         return -logp
     
    
    def sample(self, N):
         #产生N 个点,这些点符合正太分布
         x = np.random.normal(self.mu, self.sigma,N)
         
         return x



class Uniform(pdf):
     #均匀分布的概率密度
      def __init__(self, low, high):
          
          self.low = low
          self.high = high
          
          
      def __call__(self, x):
             #logq 功能
              N = len(x)
              a = np.repeat(-np.log(self.high-self.low), N)
              
              return -a
          
         
      def sample(self, N):
              #产生N 点,这些点符合均匀分布
              x = np.random.uniform(self.low, self.high,N)
              
              return x
          
class ImportanceSampler:
    
    
    def __init__(self, p_dist, q_dist):
        
        self.p_dist = p_dist
        self.q_dist = q_dist
        
    
    def sample(self, N):
        #采样
        samples = self.q_dist.sample(N)
        weights = self.calc_weights(samples)
        
        normal_weights = weights - logsumexp(weights)
        
        return samples, normal_weights
    
    
    def calc_weights(self, samples):
        #log (p/q) =log(p)-log(q)
        return self.p_dist(samples)-self.q_dist(samples)



if __name__ == "__main__":

    N = 10000
    p = Norm()
    q = Uniform(-10, 10)  
    
    sampler = ImportanceSampler(p, q)
    
    #samples 从q(x)采样出来的点,weight_sample
    samples,weight_sample= sampler.sample(N)
    #以weight_sample的概率,从samples中抽样 N 个点
    samples = np.random.choice(samples,N, p = np.exp(weight_sample))
    
    plt.hist(samples, bins=100)
        
       


二 易策略 off-policy 原理

     target policy \pi: 原始策略 

        x:     这里面代表基于原始策略,得到的轨迹

                  \begin{bmatrix} s_0,a_0,r_1,....s_{T-1},a_{T-1},r_T,s_T \end{bmatrix}

       p(x):   该轨迹的概率

       f(x):    该轨迹的累积奖赏

      期望的累积奖赏:

                    u_f=\int_{x} f(x)p(x)dx \approx \frac{1}{N}\sum f(x_i)

    behavior policy \pi^{'}: 行为策略

     q(x): 代表各种轨迹的采样概率

    则累积奖赏函数f在概率p 也可以等价的写为:

     u_f=\int_{x}q(x)\frac{p(x)}{q(x)}f(x)dx

     E[f] \approx \frac{1}{m}\sum_{i=1}^{m}\frac{p(x_i)}{q(x_i)}f(x_i)

   

     P_i^{\pi} 和 P^{\pi^{'}} 分别表示两个策略产生i 条轨迹的概率,对于给定的一条轨迹

    \begin{bmatrix} s_0,a_0,r_1,....s_{T-1},a_{T-1},r_T,s_T \end{bmatrix}

    原始策略\pi 产生该轨迹的概率:

     P^{\pi}=\prod_{i=0}^{T-1} \pi(s_i,a_i)P_{s_i\rightarrow s_{i+1}}^{a_i}

    P^{\pi^{'}}=\prod_{i=0}^{T-1} \pi^{'}(s_i,a_i)P_{s_i\rightarrow s_{i+1}}^{a_i}

   则

    w(s)=\frac{P^{\pi}}{p^{\pi^{'}}}=\prod_{i=0}^{T-1}\frac{\pi(s_i,a_i)}{\pi^{'}(s_i,a_i)}

  若\pi 为确定性策略,但是\pi^{'} 是\pi\epsilon -贪心策略:

原始策略   p_i=\left\{\begin{matrix} \pi(s_i,a_i)=1, if: a_i==\pi(x_i) \\ \pi(s_i,a_i)=0, if: a_i \neq \pi(x_i) \end{matrix}\right.

行为策略: q_i=\left\{\begin{matrix} \pi^{'}(s_i,a_i)=1-\epsilon+\frac{\epsilon }{|A|} , if: a_i==\pi(x_i) \\ \pi^{'}(s_i,a_i)=\frac{\epsilon }{|A|}, if: a_i \neq \pi(x_i) \end{matrix}\right.

  现在通过行为策略产生的轨迹度量权重w

 理论上应该是连乘的,但是p_i=0, if a_i \neq \pi(x_i),

 考虑到只是概率的比值,上面可以做个替换

 w(s)=\frac{p^{\pi}}{p^{\pi^{'}}}=\prod\frac{e^{p_i}}{e^{q_i}}=\prod e^{p_i-q_i}

其中: w_i=\frac{e^{p_i}}{e^{q_i}}=e^{p_i-q_i}更灵活的利用importance sample)

其核心是要计算两个概率比值,上面的例子是去log,再归一化


三  方差影响


四  代码

代码里面R的计算方式跟上面是不同的,

R=\frac{1}{T-t}(\sum_{i=t}^{T-1}r_i)(\prod_{j=t}^{T-1}w_j)

w_j=e^{p_j-q_j}

# -*- coding: utf-8 -*-
"""
Created on Wed Nov  8 11:56:26 2023

@author: chengxf2
"""

import numpy as ap
# -*- coding: utf-8 -*-
"""
Created on Fri Nov  3 09:37:32 2023

@author: chengxf2
"""

# -*- coding: utf-8 -*-
"""
Created on Thu Nov  2 19:38:39 2023

@author: cxf
"""
import numpy as np
import random
from enum import Enum

class State(Enum):
    #状态空间#
    shortWater =1 #缺水
    health = 2   #健康
    overflow = 3 #溢水
    apoptosis = 4 #凋亡

class Action(Enum):
    #动作空间A#
    water = 1 #浇水
    noWater = 2 #不浇水
    
class Env():
    
    def reward(self, state):
        #针对转移到新的环境奖赏    
        r = -100
        if state is State.shortWater:
            r =-1
        elif state is State.health:
            r = 1
        elif state is State.overflow:
            r= -1
        else: # State.apoptosis
            r = -100
        return r
            
    
    def action(self, state, action):

         if state is State.shortWater:
         
             if action is Action.water :
                 newState =[State.shortWater, State.health]
                 p =[0.4, 0.6]
             else:
                 newState =[State.shortWater, State.apoptosis]
                 p =[0.4, 0.6]
             
            
         elif state is State.health:
             #健康
             if action is Action.water :
                 newState =[State.health, State.overflow]
                 p =[0.6, 0.4]
             else:
                 newState =[State.shortWater, State.health]
                 p =[0.6, 0.4]
             
         elif state is State.overflow:
             #溢水
             if action is Action.water :
                 newState =[State.overflow, State.apoptosis]
                 p =[0.6, 0.4]
             else:
                 newState =[State.health, State.overflow]
                 p =[0.6, 0.4]
             
         else:  
             #凋亡
                 newState=[State.apoptosis]
                 p =[1.0]
         #print("\n S",S, "\t prob ",proba)
         nextState = random.choices(newState, p)[0]
         r = self.reward(nextState)
         return nextState,r
         

     
    def __init__(self):
         
        self.name = "环境空间"
         
    
     
    
    
    
class Agent():
    
    
    def initPolicy(self):
        #初始化累积奖赏
        self.Q ={} #(state,action) 的累积奖赏
        self.count ={} #(state,action) 执行的次数
    
        for state in self.S:
            for action in self.A:
                self. Q[state, action] = 0.0
                self.count[state,action]= 0

            action = self.randomAction()
            self.policy[state]= Action.noWater #初始化都不浇水
            
    def randomAction(self):
       #随机策略
       action = random.choices(self.A, [0.5,0.5])[0]
       return action
   
    def behaviorPolicy(self):
        
        #使用e-贪心策略
        state = State.shortWater #从缺水开始
        env = Env()
        trajectory ={}#[s0,a0,r0]--[s1,a1,r1]--[sT-1,aT-1,rT-1]
        
        for t in range(self.T):
            #选择策略
            rnd = np.random.rand() #生成随机数
            if rnd <self.epsilon:
                action =self.randomAction()
            else:
                #通过原始策略选择action
                action = self.policy[state] 
            newState,reward = env.action(state, action) 
            trajectory[t]=[state,action,reward]
            state = newState
        
        return trajectory
    
    def calcW(self,trajectory):
        #计算权重
        
        q1 = 1.0-self.epsilon+self.epsilon/2.0 # a== 原始策略
        q2 = self.epsilon/2.0   # a!=原始策略
        
        w ={}
        for t, value in trajectory.items():
            #[state, action,reward]
            action =value[1]
            state = value[0]
            
            if action == self.policy[state]:
                p = 1
                q = q1
            else:
                p = 0
                q = q2
           
            w[t] = round(np.exp(p-q),3)
        #print("\n w ",w)
        return w
                
            
        
        
     

              
 
           
           
    def getReward(self,t,wDict,trajectory):
        
        p = 1.0
        r=  0
        #=[state,action,reward]
        for i in range(t,self.T):
            r+=trajectory[t][-1]
            w =wDict[t]
            p =p*w
        
        R = p*r
        
        m = self.T-t
        
        return R/m
    
    def  improve(self):
       
        a = Action.noWater
        for state in self.S:
             maxR = self.Q[state, a]
             for action in self.A:
                 R = self.Q[state,action]
                 if R>=maxR:
                     maxR = R
                     self.policy[state]= action
                 
                  
            
            
        
        
    def learn(self):
        
        self.initPolicy()
  
  
        
        for s in range(1,self.maxIter): #采样第S 条轨迹
            
               #通过行为策略(e-贪心策略)产生轨迹
               trajectory =self.behaviorPolicy()
               w = self.calcW(trajectory)
               
               print("\n 迭代次数 %d"%s ,"\t 缺水:",self.policy[State.shortWater].name,
                                         "\t 健康:",self.policy[State.health].name,
                                        "\t 溢水:",self.policy[State.overflow].name,
                                        "\t 凋亡:",self.policy[State.apoptosis].name)
               
               #策略评估
               for t in range(self.T):
                   R = self.getReward(t, w,trajectory)
                   state = trajectory[t][0]
                   action = trajectory[t][1]
                   Q = self.Q[state,action]
                   count  = self.count[state, action]
                   
                   self.Q[state,action] = (Q*count+R)/(count+1)
                   self.count[state, action]=count+1
                   
                
               
               #获取权重系数
               self.improve() 

                        

                

    
    def __init__(self):
        
        self.S = [State.shortWater, State.health, State.overflow, State.apoptosis]
        self.A = [Action.water, Action.noWater]
        self.Q ={} #累积奖赏
        self.count ={}
        self.policy ={} #target Policy
        self.maxIter =500
        self.epsilon = 0.2
        self.T = 10


    
if  __name__ == "__main__":
    
     agent = Agent()
     agent.learn()
    

https://img2020.cnblogs.com/blog/1027447/202110/1027447-20211013112906490-1926128536.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1194318.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ros1 基础学习10 -全局字典参数的定义,获取,改值

全局字典参数的定义&#xff0c;获取&#xff0c;改值 一、参数模型二、 创建功能包三、参数命令行的使用(rosparam)四、使用程序来使用参数&#xff08;C&#xff09;4.1创建代码4.2编译4.3 编译文件 测试 在ROS Master中&#xff0c;存在一个参数服务器&#xff08;Parameter…

MPSO-WPA

MPSO-WPA算法 DCAP means ’ discretized Cauchy’s argument principle’ 辅助信息 作者未提供代码

使用github copilot

现在的大模型的应用太广了&#xff0c;作为程序员我们当然野可以借助大模型来帮我们敲代码。 下面是自己注册使用github copilot的过程。 一、注册github copilot 1. 需要拥有github账号 &#xff0c;登录github之后&#xff0c;点右侧自己的头像位置&#xff0c;下面会出现…

【Linux网络】手把手实操Linux系统网络服务DHCP

目录 一、什么是dhcp 二、详解dhcp的工作原理 三、dhcp的实操 第一步&#xff1a;3台机器的防火墙和安全机制都需要关闭&#xff01;&#xff01;&#xff01; 第二步&#xff1a;Linux下载dhcp软件&#xff0c;并查看配置文件位置 第三步&#xff1a;读配置文件&#xf…

(二十七)ATP应用测试平台——基于mybatisplus和aop切面实现数据权限隔离的案例实战

前言 在实际项目开发中&#xff0c;我们经常会用到俩种权限&#xff0c;一种是功能权限&#xff0c;一种是数据权限。功能权限主要是用来限制用户的操作&#xff0c;而数据权限是限制用户能查看到哪些数据。功能权限我们可以使用流行的框架shiro或者spring-security实现&#…

智慧在线拜佛上供品花供果祈福求愿公众号开发

智慧在线拜佛上供品花供果祈福求愿公众号开发 在线点灯祈福&#xff1a;用户可以在线选择点灯祈福的数量和供养的香灯类型&#xff0c;进行祈福祈愿。 上供品花&#xff1a;用户可以选择不同的鲜花供养&#xff0c;包括鲜花种类、数量和价值&#xff0c;以及写上心愿祝福语。 …

VEX —— Intrinsic attribute

目录 查看 使用 PackedGeometry Intrinsic attribute 内在属性是已经被计算的值&#xff08;从几何体派生出来的&#xff09;&#xff0c;可像属性一样访问&#xff1b; 查看 ginfo -I&#xff0c;打印所有内在属性&#xff1b;geometry spreadsheet&#xff0c;查看内在属性…

Windows 10 下使用Visual Studio 2017 编译CEF SDK

1.下载CEF SDK 由于需要跑在32位的机器&#xff0c;所以选择下载32位的SDKCEF Automated Builds 选择 Current Stable Build (Preferred) &#xff0c;这是当前稳定版本&#xff0c;CEF版本118 下载成功解压 2.下载编译工具 CMake 下载地址&#xff1a;CMake 配置CMake指向…

NodeJS 入门笔记

文档地址 课程地址 源码 提取码&#xff1a;963h hello wrold console.log(hello, world);node hello.jsnodejs 中不能使用 DOM(document) 和 BOM(window) 的 API&#xff1a; documentwindowhistorynavigatorlocation 但是下面的 API 是相通的&#xff1a; consoletimer…

AndroidStudio gitee令牌过期 解决方式 remote:Oauth: Access token is expired

记一次&#xff0c;gitee令牌过期 解决方式 Oauth: Access token is expired fatal: unable to access ‘https://gitee.com/xxxx.git/’: The requested URL returned error: 403 remote: [session-e14669a3] Oauth: Access token is expired fatal: unable to access https…

Swift编写爬取商品详情页面的爬虫程序

以下是一个使用Swift编写的基本爬虫程序&#xff0c;该程序使用Selenium库模拟浏览器行为来爬取商品详情页面的内容。 import Foundation import Selenium// 设置爬虫ip信息 let proxyHost "duoip" let proxyPort 8000 let proxy SeleniumProxy(httpProxy: "…

【MSF服务】3389远程连接命令扩展

攻击机IP地址&#xff08;kali&#xff09;&#xff1a;192.168.200.14 靶子机IP地址&#xff08;windows 10&#xff09;&#xff1a;192.168.200.81 前提&#xff1a;获取目标主机系统权限之后的操作 远程连接桌面 rdesktop -u username -p password iprdesktop报错 解决…

lesson4-C++内存管理

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 C/C内存分布 C语言中动态内存管理方式 C中动态内存管理 operator new与operator delete函数 new和delete的实现原理 定位new表达式(placement-new) 常见面试题 C/C内存分布 我们先来看一段代码&#xff1a; int…

【搭建IIS网站教程】

文章目录 一、搭建IIS网站二、http重定向三、虚拟目录四、用域名访问网站五、网站安全六、小知识总结 一、搭建IIS网站 1、Windows Server 2008中配置IIS 打开服务器管理器&#xff0c;角色&#xff0c;添加角色&#xff0c;然后点击下一步 选择安装web服务器iis 选择角色…

纯python代码快速实现简易带界面的数字华容道小游戏

数字华容道是一种经典的益智游戏&#xff0c;旨在通过移动数字方块的位置&#xff0c;将它们按照正确的顺序排列。游戏板由一个4x4的方格组成&#xff0c;其中包含了编号为1到15的数字方块&#xff0c;以及一个空白方块。 游戏开始时&#xff0c;数字方块被随机打乱并填充到方格…

Linux-用户与用户组,权限

1.用户组管理&#xff08;以下命令需root用户执行&#xff09; ①创建用户组 groupadd 用户组名 ②删除用户组 groupdel 用户组名 2.用户管理&#xff08;以下命令需root用户执行&#xff09; ①创建用户 useradd [-g -d] 用户名 >-g&#xff1a;指定用户的组&#xff0c;不…

香橙派5部署chatglm2-6b模型

香橙派5部署chatglm2-6b模型 环境信息&#xff1a; 部署服务器&#xff1a;orangepi 5 16G版本 系统版本&#xff1a;Ubuntu 22.04.3 LTS 参考文档&#xff1a; 利用GPU加速&#xff0c;在Orange Pi上跑LLMs &#xff1a; https://zhuanlan.zhihu.com/p/650110025 遥遥领…

Python语法基础(变量 注释 数据类型 输入与输出 运算符 缩进)

目录 变量变量命名规则变量的类型变量的创建变量的作用域 注释的方法数据类型对象和引用的概念Number(数字)数据转换 输入与输出输入函数输出函数输出函数的end参数输出格式多行语句 运算符算术运算符赋值运算符三目运算符运算符的优先级 缩进缩进格式注意事项层级嵌套 变量 标…

Web实验总

目录 网站需求&#xff1a; 思路&#xff1a; 实验步骤&#xff1a; 第一步&#xff1a;准备工作 第二步&#xff1a;新建一个存储网页的目录 第三步&#xff1a;修改本地hosts映射 第四步&#xff1a;修改配置文件&#xff0c;建立基于http服务的网站 1)创建用户song和…

计算机考研408到底有多难?25届开个好头很有必要

前言 大家好&#xff0c;我是陈橘又青&#xff0c;相信关注我的各位小伙伴们中&#xff0c;大多都是在计算机专业的大学生吧&#xff01; 每天都有许多人在后台私信我&#xff0c;问我要不要考研&#xff0c;我想说这个东西是因人而异的&#xff0c;像我本人就选择了就业&…