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

前言:

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

     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.mfbz.cn/a/127401.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【K8s集群离线安装-kubeadm】

1、kubeadm概述 kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。这个工具能通过两条指令快速完成一个kubernetes集群的部署。 2、环境准备 2.1 软件环境 软件版本操作系统CentOS 7Docker19.03.13K8s1.23 2.2 服务器 最小硬件配置&#xff1a;2核CPU、2G内存…

19.5 Boost Asio 传输结构体

同步模式下的结构体传输与原生套接字实现方式完全一致&#xff0c;读者需要注意的是在接收参数是应该使用socket.read_some函数读取&#xff0c;发送参数则使用socket.write_some函数实现&#xff0c;对于套接字的解析同样使用强制指针转换的方法。 服务端代码如下所示 #incl…

「Verilog学习笔记」4位数值比较器电路

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 分析 这里要注意题目的“门级描述方式”&#xff0c;所以我们只能使用基本门电路&#xff1a;&,|,!,^,^~。 具体实现思路&#xff1a;通过真值表得出Y0 Y1 Y2的逻辑表达…

Vue3使用vue-print-nb插件打印功能

插件官网地址https://www.npmjs.com/package/vue-print-nb 效果展示: 打印效果 根据不同的Vue版本安装插件 //Vue2.0版本安装方法 npm install vue-print-nb --save pnpm install vue-print-nb --save yarn add vue-print-nb//Vue3.0版本安装方法&#xff1a; npm install vue3…

优思学院|CTP和CTQ是什么?有什么区别?

CTQ 关键质量特性 CTQ是在六西格玛管理中常用的重要词汇&#xff0c;所以很多不同界别的人仕都可能听过&#xff0c;CTQ的意思是关键质量特性&#xff0c;Critical To Quality 的缩写。 六西格玛管理提倡的方法是通过客户的声音 (Voice of customer-VOC) &#xff0c;然后把它…

绝对力作:解锁string的所有关键接口,万字深度解析!

W...Y的主页 &#x1f60a; &#x1f354;前言&#xff1a; 通过博主的上篇文章&#xff0c;我相信大家已经认识了STL并且已经迫不及待想学习了&#xff0c;现在我们就走近STL的第一种类——string。 目录 为什么学习string类&#xff1f; C语言中的字符串 标准库中的str…

使用 Socks5 来劫持 HTTPS(TCP-TLS) 之旅

MITM 劫持的过程中&#xff0c;HTTP 协议并不是唯一选择。 实际在 MITM 使用过程中&#xff0c;BurpSuite 和 Yakit 提供的交互式劫持工具只能劫持 HTTP 代理的 TLS 流量&#xff1b;但是这样是不够的&#xff0c;有时候我们并不能确保 HTTP 代理一定生效&#xff0c;或者说特…

【js逆向实战】某sakura动漫视频逆向

写在前面 再写一个逆向实战&#xff0c;后面写点爬虫程序来实现一下。 网站简介与逆向目标 经典的一个视频网站&#xff0c;大多数视频网站走的是M3U8协议&#xff0c;就是一个分段传输&#xff0c;其实这里就有两个分支。 通过传统的m3u8协议&#xff0c;我们可以直接进行分…

python回文日期 并输出下一个ABABBABA型回文日期

题目&#xff1a; 输入&#xff1a; 输入包含一个八位整数N&#xff0c;表示日期 对于所有的测评用例&#xff0c;10000101 ≤N≤89991231&#xff0c;保证N是一个合法日期的8位数表示 输出&#xff1a; 输出两行&#xff0c;每行一个八位数。第一行表示下一个回文日期第二…

【论文阅读】DALL·E: Zero-Shot Text-to-Image Generation

OpenAI第一代文本生成图片模型 paper&#xff1a;https://arxiv.org/abs/2102.12092 DALLE有120亿参数&#xff0c;基于自回归transformer&#xff0c;在2.5亿 图片-文本对上训练的。实现了高质量可控的text to image&#xff0c;同时也有zero-shot的能力。 DALL-E没有使用扩…

【腾讯云 HAI域探秘】探索AI绘画之路:利用腾讯云HAI服务打造智能画家

目录 前言1 使用HAI服务作画的步骤1.1 注册腾讯云账户1.2 创建算力服务器1.3 进入模型管理界面1.4 汉化界面1.5 探索AI绘画 2 模型参数的含义和调整建议2.1 模型参数的含义和示例2.2 模型参数的调整建议 3 调整参数作画的实践和效果3.1 实践说明3.2 实践效果13.3 实践效果23.4 …

专门为Web应用程序提供安全保护的设备-WAF

互联网网站面临着多种威胁&#xff0c;包括网络钓鱼和人为的恶意攻击等。这些威胁可能会导致数据泄露、系统崩溃等严重后果。 因此&#xff0c;我们需要采取更多有效的措施来保护网站的安全。其中WAF&#xff08;Web application firewall&#xff0c;Web应用防火墙&#xff0…

网站接口测试记录

1.被测试服务器端口输入htop指令进行cpu监控 2.测试机器安装宝塔-》我的工具-》进行网站测试 访问地址&#xff1a;https://www.bt.cn/bbs/thread-52772-1-1.html

Spring Cloud智慧工地管理平台源码,智慧工地APP源码,实现对劳务人员、施工进度、工地安全、材料设备、环境监测等方面的实时监控和管理

智慧工地管理平台源码&#xff0c;智慧工地APP源码&#xff0c; 智慧工地管理平台实现对人员管理、施工进度、安全管理、材料管理、设备管理、环境监测等方面的实时监控和管理&#xff0c;提高施工效率和质量&#xff0c;降低安全风险和环境污染。智慧工地平台支持项目级、公司…

SpringCloud——负载均衡——Ribbon

负载均衡分为集中式LB(Nginx实现)和进程内LB(Ribbon)。 Ribbon简单来说就是负载均衡RestTemplate调用。 1.Ribbon在工作中分成两步 1.先选择EurekaServer&#xff0c;它优先选择在同一个区域内负载较少的EurekaServer。 2.在根据用户指定的策略&#xff0c;从服务注册的列表…

Go 什么是循环依赖

Go 中的循环依赖是指两个或多个包之间相互引用&#xff0c;形成了一个循环依赖关系。这种情况下&#xff0c;包 A 依赖包 B&#xff0c;同时包 B 也依赖包 A&#xff0c;导致两个包之间无法明确地确定编译顺序&#xff0c;从而可能引发编译错误或其他问题。循环依赖是 Go 中需要…

js实现向上、向下、向左、向右无缝滚动

向左滚动 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, ini…

ClickHouse Keeper: Coordination without the drawbacks没有缺点的分布式协作系统

ClickHouse Keeper 介绍 现代分布式系统需要一个共享和可靠的信息存储库和共识系统来协调和同步分布式操作。对于ClickHouse来说&#xff0c;ZooKeeper最初是被选中的。它的广泛使用是可靠的&#xff0c;提供了简单而强大的API&#xff0c;并提供了合理的性能。 然而&#xf…

三菱FX3U系列-定位指令

目录 一、简介 二、指令形式 1、相对定位[DRVI、DDRVI] 2、绝对定位[DRVA、DDRVA] 三、总结 一、简介 定位指令用于控制伺服电机或步进电机的位置移动。可以通过改变脉冲频率和脉冲数量来控制电机的移动速度和移动距离&#xff0c;同时还可以指定移动的方向。 二、指令形…

【K-means聚类算法】实现鸢尾花聚类

文章目录 前言一、数据集介绍二、使用步骤1.导包1.2加载数据集1.3绘制二维数据分布图1.4实例化K-means类&#xff0c;并且定义训练函数1.5训练1.6可视化展示2.聚类算法2.1.可视化生成3其他聚类算法进行鸢尾花分类 前言 例如&#xff1a;随着人工智能的不断发展&#xff0c;机器…