强化学习编程实战-1-一个及其简单的强化学习实例(多臂赌博机)
1.1 多臂赌博机
一台拥有K个臂的机器,玩家每次可以摇动K个臂中的一个,摇动后,会吐出数量不等的金币,吐出金币的数量服从一定的概率分布,而且不同臂的概率分布不同。
多臂赌博机的问题是:假设玩家共有N次摇地摇臂的机会,每次如何选择摇动才能使N轮之后得到的金币最多?
对于这个问题,如果提前知道哪个臂吐的金币最多,那么可以每次都摇动那个臂。但是,问题使并不知道那个臂能获得最多金币?该采取什么策略?
1.1.1
-greedy策略
一个很直观的想法:既然不知道哪个臂吐的金币最多,那么可以先对每个臂都尝试几次(如都10次),找出那个臂吐出的金币最多,然后一直摇动它。
其实这个最简单、最朴素的想法已经蕴含了算法学习最基本的两个过程:采集数据和学习。首先,对每个臂进行尝试就是采集数据,其次,学习就是利用这些数据知道哪个臂回吐出最多的金币。一个最简单的方法就是计算每个臂的平均吐钱数量,然后,一直摇那个臂。
我们可以将这个算法用形式化的代数来表示。用s表示当前赌博机,用A表示可以选择的动作,即A={1,2,3}。其中a=1表示摇动第一个臂,依次类推。用回报表示摇动赌博机的摇臂后获得的金币的数目。用Q(a)表示摇动动作a获得的金币的平均回报,则
,其中n为摇动动作的总次数。R(a)为摇动动作a的总回报。
算法的伪代码
1-3行:初始化每个动作的总回报R(a),以及摇动该动作的次数N(a)。
4-6行:每个臂都尝试次,计算每个摇臂总的金币数。
7-9行:算出使得总回报最大的那个臂,然后一直摇动它。
这是一个简单、朴素的想法,但并不是一个好的算法。原因如下:缺点
(1)不应该以总回报最大为目的来选择当前哪个臂,而是应该选择当前平均回报最大的臂。
(2)不应该只摇动当前平均回报最大的臂,因为它不一定使最好的那个臂。所以,我们除了关注当前平均回报最大的臂,还要保留一定的概率去摇动其他的臂,以便发现更好的臂。
以上两点对应着强化学习算法中最重要的概念:利用策略和探索策略平衡。
利用:exploitation,是利用当前的数据总结得到的最好的策略,采用该策略,我们可以得到较高的回报。
探索:exploration,该策略可以帮我们找到更好的臂,甚至找到最优的臂。
强化学习算法在训练的过程中所用到的策略是平衡了利用和探索的策略,最常见的是-greedy策略,公式表示:
该策略,在每次选择摇动哪个臂时,应该以1-的概率去摇动当前平均值最大的臂,以
的概率在所有动作中均匀随机地选择动作。这样可以在有限的次数中得到尽可能多的回报,同时不失去找到最好的臂的机会。
第1-4行:初始化总回报R(a),初始化每个动作的平均回报Q(a),每个动作的次数N(a).
第6行:在每次摇臂之前,采用-greedy策略,选择要摇动的臂a。
第7行:动作a的次数N(a)+1.
第8行:根据动作a和环境返回的回报(a),更新动作a的平均回报。
第9行:计算总的收益。
第10行:玩家尝试N次之后,返回总的收益。
在多臂赌博机中,平衡利用和探索的策略还有玻尔兹曼策略和UCB策略。
1.1.2 玻尔兹曼策略
e-greedy策略给对应值函数最大的那个动作一个比较大的概率,而其他动作,不管值函数的大小如何,被采样的概率都是相等。
但这中概率的分配策略不太合理。按理说,非贪婪的动作也有好坏之分,那些对应值函数大的动作应该比那些对应值函数小的动作采样的概率大。于是玻尔兹曼策略根据值函数对动作的采样的概率进行了软处理,表示下式1-2为
其中为温度调节参数,可以用来调节探索和利用和比例。
越小,玻尔兹曼越接近贪婪策略,利用所占的比例越大,探索越少。反之,探索越多。伪代码只需替换图1-3中的e-greedy策略为公式1-2.
1.1.3 UCB策略
UCB(Upper Confidence Boundn)置信上限。在统计学中常常用置信区间来表示不确定性。在这里,我们用置信区间来表示探索。
UCB策略公式
其中t为当前摇臂动作的总次数,N(a)为动作a的总次数。
下图为3种策略,总回报和摇动次数之后的关系。e-greedy策略回报最低,但却是形式最简单、最通用,可广泛用于各种任务的学习和探索训练中。
1.2 多臂赌博机代码实现
基于上文提到的三种学习策略。
①首先,我们先创建一个KB_Game类,
②在类KB_Game中定义方法step(),用于模拟多臂赌博机如何给出回报。该方法的输入为动作,输出为回报。用正态分布来模拟玩家在每次摇动摇臂后得到的回报。step()方法实际上提供了多臂赌博机的模拟器。
③接下来,实现3种选择动作的策略方法choose_action().该方法的输入参数为测量类别policy,有3种,对应上文的三种策略e_greedy,ucb和boltzmann.另外还有一个参数字典**kwargs,对应传递相应的策略的所对应超参数,如e-greedy策略中的epsilon,UCB策略中的超参数c_ratio,以及玻尔兹曼中的温度‘temperature'.UCB算法的每一步是依次摇动每个臂,因此在程序中对应的代码为判断每个动作的次数,如果有等于零的,那么选择该动作。
④有了模拟器和动作选择策略,下面就可以通过交互进行学习训练。定义方法train().该方法的输入参数有play_total(表示训练的总次数),policy(训练的策略),**kwargs(相应策略的超参数字典).
⑤智能体通过学习的策略选择动作,然后将动作传给step()方法,相当于跟多臂赌博机进行了一次交互,从多臂赌博机中获得回报r,智能体根据立即回报更新每个动作的平均回报q,计算当前的累计回报并作相应的保存。
⑥在每次训练新的策略的时候,我们需要将类KB_Game中的成员变量进行重置,定义reset()方法进行重置,重置的变量有平均回报q,各动作的次数action_counts,当前的累积回报current_cumulative_reward,玩家尝试的次数counts,玩家尝试的历史counts_history、玩家累积回报的历史cumulative_rewards_history、动作a、回报reward。
⑦为了更直观比较3种不同策略的学习性能,需要画图展示,我们用方法plot()来实现。得到如下的结果。显然ucb比其他两个策略要好。
代码如下
import numpy as np
import matplotlib.pyplot as plt
class KB_Game:def __init__(self,*args,**kwargs):self.q=np.array([0.0,0.0,0.0]) #每个臂的平均回报self.action_counts=np.array([0,0,0]) #摇动每个臂的次数self.current_cumulative_rewards=0.0 #当前累积回报总和self.actions=[1,2,3] #3个不同的摇臂self.counts=0 #玩家玩游戏的次数self.counts_history=[] #玩家而玩游戏的次数记录self.cumulative_rewards_history=[] #累积回报的记录self.a=1 #玩家当前动作,初始化为1,摇第一个摇臂self.reward=0 #当前回报,初始值为0def step(self,a):#模拟器r=0if a==1:r=np.random.normal(1,1) #正态分布,均值为1,方差为1if a==2:r=np.random.normal(2,1)if a==3:r=np.random.normal(1.5,1)return rdef choose_action(self,policy,**kwargs): #动作策略action=0if policy=='e_greedy':if np.random.random()<kwargs['epsilon']:action=np.random.randint(1,4)else:action=np.argmax(self.q)+1if policy=='ucb':c_ratio=kwargs['c_ratio']if 0 in self.action_counts:action=np.where(self.action_counts==0)[0][0]+1else:value=self.q+c_ratio*np.sqrt(np.log(self.counts)/self.action_counts)action=np.argmax(value)+1if policy=='boltzmann':tau=kwargs['temperature']p=np.exp(self.q/tau)/(np.sum(np.exp(self.q/tau)))action=np.random.choice([1,2,3],p=p.ravel())return actiondef train(self,play_total,policy,**kwargs):reward_1=[]reward_2=[]reward_3=[]for i in range(play_total):action=0if policy=='e_greedy':action=self.choose_action(policy,epsilon=kwargs['epsilon'])if policy=='ucb':action=self.choose_action(policy,c_ratio=kwargs['c_ratio'])if policy=='boltzmann':action=self.choose_action(policy,temperature=kwargs['temperature'])self.a=action#print(self.a)#与环境交互一次self.r=self.step(self.a)self.counts+=1#更新值函数self.q[self.a-1]=(self.q[self.a-1]*self.action_counts[self.a-1]+self.r)/(self.action_counts[self.a-1]+1)self.action_counts[self.a-1]+=1reward_1.append([self.q[0]])reward_2.append([self.q[1]])reward_3.append([self.q[2]])self.current_cumulative_rewards+=self.rself.cumulative_rewards_history.append(self.current_cumulative_rewards)self.counts_history.append(i)def reset(self):self.q=np.array([0.0,0.0,0.0]) #每个臂的平均回报self.action_counts=np.array([0,0,0]) #摇动每个臂的次数self.current_cumulative_rewards=0.0 #当前累积回报总和self.counts=0 #玩家玩游戏的次数self.counts_history=[] #玩家而玩游戏的次数记录self.cumulative_rewards_history=[] #累积回报的记录self.a=1 #玩家当前动作,初始化为1,摇第一个摇臂self.reward=0 #当前回报,初始值为0def plot(self,colors,policy,style):plt.figure(1) #创建画布plt.plot(self.counts_history,self.cumulative_rewards_history,colors,label=policy)plt.legend() #加上图列plt.xlabel('n',fontsize=18)plt.ylabel('total rewards',fontsize=18)if __name__=='__main__':np.random.seed(0)k_gamble=KB_Game()total=2000k_gamble.train(play_total=total,policy='e_greedy',epsilon=0.05)k_gamble.plot(colors='r',policy='e_greedy',style='-.')k_gamble.reset()k_gamble.train(play_total=total,policy='boltzmann',temperature=1)k_gamble.plot(colors='b',policy='boltzmann',style='--')k_gamble.reset()k_gamble.train(play_total=total,policy='ucb',c_ratio=0.5)k_gamble.plot(colors='g',policy='ucb',style='-')plt.show()
相关文章:

强化学习编程实战-1-一个及其简单的强化学习实例(多臂赌博机)
1.1 多臂赌博机 一台拥有K个臂的机器,玩家每次可以摇动K个臂中的一个,摇动后,会吐出数量不等的金币,吐出金币的数量服从一定的概率分布,而且不同臂的概率分布不同。 多臂赌博机的问题是:假设玩家共有N次摇地…...

Golang语法规范和风格指南(一)——简单指南
1. 前引 一个语言的规范的学习是重要的,直接关系到你的代码是否易于维护和理解,同时学习好对应的语言规范可以在前期学习阶段有效规避该语言语法和未知编程风格的冲突。 这里是 Google 提供的规范,有助于大家在开始学习阶段对 Golang 进行一…...

数据机构记录顺序表-笔记1
一、线性表的基本概念 数据元素:线性表中的基本单位,每个元素都是线性表的一部分。 数据项:数据元素的具体值。 存储位置:线性表中的元素在内存中的具体存储位置。 线性表按存储结构可以分为顺序表和链表两大类: 1.1…...

考研必备~总结严蔚敏教授《数据结构》课程的重要知识点及考点
作者主页:知孤云出岫 目录 1. 基本概念1.1 数据结构的定义1.2 抽象数据类型 (ADT) 2. 线性表2.1 顺序表2.2 链表 3. 栈和队列3.1 栈3.2 队列 4. 树和二叉树4.1 树的基本概念4.2 二叉树 5. 图5.1 图的基本概念5.2 图的遍历 6. 查找和排序6.1 查找6.2 排序 7. 重点考…...

【数据分享】国家级旅游休闲街区数据(Excel/Shp格式/免费获取)
之前我们分享过从我国文化和旅游部官网整理的2018-2023年我国50个重点旅游城市星级饭店季度经营状况数据(可查看之前的文章获悉详情)!文化和旅游部官网上也分享有很多与旅游相关的常用数据,我们基于官网发布的名单文件整理得到全国…...

Linux开发:进程间通过Unix Domain Socket传递数据
进程间传递数据的方式有很多种,Linux还提供一种特殊的Socket用于在多进程间传递数据,就是Unix Domain Socket(UDS)。 虽然通过普通的Socket也能做到在多进程间传递数据,不过这样需要通过协议栈层的打包与拆包,未免有些浪费效率,通过UDS,数据仅仅通过一个特殊的sock文件…...

Redis基础教程(九):redis有序集合
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝Ὁ…...

Servlet与Servlet容器
什么是Servlet? Servlet是Java EE(现称Jakarta EE)中的一个组件,通常用于创建动态Web内容。Servlet是运行在Web服务器上的Java程序,它处理客户端的请求并生成响应。Servlet的核心功能是处理HTTP请求和响应。下面是一个servlet例…...

腾讯centos mysql安装
腾讯centos mysql安装 腾讯云提供了一系列的云计算服务,包括操作系统、数据库、服务器等。在腾讯云上安装CentOS操作系统和MySQL数据库可以按照以下步骤进行: 登录腾讯云控制台(登录 - 腾讯云)。在控制台页面上方的搜索框中输入…...

c_各个unsigned int 和 int的取值范围
bool, uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t 取值范围分别是什么? 定义形式: typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long uint64_…...

C#/WPF 自制截图工具
在日常使用电脑办公时,我们经常遇到需要截图然后保存图片,我们往往需要借助安装截图工具才能实现,现在我们通过C#自制截图工具,也能够轻松进行截图。 我们可以通过C#调用WindousAPI来实现截图,实例代码如下:…...

以腾讯为例,手把手教你搭建产品帮助中心
一个精心设计的产品帮助中心对于提高用户满意度和体验至关重要。腾讯,作为全球领先的互联网企业,通过其多样化的产品线(包括微信、QQ、腾讯游戏、腾讯视频等)吸引了亿万用户。下面将以腾讯为例,向您展示如何搭建一个高…...

计算机网络概述--自我学习用
计算网络体系概述 相关问题 计算机网络为什么要分层?计算机网络是怎么分层的?三种计算机网络模型的关系是什么?每一层分别包含哪些协议?计算机网络中,数据如何在各层中传播?数据在网络各层中的存在形式是…...

超级好用的java http请求工具
kong-http 基于okhttp封装的轻量级http客户端 使用方式 Maven <dependency><groupId>io.github.kongweiguang</groupId><artifactId>kong-http</artifactId><version>0.1</version> </dependency>Gradle implementation …...

在原有的iconfont.css文件中加入新的字体图标
前言:在阿里图标库中,如果你没有这个字体图标的线上项目,那么你怎么在本地项目中的原始图标文件中添加新的图标呢? 背景:现有一个vue项目,下面是这个前端项目的字体图标文件。现在需要新开发功能页&#x…...

使用 ESP32-WROOM + DHT11 做个无屏温湿度计
最近梅雨天,有个房间湿度很大,而我需要远程查看温湿度,所以无所谓有没有显示屏,某宝上的温湿度计都是带屏的,如果连WIFI查看温湿度操作也比较麻烦,还需要换电池,实在不能满足我的需求࿰…...

如何使用 SwiftUI 构建 visionOS 应用
文章目录 前言WindowsVolumes沉浸式空间结论 前言 Apple Vision Pro 即将推出,现在是看看 SwiftUI API 的完美时机,这使我们能够将我们的应用程序适应 visionOS 提供的沉浸式世界。苹果表示,构建应用程序的最佳方式是使用 Swift 和 SwiftUI。…...

InspireFace-商用级的跨平台开源人脸分析SDK
InspireFace-商用级的跨平台开源人脸分析SDK InspireFaceSDK是由insightface开发的⼀款⼈脸识别软件开发⼯具包(SDK)。它提供了⼀系列功能,可以满⾜各种应⽤场景下的⼈脸识别需求,包括但不限于闸机、⼈脸⻔禁、⼈脸验证等。 该S…...

华为HCIP Datacom H12-821 卷24
1.单选题 企业大楼有大量员工通常都在上班时在大厅开始接入到公司的WLAN网络,随着每位员工走到各自的工位过程中,每个人的移动端叶通过漫游的方式漫游到各自的网络覆盖区域。为了尽量保证每个终端的IP地址是固定的,建议的做法是? A、配置VLAN Pool并配置顺序算法 B、…...

TikTok马来西亚直播网络怎么配置?
TikTok是一款全球流行的社交媒体应用,在东南亚地区拥有大量用户。在马来西亚这个多元化的国家,配置高效稳定的直播网络对TikTok的运营至关重要。 配置马来西亚直播网络的必要性 广泛的地理覆盖:马来西亚包括大片陆地和众多岛屿,网…...

基于若依的文件上传、下载
基于若依实现文件上传、下载 文章目录 基于若依实现文件上传、下载1、前端实现-文件上传1.1 通用上传分析1.2 修改实现上传接口 2、后端实现-文件上传3、后端实现-文件下载4、前端实现-文件下载 官网其实也写了,但是我是自己改造封装了一下,再次迈向全栈…...

论文回顾 | CVPR 2021 | How to Calibrate Your Event Camera | 基于图像重建的事件相机校准新方法
论文速览 | CVPR 2021 | How to Calibrate Your Event Camera | 基于图像重建的事件相机校准新方法 1 引言 在计算机视觉和机器人领域,相机校准一直是一个基础而又重要的问题。传统的相机校准方法主要依赖于从已知校准图案中提取角点,然后通过优化算法求解相机的内参和外参。这…...

高级java每日一道面试题-2024年7月1日
题目:请解释 Java 中的内存泄漏,并说明如何检测和避免内存泄漏。 答案: 内存泄漏指的是程序中不再使用的对象,由于某些原因没有被垃圾回收器回收,仍然占据着内存空间,导致可用内存逐渐减少,最…...

当需要对多个表进行联合更新操作时,怎样确保数据的一致性?
文章目录 一、问题分析二、解决方案三、示例代码(以 MySQL 为例)四、加锁机制示例五、测试和验证六、总结 在数据库管理中,经常会遇到需要对多个表进行联合更新的情况。这种操作带来了一定的复杂性,因为要确保在整个更新过程中数据…...

数据结构-线性表的应用
目录 前言一、有序表的合并1.1 顺序表实现1.2 单链表实现 二、稀疏多项式的相加和相乘2.1 稀疏多项式的相加2.2 稀疏多项式的相乘 总结 前言 本篇文章介绍线性表的应用,分别使用顺序表和单链表实现有序表的合并,最后介绍如何使用单链表实现两个稀疏多项…...

cpp http server/client
httplib 使用httplib库 basedemo server.cpp #include "httplib.h" #include <iostream> using namespace httplib;int main(void) {Server svr;svr.Get("/hello", [](const Request& req, Response& res) {std::cout << "lo…...

昇思25天学习打卡营第2天|MindSpore快速入门
打卡 目录 打卡 快速入门案例:minist图像数据识别任务 案例任务说明 流程 1 加载并处理数据集 2 模型网络构建与定义 3 模型约束定义 4 模型训练 5 模型保存 6 模型推理 相关参考文档入门理解 MindSpore数据处理引擎 模型网络参数初始化 模型优化器 …...

django之url路径
方式一:path 语法:<<转换器类型:自定义>> 作用:若转换器类型匹配到对应类型的数据,则将数据按照关键字传参的方式传递给视图函数 类型: str: 匹配除了”/“之外的非空字符串。 /test/zvxint: 匹配0或任何…...

【OnlyOffice】桌面应用编辑器,插件开发大赛,等你来挑战
OnlyOffice,桌面应用编辑器,最近版本已从8.0升级到了8.1 从PDF、Word、Excel、PPT等全面进行了升级。随着AI应用持续的火热,OnlyOffice也在不断推出AI相关插件。 因此,在此给大家推荐一下OnlyOffice本次的插件开发大赛。 详细信息…...

[学习笔记]SQL学习笔记(连载中。。。)
学习视频:【数据库】SQL 3小时快速入门 #数据库教程 #SQL教程 #MySQL教程 #database#Python连接数据库 目录 1.SQL的基础知识1.1.表(table)和键(key)1.2.外键、联合主键 2.MySQL安装(略,请自行参考视频)3.基本的MySQL语法3.1.规…...