17、深度强化学习中的Q学习算法详解

深度强化学习中的Q学习算法详解

1. 策略选择与Q函数

在强化学习中,我们大部分时间会选择最大价值的行动。不过,为了提高模型的探索能力,我们通常会保留一个小概率的随机选择,即选择非最大行动价值对。这个随机探索的概率被称为epsilon,基于此的策略被称为epsilon - 贪婪策略。与之相对,如果我们一直只选择最大值而不进行探索,那就是贪婪策略。

初始时,我们可能不知道最优的行动价值函数,也就无法得到最优策略。我们需要迭代行动价值函数,找到能带来最大奖励的那个,这就是最优Q函数,记为Q ,进而得到最优策略Pi

我们使用神经网络来学习这个Q函数,因为神经网络是通用函数逼近器。一旦我们得到了行动价值函数,智能体就能学习到问题的最优策略。

1.1 Bellman方程

重新定义目标方程,我们可以得到:
[Q(s,a)=r_{t + 1}+\gamma r_{t + 2}+\gamma^2 r_{t + 3}+\cdots]
递归定义这个方程,就得到了Bellman方程:
[Q(s,a)=r+\gamma Q(s’,\pi(s’))]
简单来说,Bellman方程表明每个点的回报等于下一个时间步的估计奖励加上后续状态的折扣奖励。任何策略的值函数都遵循Bellman方程。

1.2 寻找最优Q函数

如果我们有了最优Q函数,就可以通过选择回报最高的行动来找到最优策略。

1.3 深度Q学习

深度Q学习算法使用神经网络来解决Q学习问题,对于具有连续空间的强化学习问题(即不终止的任务)效果很好。

我们之前提到了价值函数(V)和行动价值函数(Q),由于神经网络是通用函数逼近器,我们可以假设它们是带有可训练权重的神经网络。价值函数会输入状态和网络权重,输出当前状态的值。我们需要计算某种误差,将其反向传播到网络中,并使用梯度下降进行训练。我们要将网络的输出(价值函数)与我们认为的最优值进行比较。

根据Bellman方程,我们可以通过考虑下一个状态的值来计算期望Q,通过考虑到目前为止的累积奖励来计算当前Q。使用这两个Q函数之间的均方误差(MSE)作为损失。当误差较大时,研究人员建议使用平均绝对误差代替MSE,这种损失被称为Huber损失。误差公式如下:
[Error (Loss)=R+\gamma \max(Q_{target}) - Q_{current}]
其中,(Q_{target}) 使用贪婪策略,(Q_{current}) 使用epsilon - 贪婪策略。

1.4 训练循环

训练循环的代码如下:

# 初始化权重
w = ...  # 随机初始化
# 采用epsilon - 贪婪策略
π = epsilon - greedy
# 遍历所有回合
for i_episode in range(num_episodes):
    # 重置环境
    env.reset()
    # 获取上一帧画面
    last_screen = get_screen()
    # 获取当前帧画面
    current_screen = get_screen()
    # 当前状态为两帧画面之差
    state = current_screen - last_screen
    # 遍历每个时间步
    for t in count():
        # 根据当前状态选择行动
        action = select_action(state)
        # 执行行动,获取奖励和完成标志
        _, reward, done, _ = env.step(action.item())
        reward = torch.tensor([reward], device=device)
        # 观察新状态
        last_screen = current_screen
        current_screen = get_screen()
        if not done:
            next_state = current_screen - last_screen
        else:
            next_state = None
        # 将转移存储到记忆中
        memory.push(state, action, next_state, reward)
        # 转移到下一个状态
        state = next_state
        # 进行一次优化步骤
        optimize_model()
        if done:
            break
    # 每TARGET_UPDATE个回合更新一次目标网络
    if i_episode % TARGET_UPDATE == 0:
        target_net.load_state_dict(policy_net.state_dict())
env.close()

这里使用epsilon - 贪婪策略选择行动并更新策略,这是一种在线策略算法。在线策略算法学习速度快,收敛迅速,但学习的策略和决策策略紧密相关。与之相对的是离线策略算法,Q学习就是一种离线策略算法,它有两个策略:用于推断行动的epsilon - 贪婪策略(策略网络)和用于更新的贪婪策略(目标网络)。我们会定期将策略网络的权重复制到目标网络,以避免追逐一个移动的目标。

1.5 经验回放

为了改进算法,我们可以添加一个有限的经验记忆库,每个事务是一个元组,包含状态、采取的行动、下一个状态和奖励。

from collections import namedtuple

Transition = namedtuple('Transition',  
                      ('state', 'action', 'next_state', 'reward'))

class ReplayMemory(object):
    def __init__(self, capacity):
        self.capacity = capacity
        self.memory = []
        self.position = 0

    def push(self, *args):
        if len(self.memory) < self.capacity:
            self.memory.append(None)
        self.memory[self.position] = Transition(*args)
        self.position = (self.position + 1) % self.capacity

    def sample(self, batch_size):
        return random.sample(self.memory, batch_size)

    def __len__(self):
        return len(self.memory)

memory = ReplayMemory(10000)

我们会在优化模型时随机采样一些经验进行学习。

1.6 Gym环境

我们使用OpenAI的Gym来获取环境参数,这里以训练一个平衡杆为例。

import gym
import torch

env = gym.make('CartPole-v0').unwrapped
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

在这个环境中,每个观察或状态有四个值:位置、速度、杆的角度和杆尖的速度,可采取的行动是向左或向右移动。

1.7 获取屏幕函数

import numpy as np
import torchvision.transforms as T
from PIL import Image

screen_width = 600

def get_screen():
    screen = env.render(mode='rgb_array').transpose((2, 0, 1))   
    screen = screen[:, 160:320]   
    world_width = env.x_threshold * 2
    scale = screen_width / world_width
    cart_location = int(env.state[0] * scale + screen_width / 2.0)   
    view_width = 320
    if cart_location < view_width // 2:
        slice_range = slice(view_width)
    elif cart_location > (screen_width - view_width // 2):
        slice_range = slice(-view_width, None)
    else:
        slice_range = slice(cart_location - view_width // 2,
                            cart_location + view_width // 2)
    screen = screen[:, :, slice_range]
    screen = np.ascontiguousarray(screen, dtype=np.float32) / 255
    screen = torch.from_numpy(screen)
    resize = T.Compose([T.ToPILImage(),
                        T.Resize(40, interpolation=Image.CUBIC),
                        T.ToTensor()])
    return resize(screen).unsqueeze(0).to(device)   

这个函数会从环境中获取屏幕,裁剪出以平衡杆为中心的正方形图像,将其转换为张量,进行一些变换,添加一个维度并返回。

1.8 定义网络

import torch.nn as nn
import torch.nn.functional as F

class DQN(nn.Module):
    def __init__(self):
        super(DQN, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=5, stride=2)
        self.bn1 = nn.BatchNorm2d(16)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=5, stride=2)
        self.bn2 = nn.BatchNorm2d(32)
        self.conv3 = nn.Conv2d(32, 32, kernel_size=5, stride=2)
        self.bn3 = nn.BatchNorm2d(32)
        self.head = nn.Linear(448, 2)

    def forward(self, x):
        x = F.relu(self.bn1(self.conv1(x)))
        x = F.relu(self.bn2(self.conv2(x)))
        x = F.relu(self.bn3(self.conv3(x)))
        return self.head(x.view(x.size(0), -1))

policy_net = DQN().to(device)
target_net = DQN().to(device)
target_net.load_state_dict(policy_net.state_dict())
target_net.eval()

我们定义了两个网络:策略网络和目标网络。将策略网络的权重复制到目标网络,目标网络处于评估模式,这样在反向传播时不会更新其权重。我们在每个步骤推断策略网络,但会定期更新目标网络。

1.9 选择行动函数

import math
import random

EPS_START = 0.9
EPS_END = 0.05
EPS_DECAY = 200
steps_done = 0

def select_action(state):
    global steps_done
    eps_threshold = EPS_END + (EPS_START - EPS_END) * \
        math.exp(-1. * steps_done / EPS_DECAY)
    steps_done += 1
    sample = random.random()
    if sample > eps_threshold:
        with torch.no_grad():
            return policy_net(state).max(1)[1].view(1, 1)
    else:
        return torch.tensor([[random.randrange(2)]],  
device=device, dtype=torch.long)

这个函数使用epsilon - 贪婪策略选择行动,在一定比例的时间内从策略网络推断行动,但也有eps_threshold的概率随机选择行动。

1.10 训练循环

from itertools import count
import torch.optim as optim

num_episodes = 20
TARGET_UPDATE = 5

for i_episode in range(num_episodes):
    env.reset()
    last_screen = get_screen()
    current_screen = get_screen()
    state = current_screen - last_screen
    for t in count():
        action = select_action(state)
        _, reward, done, _ = env.step(action.item())
        reward = torch.tensor([reward], device=device)
        last_screen = current_screen
        current_screen = get_screen()
        if not done:
            next_state = current_screen - last_screen
        else:
            next_state = None
        memory.push(state, action, next_state, reward)
        state = next_state
        optimize_model()
        if done:
            break
    if i_episode % TARGET_UPDATE == 0:
        target_net.load_state_dict(policy_net.state_dict())

env.close()

在每个回合中,我们重置环境,获取当前状态,选择行动,执行行动并获取奖励和新状态,将转移存储到记忆中,然后进行优化。每5个回合更新一次目标网络。

1.11 优化模型函数

BATCH_SIZE = 64
GAMMA = 0.999
optimizer = optim.RMSprop(policy_net.parameters())

def optimize_model():
    if len(memory) < BATCH_SIZE:
        return
    transitions = memory.sample(BATCH_SIZE)
    batch = Transition(*zip(*transitions))
    state_batch = torch.cat(batch.state)
    action_batch = torch.cat(batch.action)
    state_values = policy_net(state_batch)   
    state_action_values = state_values.gather(1, action_batch)
    non_final_mask = torch.tensor(tuple(map(
                                        lambda s: s is not None,
                                         batch.next_state)),
                                         device=device, 
                                         dtype=torch.uint8)
    non_final_next_states = torch.cat([s for s in batch.next_state if s is not None])
    next_state_values = torch.zeros(BATCH_SIZE, device=device)   
    next_state_values[non_final_mask] = target_net(non_final_next_states).max(1)[0].detach()
    reward_batch = torch.cat(batch.reward)
    expected_state_action_values = (next_state_values * GAMMA) + reward_batch
    loss = F.smooth_l1_loss(state_action_values, expected_state_action_values.unsqueeze(1))
    optimizer.zero_grad()
    loss.backward()
    for param in policy_net.parameters():
        param.grad.data.clamp_(-1, 1)
    optimizer.step()

这个函数是优化的核心部分。我们从记忆库中采样经验,将状态、行动和奖励转换为批次,通过策略网络获取状态值,进而得到实际Q函数。然后,我们创建一个掩码来区分非最终状态和最终状态,通过目标网络计算期望Q函数,计算损失并将误差反向传播到策略网络。我们还使用梯度裁剪来确保梯度不会过大。

1.12 训练方式对比

训练神经网络需要一些时间,因为过程中需要渲染每一帧并计算误差。我们也可以采用更简单的方法,直接使用速度和位置来构建损失函数,这样训练时间会更短,因为不需要渲染每一帧,直接从env.state获取输入即可。

1.13 算法改进方向

该算法有很多改进方向,例如为智能体添加想象力,使其能更好地探索,在脑海中想象行动并做出更好的预测。

1.14 总结

我们学习了无监督学习中的一个全新领域:强化学习。我们了解了如何为强化学习问题构建模型,并训练了一个模型,使其能够根据环境提供的一些测量值学习如何平衡一个平衡杆。这些知识可以应用于教机器人走路、驾驶汽车和玩游戏等,是深度学习较为实际的应用之一。

1.15 流程图

graph TD;
    A[初始化环境和网络] --> B[开始回合];
    B --> C[获取当前状态];
    C --> D[选择行动];
    D --> E[执行行动并获取奖励和新状态];
    E --> F[存储转移到记忆中];
    F --> G[优化模型];
    G --> H{回合是否结束};
    H -- 否 --> C;
    H -- 是 --> I{是否更新目标网络};
    I -- 是 --> J[更新目标网络权重];
    I -- 否 --> K[结束当前回合];
    K --> B;

1.16 表格:主要参数说明

参数 说明
EPS_START epsilon的起始值
EPS_END epsilon的最终值
EPS_DECAY epsilon的衰减率
BATCH_SIZE 批次大小
GAMMA 折扣因子
TARGET_UPDATE 目标网络更新周期
num_episodes 回合数

2. 核心概念总结

2.1 策略类型

在强化学习中,策略的选择对智能体的学习和决策起着关键作用。以下是两种主要策略的详细对比:
| 策略类型 | 描述 | 优点 | 缺点 |
| ---- | ---- | ---- | ---- |
| epsilon - 贪婪策略 | 大部分时间选择最大价值的行动,但保留小概率随机选择非最大行动价值对,随机探索概率为epsilon | 提高模型的探索能力,避免陷入局部最优 | 探索过程可能引入噪声,影响学习效率 |
| 贪婪策略 | 始终只选择最大值,不进行探索 | 决策简单直接,在某些已知环境中可快速收敛到局部最优 | 容易陷入局部最优,无法充分探索环境 |

2.2 网络结构

我们定义了两个重要的神经网络:策略网络(policy_net)和目标网络(target_net)。它们的结构和作用如下:

import torch.nn as nn
import torch.nn.functional as F

class DQN(nn.Module):
    def __init__(self):
        super(DQN, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=5, stride=2)
        self.bn1 = nn.BatchNorm2d(16)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=5, stride=2)
        self.bn2 = nn.BatchNorm2d(32)
        self.conv3 = nn.Conv2d(32, 32, kernel_size=5, stride=2)
        self.bn3 = nn.BatchNorm2d(32)
        self.head = nn.Linear(448, 2)

    def forward(self, x):
        x = F.relu(self.bn1(self.conv1(x)))
        x = F.relu(self.bn2(self.conv2(x)))
        x = F.relu(self.bn3(self.conv3(x)))
        return self.head(x.view(x.size(0), -1))

policy_net = DQN().to(device)
target_net = DQN().to(device)
target_net.load_state_dict(policy_net.state_dict())
target_net.eval()
  • 策略网络(policy_net) :用于实时推断智能体的行动,在每个步骤中都进行使用。
  • 目标网络(target_net) :定期从策略网络复制权重,处于评估模式,在反向传播时不更新其权重,用于计算期望Q值,避免目标值的频繁变动,使学习过程更加稳定。

2.3 关键函数及作用

以下是代码中几个关键函数的详细说明:
| 函数名 | 作用 |
| ---- | ---- |
| select_action(state) | 使用epsilon - 贪婪策略选择行动,根据随机数和eps_threshold决定是从策略网络推断行动还是随机选择行动 |
| optimize_model() | 优化模型的核心函数,从记忆库中采样经验,计算实际Q值和期望Q值,计算损失并反向传播误差到策略网络,同时使用梯度裁剪确保梯度稳定 |
| get_screen() | 从环境中获取屏幕图像,裁剪出以平衡杆为中心的正方形图像,转换为张量并进行必要的变换,用于表示当前状态 |

2.4 训练流程

整个训练过程可以用以下流程图表示:

graph LR;
    A[初始化环境和网络] --> B[初始化参数和变量];
    B --> C[开始回合循环];
    C --> D[重置环境并获取初始状态];
    D --> E[开始时间步循环];
    E --> F[选择行动];
    F --> G[执行行动并获取奖励和新状态];
    G --> H[存储转移到记忆中];
    H --> I[优化模型];
    I --> J{回合是否结束};
    J -- 否 --> E;
    J -- 是 --> K{是否更新目标网络};
    K -- 是 --> L[更新目标网络权重];
    K -- 否 --> M[结束当前回合];
    M --> C;

具体步骤如下:
1. 初始化 :初始化环境、网络(策略网络和目标网络)、参数(如epsilon、批次大小、折扣因子等)和变量(如步数计数器)。
2. 回合循环 :开始多个回合的训练,每个回合代表一次完整的任务执行。
3. 重置环境 :在每个回合开始时,重置环境并获取初始状态。
4. 时间步循环 :在每个回合内,按时间步进行循环,直到回合结束。
5. 选择行动 :使用 select_action 函数根据当前状态选择行动。
6. 执行行动 :执行选择的行动,从环境中获取奖励和新状态。
7. 存储转移 :将当前状态、行动、下一个状态和奖励存储到记忆库中。
8. 优化模型 :调用 optimize_model 函数进行模型优化。
9. 回合结束判断 :判断当前回合是否结束,如果未结束则继续时间步循环;如果结束,则判断是否需要更新目标网络。
10. 更新目标网络 :根据设定的更新周期,决定是否更新目标网络的权重。

2.5 算法改进思路

虽然当前的Q学习算法已经取得了不错的效果,但仍有一些改进的方向:
- 添加想象力 :为智能体添加想象力模块,使其能够在脑海中模拟未来的行动和结果,从而更好地探索环境,做出更优的决策。例如,可以使用生成模型来预测未来可能的状态和奖励。
- 多策略融合 :结合多种不同的策略,根据环境的不同阶段和状态动态选择合适的策略,以平衡探索和利用的关系。
- 自适应参数调整 :根据学习过程中的反馈动态调整参数,如epsilon的衰减率、折扣因子等,使算法能够更好地适应不同的环境和任务。

2.6 应用拓展

强化学习的应用非常广泛,除了平衡杆问题,还可以应用于以下领域:
- 机器人控制 :教机器人完成各种任务,如走路、抓取物体、导航等。
- 自动驾驶 :训练自动驾驶汽车在复杂的交通环境中做出决策,如加速、减速、转弯等。
- 游戏开发 :使游戏智能体能够学习并掌握游戏策略,如玩棋类游戏、电子竞技游戏等。

通过不断地改进和优化算法,强化学习在更多领域的应用前景将更加广阔。

内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
内容概要:本文系统阐述了企业新闻发稿在生成式引擎优化(GEO)时代下的全渠道策略与效果评估体系,涵盖当前企业传播面临的预算、资源、内容与效果评估四大挑战,并深入分析2025年新闻发稿行业五大趋势,包括AI驱动的智能化转型、精准化传播、首发内容价值提升、内容资产化及数据可视化。文章重点解析央媒、地方官媒、综合门户和自媒体四类媒体资源的特性、传播优势与发稿策略,提出基于内容适配性、时间节奏、话题设计的策略制定方法,并构建涵盖品牌价值、销售转化与GEO优化的多维评估框架。此外,结合“传声港”工具实操指南,提供AI智能投放、效果监测、自媒体管理与舆情应对的全流程解决方案,并针对科技、消费、B2B、区域品牌四大行业推出定制化发稿方案。; 适合人群:企业市场/公关负责人、品牌传播管理者、数字营销从业者及中小企业决策者,具备一定媒体传播经验并希望提升发稿效率与ROI的专业人士。; 使用场景及目标:①制定科学的新闻发稿策略,实现从“流量思维”向“价值思维”转型;②构建央媒定调、门户扩散、自媒体互动的立体化传播矩阵;③利用AI工具实现精准投放与GEO优化,提升品牌在AI搜索中的权威性与可见性;④通过数据驱动评估体系量化品牌影响力与销售转化效果。; 阅读建议:建议结合文中提供的实操清单、案例分析与工具指南进行系统学习,重点关注媒体适配性策略与GEO评估指标,在实际发稿中分阶段试点“AI+全渠道”组合策略,并定期复盘优化,以实现品牌传播的长期复利效应。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值