Pytorch深度强化学习1-2:详解K摇臂赌博机模型和ϵ-贪心算法

news/2024/5/19 0:11:14 标签: pytorch, 人工智能, 强化学习, 机器人, python

目录

0 专栏介绍

本专栏重点介绍强化学习技术的数学原理,并且采用Pytorch框架对常见的强化学习算法、案例进行实现,帮助读者理解并快速上手开发。同时,辅以各种机器学习、数据处理技术,扩充人工智能的底层知识。

🚀详情:《Pytorch深度强化学习


1 K-摇臂赌博机

单步强化学习是最简单的强化学习模型,其以贪心策略为核心最大化单步奖赏

如图所示,单步强化学习的理论模型是 K K K-摇臂赌博机( K K K-armed bandit),描述如下: K K K-摇臂赌博机有 K K K个摇臂,赌徒在投入一个硬币后可选择按下其中一个摇臂,每个摇臂以一定的概率吐出硬币(硬币数量来自一个赌徒未知的概率分布),因此仅通过一次试验并不能确切地了解摇臂的奖赏期望,赌徒的目标是通过一定的策略最大化自己的奖赏,即获得最多的硬币。 K K K-摇臂赌博机问题抽象为强化学习任务后,摇臂即为某个状态下对应的 K K K个动作;硬币即为该状态下执行某动作后的奖赏值


在这里插入图片描述

针对 K K K-摇臂赌博机问题有两种思路:

  • 仅探索法(exploration-only):将所有的尝试机会平均分配给每个摇臂,即轮流按下每个摇臂若干次,最后以每个摇臂各自的平均吐币数作为奖赏期望的近似估计;
  • 仅利用法 (exploitation-only):按下目前最优的——到目前为止平均奖赏最大的摇臂,若有多个摇臂同为最优,则从中随机选取一个

以上两种思路相互矛盾,构成强化学习所面临的探索-利用窘境(Exploration-Exploitation dilemma):仅探索法能很好地估计每个摇臂的性能,却会失去很多选择最优摇臂的机会;仅利用法局部性能较好,但因为过于贪心无法衡量各个摇臂,因此很可能选不到最优摇臂。这两种思路都难以使最终的累积奖赏最大化,欲使累积奖赏最大,则必须在探索与利用之间达成较好的折中。

在这里插入图片描述

K K K-摇臂赌博机应用在离散状态空间、动作空间上一般强化学习任务的方式是:将每个状态上动作的选择看作一个 K K K-摇臂赌博机问题,对每个状态分别记录各动作的尝试次数、当前平均累积奖赏等信息,训练一定次数后,即可基于赌博机算法进行动作决策。但是这种做法没有考虑强化学习任务马尔科夫决策过程的结构,具有局限性

2 ϵ \epsilon ϵ-贪心算法

ϵ \epsilon ϵ-贪心算法基于一个概率 ϵ \epsilon ϵ来对探索和利用进行折中:每次尝试时以 ϵ \epsilon ϵ的概率进行探索,此时以均匀概率随机选取一个动作;以 1 − ϵ 1-\epsilon 1ϵ的概率进行利用,此时选择当前平均奖赏最高的动作(若有多个,则随机选取一个)。若动作奖赏的不确定性较大则需更多的探索,此时需要较大的 ϵ \epsilon ϵ值;反之若动作奖赏的不确定性较小,则少量的尝试就能很好地近似真实奖赏,此时需要较小的 ϵ \epsilon ϵ值即可。通常可令 ϵ \epsilon ϵ随尝试次数的增加而逐渐减小,例如令

ϵ = 1 / t \epsilon ={{1}/{\sqrt{t}}} ϵ=1/t

在这里插入图片描述

3 softmax算法

Softmax算法基于当前已知的动作平均奖赏来对探索和利用进行折中:若各动作的平均奖赏相当,则选取各动作的概率也相当;若某些动作的平均奖赏明显高于其他动作,则它们被选取的概率也明显更高。其中温度 τ > 0 \tau >0 τ>0趋于0算法趋于仅利用;趋于无穷大算法趋于仅探索。

在这里插入图片描述

4 Python实现与分析

首先我们先模拟一个 K K K-摇臂赌博机

python">class Bandit:
    def __init__(self) -> None:
        self.k = 0
        self.handler = []
    
    # @breif:添加摇臂
    def addHandler(self, pList, vList):
        h = BanditHandler(pList, vList)
        self.handler.append(h)
        self.k = self.k + 1
    
    # @breif:删除摇臂
    def delHandler(self, i):
        if i > self.k - 1:
            print("handler index i is invalid! i should be less than k!")
        else:          
            self.handler.pop(i)
            self.k = self.k - 1  

    # @breif: 选择摇臂i并弹出奖赏
    def getReward(self, i):
        if i > self.k - 1:
            print("handler index i is invalid! i should be less than k!")
        else:          
            return self.handler[i].pull()

接着实现上述的四种算法

  • 仅探索法

    python">def explorationOnly(self, T):
        # 累计奖赏
        r = 0
        rList = []
        # 完全随机选取摇臂
        for i in range(T):
            hIndex = random.randint(0, self.kBandit.k - 1)
            r = r + self.kBandit.handler[hIndex].pull()
            rList.append(r / (i + 1))
        return rList
    
  • 仅利用法

    python">def exploitationOnly(self, T):
        # 累计奖赏
        r = 0
        rList = []
        # 各摇臂平均奖赏初始化
        g = [0 for i in range(self.kBandit.k)]
        # 各摇臂选中次数初始化
        count = [0 for i in range(self.kBandit.k)]
        for i in range(T):
            hIndex = g.index(max(g))
            v = self.kBandit.handler[hIndex].pull()
            r = r + v
            g[hIndex] = (g[hIndex] * count[hIndex] + v) / (count[hIndex] + 1)
            count[hIndex] = count[hIndex] + 1
            rList.append(r / (i + 1))
        return rList
    
  • ϵ \epsilon ϵ-贪心算法

    python">def eGredy(self, T, e):
        # 累计奖赏
        r = 0
        rList = []
        # 各摇臂平均奖赏初始化
        g = [0 for i in range(self.kBandit.k)]
        # 各摇臂选中次数初始化
        count = [0 for i in range(self.kBandit.k)]
        for i in range(T):
            if random.random() < e:
                hIndex = random.randint(0, self.kBandit.k - 1)
            else:
                hIndex = g.index(max(g))
            v = self.kBandit.handler[hIndex].pull()
            r = r + v
            g[hIndex] = (g[hIndex] * count[hIndex] + v) / (count[hIndex] + 1)
            count[hIndex] = count[hIndex] + 1
            rList.append(r / (i + 1))
        return rList
    

在本案例中,各个算法计算迭代若干次后的平均奖励曲线如图所示

在这里插入图片描述

本文完整工程代码请通过下方名片联系博主获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《Pytorch深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

http://www.niftyadmin.cn/n/1008760.html

相关文章

JS中的异步与Promise使用

同步与异步 我们知道JS是一个单线程的语言&#xff0c;即在同一时间只能做一件事情。为什么设计为当线程呢。&#xff1f;在早期JS是为了在浏览器中运行&#xff0c;我们可以利用JS来制作一些页面的效果也可以和用户做一些交互。所以设计为单线程也是为了避免复杂度。比如在网…

给nginx配置站点访问密码

当我们的站点需要账密才能访问时&#xff0c;可以借助nginx来简单配置。 1. 安装apache2-utils 模块 sudo apt update sudo apt upgrade -y sudo apt install apache2-utils 2.设置一个账密文件 这条命令会要求输入密码和再次确认密码&#xff0c;这个密码就是登录密码。 …

文件操作 -- C语言

在之前学习的时候&#xff0c;我们可以发现当程序运行完&#xff0c;我们之前保存的数据就会消失&#xff0c;再次运行时还得重新输入&#xff0c;为了使我们保存的数据在下次运行时还能使用&#xff0c;我们这篇文章来学习一下怎么使用文件操作&#xff0c;将我们的数据保存在…

简单三步完成离线升级TIDB v7.1(服务器无互联网环境)

作者&#xff1a; bert 原文来源&#xff1a; https://tidb.net/blog/e35af409 离线升级使用场景 我们知道&#xff0c;大多数公司的生产服务器的安全策略都不太允许连接互联网。加上TIDB的版本更新迭代非常快&#xff0c;默认适用升级需要连接互联网下载升级包部署。因此在…

【Flask】SQLAlchemy

文章目录 SQLAlchemy是什么为什么使用orm定义安装组成部分SQLAlchemy本身无法操作数据库&#xff0c;其必须以来pymsql等第三方插件 SQLAlchemy的使用原生sql使用orm映射数据表 外键关系一对多(ForeignKey)多对多 使用orm操作记录简单表操作基于scoped_session实现线程安全 CRU…

TCP的三次握手,四次挥手

1.TCP协议介绍 传输控制协议&#xff08;TCP&#xff0c;Transmission Control Protocol&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。由IETF的RFC 793 [1] 定义…

【linux】一些linux系统下的常用命令(本地使用、远程服务器连接常用)

一些linux常用命令 linux 常用命令打开某个文件夹查看某个目录的所有内容复制文件命令移动命令创建文件夹删除文件或目录当前目录创建文件找文件/文件夹查看目录或文件夹大小更改文件或目录权限查看文件内容之vim查看之前输入的命令行下载某个东西到某个位置解压缩查看CPU占用情…

OpenCV(加载、修改、保存图像)

目录 1、图像加载 2、显示图像 3、修改图像 4、图像保存 OpenCV官方文档查询地址&#xff1a;OpenCV: OpenCV modules 1、图像加载 加载图像&#xff08;用cv::imread )imread功能是加载图像文件成为一个Mat对象&#xff0c;其中第一个参数表示图像文件名称 第二个参数&…