從代碼學習深度強化學習 - 多臂老虎機 PyTorch版

文章目錄

  • 前言
  • 創建多臂老虎機環境
  • 多臂老虎機算法基本框架(基類)
  • 1. ε-貪心算法 (Epsilon-Greedy)
  • 2. 隨時間衰減的ε-貪婪算法 (Decaying ε-Greedy)
  • 3. 上置信界算法 (Upper Confidence Bound, UCB)
  • 4. 湯普森采樣算法 (Thompson Sampling)
  • 總結


前言

歡迎來到“從代碼學習深度強化學習”系列!在本篇文章中,我們將深入探討一個強化學習中的經典問題——多臂老虎機(Multi-Armed Bandit, MAB)

多臂老虎機問題,顧名思義,源于一個賭徒在賭場面對一排老虎機(即“多臂老虎機”)的場景。每個老虎機(“臂”)都有其內在的、未知的獲獎概率。賭徒的目標是在有限的回合內,通過選擇拉動不同的老虎機,來最大化自己的總收益。

這看似簡單的場景,卻完美地詮釋了強化學習中的一個核心困境:探索(Exploration)與利用(Exploitation)的權衡

  • 利用(Exploitation):選擇當前已知收益最高的老虎機。這能保證我們在短期內獲得不錯的收益,但可能會錯過一個潛在收益更高但尚未被充分嘗試的選項。
  • 探索(Exploration):嘗試那些我們不確定其收益的老虎機。這可能會在短期內犧牲一些收益,但卻有機會發現全局最優的選擇,從而獲得更高的長期總回報。

為了量化算法的性能,我們引入一個重要概念——累積懊悔(Cumulative Regret)。懊悔指的是在某一步選擇的動作所帶來的期望收益與“上帝視角”下最優動作的期望收益之差。一個優秀的算法,其目標就是最小化在整個過程中的累積懊悔。

在本篇博客中,我們將通過 Python 代碼,從零開始實現一個多臂老虎機環境,并逐步實現和對比以下四種經典的求解策略:

  1. ε-貪心算法 (Epsilon-Greedy)
  2. 隨時間衰減的ε-貪心算法 (Decaying Epsilon-Greedy)
  3. 上置信界算法 (Upper Confidence Bound, UCB)
  4. 湯普森采樣算法 (Thompson Sampling)

關于 PyTorch: 盡管標題提及 PyTorch,但對于 MAB 這種基礎問題,使用 NumPy 能更清晰地展示算法的核心邏輯,而無需引入深度學習框架的復雜性。本文中的實現將基于 NumPy,但其核心思想(如價值估計、策略選擇)是構建更復雜的深度強化學習算法(如DQN)的基石,在那些場景中 PyTorch 將發揮關鍵作用。

讓我們開始吧!

完整代碼:下載鏈接

創建多臂老虎機環境

多臂老虎機問題可以表示為一個元組 ? A , R ? \langle\mathcal{A},\mathcal{R}\rangle ?A,R? ,其中:

  • A \mathcal{A} A為動作集合,其中一個動作表示拉動一個拉桿。若多臂老虎機一共有 K K K根拉桿,那動作空間就是集合 { a 1 , … , a K } \{a_1,\ldots,a_K\} {a1?,,aK?},我們用 a t ∈ A a_t\in\mathcal{A} at?A表示任意一個動作;
  • R \mathcal{R} R為獎勵概率分布,拉動每一根拉桿的動作 a a a都對應一個獎勵概率分布 R ( r ∣ a ) \mathcal{R}(r|a) R(ra),不同拉桿的獎勵分布通常是不同的。

假設每個時間步只能拉動一個拉桿,多臂老虎機的目標為最大化一段時間步 T T T內累積的獎勵: max ? ∑ t = 1 T r t , r t ~ R ( ? ∣ a t ) \max\sum_{t=1}^Tr_t, r_t\sim\mathcal{R}\left(\cdot|a_t\right) maxt=1T?rt?,rt?R(?at?)。其中 a t a_t at?表示在第 t t t個時間步拉動某一拉桿的動作, r t r_t rt?表示動作 a t a_t at?獲得的獎勵。

首先,我們需要一個模擬環境。我們創建一個 BernoulliBandit 類來模擬一個擁有 K 個臂的老虎機。每個臂都服從伯努利分布,即每次拉動它,會以一個固定的概率 p 獲得獎勵 1(獲獎),以 1-p 的概率獲得獎勵 0(未獲獎)。在我們的環境中,這 K 個臂的獲獎概率 p 是在初始化時隨機生成的,并且對我們的算法(智能體)是未知的。

# 導入需要使用的庫
import numpy as np  # numpy是支持數組和矩陣運算的科學計算庫
import matplotlib.pyplot as plt  # matplotlib是繪圖庫class BernoulliBandit:"""伯努利多臂老虎機類該類實現了一個多臂老虎機問題的環境,每個拉桿都服從伯努利分布"""def __init__(self, K):"""初始化伯努利多臂老虎機參數:K (int): 拉桿個數,標量屬性:probs (numpy.ndarray): 每個拉桿的獲獎概率數組,維度為 (K,)best_idx (int): 獲獎概率最大的拉桿索引,標量best_prob (float): 最大的獲獎概率值,標量K (int): 拉桿總數,標量"""# 隨機生成K個0~1之間的數,作為拉動每根拉桿的獲獎概率# probs: (K,) - K個拉桿的獲獎概率數組self.probs = np.random.uniform(size=K)# 找到獲獎概率最大的拉桿索引# best_idx: 標量 - 最優拉桿的索引號self.best_idx = np.argmax(self.probs)# 獲取最大的獲獎概率# best_prob: 標量 - 最大獲獎概率值self.best_prob = self.probs[self.best_idx]# 保存拉桿總數# K: 標量 - 拉桿個數self.K = Kdef step(self, k):"""執行一次拉桿動作當玩家選擇了k號拉桿后,根據該拉桿的獲獎概率返回獎勵結果參數:k (int): 選擇的拉桿編號,標量,取值范圍為 [0, K-1]返回:int: 獎勵結果,標量1 表示獲獎0 表示未獲獎"""# 根據k號拉桿的獲獎概率進行伯努利采樣# np.random.rand(): 標量 - 生成[0,1)之間的隨機數# self.probs[k]: 標量 - k號拉桿的獲獎概率if np.random.rand() < self.probs[k]:return 1  # 獲獎else:return 0  # 未獲獎# 設定隨機種子,使實驗具有可重復性
np.random.seed(1)# 設置拉桿數量
# K: 標量 - 多臂老虎機的拉桿個數
K = 10# 創建一個10臂伯努利老虎機實例
# bandit_10_arm: BernoulliBandit對象 - 包含10個拉桿的老虎機
bandit_10_arm = BernoulliBandit(K)# 輸出老虎機的基本信息
print("隨機生成了一個%d臂伯努利老虎機" % K)
print("獲獎概率最大的拉桿為%d號,其獲獎概率為%.4f" % (bandit_10_arm.best_idx, bandit_10_arm.best_prob))

運行以上代碼,我們創建了一個10臂老虎機,并打印出了最優拉桿的信息。在我們的實驗中,1號拉桿是收益最高的,其獲獎概率為 0.7203。這個信息算法本身是不知道的,但我們可以用它來計算懊悔。

隨機生成了一個10臂伯努利老虎機
獲獎概率最大的拉桿為1號,其獲獎概率為0.7203

多臂老虎機算法基本框架(基類)

為了方便實現和比較不同的算法,我們先定義一個 Solver 基類。這個基類包含了所有算法都需要共享的功能,例如記錄每個臂被拉動的次數、記錄歷史動作以及計算和更新累積懊悔。具體的決策邏輯(run_one_step)將由各個子類來實現, 需要求解的是選取某根拉桿的策略。

累積懊悔

對于每一個動作,我們定義其期望獎勵為 Q ( a ) = E r ~ R ( ? ∣ a ) [ r ] {Q}(a)=\mathbb{E}_{r\sim\mathcal{R}(\cdot|a)}\begin{bmatrix}r\end{bmatrix} Q(a)=ErR(?a)?[r?]。于是,至少存在一根拉桿,它的期望獎勵不小于拉動其他任意一根拉桿,我們將該最優期望獎勵表示為 Q ? = max ? a ∈ A Q ( a ) Q^*=\max_{a\in\mathcal{A}}Q(a) Q?=maxaA?Q(a)。為了更加直觀、方便地觀察拉動一根拉桿的期望獎勵離最優拉桿期望獎勵的差距,我們引入懊悔(regret)概念。懊悔定義為拉動當前拉桿的動作與最優拉桿的期望獎勵差,即 R ( a ) = Q ? ? Q ( a ) R(a)=Q^*-Q(a) R(a)=Q??Q(a)累積懊悔(cumulative regret)即操作 T T

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/84632.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/84632.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/84632.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android學習之Window窗口

Android Window機制學習筆記 在使用Window Flag實現界面全屏功能時&#xff0c;發現自身對Android Window機制缺乏系統認知&#xff0c;因此進行了專項學習與整理。 本文主要參考以下優質資料&#xff1a; Android的Window詳解Android官方Window文檔 Window基本概念 1. Win…

華為云 Flexus+DeepSeek 征文|搭建部署Dify-LLM推理引擎,賦能AI Agent智能體實現動態聯網搜索能力

華為云 Flexus 云服務器 X 實例專門為 AI 應用場景設計。它提供了強大的計算能力&#xff0c;能夠滿足 DeepSeek 模型以及后續搭建 AI Agent 智能體過程中對于數據處理和模型運行的高要求。在網絡方面&#xff0c;具備高速穩定的網絡帶寬&#xff0c;這對于需要頻繁聯網搜索信息…

Python 100個常用函數全面解析

Python 100個常用函數全面解析 1. 類型轉換函數 1.1 int() 將字符串或數字轉換為整數。 # 基本用法 int(123) # 123 int(3.14) # 3# 指定進制轉換 int(1010, 2) # 10 (二進制轉十進制) int(FF, 16) # 255 (十六進制轉十進制)# 臨界值處理 int() # ValueError: …

分享在日常開發中常用的ES6知識點【面試常考】

前言 在日常的業務開發中&#xff0c;可以熟悉運用掌握的知識點快速解決問題很重要。這篇分享JS相關的知識點&#xff0c;主要就是對數據的處理。 注意&#xff1a;本篇分享的知識點&#xff0c;只是起到一個拋磚引玉的作用&#xff0c;詳情的使用和更多的ES6知識點還請參考官…

CHI協議驗證中的異常及邊界驗證

CHI協議驗證中的異常及邊界驗證 針對 CHI 協議的錯誤注入工具、覆蓋率衡量方法及實際項目中的投入平衡 CHI 協議作為多核系統中復雜的緩存一致性協議,驗證其行為需要強大的工具和方法來執行錯誤注入和邊界條件測試,并衡量測試覆蓋率。以下詳細討論常用工具、覆蓋率評估方法及…

技術專欄|LLaMA家族——模型架構

LLaMA的模型架構與GPT相同&#xff0c;采用了Transformer中的因果解碼器結構&#xff0c;并在此基礎上進行了多項關鍵改進&#xff0c;以提升訓練穩定性和模型性能。LLaMA的核心架構如圖 3.14 所示&#xff0c;融合了后續提出的多種優化方法&#xff0c;這些方法也在其他模型&a…

電腦插入多塊移動硬盤后經常出現卡頓和藍屏

當電腦在插入多塊移動硬盤后頻繁出現卡頓和藍屏問題時&#xff0c;可能涉及硬件資源沖突、驅動兼容性、供電不足或系統設置等多方面原因。以下是逐步排查和解決方案&#xff1a; 1. 檢查電源供電問題 問題原因&#xff1a;多塊移動硬盤同時運行可能導致USB接口供電不足&#x…

Go 語言實現高性能 EventBus 事件總線系統(含網絡通信、微服務、并發異步實戰)

前言 在現代微服務與事件驅動架構&#xff08;EDA&#xff09;中&#xff0c;事件總線&#xff08;EventBus&#xff09; 是實現模塊解耦與系統異步處理的關鍵機制。 本文將以 Go 語言為基礎&#xff0c;從零構建一個高性能、可擴展的事件總線系統&#xff0c;深入講解&#…

npm ERR! @biomejs/biome@1.9.4 postinstall: `node scripts/postinstall.js`

npm install 報錯如下, npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! @biomejs/biome@1.9.4 postinstall: `node scripts/postinstall.js` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the @biomejs/biome@1.9.4 postinstall script. npm ERR! This is pro…

APMPlus × veFaaS 一鍵開啟函數服務性能監控,讓函數運行全程可觀測

資料來源&#xff1a;火山引擎-開發者社區 近年來&#xff0c;無服務器架構&#xff08;Serverless&#xff09;的崛起讓開發者得以從基礎設施的復雜性中解放&#xff0c;專注于業務邏輯創新。但隨著采用率提升&#xff0c;新的問題開始出現——函數實例的短暫生命周期、動態變…

瑪哈特零件矯平機:精密制造中的平整度守護者

在精密制造、模具、沖壓、鈑金加工、汽車零部件、航空航天以及電子設備等眾多工業領域&#xff0c;零件的平整度&#xff08;Flatness&#xff09;是一項至關重要的質量指標。微小的翹曲、扭曲或彎曲都可能導致裝配困難、功能失效、外觀缺陷甚至影響整機性能。為了消除零件在加…

std::make_shared簡化智能指針 `std::shared_ptr` 的創建過程,并提高性能(減少內存分配次數,提高緩存命中率)

std::make_shared 是 C 標準庫中的一個函數模板&#xff0c;用于簡化智能指針 std::shared_ptr 的創建過程。引入 std::make_shared 的主要原因是提高代碼的安全性、性能和可讀性。以下是詳細分析&#xff1a; 1. 安全性提升 避免顯式調用 new 導致的錯誤 在不使用 std::make…

JDK版本如何絲滑切換

一句話總結 》》》步驟分為&#xff1a; 下載對應JDK配置環境變量 下載JDK 如何下載JDK這里不必多提&#xff0c;提出一點&#xff0c;就是多個版本的JDK最好放在一個文件夾里&#xff08;忽略我的java文件夾&#xff0c;這里都是不同的jdk版本&#xff09;&#xff1a; 配置環…

Rust 通用代碼生成器:蓮花,紅蓮嘗鮮版三十六,啞數據模式圖片初始化功能介紹

Rust 通用代碼生成器&#xff1a;蓮花&#xff0c;紅蓮嘗鮮版三十六&#xff0c;啞數據模式圖片初始化功能介紹 Rust 通用代碼生成器蓮花&#xff0c;紅蓮嘗鮮版三十六。支持全線支持圖片預覽&#xff0c;可以直接輸出帶圖片的啞數據模式快速原型。啞數據模式和枚舉支持圖片。…

45. Jump Game II

目錄 題目描述 貪心 題目描述 45. Jump Game II 貪心 正向查找可到達的最大位置 時間復雜度O(n) class Solution { public:int jump(vector<int>& nums) {int n nums.size();if(n 1)return 0;int cur_cover 0;int cover 0;int res 0;for(int i 0;i < …

model.classifier 通常指模型的分類頭 是什么,詳細舉例說明在什么部位,發揮什么作用

model.classifier 通常指模型的分類頭 是什么,詳細舉例說明在什么部位,發揮什么作用 在深度學習模型中,分類頭(Classifier Head)是指模型末端用于完成分類任務的組件,通常是一個或多個全連接層(線性層)。它的作用是將模型提取的高層語義特征映射到具體的分類標簽空間。…

機器學習+城市規劃第十四期:利用半參數地理加權回歸來實現區域帶寬不同的規劃任務

機器學習城市規劃第十四期&#xff1a;利用半參數地理加權回歸來實現區域帶寬不同的規劃任務 引言 在城市規劃中&#xff0c;如何根據不同地區的地理特征來制定有效的規劃方案是一個關鍵問題。不同區域的需求和規律是不同的&#xff0c;因此我們必須考慮到地理空間的差異性。…

Kivy的ButtonBehavior學習

Kivy的ButtonBehavior學習 ButtonBehavior 簡介1、主要特點2、基本用法3、主要事件4、常用屬性5、方法代碼示例 文檔&#xff1a;https://kivy.org/doc/stable/api-kivy.uix.behaviors.button.html#kivy.uix.behaviors.button.ButtonBehavior ButtonBehavior 簡介 ButtonBeha…

WPS中將在線鏈接轉為圖片

WPS中將在線鏈接轉為圖片 文章目錄 WPS中將在線鏈接轉為圖片一&#xff1a;解決方案1、下載圖片&#xff0c;精確匹配&#xff08;會員功能&#xff09;2、將在線鏈接直接轉為圖片 一&#xff1a;解決方案 1、下載圖片&#xff0c;精確匹配&#xff08;會員功能&#xff09; …

API:解鎖數字化協作的鑰匙及開放實現路徑深度剖析

API:解鎖數字化協作的鑰匙及開放實現路徑深度剖析 一、API 的概念與本質 (一)定義與基本原理 API(Application Programming Interface,應用程序編程接口)是一組定義、協議和工具,用于構建和集成軟件應用程序。它如同一個精心設計的合約,詳細規定了軟件組件之間相互交…