最新资讯

  • 【强化学习】REINFORCE 算法

【强化学习】REINFORCE 算法

2026-02-02 02:52:53 栏目:最新资讯 3 阅读

目录

一、引言

二、REINFORCE 算法的核心定位与关键特性

三、REINFORCE 算法的数学基础(通俗推导,贴合代码)

1. 核心目标:最大化策略的期望累计回报

2. 关键推导:策略梯度的无偏估计

3. 工程化转化:梯度下降替代梯度上升

四、代码与算法的逐模块对应实现

模块 1:策略网络(PolicyNet)—— 实现策略πθ​(a∣s)的参数化

模块 2:REINFORCE 算法核心类 —— 实现策略采样、累计回报计算、策略梯度更新

2.1 __init__:初始化算法核心组件

2.2 take_action:根据策略πθ​(a∣s)采样动作(同策略探索)

2.3 update:REINFORCE 算法的核心 —— 实现蒙特卡洛策略梯度更新

模块 3:超参数与环境初始化 —— 工程化适配,保证实验可复现

模块 4:蒙特卡洛训练循环 —— 采集完整轨迹,实现回合式更新

模块 5:结果可视化 —— 分析训练收敛趋势

五、REINFORCE 算法的完整执行流程(结合代码)

六、REINFORCE 算法的Python代码完整实现

七、程序运行结果展示

八、REINFORCE 算法的优缺点(结合代码表现)

优点(代码完美体现)

缺点(代码训练中会体现)

九、经典改进方向(解决高方差 / 低效率问题)

十、总结


一、引言

REINFORCE 算法策略梯度(Policy Gradient, PG) 家族中最经典、最基础的无模型强化学习算法,由 Williams 在 1992 年提出。核心特点是直接参数化策略、通过蒙特卡洛(MC)方式采集完整回合数据、用梯度上升最大化期望累计回报,区别于 DQN 这类先学习值函数再推导策略的 “间接法”,REINFORCE 是直接优化策略的 “直接法”,非常适合离散动作空间(如 CartPole-v1 的左右两个动作)。

二、REINFORCE 算法的核心定位与关键特性

先明确算法的核心属性,这是理解代码设计的基础,代码的每一处实现都贴合这些特性:

  1. 无模型(Model-Free):无需学习环境的状态转移模型P(s′∣s,a)和奖励模型R(s,a),仅通过与环境交互采集的轨迹数据更新策略,代码中仅用env.step()env.reset()交互,无任何环境模型相关代码。
  2. 同策略(On-Policy):必须用当前策略采样的轨迹数据来更新策略,采样和更新的策略是同一个,代码中每回合用agent.take_action()(当前策略)采样动作,采集完轨迹后直接用该轨迹更新策略,无经验回放(经验回放是异策略的典型特征)。
  3. 蒙特卡洛(MC)式更新:必须采集完整的回合轨迹(从初始状态到终止状态),只有拿到回合的全部奖励,才能计算每一步的累计折扣回报,代码中每个回合结束后才调用agent.update(),而非步更 / 半回合更,这是蒙特卡洛的核心标志。
  4. 离散动作空间适配:策略网络输出动作的概率分布,通过类别分布(Categorical)采样动作,代码中用torch.distributions.Categorical实现,完美适配 CartPole-v1 的二分类动作。
  5. 梯度上升最大化回报:目标是找到策略参数,让策略的期望累计回报最大;因 PyTorch 仅支持梯度下降,故将 “最大化回报” 转化为 “最小化负的回报损失”,代码中损失函数为- log_prob * G就是这个逻辑。

三、REINFORCE 算法的数学基础(通俗推导,贴合代码)

REINFORCE 的核心是推导出策略梯度的无偏估计,让代码的更新逻辑有理论支撑。

1. 核心目标:最大化策略的期望累计回报

我们用参数θ表示策略网络(代码中是 PolicyNet 的权重),策略记为,表示在状态s下,策略θ选择动作a的概率。

算法的核心目标是找到最优参数θ∗,让策略的期望累计折扣回报J(θ)最大:

其中​是从初始状态开始的累计折扣回报,​​表示对策略​采样的所有轨迹求期望。

2. 关键推导:策略梯度的无偏估计

要最大化J(θ),需要计算J(θ)对参数θ的梯度(即策略梯度),然后用梯度上升更新θ:

(α是学习率,代码中由 Adam 优化器自适应调整)

Williams 通过数学推导,得出策略梯度的无偏蒙特卡洛估计(这是 REINFORCE 的核心公式):

  • N:训练的回合数(代码中每次 update 对应 1 个回合,N=1);
  • ​:第n个回合的步数;
  • :第n回合t步,策略选择动作an,t​的对数概率(代码中log_prob);
  • ,t​:第n回合t步开始到回合结束的累计折扣回报(代码中G),计算式为:

是折扣因子(代码中gamma=0.98),用于衰减远期奖励的权重,让算法更关注近期奖励。

3. 工程化转化:梯度下降替代梯度上升

PyTorch 等深度学习框架仅支持梯度下降(最小化损失函数),因此将策略梯度的最大化目标转化为最小化负的策略梯度损失

​这就是代码中loss = - log_prob * G理论根源,反向传播该损失的梯度,等价于对原目标做梯度上升。

四、代码与算法的逐模块对应实现

代码分为策略网络(PolicyNet)REINFORCE 算法核心类超参数与环境初始化蒙特卡洛训练循环结果可视化5 个模块,每个模块都严格对应 REINFORCE 算法的理论要求,下面逐模块讲解。

模块 1:策略网络(PolicyNet)—— 实现策略πθ​(a∣s)的参数化

策略网络是 REINFORCE 的 “核心载体”,作用是将状态s映射为动作a的概率分布,代码中是两层全连接网络,适配 CartPole-v1 的简单状态空间(4 维观测)。

class PolicyNet(torch.nn.Module):
    def __init__(self, state_dim, hidden_dim, action_dim):
        super(PolicyNet, self).__init__()
        self.fc1 = torch.nn.Linear(state_dim, hidden_dim)  # 状态映射到隐藏层
        self.fc2 = torch.nn.Linear(hidden_dim, action_dim) # 隐藏层映射到动作空间

    def forward(self, x):
        x = F.relu(self.fc1(x))  # 非线性激活,拟合复杂状态-动作映射
        return F.softmax(self.fc2(x), dim=1)  # 转概率分布(和为1)

算法对应点

  1. 输入state_dim(CartPole-v1 为 4):环境的观测维度,对应状态s;
  2. 输出action_dim(CartPole-v1 为 2):离散动作的数量,输出值经softmax激活后,直接表示πθ​(a∣s)(状态s下选每个动作的概率);
  3. softmax的必要性:保证输出是合法的概率分布(所有动作的概率和为 1),这是策略πθ​(a∣s)的基本要求。
模块 2:REINFORCE 算法核心类 —— 实现策略采样、累计回报计算、策略梯度更新

这是代码的核心,完全实现了 REINFORCE 的三大核心功能:动作采样累计折扣回报Gt​计算策略梯度更新,分为__init__take_actionupdate三个方法。

2.1 __init__:初始化算法核心组件
def __init__(self, state_dim, hidden_dim, action_dim, learning_rate, gamma, device):
    self.policy_net = PolicyNet(state_dim, hidden_dim, action_dim).to(device)  # 策略网络
    self.optimizer = torch.optim.Adam(self.policy_net.parameters(), lr=learning_rate)  # 梯度优化器
    self.gamma = gamma     # 折扣因子γ,用于计算G_t
    self.device = device   # 训练设备(GPU/CPU)

关键细节:用 Adam 自适应优化器替代原始的随机梯度上升(SGD),提升训练稳定性和收敛速度,这是工程实现的常规优化,不改变算法核心。

2.2 take_action:根据策略πθ​(a∣s)采样动作(同策略探索)
def take_action(self, state):
    # 状态转张量,消除创建警告,适配设备
    state = torch.tensor(np.array([state]), dtype=torch.float).to(self.device)
    probs = self.policy_net(state)  # 得到动作概率分布π_θ(a|s)
    action_dist = torch.distributions.Categorical(probs)  # 构建类别分布
    action = action_dist.sample()  # 从概率分布中随机采样动作
    return action.item()

算法对应点

  1. 非贪心采样:策略梯度算法需要探索环境,因此不能选概率最大的动作(贪心),而是从概率分布中随机采样(比如动作 1 概率 0.8、动作 2 概率 0.2,大概率选 1 但小概率选 2,保证探索);
  2. 类别分布(Categorical):专门用于离散动作的概率采样,输入动作概率分布,输出采样的动作索引,完美适配 REINFORCE 的离散动作要求;
  3. 同策略采样:每次采样用的都是当前策略网络的最新参数,符合 “同策略” 特性。
2.3 update:REINFORCE 算法的核心 —— 实现蒙特卡洛策略梯度更新

这部分代码完全对应策略梯度的数学公式,是算法的 “灵魂”,必须在采集完完整回合轨迹后调用

def update(self, transition_dict):
    # 从轨迹字典中取出当前回合的所有s/a/r
    reward_list = transition_dict['rewards']
    state_list = transition_dict['states']
    action_list = transition_dict['actions']

    G = 0  # 初始化累计折扣回报
    self.optimizer.zero_grad()  # 清空梯度(PyTorch梯度累加,必须手动清空)
    # 从最后一步反向遍历,计算每一步的G_t(核心!)
    for i in reversed(range(len(reward_list))):
        reward = reward_list[i]  # 当前步的奖励r_t
        # 状态转张量,适配设备
        state = torch.tensor(np.array([state_list[i]]), dtype=torch.float).to(self.device)
        # 动作转张量并reshape,匹配gather的维度要求
        action = torch.tensor([action_list[i]]).view(-1, 1).to(self.device)
        # 计算log π_θ(a_t|s_t):取当前动作对应的对数概率
        log_prob = torch.log(self.policy_net(state).gather(1, action))
        # 反向计算累计折扣回报G_t = r_t + γ * G_{t+1}
        G = self.gamma * G + reward
        # 计算单步损失:- log_prob * G(梯度下降替代梯度上升)
        loss = - log_prob * G
        loss.backward()  # 单步反向传播,累加梯度(核心!逐步计算,梯度累加)
    self.optimizer.step()  # 一次更新所有参数(同策略MC的特性)

算法核心细节(逐行对应理论)

  1. 反向遍历计算Gt​:从回合最后一步(t=T−1)往回算,是计算累计折扣回报最高效的方式,公式为​:
    • 最后一步(t=T−1):​(后面无奖励,G=0);
    • 倒数第二步(t=T−2):​;
    • 以此类推,直到第一步(t=0),完美计算每一步的
  2. gather(1, action):从策略网络输出的动作概率分布中,取出当前采样动作对应的概率(比如输出 [0.2, 0.8],采样动作 1,就取 0.8),再取对数得到
  3. 梯度累加(loss.backward()在循环内):策略梯度的公式是所有步的梯度之和,因此这里逐步计算损失并反向传播,让 PyTorch 自动累加梯度,最后一次更新参数,这是 REINFORCE 蒙特卡洛更新的标准实现。
  4. 一次更新参数(optimizer.step()在循环外):遍历完所有步、累加完所有梯度后,才调用优化器更新策略网络的参数,符合 “完整回合后更新” 的蒙特卡洛特性。
模块 3:超参数与环境初始化 —— 工程化适配,保证实验可复现

这部分是强化学习的工程实现基础,无算法理论,但直接影响训练效果和实验可复现性,代码中做了 Gymnasium 的完整适配。

# 超参数设置
learning_rate = 1e-3  # 学习率
num_episodes = 1000   # 总训练回合数
hidden_dim = 128      # 策略网络隐藏层维度
gamma = 0.98          # 折扣因子γ
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")  # 自动选设备

# 环境初始化(Gymnasium适配)
env_name = "CartPole-v1"
# 设置全局随机种子,保证实验可复现
np.random.seed(0)
torch.manual_seed(0)
random.seed(0)
env = gym.make(env_name)
# Gymnasium移除env.seed(),改用动作/观测空间种子
env.action_space.seed(0)
env.observation_space.seed(0)

# 获取环境维度
state_dim = env.observation_space.shape[0]  # 状态维度:4
action_dim = env.action_space.n              # 动作维度:2
# 实例化REINFORCE智能体
agent = REINFORCE(state_dim, hidden_dim, action_dim, learning_rate, gamma, device)

关键工程细节

  1. 随机种子设置:强化学习的训练结果受随机采样(动作、环境)影响,设置种子后,每次训练的结果完全一致,方便调参和验证;
  2. Gymnasium 适配:Gym 自 2022 年废弃,Gymnasium 是官方无缝替代,代码中处理了reset/step的返回值变化(后续训练循环会详细讲);
  3. 设备自适应:自动选择 GPU(如果有)加速训练,无 GPU 则用 CPU,不影响算法逻辑。
模块 4:蒙特卡洛训练循环 —— 采集完整轨迹,实现回合式更新

这部分代码实现REINFORCE 的蒙特卡洛核心要求:与环境交互,采集完整的回合轨迹,存储所有s/a/r/s′/done,回合结束后调用agent.update()更新策略,是 “算法理论” 到 “环境交互” 的桥梁。

return_list = []  # 存储每个回合的总回报,用于可视化
for i in range(10):
    with tqdm(total=int(num_episodes / 10), desc='Iteration %d' % i) as pbar:
        for i_episode in range(int(num_episodes / 10)):
            episode_return = 0  # 存储当前回合的总回报
            # 轨迹字典:存储当前回合的所有s/a/r/s'/done(蒙特卡洛需要完整轨迹)
            transition_dict = {'states': [], 'actions': [], 'next_states': [], 'rewards': [], 'dones': []}
            state, _ = env.reset(seed=0)  # Gymnasium:reset返回(state, info)
            done = False
            while not done:
                action = agent.take_action(state)  # 同策略采样动作
                # Gymnasium:step返回(next_state, reward, terminated, truncated, info)
                next_state, reward, terminated, truncated, _ = env.step(action)
                done = terminated or truncated  # 合并终止状态(环境终止+步数截断)
                # 存储当前步的轨迹数据
                transition_dict['states'].append(state)
                transition_dict['actions'].append(action)
                transition_dict['next_states'].append(next_state)
                transition_dict['rewards'].append(reward)
                transition_dict['dones'].append(done)
                # 更新状态和当前回合总回报
                state = next_state
                episode_return += reward
            # 回合结束:存储总回报,调用update更新策略(蒙特卡洛核心!)
            return_list.append(episode_return)
            agent.update(transition_dict)
            # 每10回合打印平均回报,监控训练进度
            if (i_episode + 1) % 10 == 0:
                pbar.set_postfix({'episode': '%d' % (num_episodes / 10 * i + i_episode + 1),
                                  'return': '%.3f' % np.mean(return_list[-10:])})
            pbar.update(1)

算法与工程对应点

  1. 完整轨迹采集while not done循环直到回合终止,保证采集的是从初始状态到终止状态的完整轨迹,符合蒙特卡洛 “完整回合更新” 的要求;
  2. Gymnasium 适配:处理了 Gymnasium 与原 Gym 的返回值差异(核心工程适配,不影响算法):
    • env.reset(seed=0):返回(state, info),取第一个元素为状态;
    • env.step(action):返回(next_state, reward, terminated, truncated, info),其中terminated是环境自然终止(如 CartPole 倒了),truncated是步数截断(如 CartPole 撑到 500 步),合并为done表示回合结束;
  3. 回合式更新只有当while not done循环结束(回合终止),才调用agent.update(transition_dict),将完整轨迹传入更新策略,这是 REINFORCE 蒙特卡洛特性的核心工程实现
  4. 回报监控:用return_list存储每个回合的总回报,每 10 回合计算一次平均回报,用于监控训练收敛趋势(CartPole-v1 的最大回报是 500,平均回报稳定在 500 表示算法收敛)。
模块 5:结果可视化 —— 分析训练收敛趋势

强化学习的训练过程存在大量噪声(因动作是随机采样的),直接绘制原始回报曲线会波动剧烈,因此代码中绘制了原始回报曲线移动平均(Moving Average)回报曲线,后者用于平滑噪声,清晰展示收敛趋势。

# 绘制原始回报曲线并保存
episode_list = list(range(len(return_list)))
plt.plot(episode_list, return_list)
plt.xlabel('Episodes')
plt.ylabel('Returns')
plt.title('REINFORCE on {}'.format(env_name))
plt.savefig('REINFORCE on CartPole-v1_training.png')
plt.show()

# 绘制移动平均回报曲线并保存(窗口大小9,平滑噪声)
mv_return = rl_utils.moving_average(return_list, 9)
plt.plot(episode_list, mv_return)
plt.xlabel('Episodes')
plt.ylabel('Moving Average Returns')
plt.title('REINFORCE on {}'.format(env_name))
plt.savefig('REINFORCE on CartPole-v1_moving_average.png')
plt.show()

关键作用

  • 原始回报曲线:展示每回合的真实训练效果,能看到噪声波动;
  • 移动平均曲线:用rl_utils.moving_average计算窗口内的平均回报,平滑噪声,能清晰看到算法是否收敛、收敛速度、收敛稳定性(比如 CartPole-v1 的移动平均曲线会逐渐上升,最终稳定在 500)。

五、REINFORCE 算法的完整执行流程(结合代码)

将上述模块串联,代码的执行流程就是 REINFORCE 算法的标准执行流程,一步一步清晰明了:

  1. 初始化:创建 CartPole-v1 环境,初始化策略网络和 REINFORCE 智能体,设置超参数和随机种子;
  2. 循环训练回合:总共有 1000 个训练回合,分 10 次迭代,每次 100 回合;
  3. 采集完整轨迹:对每个回合,从env.reset()开始,用当前策略agent.take_action()采样动作,通过env.step()与环境交互,采集每一步的s/a/r/s′/done,直到回合终止,得到完整轨迹;
  4. 蒙特卡洛策略梯度更新:回合终止后,将完整轨迹传入agent.update(),反向计算每一步的累计折扣回报Gt​,计算策略梯度并累加,最后一次更新策略网络的参数;
  5. 监控训练进度:存储每个回合的总回报,每 10 回合打印平均回报,监控收敛趋势;
  6. 可视化结果:训练结束后,绘制原始回报曲线和移动平均回报曲线,分析算法收敛效果;
  7. 收敛标志:当 CartPole-v1 的回合平均回报稳定在 500(环境最大步数),表示策略收敛,智能体能稳定让小车保持平衡。

六、REINFORCE 算法的Python代码完整实现

先实现rl_utils库,它包含一些函数,如绘制移动平均曲线、计算优势函数等,不同的算法可以一起使用这些函数。

rl_utils.py中的Python代码如下:

from tqdm import tqdm
import numpy as np
import torch
import collections
import random


class ReplayBuffer:
    def __init__(self, capacity):
        self.buffer = collections.deque(maxlen=capacity)

    def add(self, state, action, reward, next_state, done):
        self.buffer.append((state, action, reward, next_state, done))

    def sample(self, batch_size):
        transitions = random.sample(self.buffer, batch_size)
        state, action, reward, next_state, done = zip(*transitions)
        return np.array(state), action, reward, np.array(next_state), done

    def size(self):
        return len(self.buffer)


def moving_average(a, window_size):
    cumulative_sum = np.cumsum(np.insert(a, 0, 0))
    middle = (cumulative_sum[window_size:] - cumulative_sum[:-window_size]) / window_size
    r = np.arange(1, window_size - 1, 2)
    begin = np.cumsum(a[:window_size - 1])[::2] / r
    end = (np.cumsum(a[:-window_size:-1])[::2] / r)[::-1]
    return np.concatenate((begin, middle, end))


def train_on_policy_agent(env, agent, num_episodes):
    return_list = []
    for i in range(10):
        with tqdm(total=int(num_episodes / 10), desc='Iteration %d' % i) as pbar:
            for i_episode in range(int(num_episodes / 10)):
                episode_return = 0
                transition_dict = {'states': [], 'actions': [], 'next_states': [], 'rewards': [], 'dones': []}
                state, _ = env.reset()  # 适配Gymnasium:reset返回(state, info)
                done = False
                while not done:
                    action = agent.take_action(state)
                    # 适配Gymnasium:step返回(next_state, reward, terminated, truncated, info)
                    next_state, reward, terminated, truncated, _ = env.step(action)
                    done = terminated or truncated  # 终止=环境终止+步数截断
                    transition_dict['states'].append(state)
                    transition_dict['actions'].append(action)
                    transition_dict['next_states'].append(next_state)
                    transition_dict['rewards'].append(reward)
                    transition_dict['dones'].append(done)
                    state = next_state
                    episode_return += reward
                return_list.append(episode_return)
                agent.update(transition_dict)
                if (i_episode + 1) % 10 == 0:
                    pbar.set_postfix({'episode': '%d' % (num_episodes / 10 * i + i_episode + 1),
                                      'return': '%.3f' % np.mean(return_list[-10:])})
                pbar.update(1)
    return return_list


def train_off_policy_agent(env, agent, num_episodes, replay_buffer, minimal_size, batch_size):
    return_list = []
    for i in range(10):
        with tqdm(total=int(num_episodes / 10), desc='Iteration %d' % i) as pbar:
            for i_episode in range(int(num_episodes / 10)):
                episode_return = 0
                state, _ = env.reset()  # 适配Gymnasium
                done = False
                while not done:
                    action = agent.take_action(state)
                    # 适配Gymnasium step返回值
                    next_state, reward, terminated, truncated, _ = env.step(action)
                    done = terminated or truncated
                    replay_buffer.add(state, action, reward, next_state, done)
                    state = next_state
                    episode_return += reward
                    if replay_buffer.size() > minimal_size:
                        b_s, b_a, b_r, b_ns, b_d = replay_buffer.sample(batch_size)
                        transition_dict = {'states': b_s, 'actions': b_a, 'next_states': b_ns, 'rewards': b_r,
                                           'dones': b_d}
                        agent.update(transition_dict)
                return_list.append(episode_return)
                if (i_episode + 1) % 10 == 0:
                    pbar.set_postfix({'episode': '%d' % (num_episodes / 10 * i + i_episode + 1),
                                      'return': '%.3f' % np.mean(return_list[-10:])})
                pbar.update(1)
    return return_list


def compute_advantage(gamma, lmbda, td_delta):
    td_delta = td_delta.detach().numpy()
    advantage_list = []
    advantage = 0.0
    for delta in td_delta[::-1]:
        advantage = gamma * lmbda * advantage + delta
        advantage_list.append(advantage)
    advantage_list.reverse()
    return torch.tensor(advantage_list, dtype=torch.float)

REINFORCE 算法的Python代码如下:

import gymnasium as gym
import torch
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt
import rl_utils
import random  # 用于设置全局随机种子
from tqdm import tqdm

# 策略网络
class PolicyNet(torch.nn.Module):
    def __init__(self, state_dim, hidden_dim, action_dim):
        super(PolicyNet, self).__init__()
        self.fc1 = torch.nn.Linear(state_dim, hidden_dim)
        self.fc2 = torch.nn.Linear(hidden_dim, action_dim)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        return F.softmax(self.fc2(x), dim=1)

# REINFORCE算法
class REINFORCE:
    def __init__(self, state_dim, hidden_dim, action_dim, learning_rate, gamma, device):
        self.policy_net = PolicyNet(state_dim, hidden_dim, action_dim).to(device)
        self.optimizer = torch.optim.Adam(self.policy_net.parameters(), lr=learning_rate)
        self.gamma = gamma
        self.device = device

    def take_action(self, state):
        state = torch.tensor(np.array([state]), dtype=torch.float).to(self.device)
        probs = self.policy_net(state)
        action_dist = torch.distributions.Categorical(probs)
        action = action_dist.sample()
        return action.item()

    def update(self, transition_dict):
        reward_list = transition_dict['rewards']
        state_list = transition_dict['states']
        action_list = transition_dict['actions']

        G = 0
        self.optimizer.zero_grad()
        # 从最后一步反向计算累计回报
        for i in reversed(range(len(reward_list))):
            reward = reward_list[i]
            state = torch.tensor(np.array([state_list[i]]), dtype=torch.float).to(self.device)
            action = torch.tensor([action_list[i]]).view(-1, 1).to(self.device)
            log_prob = torch.log(self.policy_net(state).gather(1, action))
            G = self.gamma * G + reward
            loss = - log_prob * G  # 损失为负的对数概率乘累计回报(梯度上升等价于损失下降)
            loss.backward()  # 逐步反向传播计算梯度
        self.optimizer.step()  # 一次更新所有参数(同策略算法特性)

# 超参数设置
learning_rate = 1e-3
num_episodes = 1000  # 总训练回合数,原代码循环分10次,每次100回合,匹配总次数
hidden_dim = 128
gamma = 0.98
# 自动选择GPU/CPU
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")

# 环境初始化
env_name = "CartPole-v1"
# 设置全局随机种子(保证实验可复现)
np.random.seed(0)
torch.manual_seed(0)
random.seed(0)
# 创建环境,设置环境种子
env = gym.make(env_name)
env.action_space.seed(0)
env.observation_space.seed(0)

# 获取环境维度
state_dim = env.observation_space.shape[0]
action_dim = env.action_space.n
# 实例化REINFORCE智能体
agent = REINFORCE(state_dim, hidden_dim, action_dim, learning_rate, gamma, device)

# 训练循环
return_list = []
for i in range(10):
    # 总回合数1000,分10次迭代,每次100回合
    with tqdm(total=int(num_episodes / 10), desc='Iteration %d' % i) as pbar:
        for i_episode in range(int(num_episodes / 10)):
            episode_return = 0
            transition_dict = {'states': [], 'actions': [], 'next_states': [], 'rewards': [], 'dones': []}
            # 适配Gymnasium:reset返回(state, info),取第一个元素
            state, _ = env.reset(seed=0)  # 重置时指定seed
            done = False
            while not done:
                action = agent.take_action(state)
                # 适配Gymnasium:step返回(next_state, reward, terminated, truncated, info)
                next_state, reward, terminated, truncated, _ = env.step(action)
                # Gymnasium将done拆分为terminated(环境终止)和truncated(步数截断),合并为done
                done = terminated or truncated
                # 存储转移数据
                transition_dict['states'].append(state)
                transition_dict['actions'].append(action)
                transition_dict['next_states'].append(next_state)
                transition_dict['rewards'].append(reward)
                transition_dict['dones'].append(done)
                # 更新状态和累计回报
                state = next_state
                episode_return += reward
            # 存储当前回合回报
            return_list.append(episode_return)
            # 更新策略网络
            agent.update(transition_dict)
            # 每10回合打印一次平均回报
            if (i_episode + 1) % 10 == 0:
                pbar.set_postfix({'episode': '%d' % (num_episodes / 10 * i + i_episode + 1),
                                  'return': '%.3f' % np.mean(return_list[-10:])})
            pbar.update(1)

# 绘制训练曲线
episode_list = list(range(len(return_list)))
plt.plot(episode_list, return_list)
plt.xlabel('Episodes')
plt.ylabel('Returns')
plt.title('REINFORCE on {}'.format(env_name))
plt.savefig('REINFORCE on CartPole-v1_training.png')
plt.show()

# 绘制移动平均曲线,平滑显示训练趋势
mv_return = rl_utils.moving_average(return_list, 9)
plt.plot(episode_list, mv_return)
plt.xlabel('Episodes')
plt.ylabel('Moving Average Returns')
plt.title('REINFORCE on {}'.format(env_name))
plt.savefig('REINFORCE on CartPole-v1_moving_average.png')
plt.show()

七、程序运行结果展示

Iteration 0: 100%|██████████| 100/100 [00:01<00:00, 77.79it/s, episode=100, return=32.300]
Iteration 1: 100%|██████████| 100/100 [00:02<00:00, 42.19it/s, episode=200, return=65.400]
Iteration 2: 100%|██████████| 100/100 [00:06<00:00, 15.55it/s, episode=300, return=200.400]
Iteration 3: 100%|██████████| 100/100 [00:08<00:00, 11.99it/s, episode=400, return=213.200]
Iteration 4: 100%|██████████| 100/100 [00:06<00:00, 16.56it/s, episode=500, return=130.000]
Iteration 5: 100%|██████████| 100/100 [00:10<00:00,  9.25it/s, episode=600, return=343.400]
Iteration 6: 100%|██████████| 100/100 [00:14<00:00,  6.99it/s, episode=700, return=319.700]
Iteration 7: 100%|██████████| 100/100 [00:17<00:00,  5.80it/s, episode=800, return=224.100]
Iteration 8: 100%|██████████| 100/100 [00:08<00:00, 12.45it/s, episode=900, return=176.100]
Iteration 9: 100%|██████████| 100/100 [00:07<00:00, 14.16it/s, episode=1000, return=158.500]

八、REINFORCE 算法的优缺点(结合代码表现)

优点(代码完美体现)
  1. 直接优化策略:无需学习值函数,直接参数化并优化策略,策略表达更灵活,既适合离散动作空间(如本代码),也可轻松适配连续动作空间(改策略网络输出和采样分布即可,如用正态分布采样连续动作);
  2. 实现简单:核心逻辑仅 “采样轨迹 - 计算 G_t - 更新策略” 三步,代码量少,无复杂的值函数拟合、目标网络等模块;
  3. 无偏估计:蒙特卡洛方式用完整回合的回报计算Gt​,是策略梯度的无偏估计,训练收敛后策略的性能更稳定。
缺点(代码训练中会体现)
  1. 高方差:蒙特卡洛的无偏估计伴随高方差,导致训练回报曲线波动剧烈,收敛速度慢(本代码中训练前期回报波动大,后期才逐渐收敛);
  2. 同策略效率低:必须用当前策略采样的轨迹更新,采样的轨迹用过一次就丢弃,不能复用(如 DQN 的经验回放),数据利用率极低;
  3. 只能回合更新:必须等回合结束才能更新,无法进行步更 / 半回合更,对长回合任务(如 Atari 游戏)训练效率极低;
  4. 无探索 - 利用平衡的显式控制:仅通过动作概率采样实现探索,无专门的探索机制(如 ε- 贪心),探索策略较粗糙。

九、经典改进方向(解决高方差 / 低效率问题)

针对 REINFORCE 的缺点,后续有很多经典改进版,都是工业界常用的策略梯度算法:

  1. REINFORCE with Baseline:引入值函数作为基线(Baseline),将损失改为−logp​rob⋅(Gt​−V(st​)),大幅降低方差,不改变无偏性;
  2. Actor-Critic(AC):结合策略梯度(Actor)和值函数(Critic),用 TD 误差替代蒙特卡洛的Gt​,实现步更 / 半回合更,提升训练效率;
  3. A2C/A3C:在 AC 基础上做并行训练,进一步提升训练速度;
  4. PPO(Proximal Policy Optimization):当前最主流的策略梯度算法,在同策略的基础上引入信任域,允许轨迹复用,兼顾效率和稳定性,是工业界的 “首选方案”。

十、总结

本文详细介绍了REINFORCE算法的原理与实现。REINFORCE是一种基于策略梯度的无模型强化学习算法,直接优化策略参数,适用于离散动作空间。文章从算法定位、数学推导、代码实现三个层面展开:首先阐述了其无模型、同策略、蒙特卡洛更新的核心特性;然后推导了策略梯度的数学公式及其工程化实现;最后通过完整的Python代码展示了在CartPole-v1环境中的应用,包括策略网络设计、轨迹采集、蒙特卡洛更新等关键模块。实验结果表明,REINFORCE算法能够有效解决简单控制问题,但存在高方差、低效率等缺点。文章还指出了改进方向,如引入基线函数、Actor-Critic架构等。整体上,REINFORCE作为策略梯度家族的基础算法,具有理论简洁、实现直观的特点。

本文地址:https://www.yitenyun.com/4825.html

搜索文章

Tags

#服务器 #python #pip #conda #ios面试 #ios弱网 #断点续传 #ios开发 #objective-c #ios #ios缓存 #人工智能 #微信 #远程工作 #Trae #IDE #AI 原生集成开发环境 #Trae AI #kubernetes #笔记 #平面 #容器 #linux #学习方法 香港站群服务器 多IP服务器 香港站群 站群服务器 #运维 #学习 #分阶段策略 #模型协议 #银河麒麟高级服务器操作系统安装 #银河麒麟高级服务器V11配置 #设置基础软件仓库时出错 #银河麒高级服务器系统的实操教程 #生产级部署银河麒麟服务系统教程 #Linux系统的快速上手教程 #科技 #深度学习 #自然语言处理 #神经网络 #hadoop #hbase #hive #zookeeper #spark #kafka #flink #docker #华为云 #部署上线 #动静分离 #Nginx #新人首发 #fastapi #html #css #tcp/ip #网络 #qt #C++ #github #git #harmonyos #鸿蒙PC #物联网 #websocket #PyTorch #模型训练 #星图GPU #大数据 #职场和发展 #程序员创富 #进程控制 #经验分享 #安卓 #gemini #gemini国内访问 #gemini api #gemini中转搭建 #Cloudflare #Conda # 私有索引 # 包管理 #kylin #ARM服务器 # GLM-4.6V # 多模态推理 #开源 #arm #低代码 #爬虫 #音视频 #飞牛nas #fnos #word #umeditor粘贴word #ueditor粘贴word #ueditor复制word #ueditor上传word图片 #unity #c# #游戏引擎 #数信院生信服务器 #Rstudio #生信入门 #生信云服务器 #语言模型 #大模型 #ai #ai大模型 #agent #node.js #langchain #数据库 #MobaXterm #ubuntu #内网穿透 #cpolar #ci/cd #jenkins #gitlab #开发语言 #云原生 #iventoy #VmWare #OpenEuler #儿童书籍 #儿童诗歌 #童话故事 #经典好书 #儿童文学 #好书推荐 #经典文学作品 #ssh #flutter #ide #区块链 #测试用例 #生活 #RTP over RTSP #RTP over TCP #RTSP服务器 #RTP #TCP发送RTP #前端 #nginx #后端 #serverless #diskinfo # TensorFlow # 磁盘健康 #Harbor #矩阵 #线性代数 #AI运算 #向量 #vscode #mobaxterm #计算机视觉 #aws #云计算 #AI编程 #centos #svn #c++ #算法 #牛客周赛 #分布式 #华为 #sql #AIGC #agi #android #腾讯云 #自动化 #ansible #文心一言 #AI智能体 #多个客户端访问 #IO多路复用 #回显服务器 #TCP相关API #缓存 #fabric #postgresql #openHiTLS #TLCP #DTLCP #密码学 #商用密码算法 #FTP服务器 #Reactor #javascript #vue上传解决方案 #vue断点续传 #vue分片上传下载 #vue分块上传下载 #http #项目 #高并发 #java-ee #iBMC #UltraISO #pytorch #microsoft #PyCharm # 远程调试 # YOLOFuse #php #java #jar #Dell #PowerEdge620 #内存 #硬盘 #RAID5 #windows #flask #企业开发 #ERP #项目实践 #.NET开发 #C#编程 #编程与数学 #mysql #信息与通信 #程序人生 #科研 #博士 #pycharm #鸿蒙 #jmeter #功能测试 #软件测试 #自动化测试 #网络协议 #架构 #安全 #mcu #es安装 #vue.js #散列表 #哈希算法 #数据结构 #leetcode #风控模型 #决策盲区 #数学建模 #2026年美赛C题代码 #2026年美赛 #uni-app #小程序 #notepad++ #dify #spring boot #内存治理 #django #蓝桥杯 #驱动开发 #个人开发 #mvp #设计模式 #游戏 #京东云 #性能优化 #ecmascript #elementui #DeepSeek #服务器繁忙 #AI #rocketmq #Ansible # 自动化部署 # VibeThinker #Ubuntu服务器 #硬盘扩容 #命令行操作 #VMware #web #webdav #课程设计 #计算机网络 #spring cloud #spring #json #jvm #mmap #nio #golang #redis #prometheus #开源软件 #我的世界 #jetty #udp #web安全 #阻塞队列 #生产者消费者模型 #服务器崩坏原因 #数据仓库 #c语言 #MCP #MCP服务器 #鸭科夫 #逃离鸭科夫 #鸭科夫联机 #鸭科夫异地联机 #开服 #LLM #vim #gcc #yum #vllm #Streamlit #Qwen #本地部署 #AI聊天机器人 #ModelEngine #rabbitmq #protobuf #DisM++ # 系统维护 #gpu算力 #阿里云 #设备驱动 #芯片资料 #网卡 #语音识别 #大模型学习 #AI大模型 #大模型教程 #大模型入门 #深度优先 #DFS #守护进程 #复用 #screen #全能视频处理软件 #视频裁剪工具 #视频合并工具 #视频压缩工具 #视频字幕提取 #视频处理工具 #企业微信 #Linux #TCP #线程 #线程池 #ffmpeg #Android #Bluedroid #智能手机 #everything #钉钉 #机器人 #网络安全 #todesk #AI论文写作工具 #学术论文创作 #论文效率提升 #MBA论文写作 #单片机 #stm32 #嵌入式硬件 #需求分析 #scala #测试工具 #压力测试 #信息可视化 #claude code #codex #code cli #ccusage #数据集 #Ascend #MindIE #adb #超算服务器 #算力 #高性能计算 #仿真分析工作站 #里氏替换原则 #幼儿园 #园长 #幼教 #数模美赛 #matlab #银河麒麟 #系统升级 #信创 #国产化 #银河麒麟操作系统 #openssh #华为交换机 #信创终端 #arm开发 #Modbus-TCP #azure #sizeof和strlen区别 #sizeof #strlen #计算数据类型字节数 #计算字符串长度 #编辑器 #金融 #mcp #金融投资Agent #Agent #正则 #正则表达式 #ida #DS随心转 #iphone #研发管理 #禅道 #禅道云端部署 #中间件 #AI写作 #n8n #STUN # TURN # NAT穿透 #RAID #RAID技术 #磁盘 #存储 #机器学习 #程序员 #流量监控 #架构师 #系统架构 #软考 #系统架构师 #unity3d #服务器框架 #Fantasy #elasticsearch #智能路由器 #MC #transformer #Canal #几何学 #拓扑学 #链表 #链表的销毁 #链表的排序 #链表倒置 #判断链表是否有环 #凤希AI伴侣 #生信 #酒店客房管理系统 #毕设 #论文 #java大文件上传 #java大文件秒传 #java大文件上传下载 #java文件传输解决方案 #journalctl #测试流程 #金融项目实战 #P2P #webrtc #chatgpt #RAG #全链路优化 #实战教程 #openresty #lua #wordpress #雨云 #LobeChat #vLLM #GPU加速 #mcp server #AI实战 #wsl #L2C #勒让德到切比雪夫 #电脑 #流程图 #论文阅读 #论文笔记 #毕业设计 #grafana #SSH Agent Forwarding # PyTorch # 容器化 #SSH反向隧道 # Miniconda # Jupyter远程访问 #Coze工作流 #AI Agent指挥官 #多智能体系统 #VS Code调试配置 #vue3 #天地图 #403 Forbidden #天地图403错误 #服务器403问题 #天地图API #部署报错 #SSH # ProxyJump # 跳板机 #asp.net大文件上传 #asp.net大文件上传下载 #asp.net大文件上传源码 #ASP.NET断点续传 #asp.net上传文件夹 #ping通服务器 #读不了内网数据库 #bug菌问答团队 #数码相机 #epoll #高级IO #debian #FL Studio #FLStudio #FL Studio2025 #FL Studio2026 #FL Studio25 #FL Studio26 #水果软件 #asp.net #面试 #LoRA # RTX 3090 # lora-scripts #react.js #svm #amdgpu #kfd #ROCm #1024程序员节 #claude #ddos #fiddler #opencv #数据挖掘 #googlecloud #screen 命令 #macos #vp9 #nas #支付 #whisper #远程桌面 #远程控制 #fpga开发 #LVDS #高速ADC #DDR # GLM-TTS # 数据安全 #ssl #YOLO #ui #分类 #bash #ssm #振镜 #振镜焊接 #状态模式 #若依 #quartz #框架 #llama #ceph #ai编程 #abtest #迁移重构 #数据安全 #漏洞 #代码迁移 #搜索引擎 #目标检测 #蓝耘智算 #流量运营 #用户运营 #版本控制 #Git入门 #开发工具 #代码托管 #C语言 #制造 #个人博客 #oracle #ONLYOFFICE #MCP 服务器 #模版 #函数 #类 #笔试 #嵌入式 #apache #tomcat #esp32教程 #双指针 #嵌入式编译 #ccache #distcc #WEB #前端框架 #cursor #laravel #shell #CPU利用率 #spine #进程 #操作系统 #进程创建与终止 #数组 #信号处理 #目标跟踪 #流媒体 #NAS #飞牛NAS #监控 #NVR #EasyNVR #ollama #llm #RustDesk #IndexTTS 2.0 #本地化部署 #社科数据 #数据分析 #数据统计 #经管数据 #tcpdump #embedding #ESXi #visual studio code #车辆排放 #SA-PEKS # 关键词猜测攻击 # 盲签名 # 限速机制 #Shiro #反序列化漏洞 #CVE-2016-4437 #树莓派4b安装系统 #我的世界服务器搭建 #minecraft #运营 #paddleocr #React安全 #漏洞分析 #Next.js #Spring AI #STDIO协议 #Streamable-HTTP #McpTool注解 #服务器能力 #时序数据库 #pencil #pencil.dev #设计 #产品经理 #团队开发 #墨刀 #figma #智慧校园解决方案 #智慧校园一体化平台 #智慧校园选型 #智慧校园采购 #智慧校园软件 #智慧校园专项资金 #智慧校园定制开发 #CFD #sqlite #Playbook #AI服务器 #simulink #selenium #Triton # CUDA #海外服务器安装宝塔面板 #负载均衡 #边缘计算 #MS #Materials #SSH保活 #Miniconda #远程开发 #AB包 #HeyGem # 远程访问 # 服务器IP配置 #openlayers #bmap #tile #server #vue #简单数论 #埃氏筛法 #openEuler #Hadoop #客户端 #DIY机器人工房 #vuejs #eBPF #autosar #nacos #银河麒麟aarch64 #uvicorn #uvloop #asgi #event #.net #homelab #Lattepanda #Jellyfin #Plex #Emby #Kodi #信令服务器 #Janus #MediaSoup #TensorRT # Triton # 推理优化 #zabbix #Jetty # CosyVoice3 # 嵌入式服务器 #推荐算法 #tensorflow #log #建筑缺陷 #红外 #SMTP # 内容安全 # Qwen3Guard #X11转发 #sqlserver #改行学it #创业创新 #OBC #北京百思可瑞教育 #百思可瑞教育 #北京百思教育 #智能一卡通 #门禁一卡通 #梯控一卡通 #电梯一卡通 #消费一卡通 #一卡通 #考勤一卡通 #ms-swift # 一锤定音 # 大模型微调 #deepseek #AI产品经理 #大模型开发 #机器视觉 #6D位姿 #risc-v #tdengine #涛思数据 #cpp #SSH公钥认证 # 安全加固 #求职招聘 #大语言模型 #长文本处理 #GLM-4 #Triton推理 #重构 #PowerBI #企业 #Qwen3-14B # 大模型部署 # 私有化AI #H5 #跨域 #发布上线后跨域报错 #请求接口跨域问题解决 #跨域请求代理配置 #request浏览器跨域 #运维开发 #opc ua #opc #lvs #AutoDL #Host #渗透测试 #SSRF #黑群晖 #虚拟机 #无U盘 #纯小白 #音乐分类 #音频分析 #ViT模型 #Gradio应用 #鼠大侠网络验证系统源码 #指针 #anaconda #虚拟环境 #SSH跳板机 # Python3.11 #东方仙盟 #游戏机 #JumpServer #堡垒机 #API限流 # 频率限制 # 令牌桶算法 #UDP的API使用 #处理器 #ip #微信小程序 #Gunicorn #WSGI #Flask #并发模型 #容器化 #Python #性能调优 #teamviewer #蓝湖 #Axure原型发布 #游戏私服 #云服务器 #LabVIEW知识 #LabVIEW程序 #LabVIEW功能 #labview #ambari #单元测试 #集成测试 #Socket网络编程 #turn #黑客技术 #网安应急响应 #计算机 # 目标检测 #微PE # GLM # 服务连通性 #Fluentd #Sonic #日志采集 #muduo库 #C# # REST API # GLM-4.6V-Flash-WEB #uv #uvx #uv pip #npx #Ruff #pytest #maven #intellij-idea #数据恢复 #视频恢复 #视频修复 #RAID5恢复 #流媒体服务器恢复 #web server #请求处理流程 #restful #ajax #框架搭建 #视频去字幕 #SRS #直播 #flume #milvus #springboot #知识库 #910B #昇腾 #vivado license #CVE-2025-68143 #CVE-2025-68144 #CVE-2025-68145 #零代码平台 #AI开发 #UDP #html5 #chrome #RSO #机器人操作系统 #glibc #Anaconda配置云虚拟环境 #MQTT协议 #文生视频 #CogVideoX #AI部署 #聚类 #OPCUA #环境搭建 #政务 #集成学习 #https #pandas #matplotlib #可信计算技术 #winscp #智能体 #Clawdbot #个人助理 #数字员工 #OSS #firefox # 双因素认证 #安恒明御堡垒机 #windterm #rust #powerbi #连接数据库报错 #Docker #Fun-ASR # 硬件配置 # 语音识别 #算力一体机 #ai算力服务器 #硬件工程 #微服务 #青少年编程 #scrapy #逻辑回归 #rustdesk #p2p #自动驾驶 #源码 #闲置物品交易系统 #Rust #YOLOFuse # Base64编码 # 多模态检测 #IPv6 #DNS #SMP(软件制作平台) #EOM(企业经营模型) #应用系统 #SPA #单页应用 #web3.py #系统安全 #ipmitool #BMC #项目申报系统 #项目申报管理 #项目申报 #企业项目申报 #C #wpf #JAVA #Java #bootstrap #tornado #YOLOv8 # Docker镜像 #麒麟OS #国产开源制品管理工具 #Hadess #一文上手 #swagger #IndexTTS2 # 阿里云安骑士 # 木马查杀 #reactjs #web3 #Karalon #AI Test #prompt #mamba #mariadb #1panel #vmware #pdf #贪心算法 #策略模式 #人脸识别 #人脸核身 #活体检测 #身份认证与人脸对比 #微信公众号 #LangGraph #CLI #JavaScript #langgraph.json #CMake #Make #C/C++ # 高并发部署 #学习笔记 #jdk #eclipse #servlet #vps #5G #汇编 #Anything-LLM #IDC服务器 #私有化部署 #raid #raid阵列 #模型上下文协议 #MultiServerMCPC #load_mcp_tools #load_mcp_prompt #typescript #npm #电气工程 #PLC # 水冷服务器 # 风冷服务器 #VoxCPM-1.5-TTS # 云端GPU # PyCharm宕机 #webpack #database #idea #学术写作辅助 #论文创作效率提升 #AI写论文实测 #翻译 #开源工具 #rdp #国产PLM #瑞华丽PLM #瑞华丽 #PLM #能源 #AI生成 # outputs目录 # 自动化 #esp32 arduino #Windows 更新 #ComfyUI # 推理服务器 #libosinfo #Dify #ARM架构 #鲲鹏 #结构与算法 #扩展屏应用开发 #android runtime #HBA卡 #RAID卡 #TLS协议 #HTTPS #漏洞修复 #运维安全 #产品运营 #内存接口 # 澜起科技 # 服务器主板 #联机教程 #局域网联机 #局域网联机教程 #局域网游戏 #模拟退火算法 #yolov12 #研究生life # IndexTTS 2.0 # 远程运维 #文件传输 #电脑文件传输 #电脑传输文件 #电脑怎么传输文件到另一台电脑 #电脑传输文件到另一台电脑 #说话人验证 #声纹识别 #CAM++ #性能 #优化 #RAM #mongodb #windows11 #系统修复 #Chat平台 #select #考研 #软件工程 #其他 #PTP_1588 #gPTP #Windows #RXT4090显卡 #RTX4090 #深度学习服务器 #硬件选型 #gitea #群晖 #音乐 #树莓派 #N8N #IntelliJ IDEA #Spring Boot #neo4j #NoSQL #SQL #海外短剧 #海外短剧app开发 #海外短剧系统开发 #短剧APP #短剧APP开发 #短剧系统开发 #海外短剧项目 #idm #网站 #截图工具 #批量处理图片 #图片格式转换 #图片裁剪 #万悟 #联通元景 #镜像 #cnn #结构体 #TCP服务器 #开发实战 #ThingsBoard MCP #可撤销IBE #服务器辅助 #私钥更新 #安全性证明 #双线性Diffie-Hellman #计组 #数电 #导航网 #浏览器自动化 #python #Android16 #音频性能实战 #音频进阶 #健身房预约系统 #健身房管理系统 #健身管理系统 #SSH免密登录 #clickhouse #代理 #平板 #零售 #交通物流 #智能硬件 #CTF #gateway #Comate #遛狗 #SSE # AI翻译机 # 实时翻译 #r-tree #聊天小程序 #log4j #arm64 #上下文工程 #langgraph #意图识别 #无人机 #Deepoc #具身模型 #开发板 #未来 #3d #服务器解析漏洞 #RK3576 #瑞芯微 #硬件设计 #UOS #海光K100 #统信 #NFC #智能公交 #服务器计费 #FP-增长 #数据采集 #浏览器指纹 #CANN #串口服务器 #Modbus #MOXA #ESP32 #传感器 #MicroPython #jupyter #CUDA #交互 #edge #迭代器模式 #观察者模式 #twitter #Proxmox VE #虚拟化 #硬件 # WebUI #部署 #GPU服务器 #8U #硬件架构 #线性回归 #昇腾300I DUO #NPU #intellij idea #c++20 #mybatis #cosmic #UDP套接字编程 #UDP协议 #网络测试 #vnstat #JT/T808 #车联网 #车载终端 #模拟器 #仿真器 #开发测试 #mapreduce #论文复现 #npu #memcache #测评 #大剑师 #nodejs面试题 #C2000 #TI #实时控制MCU #AI服务器电源 #攻防演练 #Java web #红队 #知识 #Llama-Factory # 树莓派 # ARM架构 #hibernate #ranger #MySQL8.0 #AI赋能盾构隧道巡检 #开启基建安全新篇章 #以注意力为核心 #YOLOv12 #AI隧道盾构场景 #盾构管壁缺陷病害异常检测预警 #隧道病害缺陷检测 #GB28181 #SIP信令 #SpringBoot #视频监控 #WT-2026-0001 #QVD-2026-4572 #smartermail #openclaw #TTS私有化 # IndexTTS # 音色克隆 #AI技术 # ARM服务器 # 大模型推理 #存储维护 #screen命令 #分布式数据库 #集中式数据库 #业务需求 #选型误 # Connection refused #AITechLab #cpp-python #CUDA版本 #智能体来了 #智能体对传统行业冲击 #行业转型 #AI赋能 #系统管理 #服务 #门禁 #梯控 #智能梯控 #源代码管理 #elk #ARM64 # DDColor # ComfyUI #Ubuntu #ESP32编译服务器 #Ping #DNS域名解析 #YOLO26 #YOLO11 #管道Pipe #system V #excel #chat #连锁药店 #连锁店 #muduo #TcpServer #accept #高并发服务器 #面向对象 #taro #SAP #ebs #metaerp #oracle ebs # keep-alive # 高并发 #appche #SSH跳转 #go #postman # GPU集群 #服务器开启 TLS v1.2 #IISCrypto 使用教程 #TLS 协议配置 #IIS 安全设置 #服务器运维工具 #Claude #clamav #AI-native #dba #LangFlow # 轻量化镜像 # 边缘计算 #国产化OS #网络编程 #Socket #套接字 #I/O多路复用 #字节序 #weston #x11 #x11显示服务器 #量子计算 #WinSCP 下载安装教程 #SFTP #FTP工具 #服务器文件传输 #计算几何 #斜率 #方向归一化 #叉积 #samba #copilot # 批量管理 #命令模式 #ASR #SenseVoice #硬盘克隆 #DiskGenius #dubbo #媒体 #opc模拟服务器 #汽车 #ArkUI #ArkTS #鸿蒙开发 #服务器线程 # SSL通信 # 动态结构体 #报表制作 #职场 #数据可视化 #用数据讲故事 #手机h5网页浏览器 #安卓app #苹果ios APP #手机电脑开启摄像头并排查 #语音生成 #TTS #图像处理 #yolo #IO #证书 #JNI #CPU #CCE #Dify-LLM #Flexus #ipv6 #Nacos #duckdb # 数字人系统 # 远程部署 #蓝牙 #LE Audio #BAP #高品质会员管理系统 #收银系统 #同城配送 #最好用的电商系统 #最好用的系统 #推荐的前十系统 #JAVA PHP 小程序 #cesium #可视化 #puppeteer #KMS #slmgr #宝塔面板部署RustDesk #RustDesk远程控制手机 #手机远程控制 #寄存器 #TRO #TRO侵权 #TRO和解 #echarts #运维工具 #智能家居 #POC #问答 #交付 #动态规划 ##程序员和算法的浪漫 #xlwings #Excel #Discord机器人 #云部署 #程序那些事 #H3C #服务器IO模型 #非阻塞轮询模型 #多任务并发模型 #异步信号模型 #多路复用模型 # 黑屏模式 # TTS服务器 #前端开发 #领域驱动 #自由表达演说平台 #演说 #移动端h5网页 #调用浏览器摄像头并拍照 #开启摄像头权限 #拍照后查看与上传服务器端 #摄像头黑屏打不开问题 #nfs #iscsi #Aluminium #Google #文件IO #输入输出流 #文件管理 #文件服务器 #kong #Kong Audio #Kong Audio3 #KongAudio3 #空音3 #空音 #中国民乐 #范式 #kmeans #长文本理解 #glm-4 #推理部署 #ET模式 #非阻塞 # 大模型 # 模型训练 #因果学习 #scanf #printf #getchar #putchar #cin #cout #图像识别 #企业级存储 #网络设备 #iot #多模态 #微调 #超参 #LLamafactory #RAGFlow #DeepSeek-R1 #Smokeping #pve #Linux多线程 #游戏程序 #Java程序员 #Java面试 #后端开发 #Spring源码 #Spring #zotero #WebDAV #同步失败 #代理模式 #工具集 #大模型应用 #API调用 #PyInstaller打包运行 #服务端部署 #ICPC #排序算法 #排序 #农产品物流管理 #物流管理系统 #农产品物流系统 #农产品物流 #xss #欧拉 #CSDN #paddlepaddle #aiohttp #asyncio #异步 #Langchain-Chatchat # 国产化服务器 # 信创 #软件 #本地生活 #电商系统 #商城 #土地承包延包 #领码SPARK #aPaaS+iPaaS #数字化转型 #智能审核 #档案数字化 #麒麟 #ShaderGraph #图形 #VSCode # SSH #.netcore # 自动化运维 #VMware Workstation16 #服务器操作系统 #儿童AI #图像生成 #pjsip # 模型微调 #实体经济 #商业模式 #软件开发 #数智红包 #商业变革 #创业干货 #2026AI元年 #年度趋势 #Zabbix #CosyVoice3 #语音合成 #游戏美术 #技术美术 #游戏策划 #用户体验 #HistoryServer #Spark #YARN #jobhistory #FASTMCP #ZooKeeper #ZooKeeper面试题 #面试宝典 #深入解析 #大模型部署 #mindie #大模型推理 #业界资讯 #n8n解惑 #区间dp #二进制枚举 #图论 #Go并发 #高并发架构 #Goroutine #系统设计 #Tracker 服务器 #响应最快 #torrent 下载 #2026年 #Aria2 可用 #迅雷可用 #BT工具通用 #net core #kestrel #web-server #asp.net-core #多线程 #性能调优策略 #双锁实现细节 #动态分配节点内存 #markdown #建站 #EMC存储 #NetApp存储 #ue5 #大学生 #大作业 # 显卡驱动备份 #eureka #AI智能棋盘 #Rock Pi S #广播 #组播 #并发服务器 #x86_64 #数字人系统 #插入排序 #企业存储 #RustFS #对象存储 #高可用 #三维 #3D #三维重建 #asp.net上传大文件 #性能测试 #LoadRunner #测试覆盖率 #可用性测试 #rtsp #转发 #编程 #c++高并发 #百万并发 #Termux #Samba #SSH别名 #TFTP #NSP #下一状态预测 #aigc #数字孪生 #三维可视化 # 远程开发 # Qwen3Guard-Gen-8B #信创国产化 #达梦数据库 #工厂模式 #CVE-2025-61686 #路径遍历高危漏洞 #智慧城市 #uip #随机森林 # 代理转发 #经济学 #GPU ##租显卡 #进程等待 #wait #waitpid # 服务器IP # 端口7860 # HiChatBox # 离线AI #WinDbg #Windows调试 #内存转储分析 #SMARC #ARM #全文检索 #Node.js #漏洞检测 #CVE-2025-27210 # 公钥认证 # GPU租赁 # 自建服务器 #PyTorch 特性 #动态计算图 #张量(Tensor) #自动求导Autograd #GPU 加速 #生态系统与社区支持 #与其他框架的对比 #VibeVoice # 语音合成 # 云服务器 #devops #cascadeur #设计师 #AI视频创作系统 #AI视频创作 #AI创作系统 #AI视频生成 #AI工具 #AI创作工具 #web服务器 #AI+ #coze #AI入门 #React #Next #CVE-2025-55182 #RSC #MinIO服务器启动与配置详解 #H5网页 #网页白屏 #H5页面空白 #资源加载问题 #打包部署后网页打不开 #HBuilderX #A2A #GenAI #Xshell #Finalshell #生物信息学 #组学 #VMWare Tool #心理健康服务平台 #心理健康系统 #心理服务平台 #心理健康小程序 #SSH复用 #磁盘配额 #存储管理 #形考作业 #国家开放大学 #系统运维 #自动化运维 #插件 #统信UOS #win10 #qemu #DHCP #C++ UA Server #SDK #跨平台开发 #DAG #HarmonyOS #outlook #错误代码2603 #无网络连接 #2603 #注入漏洞 #nvidia #vertx #vert.x #vertx4 #runOnContext #ngrok #视觉检测 #visual studio #GATT服务器 #蓝牙低功耗 #密码 #safari #b树 #gRPC #注册中心 #Tokio #异步编程 #系统编程 #Pin #http服务器 #win11 #机器人学习 # ControlMaster # IP配置 # 0.0.0.0 #galeweather.cn #高精度天气预报数据 #光伏功率预测 #风电功率预测 #高精度气象 #memory mcp #Cursor #网路编程 #c #勒索病毒 #勒索软件 #加密算法 #.bixi勒索病毒 #数据加密 # 远程连接 #fs7TF #Buck #NVIDIA #交错并联 #DGX #实时音视频 #贴图 #材质 #IFix #webgl #星际航行 #agentic bi #AI 推理 #NV #ServBay #安全架构 #Keycloak #Quarkus #AI编程需求分析 #ansys #ansys问题解决办法 # 网络延迟 #远程软件 #ARMv8 #内存模型 #内存屏障 #娱乐 #敏捷流程 # OTA升级 # 黄山派 #内网 # IndexTTS2 #canvas层级太高 #canvas遮挡问题 #盖住其他元素 #苹果ios手机 #安卓手机 #调整画布层级 #测速 #iperf #iperf3 #学术生涯规划 #CCF目录 #基金申请 #职称评定 #论文发表 #科研评价 #顶会顶刊 #编程助手 #视频 #代理服务器 #分子动力学 #化工仿真 #雨云服务器 #Minecraft服务器 #教程 #MCSM面板 #Apple AI #Apple 人工智能 #FoundationModel #Summarize #SwiftUI #SEO优化 #跳槽 #工作 #超时设置 #客户端/服务器 #挖矿 #Linux病毒 #节日 #sql注入 #Kuikly #openharmony #基础语法 #标识符 #常量与变量 #数据类型 #运算符与表达式 #地理 #遥感 # 服务器配置 # GPU #主板 #总体设计 #电源树 #框图 #Gateway #认证服务器集成详解 #Archcraft #ftp #sftp #uniapp #合法域名校验出错 #服务器域名配置不生效 #request域名配置 #已经配置好了但还是报错 #uniapp微信小程序 #Linly-Talker # 数字人 # 服务器稳定性 #华为od #华为机试 #外卖配送 #react native #cpu #工程设计 #预混 #扩散 #燃烧知识 #层流 #湍流 #实在Agent # 批量部署 #榛樿鍒嗙被 #传统行业 # 键鼠锁定 #mtgsig #美团医药 #美团医药mtgsig #美团医药mtgsig1.2 #远程连接 #后端框架 #RWK35xx #语音流 #实时传输 #node #电子电气架构 #系统工程与系统架构的内涵 #Routine #人脸活体检测 #live-pusher #动作引导 #张嘴眨眼摇头 #苹果ios安卓完美兼容 #gnu #glances #pxe #参数估计 #矩估计 #概率论 #强化学习 #策略梯度 #REINFORCE #蒙特卡洛 #百度 #ueditor导入word #MCP服务器注解 #异步支持 #方法筛选 #声明式编程 #自动筛选机制 #可再生能源 #绿色算力 #风电 #TURN # WebRTC #麦克风权限 #访问麦克风并录制音频 #麦克风录制音频后在线播放 #用户拒绝访问麦克风权限怎么办 #uniapp 安卓 苹果ios #将音频保存本地或上传服务器 # child_process #sentinel #scikit-learn #安全威胁分析 #仙盟创梦IDE #composer #symfony #java-zookeeper #GLM-4.6V-Flash-WEB # AI视觉 # 本地部署 #网络攻击模型 #pyqt #vrrp #脑裂 #keepalived主备 #高可用主备都持有VIP #coffeescript #AI应用编程 #软件需求 #dlms #dlms协议 #逻辑设备 #逻辑设置间权限 #r语言 #AI大模型应用开发 #Minecraft #PaperMC #我的世界服务器 #EN4FE #STDIO传输 #SSE传输 #WebMVC #WebFlux #ue4 #DedicatedServer #独立服务器 #专用服务器 #gpt #语义搜索 #嵌入模型 #Qwen3 #AI推理 #工业级串口服务器 #串口转以太网 #串口设备联网通讯模块 #串口服务器选型 #入侵 #日志排查 #个性化推荐 #BERT模型 #tcp/ip #网络 #人大金仓 #Kingbase #小艺 #搜索 #Spring AOP #电商 #多进程 #python技巧 #高考 #工程实践 #租显卡 #训练推理 #就业 #wps #高仿永硕E盘的个人网盘系统源码 #轻量化 #低配服务器 #国产操作系统 #V11 #kylinos #KMS激活 #API #poll #支持向量机 #numpy #VPS #搭建 #递归 #线性dp #Syslog #系统日志 #日志分析 #日志监控 #Autodl私有云 #深度服务器配置 #音诺ai翻译机 #AI翻译机 # Ampere Altra Max #sklearn #文本生成 #CPU推理 #stl #IIS Crypto #blender #warp #人脸识别sdk #视频编解码 #挖漏洞 #攻击溯源 #Prometheus #人形机器人 #人机交互 #xml #统信操作系统 #计算机毕业设计 #程序定制 #毕设代做 #课设 #交换机 #三层交换机 #域名注册 #新媒体运营 #网站建设 #国外域名 #高斯溅射 #DDD #tdd #easyui #Puppet # TTS #电梯 #电梯运力 #电梯门禁 #数据报系统 #云开发 # GPU服务器 # tmux #程序开发 #程序设计 #个人电脑 #KMS 激活 #idc #MC群组服务器 #题解 #图 #dijkstra #迪杰斯特拉 #bond #服务器链路聚合 #网卡绑定 #gpu #nvcc #cuda #智能制造 #供应链管理 #工业工程 #库存管理 #漏洞挖掘 #unix #CS2 #debian13 #BoringSSL #RK3588 #RK3588J #评估板 #核心板 #嵌入式开发 #模块 # 权限修复 #ICE # 鲲鹏 #SQL注入主机 #http头信息 #Coturn #k8s #Cpolar #国庆假期 #服务器告警 #温湿度监控 #WhatsApp通知 #IoT #MySQL #Moltbook #银河麒麟服务器系统 #Kylin-Server #服务器安装 #短剧 #短剧小程序 #短剧系统 #微剧 # 智能运维 # 性能瓶颈分析 #resnet50 #分类识别训练 #空间计算 #原型模式 #nosql #戴尔服务器 #戴尔730 #装系统 #OpenManage #junit #文件上传漏洞 #I/O模型 #并发 #水平触发、边缘触发 #多路复用 #数据访问 #vncdotool #链接VNC服务器 #如何隐藏光标 # 服务器IP访问 # 端口映射 #Python3.11 #Spire.Office #隐私合规 #网络安全保险 #法律风险 #风险管理 #bug #FHSS #CNAS #CMA #程序文件 #静脉曲张 #腿部健康 #clawdbot #远程访问 #远程办公 #飞网 #安全高效 #配置简单 #快递盒检测检测系统 #wireshark #网络安全大赛 #lucene #FaceFusion # Token调度 # 显存优化 #WRF #WRFDA #nodejs #云服务器选购 #Saas #公共MQTT服务器 #mssql #算力建设 #RPA #影刀RPA #AI办公 #单例模式 #懒汉式 #恶汉式 #具身智能 #SSH密钥 #练习 #基础练习 #循环 #九九乘法表 #计算机实现 #dynadot #域名 #ETL管道 #向量存储 #数据预处理 #DocumentReader # DIY主机 # 交叉编译 #HarmonyOS APP #esb接口 #走处理类报异常 #网络配置实战 #Web/FTP 服务访问 #计算机网络实验 #外网访问内网服务器 #Cisco 路由器配置 #静态端口映射 #网络运维 #windbg分析蓝屏教程 #le audio #低功耗音频 #通信 #连接 #视觉理解 #Moondream2 #多模态AI #docker-compose #smtp #smtp服务器 #PHP #银河麒麟部署 #银河麒麟部署文档 #银河麒麟linux #银河麒麟linux部署教程 #声源定位 #MUSIC #路由器 #CA证书 #ROS #CS336 #Assignment #Experiments #TinyStories #Ablation #gerrit # 环境迁移 #余行补位 #意义对谈 #余行论 #领导者定义计划 #rag #xshell #host key #ossinsight #AE #卷积神经网络 #cocos2d #图形渲染 #rsync # 数据同步 #小智 #claudeCode #content7 #odoo #期刊 #SCI #游戏服务器断线 # 串口服务器 # NPort5630 #YOLO识别 #YOLO环境搭建Windows #YOLO环境搭建Ubuntu #OpenHarmony #Python办公自动化 #Python办公 #语义检索 #向量嵌入 #boltbot #超算中心 #PBS #lsf #反向代理 # ms-swift #PN 结 #adobe #L6 #L10 #L9 #数据迁移 #MinIO #express #cherry studio #阿里云RDS #gmssh #宝塔 #Exchange #free #vmstat #sar #系统安装 #铁路桥梁 #DIC技术 #箱梁试验 #裂纹监测 #四点弯曲 #AI Agent #开发者工具 #边缘AI # Kontron # SMARC-sAMX8 #okhttp #计算机外设 #remote-ssh #Qwen3-VL # 服务状态监控 # 视觉语言模型 #健康医疗 #Tetrazine-Acid #1380500-92-4 #职场发展 #隐函数 #常微分方程 #偏微分方程 #线性微分方程 #线性方程组 #非线性方程组 #复变函数 #AI应用 #bigtop #hdp #hue #kerberos #Beidou #北斗 #SSR #UDP服务器 #recvfrom函数 #Ward #docker安装seata #思爱普 #SAP S/4HANA #ABAP #NetWeaver #信息安全 #信息收集 #claude-code #高精度农业气象 #生产服务器问题查询 #日志过滤 #4U8卡 AI 服务器 ##AI 服务器选型指南 #GPU 互联 #GPU算力 #日志模块 #WAN2.2 # AI部署 #材料工程 #智能电视 #VMware创建虚拟机 #远程更新 #缓存更新 #多指令适配 #物料关联计划 #dash #决策树 #DooTask #sglang #防毒面罩 #防尘面罩 #m3u8 #HLS #移动端H5网页 #APP安卓苹果ios #监控画面 直播视频流 #UEFI #BIOS #Legacy BIOS #开关电源 #热敏电阻 #PTC热敏电阻 #身体实验室 #健康认知重构 #系统思维 #微行动 #NEAT效应 #亚健康自救 #ICT人 # 服务器迁移 # 回滚方案 #云计算运维 #效率神器 #办公技巧 #自动化工具 #Windows技巧 #打工人必备 #旅游 #西门子 #汇川 #Blazor #dreamweaver #晶振 #运维 #夏天云 #夏天云数据 #hdfs #华为od机试 #华为od机考 #华为od最新上机考试题库 #华为OD题库 #华为OD机试双机位C卷 #od机考题库 #AI工具集成 #容器化部署 #分布式架构 #Matrox MIL #二次开发 #实时检测 #CMC #防火墙 #0day漏洞 #DDoS攻击 #漏洞排查 #AI电商客服 #spring ai #oauth2 #nmodbus4类库使用教程 #rtmp #基金 #股票 # 局域网访问 # 批量处理 # 高温监控 #jquery #fork函数 #进程创建 #进程终止 #moltbot #session #JADX-AI 插件 #starrocks #运动 #LED #设备树 #GPIO #tekton #OpenAI #故障 #新浪微博 #传媒 #DuckDB #协议 #Arduino BLDC #核辐射区域探测机器人 #二值化 #Canny边缘检测 #轮廓检测 #透视变换 #esp32 #mosquito #2025年 #FRP #AI教程 #自动化巡检 #istio #服务发现