David Silver Lecture 8: Integrating Learning and Planning

news2024/11/24 19:38:51

1 Introduction

1.1 Model based Reinforcement Learning

在这里插入图片描述

1.2 model based and model free RL

在这里插入图片描述

2 Model-Based Reinforcement Learning

2.1 outline

在这里插入图片描述
在这里插入图片描述

2.2 Learning a model

2.2.1 what is a model

model主要是指,state transitions和相应的reward。
在这里插入图片描述

2.2.2 Model learning

在这里插入图片描述

2.2.3 Examples of Models

在这里插入图片描述

  • table lookup model
import numpy as np

class TableModel:
    def __init__(self, num_states, num_actions):
        # Initialize the table with zeros
        self.table = np.zeros((num_states, num_actions, num_states))

    def update(self, state, action, next_state):
        # Increment the count for the observed transition
        self.table[state, action, next_state] += 1

    def predict(self, state, action):
        # Normalize the table to get probabilities
        prob = self.table[state, action] / np.sum(self.table[state, action])
        
        # Sample next state
        next_state = np.random.choice(np.arange(num_states), p=prob)
        
        return next_state

2.3 Planning with a model

在这里插入图片描述

2.3.1 Sample based planning

在这里插入图片描述

基于样本的规划(sample-based planning)方法是一种在模型中进行搜索的方法,以找到最优策略。这种方法的主要思想是通过模拟随机样本的方式来近似解决决策问题,而不是直接在整个状态空间上进行搜索。

一个简单的问题:假设我们有一个简单的迷宫问题。在每个时间步,代理可以选择上、下、左或右移动一步。我们的目标是找到从起始位置到目标位置的最短路径。

1.初始化 Q 值和 eligibility traces。
2.在给定的迷宫中,从起始位置开始,选择一个动作。初始动作可以是随机选择的,也可以是根据当前策略选择的。
3.执行选定的动作,观察结果状态和奖励。
4.在结果状态处,根据 SARSA(λ) 更新规则,选择下一个动作,并更新 Q 值和 eligibility traces。
5.重复步骤 3 和 4,直到到达目标状态或达到最大步数。
6.使用更新的 Q 值,更新策略。
7.通过模拟一系列随机样本,使用基于样本的规划方法更新策略。
8.重复步骤 2 到 7,直到策略收敛。

import numpy as np

# 迷宫的尺寸
size = (10, 10)
# 目标位置
goal = (9, 9)
# ε-贪心策略的参数
epsilon = 0.1
# 衰减因子
gamma = 0.95
# Sarsa(λ)的参数
lambda_ = 0.9
# 动作集合
actions = [(0, -1), (-1, 0), (0, 1), (1, 0)]
# 学习率
alpha = 0.5

# 初始化Q值和E痕迹
Q = np.zeros(size + (len(actions),))
E = np.zeros_like(Q)

# 对于每一步
for episode in range(1000):
    # 初始化状态
    state = (0, 0)
    # 选择一个动作
    if np.random.rand() < epsilon:
        action = np.random.choice(len(actions))
    else:
        action = np.argmax(Q[state])

    while state != goal:
        # 执行动作并观察结果
        next_state = (state[0] + actions[action][0], state[1] + actions[action][1])
        next_state = max(0, min(size[0]-1, next_state[0])), max(0, min(size[1]-1, next_state[1]))

        # 选择下一个动作
        if np.random.rand() < epsilon:
            next_action = np.random.choice(len(actions))
        else:
            next_action = np.argmax(Q[next_state])

        # 计算奖励
        reward = -1 if next_state != goal else 0

        # 更新Q值和E痕迹
        delta = reward + gamma * Q[next_state + (next_action,)] - Q[state + (action,)]
        E[state + (action,)] += 1
        Q += alpha * delta * E
        E *= gamma * lambda_

        # 移动到下一个状态
        state = next_state
        action = next_action

# 现在,Q值应该为每个状态动作对给出最优路径

2.3.2 Planning with an Inaccurate Model

在这里插入图片描述

3 Integrated Architecture

3.1 Dyna

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在Dyna中,一个智能体同时进行两种类型的学习:直接从与环境的交互中学习(模型自由学习),以及通过模拟环境并从中学习(模型驱动学习)。Dyna架构的主要组件包括:

1智能体:智能体执行操作,观察结果,并进行学习。
2模型:模型预测结果,例如下一个状态和奖励。
3价值函数:价值函数(例如,Q函数)预测每个状态-动作对的价值。
4策略:策略决定智能体在每个状态下应执行的动作。

下面是Dyna架构的工作步骤:

1直接强化学习:智能体在环境中执行操作,观察结果,并直接从中更新价值函数。
2模型学习:智能体在环境中执行操作,观察结果,并从中学习模型。
3模型驱动学习:智能体使用模型进行模拟,并从模拟中更新价值函数。

Dyna架构的优点是,它能够同时利用模型自由和模型驱动的优点。模型自由学习可以直接从实际经验中学习,而模型驱动学习可以通过模拟来有效地利用已有知识。另一方面,Dyna架构的缺点是,它需要一个准确的模型才能有效。如果模型不准确,那么通过模型驱动学习产生的结果可能会误导智能体。

import numpy as np

# 参数设置
n_states = 5
n_actions = 2
n_steps = 1000
alpha = 0.1
gamma = 0.95
epsilon = 0.1
n_planning_steps = 5

# 初始化
Q = np.zeros((n_states, n_actions))
model = dict()

for step in range(n_steps):
    # 直接强化学习
    s = np.random.randint(n_states)
    a = np.random.choice([np.argmax(Q[s]), np.random.randint(n_actions)], p=[1-epsilon, epsilon])
    r = np.random.randn()
    s_ = np.random.randint(n_states)
    Q[s, a] += alpha * (r + gamma * np.max(Q[s_]) - Q[s, a])

    # 模型学习
    model[(s, a)] = (r, s_)

    # 模型驱动学习
    for _ in range(n_planning_steps):
        sa = list(model.keys())[np.random.randint(len(model))]
        r, s_ = model[sa]
        Q[sa] += alpha * (r + gamma * np.max(Q[s_]) - Q[sa])

print(Q)

算法步骤
在这里插入图片描述

4 Simulation Based Search

4.1 Outline

4.1.1 Forward search

在这里插入图片描述
在这里插入图片描述

4.1.2 Simulation-based Search

模拟基础搜索(Simulation-Based Search)是一种强化学习方法,它利用模拟来预测智能体在环境中执行特定动作的结果,并据此选择最优的动作。这种方法通常用在环境模型已知或可学习的情况下。

  • 优点:
    1减少了实际交互的需求:模拟基础搜索通过模拟环境来预测结果,而不需要实际在环境中执行动作,这大大减少了实际交互的需求。
    2提高了学习效率:由于模拟基础搜索可以在每次实际交互之间进行多次模拟,因此它可以更快地学习环境。

  • 缺点
    1模型的准确性:模拟基础搜索的性能严重依赖于模型的准确性。如果模型不准确,那么模拟的结果可能会误导智能体。
    2计算成本:模拟基础搜索需要大量的计算资源来进行模拟,这可能会限制它在复杂环境中的应用。
    在这里插入图片描述
    在这里插入图片描述
    让我们考虑一个更为典型的强化学习问题,如MountainCar问题。在这个问题中,智能体需要驾驶一辆车从一个山谷中爬出来。车的引擎不够强,不能直接爬上山坡,因此必须利用动量来到达目标。

在这个问题中,我们可以使用模拟基础搜索来找到最佳的行动策略。我们的模型会模拟车在执行特定动作后的位置和速度,我们的策略将基于这些模拟结果来选择动作。这是一个典型的强化学习问题,因为智能体需要通过与环境的交互来学习如何最大化累积奖励。

在以下代码中,我们将使用OpenAI的gym库来设置MountainCar环境,并使用一种称为Monte Carlo Tree Search(MCTS)的模拟基础搜索算法来解决这个问题:

解决思路:
我们创建了一个名为Node的类,该类表示Monte Carlo Tree Search(MCTS)的一个节点。simulate函数负责执行模拟,它在每个步骤中选择一个动作,然后执行这个动作并添加新的子节点。我们的策略是一个简单的随机策略,它在每个步骤中随机选择一个动作。在每次模拟结束后,我们根据平均奖励选择最好的子节点作为下一步的状态。

import gym
import numpy as np

class Node:
    def __init__(self, state, parent=None):
        self.state = state
        self.parent = parent
        self.children = []
        self.rewards = []

    def add_child(self, child):
        self.children.append(child)

    def add_reward(self, reward):
        self.rewards.append(reward)

    def is_leaf(self):
        return len(self.children) == 0

    def is_root(self):
        return self.parent is None

    def get_average_reward(self):
        return np.mean(self.rewards)

def simulate(node, env, policy, max_steps=200):
    env.state = node.state
    for _ in range(max_steps):
        action = policy(env.state)
        state, reward, done, _ = env.step(action)
        child = Node(state, parent=node)
        node.add_child(child)
        node.add_reward(reward)
        node = child
        if done:
            break

def best_child(node):
    best_score = -np.inf
    best_child = None
    for child in node.children:
        score = child.get_average_reward()
        if score > best_score:
            best_score = score
            best_child = child
    return best_child

def mcts(state, env, policy, n_simulations=100):
    root = Node(state)
    for _ in range(n_simulations):
        simulate(root, env, policy)
    return best_child(root).state

env = gym.make('MountainCar-v0')

# Dummy policy
def policy(state):
    return env.action_space.sample()

# Initial state
state = env.reset()

# Run MCTS
for _ in range(200):
    next_state = mcts(state, env, policy)
    state = next_state
    env.render()

env.close()

在这里插入图片描述

4.2 Monte-Carlo Search

MCTS包括四个步骤:选择(Selection)、扩展(Expansion)、模拟(Simulation)和反向传播(Backpropagation)。在选择步骤,算法从根节点开始,按某种策略选择子节点,直到找到一个尚未完全扩展的节点。在扩展步骤,算法选择一个未被评估过的子节点进行扩展。在模拟步骤,算法模拟一次随机对战,得到此次对战的结果。在反向传播步骤,算法将模拟的结果反向传播到所有经过的节点,并更新这些节点的评估值。

Tic-Tac-Toe游戏

from copy import deepcopy
import numpy as np

class Node:
    def __init__(self, state, parent=None):
        self.state = state
        self.parent = parent
        self.children = []
        self.wins = 0
        self.visits = 0

    def add_child(self, child):
        self.children.append(child)

class TicTacToe:
    def __init__(self):
        self.board = np.zeros((3, 3))
        self.player = 1

    def get_valid_moves(self):
        return np.argwhere(self.board == 0)

    def make_move(self, move):
        self.board[move[0], move[1]] = self.player
        self.player = -1 if self.player == 1 else 1

    def game_over(self):
        for player in [-1, 1]:
            for axis in [0, 1]:
                if (self.board.sum(axis=axis) == player*3).any():
                    return True
            if np.diag(self.board).sum() == player*3 or np.diag(np.fliplr(self.board)).sum() == player*3:
                return True
        return False

    def get_winner(self):
        for player in [-1, 1]:
            for axis in [0, 1]:
                if (self.board.sum(axis=axis) == player*3).any():
                    return player
            if np.diag(self.board).sum() == player*3 or np.diag(np.fliplr(self.board)).sum() == player*3:
                return player
        return 0

def UCT(node):
    return node.wins / node.visits + np.sqrt(2*np.log(node.parent.visits)/node.visits)

def select(node):
    while len(node.children) > 0:
        node = max(node.children, key=UCT)
    return node

def expand(node, game):
    for move in game.get_valid_moves():
        game_copy = deepcopy(game)
        game_copy.make_move(move)
        node.add_child(Node(game_copy.board, parent=node))

def simulate(game):
    while not game.game_over():
        moves = game.get_valid_moves()
        move = moves[np.random.randint(len(moves))]
        game.make_move(move)
    return game.get_winner()

def backpropagate(node, result):
    while node is not None:
        node.visits += 1
        if result == 1:
            node.wins += 1
        node = node.parent

def mcts(game, n_simulations=100):
    root = Node(game.board)

    for _ in range(n_simulations):
        node = select(root)
        game_copy = deepcopy(game)
        game_copy.board = node.state
        if not game_copy.game_over():
            expand(node, game_copy)
            if len(node.children) > 0:
                node = node.children[np.random.randint(len(node.children))]
                game_copy.board = node.state
        result = simulate(game_copy)
        backpropagate(node, result)

    return max(root.children, key=lambda x: x.visits).state

game = TicTacToe()
while not game.game_over():
    print(game.board)
    if game.player == 1:
        moves = game.get_valid_moves()
        move = moves[np.random.randint(len(moves))]
    else:
        move = np.argwhere(mcts(game) != 0)[0]
    game.make_move(move)
print(game.board)

代码的实现思路
Node类:表示MCTS中的一个节点。每个节点都有一个状态(对应井字棋的棋盘),可能有一个父节点,有一系列的子节点,以及节点被访问的次数(visits)和在模拟游戏中赢得的次数(wins)。

TicTacToe类:表示井字棋游戏。棋盘被表示为一个3x3的矩阵,其中0表示空位,1表示玩家1的棋子,-1表示玩家2的棋子。游戏类包含了获取有效移动的方法(get_valid_moves),执行移动的方法(make_move),检查游戏是否结束的方法(game_over),和获取胜者的方法(get_winner)。

UCT函数:计算节点的上限置信区间(Upper Confidence Bound,UCT)。UCT用于在选择阶段决定哪个子节点应该被访问。它是一个基于节点的平均奖励和访问次数的值。

select函数:实现MCTS的选择阶段。从根节点开始,每次都选择UCT值最高的子节点,直到找到一个尚未完全扩展的节点。

expand函数:实现MCTS的扩展阶段。对于给定的节点和游戏状态,生成所有可能的下一步移动并添加为子节点。

simulate函数:实现MCTS的模拟阶段。对游戏进行随机模拟,直到游戏结束,然后返回游戏结果。

backpropagate函数:实现MCTS的反向传播阶段。更新从叶节点到根节点路径上的所有节点的访问次数和胜利次数。

mcts函数:实现MCTS算法的主循环。进行指定次数的模拟,然后返回访问次数最多的子节点的状态。

主循环:创建一个井字棋游戏,然后在游戏结束之前,轮流让玩家1(使用随机策略)和玩家2(使用MCTS)进行移动。

  • simple Monte-carlo search
    根据现有的规则,对所有的action,simulate k 步,更新Q值,选择最好的action
    在这里插入图片描述

  • Monte-Carlo Tree Search Evaluation
    在这里插入图片描述
    在MCTS中,找到最好的动作主要涉及以下四个步骤:

  • 选择(Selection):从根节点开始,按照某种策略(如 UCB1)选择子节点,直到找到一个未完全扩展或终止的节点。

  • 扩展(Expansion):如果找到的节点不是终止节点,那么就创建一个或多个新的子节点,并选择其中一个。

  • 模拟(Simulation):从选定的节点开始,进行 Monte Carlo 模拟,即按照一定策略(通常是随机策略)选择动作,直到游戏结束。

  • 回传(Backpropagation):根据模拟的结果,更新从根节点到选定节点路径上的所有节点。通常,每个节点会记录模拟的次数和获得的总奖励。

通过反复执行这四个步骤,MCTS会逐渐扩展其游戏树,并越来越偏向于选择有希望的动作。最后,从根节点开始,选择模拟次数最多或平均奖励最高的动作,就是 MCTS 找到的最好动作。

这个过程的一个关键点是,MCTS 利用了游戏树和回传步骤来维护关于每个状态和动作的信息,这使得 MCTS 能够根据以前的模拟结果来指导未来的模拟。这一点是简单的 Monte Carlo 搜索所没有的,它会独立地对每个动作进行模拟,而忽略了这些动作之间可能的关系。
在这里插入图片描述

4.3 MCTS in Go

  • position Evaluation in Go
    在这里插入图片描述
  • Monte-carlo Evaluation in Go
    在这里插入图片描述
  • Applying Monte-Carlo Tree Search
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • Advantages of MC Tree Search
    在这里插入图片描述

4.4 Temporal Difference Search

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • Dyna-2
    在这里插入图片描述

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

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

相关文章

Fabric 超级账本学习【12】Hyperledger Fabric 2.4+Gin框架+Gateway 读取/写入账本数据 (Go版本)

文章目录 Fabric2.4Gin框架Gateway 读取/写入账本数据Gin框架优点Fabric-GatewayGateway搭建客户端我们需要准备哪些文件Gateway Client 为什么整个过程没有指定过背书节点?&#xff08;请求背书原理&#xff09;安装Gin前提条件成功部署Fabric2.4&#xff08;或其他版本的&am…

Qt 自定义窗口的标题栏,重写鼠标事件实现,隐藏窗口,最大化/最小化窗口,关闭窗口

Qt 自定义窗口的标题栏&#xff0c;重写鼠标事件实现&#xff0c;隐藏窗口&#xff0c;最大化/最小化窗口&#xff0c;关闭窗口 1、main.cpp #include "widget.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widg…

ArcGis教程-画一幅城市的shp地图

怎样使用ArcGis10.6得到这么一幅shp地图呢&#xff1f; 首先打开ArcGis10.6&#xff0c;点击带黄底的小加号&#xff0c;添加底图。 可以选择中国地图彩色版&#xff0c;然后双击&#xff0c;转动鼠标滑轮找到属于自己的城市。 点击-目录&#xff0c;在新建的文件夹里右击-新建…

TS:如何判断联合类型变量的具体类型?

一 表示一个值可以是几种类型之一&#xff1a;联合类型 在TS中我们常会遇到这样一个问题。 一个变量&#xff0c;即可能是这种类型&#xff0c;也可能是那种类型&#xff0c;然后根据传入的类型的不同进行不同的操作。 比如下面这种情况&#xff1a; if (pet.name fish) {p…

三种灰狼优化算法(Grey Wolf Optimization)及仿真实验——附代码Matalb

目录 摘要&#xff1a; 灰狼算法原理&#xff1a; 灰狼算法流程&#xff1a; 改进的灰狼算法&#xff1a; 多目标的灰狼算法&#xff1a; 三种灰狼算法运行效果&#xff1a; &#xff08;1&#xff09;GWO &#xff08;2&#xff09;I-GWO &#xff08;3&#xff09;M…

Windows Server 2016 中文版、英文版下载 (updated May 2023)

Windows Server 2016 中文版、英文版下载 (updated May 2023) Windows Server 2016 Version 1607&#xff0c;2023 年 5 月更新 请访问原文链接&#xff1a;https://sysin.org/blog/windows-server-2016/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者…

4.7 树的实现(上)

树 树&#xff08;Tree&#xff09;是n&#xff08;n≥0&#xff09;个节点的有限集合T&#xff0c;它满足两个条件 &#xff1a; 有且仅有一个特定的称为根&#xff08;Root&#xff09;的节点&#xff1b; 其余的节点可以分为m&#xff08;m≥0&#xff09;个互不相交的有…

电子企业WMS仓储管理系统解决方案

随着科技的飞速发展&#xff0c;电子制造行业对仓储管理系统的需求也越来越高。电子企业需要一种能够规划、执行和优化仓库货物流通的IT解决方案&#xff0c;以实现自动化操作和提高效率。本文将探讨电子企业WMS仓储管理系统解决方案&#xff0c;从需求分析、系统设计、实施与运…

在Windows系统中安装Wireshark(图文)

1.打开Wireshark官网后&#xff0c;点Get Acquainted->Download后进入到下载界面&#xff0c;在Stable Release中选择下载Windows 64位的安装包&#xff0c;单击Windows Installer(64-bit) 下载。 2.双击下载的安装包&#xff0c;如下图&#xff0c;点击Next。 3.点Noted&am…

ELK的安装部署与使用

ELK的安装与使用 安装部署 部署环境&#xff1a;Elasticsearch-7.17.3 Logstash-7.17.3 Kibana-7.17.3 一、安装部署Elasticsearch 解压目录&#xff0c;进入conf目录下编辑elasticsearch.yml文件&#xff0c;输入以下内容并保存 network.host: 127.0.0.1 http.port: 9200…

基于相似加权自组装框架的低质量少样本MRI脑卒中病变分割

文章目录 Stroke Lesion Segmentation from Low-Quality and Few-Shot MRIs via Similarity-Weighted Self-ensembling Framework摘要本文方法Soft Distribution-aware Updating (SDU) 实验结果 Stroke Lesion Segmentation from Low-Quality and Few-Shot MRIs via Similarity…

蓝桥杯模块学习5——按键

第一章 硬件部分 1.1 电路的组成部分 1.1.1 按键电路 原理图&#xff1a; 功能&#xff1a; &#xff08;1&#xff09; J5&#xff1a;当1和2相接&#xff0c;电路就变成一个4*4的矩阵键盘电路&#xff1b;当2和3相接时&#xff0c;电路变成了一个S4-S7的独立按键&#xf…

平板触控笔要原装的吗?苹果平替笔性价比高的推荐

与苹果的电容笔不同&#xff0c;市场上的电容笔只会给人一种倾斜的压感&#xff0c;并不会像苹果的电容笔那样&#xff0c;可以给人一种重力的压感。不过&#xff0c;如果你不一定要画画&#xff0c;那你就不用花很多钱去买一支苹果的原装电容笔了&#xff0c;只需一支平替电容…

ss命令使用详解

ss是Socket Statistics的缩写。顾名思义&#xff0c;ss命令可以用来获取socket统计信息&#xff0c;它可以显示和netstat类似的内容。ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息&#xff0c;而且比netstat更快速更高效。 当服务器的socket连接数量变得非常大…

从小白到专家:如何在营销中利用 AI 的力量

欢迎来到营销的未来&#xff0c;时至今日人工智能和人类专业知识以前所未有的方式结合在一起。 认识ChatGPT&#xff0c;这是改变游戏规则的革命性工具。 借助ChatGPT&#xff0c;你最终将能够利用AI的力量做出明智的、数据驱动的决策来满足你的受众需求。 但ChatGPT不仅仅是…

[高光谱]高光谱数据的获取与展示

一、环境准备 需要安装spectral包&#xff0c;这个包专门用于高光谱数据展示。 pip install spectral 二、数据加载 要预先准备原始高光谱的.mat数据和分类数据gt.mat(ground-turth)&#xff1b;然后使用scipy.io中的loadmat(.)将其读入程序。 from scipy.io import loadmat…

JCJC句子改写在线工具上线-202305

JCJC句子改写在线工具上线-202305 字根科技发布了新版JCJC在线句子改写功能。 使用网址&#xff1a; JCJC在线句子改写 新版的在线中文句子改写一共分为三种模式&#xff1a; 严谨模式普通模式休闲模式 上述三种改写模式适用于不同的改写需求&#xff0c;界面展示如下&…

springboot读取和写入csv文件数据

前言 csv格式的表格&#xff0c;和xls以及xlsx格式的表格有一些不同&#xff0c;不能够直接用处理xls的方式处理csv&#xff1b; 以下我将介绍如何读取并写入csv数据 准备工作 要处理csv格式的表格数据&#xff0c;我们首先需要引入pom.xml的依赖 <dependency><art…

Linux如何实现动态IP

Linux系统可以通过DHCP&#xff08;动态主机配置协议&#xff09;来实现动态IP。DHCP是一种自动分配IP地址的协议&#xff0c;它可以自动为网络中的设备分配IP地址、子网掩码、网关等网络参数&#xff0c;从而实现动态IP。 在Linux系统中&#xff0c;可以使用DHCP客户端工具来…

分享个常用的跨境电商数据分析平台

在跨境电商人眼中&#xff0c;适合用在跨境电商数据分析上的大数据分析平台该是怎样的&#xff1f;是效率高、财务指标计算快、业务能随时自助分析&#xff0c;最好是能将平台自身的分析经验分享给跨境电商企业&#xff0c;为企业提供更专业的服务。这样的大数据分析平台虽然少…