Keras深度学习实战(42)——强化学习基础

news2024/11/22 13:27:47

Keras深度学习实战(42)——强化学习基础

    • 0. 前言
    • 1. 强化学习基础
      • 1.1 基本概念
      • 1.2 马尔科夫决策过程
      • 1.3 目标函数
    • 2. 在具有非负奖励的模拟游戏中获取最佳动作
      • 2.1 问题设定
      • 2.2 模型分析
      • 2.3 模型构建与训练
    • 3. 在模拟游戏中获取最佳动作
      • 3.1 问题定义
      • 3.2 模型分析
      • 3.3 模型构建与训练
    • 小结
    • 系列链接

0. 前言

强化学习是当前人工智能领域的研究热点问题,强化学习主要通过考察智能体与环境的相互作用,得到策略模型、优化策略并最大化累积回报的过程。强化学习具有巨大的研究价值和应用潜力,是实现通用人工智能的关键技术。本文首先介绍强化学习的基本原理,包括马尔可夫决策过程、价值函数、探索-利用问题等,然后介绍经典的强化学习算法,最后使用 Keras 实现在游戏中模拟强化学习算法。

1. 强化学习基础

1.1 基本概念

强化学习的核心思想在于最大化智能体在相应环境中得到的累计奖励,从而学习能够令智能体完成目标任务的最佳策略。智能体 (agent) 在每个时刻可以与环境 (environment) 交互,交互过程如下所示:

智能体

每次交互,都可以得到一个具有多维特征的观察 (observation),根据观察可以得到状态 (state),智能体根据状态选择相应的动作 (action),环境会对 agent 的不同动作给予不同奖励 (reward),从状态到动作的映射函数称为策略 (policy)。通过重复执行此过程,就可以得到令累计奖励最大化的最佳策略。

1.2 马尔科夫决策过程

智能体从环境初始状态开始,根据策略模型采样某一动作,环境在动作的影响下,会从原状态改变为新状态,同时给予智能体奖励。以上过程不断重复直到达到游戏的终止状态,这个过程也称为轨迹 (trajectory),一个过程称为一个回合 (episode)。环境的当前状态通常取决于多个历史状态,计算非常复杂,为了简化计算流程,我们通常假设当前时间戳上的状态仅仅受上一状态的影响,这种性质称为马尔科夫性 (Markov Property),具有马尔科夫性的序列称为马尔科夫过程 (Markov Process)。
如果我们将执行的动作也考虑进状态转移概率,同样应用马尔科夫假设,当前状态只与上一状态和上一状态上执行的动作相关,则我们把状态和动作的有序序列叫做马尔科夫决策过程 (Markov Decision Process, MDP)。当智能体只能观察到环境的部分状态时,称为部分可观察马尔可夫决策过程 (Partially Observable Markov Decision Process , POMDP)

1.3 目标函数

智能体每次在与环境进行交互时,都会得到一个奖励,一次交互轨迹的累计奖励称为总回报 (return),但在某些环境中的奖励是十分稀疏的,例如在棋牌类游戏中,前面的动作奖励均为 0,只有游戏结束时才有表示输赢的奖励。为了权衡近期奖励与长期奖励,引入折扣率来令奖励随时间衰减。
由于环境状态转移和策略具有一定的随机性,即使使用同样的策略模型作用域同一环境,也可能产生截然不同的轨迹序列,因此强化学习的目标是最大化期望回报。

2. 在具有非负奖励的模拟游戏中获取最佳动作

在本节中,我们将了解如何在模拟游戏中采取正确动作,主要目的是进一步介绍强化学习的工作原理。

2.1 问题设定

我们首先定义环境,用于之后运行模拟。假设,有三个格子,两个玩家在上面玩游戏,初始时空白格子如下:

空白格子
玩家 11 标记一个方格,而玩家 22 标记一个方格,能够标记两个连续方格的玩家获胜,对于此问题,只有玩家 1 有机会赢得比赛。玩家 1 获胜的可能情况如下:

胜负关系分析

从问题定义中可以看出,玩家 1 获胜的方式是选择标记中间的格子。这样,不管玩家 2 选择哪个格子,玩家 1 都将在其后续操作时获胜。

2.2 模型分析

尽管玩家 1 取得胜利的动作显而易见,但对于计算机而言却并非如此。接下来,我们将了解智能体如何自动找出最佳动作。我们将采用以下策略来解决此问题:

  • 初始时空白格子
  • 玩家 1 随机选择一个盒子
  • 玩家 2 从剩余的 2 个盒子中随机选择一个盒子
  • 根据玩家 1 留下的盒子,我们更新玩家 1 的奖励:
    • 如果玩家 1 能够在两个连续的盒子中放置 1,则他是获胜者,将获得奖励 1
    • 否则,玩家 1 将获得奖励 0
  • 重复以上过程 100 次,在其中进行游戏,并存储每次的奖励
  • 计算所采取的不同策略中第一步的平均奖励
  • 第一步中选择的,在 100 次迭代中具有最高平均奖励的格子是玩家 1 第一步的最佳动作。

2.3 模型构建与训练

(1) 定义游戏环境和进行游戏的函数,在函数中,初始化一个全为 0 值的空白格子。在迭代过程中,每次生成一个名为 samp 的随机动作,玩家 1 采取第一个动作,然后玩家 2 采取第二个动作,最后一个步骤是玩家 1 采取动作,我们按此步骤填充空白格子:

import random

def play_game():
    empty_board = [0,0,0]
    move = []
    for step in range(3):
        index_to_choose = [i for i,j in enumerate(empty_board) if j==0]
        samp = random.sample(range(len(index_to_choose)), 1)[0] 
        if(step%2==0):
            empty_board[index_to_choose[samp]]=1
            move.append(index_to_choose[samp])
        else:
            empty_board[index_to_choose[samp]]=2 
    return(reward(empty_board), move[0])

(2) 定义函数 reward 以在游戏结束时计算奖励:

def reward(empty_board):
    reward = 0
    if((empty_board[0]==1 & empty_board[1]==1)|(empty_board[1]==1 & empty_board[2]==1)):
        reward = 1
    else:
        reward = 0
    return reward

(3) 进行 100 回合游戏:

rew = []
step = []
for i in range(100):
    r, move = play_game()
    rew.append(r)
    step.append(move)

(4) 计算在第一步中选择不同动作的奖励,可以看到在第一步中占据第二个格子时平均奖励最高:

sub_list = [i for i,j in enumerate(step) if j==1]
final_reward = 0
count = 0
for i in sub_list:
    final_reward += rew[i]
    count+=1
print(final_reward/count)

3. 在模拟游戏中获取最佳动作

在上一节中,我们使用了一个简单问题,即在达到目标时会得到奖励。我们可以定义一个稍微复杂的游戏,在环境中既有正奖励又有负奖励,但目标相同是最大化奖励。

3.1 问题定义

我们使用以下环境,从包含 S 的单元格开始,目标是到达奖励为 +1 的单元格:

环境定义

为了最大化获得奖励的概率,使用 Bellman 方程,该方程可以计算网格中每个单元的值:

  • 当前单元格的值 = 从当前单元格移动到下一个单元格的奖励 + 折扣因子 * 下一个单元格的值

在此问题中,移动到奖励为 +1 的单元格以外的单元格的奖励为 0,与其他单元格相比,远离目标单元格的单元格具有较低的值。一旦计算了每个单元格的值,智能体就可以移动到的所有单元格中具有最高值的单元格。

3.2 模型分析

我们用于计算每个单元格值的策略如下:

  • 初始化一个空白网格
  • 定义智能体可以在单元格中执行的动作
  • 定义智能体在当前单元格中执行的动作后将进入的下一状态
  • 计算当前状态的值,该值取决于移动到下一个状态的奖励以及下一个状态的值
  • 根据以上计算更新当前状态的单元格值
  • 存储在当前状态下执行的动作以移至下一个状态
  • 在迭代起始阶段,远离最终目标单元格的值为零,而与最终状态相邻的单元格的值则逐渐增加
  • 多次迭代更新单元格值,从而能够确定智能体遵循的最佳路线

3.3 模型构建与训练

(1) 初始化一个空网格,并定义可以在不同状态下执行的操作,其中 D 表示向下移动,R 表示向右移动,L 表示向左移动,U 表示向上移动:

empty_board = [[0,0,0]
             ,[0,0,1]]

state_actions = {(0,0):('D','R')
                 ,(0,1):('D','R','L')
                 ,(0,2):('D','L')
                 ,(1,0):('U','R')
                 ,(1,1):('L','U','R') 
                 }

(2) 定义函数,用于返回在给定当前状态下采取动作后的将进入的下一状态:

def get_next_state(curr_state, action):
    i,j = curr_state
    if action=='D':
        i = i+1
    elif action=='U':
        i = i-1
    elif action=='R':
        j = j+1
    elif action=='L':
        j = j-1
    else:
        print('unk')
    return((i,j))

(3) 初始化用于存储状态、动作和奖励的列表:

def print_values():
    print(empty_board[:][0])
    print(empty_board[:][1])
curr_state = (0,0)
state_action_reward = []
state = []
state_action = []

(4) 在一个回合中最多执行 100 个动作,在一个单元格(状态)中采取随机动作,并根据移动到下一个状态的奖励以及下一状态值计算当前状态的值。重复迭代以上步骤 100 次(回合),在一个状态中采取随机动作,然后进入下一个状态,并计算每个单元格的值:

for m in range(100):
    curr_state = (0,0)
    for k in range(100):
        reward = 0
        action = state_actions[curr_state][random.sample(range(len(state_actions[curr_state])),1)[0]]
        next_state = get_next_state(curr_state, action)
        state.append(curr_state)

        empty_board[curr_state[0]][curr_state[1]] = reward + \
                    empty_board[next_state[0]][next_state[1]]*0.9 
        
        curr_state = next_state
        state_action.append(action)

        if(next_state==(1,2)):
            reward+=1
        break
    if(m%10==0):
        print('==========')
        print_values()

运行代码后,得到的每个单元格的最终值如下所示:

[0.7290000000000001, 0.0523347633027361, 0.38742048900000015]
[0.5314410000000002, 0.9, 1]

从输出结果来看,智能体可以在游戏开始时最好采取向下的动作,因为下方单元格的值高于右侧单元格的值。

(5) 进一步,我们可以考虑使用以下环境:

empty_board = [[0,0,-1]
             ,[0,0,1]]

(6) 在不同状态可以采取的动作如下:

state_actions = {(0,0):('D','R')
                 ,(0,1):('D','R')
                 ,(1,0):('R')
                 ,(1,1):('R') 
                 }

(7) 多次迭代后,计算各个单元格中的单元格状态值:

curr_state = (0,0)
state_action_reward = []
state = []
state_action = []

for m in range(100):
    curr_state = (0,0)
    for k in range(100):
        reward = 0
        action = state_actions[curr_state][random.sample(range(len(state_actions[curr_state])),1)[0]]
        next_state = get_next_state(curr_state, action)
        state.append(curr_state)
            
        empty_board[curr_state[0]][curr_state[1]] = reward + empty_board[next_state[0]][next_state[1]]*0.9 
        
        curr_state = next_state
        state_action.append(action)
        
        if(next_state==(0,2)):
            break
        if(next_state==(1,2)):
            break
    if(m%10==0):
        print('==========')
        print_values()

结果值如下所示:

[-0.81, -0.9, -1]
[0.81, 0.9, 1]

从以上结果可以看出,智能体从左上角执行向下的动作比向右要好,因为下方单元格的状态值更高。

小结

在未知环境中,研究智能体的学习行为是一个既充满挑战又有趣的问题,强化学习通过试探与环境交互获得策略的改进,是机器学习研究中的一个重要分支。本文首先讲解了强化学习的基本概念与重要背景知识,然后利用 Keras 模拟了两个简单的游戏环境,从而加深对强化学习原理的理解。

系列链接

Keras深度学习实战(1)——神经网络基础与模型训练过程详解
Keras深度学习实战(2)——使用Keras构建神经网络
Keras深度学习实战(3)——神经网络性能优化技术
Keras深度学习实战(4)——深度学习中常用激活函数和损失函数详解
Keras深度学习实战(5)——批归一化详解
Keras深度学习实战(6)——深度学习过拟合问题及解决方法
Keras深度学习实战(7)——卷积神经网络详解与实现
Keras深度学习实战(8)——使用数据增强提高神经网络性能
Keras深度学习实战(9)——卷积神经网络的局限性
Keras深度学习实战(10)——迁移学习详解
Keras深度学习实战(11)——可视化神经网络中间层输出
Keras深度学习实战(12)——面部特征点检测
Keras深度学习实战(13)——目标检测基础详解
Keras深度学习实战(14)——从零开始实现R-CNN目标检测
Keras深度学习实战(15)——从零开始实现YOLO目标检测
Keras深度学习实战(16)——自编码器详解
Keras深度学习实战(17)——使用U-Net架构进行图像分割
Keras深度学习实战(18)——语义分割详解
Keras深度学习实战(19)——使用对抗攻击生成可欺骗神经网络的图像
Keras深度学习实战(20)——DeepDream模型详解
Keras深度学习实战(21)——神经风格迁移详解
Keras深度学习实战(22)——生成对抗网络详解与实现
Keras深度学习实战(23)——DCGAN详解与实现
Keras深度学习实战(24)——从零开始构建单词向量
Keras深度学习实战(25)——使用skip-gram和CBOW模型构建单词向量
Keras深度学习实战(26)——文档向量详解
Keras深度学习实战(27)——循环神经详解与实现
Keras深度学习实战(28)——利用单词向量构建情感分析模型
Keras深度学习实战(29)——长短时记忆网络详解与实现
Keras深度学习实战(30)——使用文本生成模型进行文学创作
Keras深度学习实战(31)——构建电影推荐系统
Keras深度学习实战(32)——基于LSTM预测股价
Keras深度学习实战(33)——基于LSTM的序列预测模型
Keras深度学习实战(34)——构建聊天机器人
Keras深度学习实战(35)——构建机器翻译模型
Keras深度学习实战(36)——基于编码器-解码器的机器翻译模型
Keras深度学习实战(37)——手写文字识别
Keras深度学习实战(38)——图像字幕生成
Keras深度学习实战(39)——音乐音频分类
Keras深度学习实战(40)——音频生成
Keras深度学习实战(41)——语音识别

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

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

相关文章

数据库原理及MySQL应用 | 数据表操作

数据表操作是数据库操作中最基本和最重要的操作。 图5-1是图书销售数据库booksale中存放的图书表books。 ■ 图5-1图书表books 01. 表的结构 表的结构也称为“型”(Type),用于描述存储于表中的数据的逻辑结构和属性。定义表就是指定义表的结构,使用数据…

Vue CLI系列之生成打包报告

文章の目录一、通过命令行参数的形式生成报告二、通过可视化的UI面板直接查看报告写在最后打包时,为了直观地发现项目中存在的问题,可以在打包时生成报告。生成报告的方式有两种: 一、通过命令行参数的形式生成报告 "scripts": {…

关于对计算机发展史、冯诺依曼体系、CPU基本工作流程以及关于编程语言的简单认识

关于计算机发展史: 关于计算机发展史,大体经历了从一般计算工具到机械计算机到目前的电子计算机的发展历程。 公元前2500年,算盘已经出现; 1694 年,德国博物学家 戈特弗里德莱布尼兹建造了“步进计算器”。 关于步进…

Djiango实现用户管理增删改成功能实战

1.0定义 前后端不分离模式 前后端分离是指前端页面看到的效果都是由后端控制,即后端渲染HTML页面,前端与后端的耦合度比较高 前后端分离模式 后端仅返回前端所需要的数据,不在渲染HTML页面,不在控制前端的效果,至…

八、kubernetes1.25应用升级、回滚

1、概述 用户希望应用程序始终可用,而开发人员则需要每天多次部署它们的新版本。在 Kubernetes 中,这些是通过滚动更新(Rolling Updates)完成的。 滚动更新 允许通过使用新的实例逐步更新 Pod 实例,零停机进行 Deploym…

Sentinel流控

Sentinel 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 1.sentinel特性 Sentinel 具有以下特征: 丰富的应用场景: Sentinel 承接了…

最优化方法——最小二乘法与梯度下降法

目录 系列文章目录 一、问题 二、实验思路综述 1.实验工具及算法 2.实验数据 3.实验目标 4.实验步骤 三、最小二乘问题引入 1.最小二乘问题样例 2.最小二乘问题解决方案及数学模型化 3.相关线性代数知识导入 3.1 梯度 3.2 矩阵的逆 3.3 QR分解 四、最小二乘法 …

用 ChatGPT 运行 Python

最近,我一直在阅读一些关于ChatGPT的有趣文章。在一篇文章中,有人发明了一种新的语言,并让ChatGPT运行它。在另一篇文章中,有人在ChatGPT中运行一个虚拟机。后者启发我提出了下面这个问题。你能在ChatGPT中运行一个交互式Python会…

【docker常用命令】

一、帮助启动类命令 (1)启动docker systemctl start docker(2)停止docker systemctl stop docker(3)重启docker systemctl restart docker(4)查看docker状态 systemctl status…

【数据预处理】基于Pandas的数据预处理技术【california_housing加州房价数据集】_后9个任务

文章目录一.需求分析二.需求解决2.1 对第一个特征(收入中位数)排序后画散点图2.2 对第一个特征(收入中位数)画分位数图并分析2.3 【选做】对所有特征画分位数图并进行分析2.4 使用线性回归方法拟合第一个特征(收入中位…

基于c# asp.net电子病历管理系统的设计与实现

摘 要 网络的广泛应用给生活带来了十分的便利。所以把电子病历管理与现在网络相结合,利用net语言建设电子病历管理系统,实现电子病历管理的信息化。则对于进一步提高医院的发展,丰富电子病历管理经验能起到不少的促进作用。 电子病历管理系统…

AbstractQueueSynchronizer

AbstractQueueSynchronizer AbstractQueueSynchronizer 是基于 FIFO线程等待队列 的一个同步器开发框架。 这篇文章首先介绍同步器概念,然后介绍AQS的结构原理 什么是Synchronizer(同步器) 并发环境下,Synchronizer用于实现线…

Windows和Mac系统实现本地部署WebPageTest工具

在项目开发或者测试的过程中,由于没有上线,我们在公网上无法访问我们的网站,但同时我们又需要查看浏览器性能,这样我们就需要在本地部署WebPageTest工具以协助进行性能测试 具体实现步骤: Windows系统: …

FFT求多项式乘积

之前在b站上看到了一些介绍FFT的视频 《快速傅里叶变换(FFT)——有史以来最巧妙的算法?》 《这个算法改变了世界》 于是打算写一篇记录一下qwq(本博客中的截图基本上来源于第一个视频) Fast Fourier Transform 是一种能在O(nlogn)O(nlogn)…

企业营销数字化转型:如何转型、如何选品、如何用好?

省时查报告-专业、及时、全面的行研报告库省时查方案-专业、及时、全面的营销策划方案库【免费下载】2022年11月份热门报告盘点2023年,如何科学制定年度规划?《底层逻辑》高清配图清华大学256页PPT元宇宙研究报告.pdf(附下载链接)…

【LeetCode】1759. 统计同构子字符串的数目

统计同构子字符串的数目 题目描述 给你一个字符串 s ,返回 s 中 同构子字符串 的数目。由于答案可能很大,只需返回对 109 7 取余 后的结果。 同构字符串 的定义为:如果一个字符串中的所有字符都相同,那么该字符串就是同构字符串…

自定义报表-FineReport JS实现隐藏Tab页

1. 概述 1.1 问题描述 在实际项目中,使用决策报表的时候,有时会用到在决策报表参数面板获取报表控件的值,那么该如何实现呢? 1.2 实现思路 使用 JS 获取报表主体的控件值: _g().getWidgetByName("area").…

【金猿人物展】数睿数据创始人兼CEO穆鸿:大数据价值创造关键在于应用普惠...

‍穆鸿本文由数睿数据创始人兼CEO穆鸿撰写并投递参与“数据猿年度金猿策划活动——2022大数据产业趋势人物榜单及奖项”评选。‍数据智能产业创新服务媒体——聚焦数智 改变商业事情还得从我2022年这一年经历的一些事情谈起,由于工作的原因,我要经常往返…

Python量化交易04——基于机器学习的交易策略

参考书目:深入浅出Python量化交易实战 学量化肯定要用的上机器学习这种强大的预测技术。本次使用机器学习构建一些简单的预测进行量化交易,使用Python进行回测。 获取数据 import pandas as pd import tushare as ts import numpy as npfrom sklearn.neighbors imp…

线程池设计与实现C

线程池实现 结构设计 先上图: 参数 线程池: 包含一个执行队列、一个任务队列mutex用来在多个线程取任务时锁任务队列,cond用来在任务队列为空时锁任务队列 如线程A锁了任务队列,去取任务时,又发现任务队列为空&…