DQN在Gym的MountainCar环境的实现

【零基础强化学习】100行代码教你实现基于DQN的gym登山车 【零基础强化学习】100行代码教你实现基于DQN的gym登山车,代码可直接跑通,包括模型搭建、训练、保存、测试!你懂的 阅读详情

DQN on MountainCar

引言

在本次实验里,我构建了DQN和Dueling DQN,并在Gymnasium库的MountainCar环境中对它们展开测试。我通过调整训练任务的超参数,同时设计不同的奖励函数及其对应参数,致力于获取更优的训练效果。最后,将训练结果进行可视化处理并加以比较。
在这里插入图片描述

DQN实现流程

实现方法

  • 实现了DQN类。
  • 实现了经验回放缓冲区(Buffer)类。
  • 编写了训练流程。
  • 将所有超参数集中配置在一处。
  • 设计了程序运行参数,具体如下:
    • --train:训练模式。
    • --test:测试模式。
    • --resume:断点续训模式。
    • --checkpoint:指定用于断点续训或测试模式加载的模型。
    • --task_name:确定任务名称,该名称与保存日志的路径相关。
    • --visualize_train:开启Gym环境的可视化功能。
    • --dueling:使用Dueling DQN网络。
    • --stop_threshold:早停阈值。

遇到的难题

难题一

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

在进行DQN训练时,进程常常在第20多轮(episode)时卡住。起初,我考虑可能是超参数设计的问题,但后来怀疑并非是训练超参数设置不当所致。我了解到Gym环境设定了停止条件,要么是完成任务,要么是达到最大步数。鉴于进程一直卡在第29轮不动,按常理应该早就达到了200步的上限,触发停止条件。然而,我在本地保存的日志文件,其TensorBoard日志文件大小却持续变化,似乎训练仍在进行。由此推测,可能是DQN算法中的经验回放缓冲区部分存在问题,导致缓冲区占用内存过大。

经过更为细致的分析,我发现编写循环终止条件时,仅设置了到达终点这一条件,而未考虑步数达到上限的情况。这就使得每次奖励值都为负几万。因此,应判定每个回合在步数达到上限时也停止。

修改终止条件后,训练能够以正常速度推进。

难题二

由于Gym中封装的MountainCar环境每走一步奖励值为 -1,小车很难学会先向左再向右冲刺的策略。

我先后尝试了多种奖励设计方法:

  1. 提取状态(statestatestate)中的位置信息(positionpositionposition),在该环境中,positionpositionposition 取值范围为 [−1.2,0.6][-1.2, 0.6][−1.2,0.6]。若 position≥0.4position \geq 0.4position≥0.4,则 rewardrewardreward 加 1,以此奖励小车到达更靠右的位置。
  2. 为奖励小车尽可能到达更靠右的位置,直接设计一个关于 positionpositionposition 的一次多项式,即 reward+=α(position+0.5)reward += \alpha(position + 0.5)reward+=α(position+0.5),加 0.5 是因为小车初始位置约为 -0.5。
  3. 奖励小车向右的速度,公式为 reward+=α(position+0.5)+βvelocityreward += \alpha(position + 0.5) + \beta velocityreward+=α(position+0.5)+βvelocity。
  4. 为激励小车更多地探索先向左再向右的路径,设计了一个势能奖励函数,采用二次多项式形式,即 reward+=α2(position+0.5)2+α1(position+0.5)+βvelocityreward += \alpha_2(position + 0.5)^2 + \alpha_1(position + 0.5) + \beta velocityreward+=α2​(position+0.5)2+α1​(position+0.5)+βvelocity。

经过逐步设计与尝试,最终发现第四种方案最为完善。经过参数调整后,成功训练小车到达山顶。
在这里插入图片描述

Dueling DQN实现流程

使用DQN的改进版本Dueling DQN,只需在DQN网络基础上拆分为两个子网络,并进行优势函数的计算。

遇到的难题

在这里插入图片描述

最初,网络结构设定为 2->128->128->128->3,训练结果难以收敛。我推测可能是网络结构过于复杂,导致权重参数极为稀疏。于是,我去掉了两个隐藏层,将网络结构改为 2->128->3,训练效果得到显著提升。
在这里插入图片描述

两种方法训练结果对比

训练曲线比较

我在代码中添加了保存TensorBoard日志的功能,这样可以通过TensorBoard查看不同训练任务的曲线变化。
在这里插入图片描述

从图中可以看出,在同一套奖励函数和参数设置下,两种方法的训练速度和收敛速度相近。

最终策略比较

通过测试功能,可以观察到两种方法训练出的策略。两种方法都能让小车成功到达山顶,但奖励表现存在些许差异。可以发现,Dueling DQN的训练结果得分更高,策略变化的波动更小。

[检查点] 从 runs/Dueling_exp6/model_final.pt 加载模型:回合数 = 2000,探索率(epsilon) = 0.600
进行 10 个回合的测试...
 测试 #1:奖励值 = -113.00
 测试 #2:奖励值 = -113.00
 测试 #3:奖励值 = -113.00
 测试 #4:奖励值 = -113.00
 测试 #5:奖励值 = -113.00
 测试 #6:奖励值 = -112.00
 测试 #7:奖励值 = -113.00
 测试 #8:奖励值 = -113.00
 测试 #9:奖励值 = -92.00
 测试 #10:奖励值 = -115.00
10 个回合的平均奖励值:-111.00 ± 6.37

[检查点] 从 runs/exp6/model_final.pt 加载模型:回合数 = 2000,探索率(epsilon) = 0.600
进行 10 个回合的测试...
 测试 #1:奖励值 = -119.00
 测试 #2:奖励值 = -121.00
 测试 #3:奖励值 = -186.00
 测试 #4:奖励值 = -160.00
 测试 #5:奖励值 = -158.00
 测试 #6:奖励值 = -115.00
 测试 #7:奖励值 = -160.00
 测试 #8:奖励值 = -158.00
 测试 #9:奖励值 = -89.00
 测试 #10:奖励值 = -119.00
10 个回合的平均奖励值:-138.50 ± 28.30

最后提供代码:

import os
import time
import argparse
import random
import numpy as np
import gymnasium as gym
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.tensorboard import SummaryWriter
from collections import deque
import matplotlib.pyplot as plt

# ---------- 参数配置区域 ----------
EPISODES = 2000                 # 最大训练轮数
BATCH_SIZE = 64                 # 批次大小
GAMMA = 0.99                    # 折扣因子
LR = 1e-3                       # 学习率
EPS_START, EPS_END = 1.0, 0.6   # ε-greedy 起始/最小
EPS_DECAY = 0.995               # ε 衰减
TARGET_UPDATE = 10              # (已废弃,按步数更新)
TARGET_UPDATE_STEPS = 500       # 梯度更新步数间隔更新目标网络
REPLAY_BUFFER_SIZE = 10000      # Replay Buffer 容量
SAVE_INTERVAL = 50              # Checkpoint 保存间隔 (episodes)
RENDER_DELAY = 0.01             # 渲染延迟(秒)
ALPHA = 6                       # reward 参数(未用)
ALPHA2 = 2
ALPHA1 = 1
BETA = 1
# ----------------------------

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# ---------- 标准 DQN ----------
class DQN(nn.Module):
    def __init__(self, obs_dim, action_dim):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(obs_dim, 128), nn.ReLU(),
          #  nn.Linear(128, 128),     nn.ReLU(),
            nn.Linear(128, action_dim)
        )
    def forward(self, x):
        return self.net(x)

# ---------- Dueling DQN ----------
class DuelingDQN(nn.Module):
    def __init__(self, obs_dim, action_dim):
        super().__init__()
        # 共享特征层
        self.feature = nn.Sequential(
            nn.Linear(obs_dim, 128), nn.ReLU(),
           # nn.Linear(128, 128),     nn.ReLU()
        )
        # Advantage 分支
        self.advantage = nn.Sequential(
           # nn.Linear(128, 128), nn.ReLU(),
            nn.Linear(128, action_dim)
        )
        # Value 分支
        self.value = nn.Sequential(
           # nn.Linear(128, 128), nn.ReLU(),
            nn.Linear(128, 1)
        )

    def forward(self, x):
        x = self.feature(x)
        adv = self.advantage(x)                    # [B, A]
        val = self.value(x)                        # [B, 1]
        # Q(s,a) = V(s) + (A(s,a) - mean_a A(s,a))
        q = val + adv - adv.mean(dim=1, keepdim=True)
        return q

class ReplayBuffer:
    def __init__(self, capacity):
        self.buffer = deque(maxlen=capacity)
    def push(self, state, action, reward, next_state, done):
        self.buffer.append((state, action, reward, next_state, done))
    def sample(self, batch_size):
        batch = random.sample(self.buffer, batch_size)
        state, action, reward, next_state, done = map(np.array, zip(*batch))
        return state, action, reward, next_state, done
    def __len__(self):
        return len(self.buffer)

def save_checkpoint(path, policy_net, target_net, optimizer, episode, epsilon, rewards):
    os.makedirs(os.path.dirname(path), exist_ok=True)
    torch.save({
        'episode': episode,
        'epsilon': epsilon,
        'policy_state': policy_net.state_dict(),
        'target_state': target_net.state_dict(),
        'optim_state': optimizer.state_dict(),
        'episode_rewards': rewards,
    }, path)
    print(f"[Checkpoint] Saved to {path}")

def load_checkpoint(path, policy_net, target_net, optimizer):
    data = torch.load(path, map_location=device)
    policy_net.load_state_dict(data['policy_state'])
    target_net.load_state_dict(data['target_state'])
    optimizer.load_state_dict(data['optim_state'])
    print(f"[Checkpoint] Loaded from {path}: episode={data['episode']}, epsilon={data['epsilon']:.3f}")
    return data['episode'], data['epsilon'], data['episode_rewards']

def train(args):
    base_dir = os.path.join('runs', args.task_name)
    env = gym.make("MountainCar-v0", render_mode="human") if args.visualize_train else gym.make("MountainCar-v0")
    obs_dim = env.observation_space.shape[0]
    action_dim = env.action_space.n

    # 根据命令行参数选择网络
    net_cls = DuelingDQN if args.dueling else DQN
    policy_net = net_cls(obs_dim, action_dim).to(device)
    target_net = net_cls(obs_dim, action_dim).to(device)
    target_net.load_state_dict(policy_net.state_dict())
    target_net.eval()
    optimizer = optim.Adam(policy_net.parameters(), lr=LR)

    buffer = ReplayBuffer(REPLAY_BUFFER_SIZE)
    writer = SummaryWriter(base_dir)
    episode_rewards = []
    epsilon = EPS_START
    start_ep = 0
    update_steps = 0

    if args.resume and args.checkpoint and os.path.isfile(args.checkpoint):
        start_ep, epsilon, episode_rewards = load_checkpoint(args.checkpoint, policy_net, target_net, optimizer)

    print("Start training...")
    for episode in range(start_ep, EPISODES):
        state, _ = env.reset()
        state = np.array(state, dtype=np.float32)
        total_r = 0.0
        done = False

        while not done:
            if args.visualize_train:
                env.render()
                time.sleep(RENDER_DELAY)

            # ε-greedy
            if random.random() < epsilon:
                action = env.action_space.sample()
            else:
                with torch.no_grad():
                    qv = policy_net(torch.from_numpy(state).unsqueeze(0).to(device))
                    action = qv.argmax(dim=1).item()

            next_s, r, terminated, truncated, _ = env.step(action)
            done = terminated or truncated
            next_s = np.array(next_s, dtype=np.float32)
            position, velocity = next_s

            shaped_r = r
            shaped_r += (ALPHA2 * (position + 0.5)**2 + ALPHA1 * (position + 0.5)) + BETA * velocity
            
            # if (position >= 0.4):
            #     shaped_r += 1

            buffer.push(state, action, shaped_r, next_s, done)
            state = next_s
            total_r += shaped_r

            # 学习更新
            if len(buffer) >= BATCH_SIZE:
                s, a, r_b, s2, d = buffer.sample(BATCH_SIZE)
                s_t = torch.from_numpy(s).to(device)
                a_t = torch.from_numpy(a).long().unsqueeze(1).to(device)
                r_t = torch.from_numpy(r_b).float().unsqueeze(1).to(device)
                s2_t = torch.from_numpy(s2).to(device)
                d_t = torch.from_numpy(d.astype(np.float32)).unsqueeze(1).to(device)

                q_curr = policy_net(s_t).gather(1, a_t)
                with torch.no_grad():
                    q_next = target_net(s2_t).max(1)[0].unsqueeze(1)
                    q_target = r_t + GAMMA * q_next * (1 - d_t)

                loss = nn.functional.mse_loss(q_curr, q_target)
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()
                writer.add_scalar("Loss/Train", loss.item(), episode)

                # 按步数更新目标网络
                update_steps += 1
                if update_steps % TARGET_UPDATE_STEPS == 0:
                    target_net.load_state_dict(policy_net.state_dict())

        # 每集结束后的记录
        epsilon = max(EPS_END, epsilon * EPS_DECAY)
        episode_rewards.append(total_r)
        writer.add_scalar("Reward/Episode", total_r, episode)
        writer.add_scalar("Epsilon", epsilon, episode)
        print(f"Episode {episode+1}/{EPISODES}  Reward={total_r:.2f}  Epsilon={epsilon:.3f}")

        # 早停检查
        if args.stop_threshold is not None and len(episode_rewards) >= 10:
            last10_avg = np.mean(episode_rewards[-10:])
            if last10_avg > args.stop_threshold:
                print(f"[Early Stop] Last 10 episodes avg reward = {last10_avg:.2f} > threshold {args.stop_threshold}")
                break

        # 定期保存
        if (episode+1) % SAVE_INTERVAL == 0:
            ckpt = os.path.join(base_dir, f"model_{episode+1}.pt")
            save_checkpoint(ckpt, policy_net, target_net, optimizer,
                            episode+1, epsilon, episode_rewards)

    # 保存最后一版模型
    final_ckpt = os.path.join(base_dir, "model_final.pt")
    save_checkpoint(final_ckpt, policy_net, target_net, optimizer,
                    episode+1, epsilon, episode_rewards)

    env.close()
    writer.close()

    # 画训练曲线
    plt.figure(figsize=(8,4))
    plt.plot(range(1, len(episode_rewards)+1), episode_rewards)
    plt.xlabel("Episode")
    plt.ylabel("Total Reward")
    plt.title("Reward Trend")
    plt.grid(True)
    plt.savefig(os.path.join(base_dir, "training_rewards.png"))
    plt.show()

    return policy_net

def test(policy_net, episodes=10):
    env = gym.make("MountainCar-v0", render_mode="human")
    rewards = []
    print(f"Testing over {episodes} episodes...")
    for i in range(episodes):
        state, _ = env.reset()
        state = np.array(state, dtype=np.float32)
        done = False
        total_r = 0.0
        while not done:
            env.render()
            with torch.no_grad():
                action = policy_net(torch.from_numpy(state).unsqueeze(0).to(device)).argmax(1).item()
            state, r, terminated, truncated, _ = env.step(action)
            done = terminated or truncated
            state = np.array(state, dtype=np.float32)
            total_r += r
            time.sleep(0.02)
        rewards.append(total_r)
        print(f" Test #{i+1}: Reward = {total_r:.2f}")
    env.close()

    mean_r = np.mean(rewards)
    std_r = np.std(rewards)
    print(f"Average Reward over {episodes} episodes: {mean_r:.2f} ± {std_r:.2f}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="DQN / DuelingDQN MountainCar with Early Stop & Step-wise Target Update")
    parser.add_argument("--train",          action="store_true")
    parser.add_argument("--test",           action="store_true")
    parser.add_argument("--resume",         action="store_true")
    parser.add_argument("--checkpoint",     type=str,   default=None)
    parser.add_argument("--task_name",      type=str,   default="default")
    parser.add_argument("--visualize_train",action="store_true")
    parser.add_argument("--dueling",        action="store_true", help="Use Dueling DQN instead of standard DQN")
    parser.add_argument("--stop_threshold", type=float, default=None,
                        help="Early stop if avg reward over last 10 eps > this")
    args = parser.parse_args()

    model = None
    if args.train:
        model = train(args)

    if args.test:
        net_cls = DuelingDQN if args.dueling else DQN
        if not model:
            dummy = net_cls(2, 3).to(device)
            opt = optim.Adam(dummy.parameters(), lr=LR)
            ckpt = args.checkpoint or os.path.join('runs', args.task_name, "model_final.pt")
            if os.path.isfile(ckpt):
                _, _, _ = load_checkpoint(ckpt, dummy, dummy, opt)
                model = dummy
        if model:
            test(model)

强化学习gym的使用之mountaincar的训练 gym地址 该任务是让小车跑到右侧的山顶,但是小车力不够它直接冲上去,需要让它左右荡到山顶。 在它的源文件中可以找到相关信息: Observation: Type: Box(2) Num Observation Min Max 0 Car Position -1.2 0.6 1 Car Velocity . 阅读详情

相关推荐

【gym】【离散动作空间】【Mountain Car 山地车】

山地车 MDP 是一种确定性 MDP,它由一辆随机放置在正弦谷底部的汽车组成,唯一可能的动作是可以在任一方向上应用于汽车的加速度。gym 中的山地车域有两个版本:一个具有离散动作,另一个具有连续动作。两端的碰撞都是无弹性的,与壁碰撞时速度设置为 0。速度t+1 = 速度t +(作用 - 1)* 力 - cos(3 * 位置t) * 重力。目标是尽快到达放置在右侧山丘顶部的旗帜,因此智能体每个时间步长都会受到 -1 的奖励。终止:车的位置大于或等于 0.5(目标位置在右侧山丘的顶部)中分配一个均匀的随机值。

wq6qeg88的博客 1077

强化学习库gym之mountain-car源码解读

一、导入相关需要的包 import math import numpy as np import gym from gym import spaces from gym.utils import seeding 二、定义MountainCarEnv类,并且继承gym的env环境,在类中分别定义方法 1、初始参数方法 def __init__(self, goal_velocity = 0): self.min_position = -1.2 # 最小位置点 ..

AndrewGSD的博客 2451

强化学习之基于gym环境的DQN算法实战(Pytorch)

DQN算法是强化学习与深度学习结合的开端,其利用深度网络来拟合值函数,利用Q-leraning算法进行强化学习。DL为Agent提供学习的大脑,RL提供了计算机制,从而达到真的AI。 之前有写过利用DQN算法去解决Cartpole任务和Mountaincar任务,具体可见强化学习之DQN算法实战(Pytorch):https://blog.youkuaiyun.com/MR_kdcon/article/details/109699297 上述的任务用的都是gym自带的环境,本文将参考经典环境Puckworld家用g

Ton的博客 1万+

在gym的MountainCar环境下,用图片帧作为状态训练DQN网络

Apply DQN in gym environment in MountainCar-v0 文章目录Apply DQN in gym environment in MountainCar-v0一、Gym Environment1.1 ACTION SPACE1.2 STATE SPACE1.3 REWARD1.4 DONE二、Deep Q-learning2.1 Preprocess Frame2.2 Stack Frames2.3 Replay Buffer2.4 Q-target network

蛋总的快乐生活 1651

OpenAI Gym 新手必看:MountainCar-v0 环境详解与实战调参技巧

本文详细解析了OpenAI Gym中的MountainCar-v0环境,包括其核心机制、奖励函数设计及DQN调参技巧。通过实战案例和优化策略,帮助新手快速掌握强化学习在经典控制问题中的应用,提升算法性能与训练效率。

weixin_33701251的博客 158

MountainCar上跑通DQN的实战避坑指南

DQN(深度Q网络)作为经典离散动作强化学习算法,其核心在于利用神经网络近似Q值函数,通过经验回放与目标网络稳定训练。然而在MountainCar这类稀疏奖励、连续状态空间的控制任务中,标准实现极易因归一化错误、epsilon衰减失配、reward shaping缺失或target network更新不当而彻底失效。技术价值体现在对探索-利用权衡、状态表征设计及TD学习稳定性的深度理解;典型应用场景包括机器人控制、自动驾驶策略预训练及教学型RL实验平台。本文聚焦MountainCar-v0环境下的DQN工程

weixin_32501329的博客 270

OpenAI Gym 新手必看:MountainCar-v0 环境详解与 DQN 实战(附完整代码)

本文为强化学习新手提供了OpenAI Gym中MountainCar-v0环境的详细解析与DQN实战指南。通过剖析环境状态、动作空间与奖励机制,并配合完整的PyTorch代码,手把手教你使用深度Q网络训练智能体学会“荡秋千”策略,最终成功登顶。

kotlin6android的博客 345

基于Python的DQN在MountainCar上的实战:从实现到调优

强化学习通过智能体与环境的交互来学习最优策略,其核心是马尔可夫决策过程和值函数近似。DQN作为深度强化学习的里程碑算法,利用神经网络拟合Q函数,解决了传统Q-learning难以处理连续状态空间的问题。在工程实践中,DQN通过经验回放和目标网络提升训练稳定性,广泛应用于游戏AI、机器人控制等领域。本文以MountainCar环境为例,详细讲解DQN的Python实现,涵盖网络结构、经验回放、目标网络同步等关键环节,并分享调参避坑经验,帮助读者快速上手深度强化学习实战。

weixin_28701593的博客 108

基于DQN与gym的小车爬坡训练

基于DQN与gym的小车爬坡训练 强化学习 pytorch

m0_50936455的博客 3402

DQN实战:用Python调通MountainCar稀疏奖励难题

强化学习是机器学习中极具挑战性的分支,其核心在于智能体通过与环境交互学习最优策略。深度Q网络(DQN)作为价值函数的深度逼近方法,用神经网络替代传统Q表,解决了连续状态空间下的泛化问题,并通过经验回放和目标网络两大机制稳定训练过程。在实际工程中,奖励稀疏和环境反馈延迟常导致算法难以收敛,MountainCar就是经典案例——每一步都是负奖励,最优策略需要先反向蓄力,对智能体的长期信用分配能力要求极高。针对这类问题,奖励塑造(Reward Shaping)通过设计位置差分与里程碑奖励提供有效引导,配合合理的探

weixin_30558697的博客 272

Python实现DQN解决MountainCar稀疏奖励问题

强化学习是让智能体通过试错与环境交互、自主优化决策策略的核心范式;其核心原理在于贝尔曼方程驱动的价值迭代与经验回放机制支撑的稳定收敛;技术价值体现在处理稀疏奖励、延迟反馈和部分可观测状态等现实挑战;典型应用场景涵盖机器人控制、智能调度与金融策略等工业级任务;而MountainCar作为经典连续控制环境,以极简二维状态和反直觉动力学,成为验证DQN算法有效性与调试能力的黄金基准——结合Python生态与PyTorch实现,可快速构建可复现、可监控、可部署的最小可行强化学习闭环。

weixin_29038303的博客 315

莫烦强化学习视频笔记:第四节 4.3 OpenAI Gym 环境库

1. 要点 手动编环境是一件很耗时间的事情, 所以如果有能力使用别人已经编好的环境, 可以节约我们很多时间. OpenAI gym 就是这样一个模块, 他提供了我们很多优秀的模拟环境. 我们的各种 RL 算法都能使用这些环境. 不过 OpenAI gym 暂时只支持 MacOS 和 Linux 系统. Windows 已经支持, 但是听说还没有全面支持, 大家时不时查看下官网, 可能就有惊喜. 实在等不及Windows更新了, 用 tkinter 来手动编写一下环境也行. 这里有我制作的很好的tkin..

sophicchen的专栏 823

DQN+PyTorch+gym倒立摆登山车源码&模型

DQN+PyTorch+gym倒立摆登山车源码&模型,博文https://blog.youkuaiyun.com/qq_33309098/article/details/104588035

强化学习案例复现(2)--- MountainCar基于DQN

本文搭建的环境范围值为4个,可直接用该DQN模型训练,但在第一期基于Q-learning的文章中,自我搭建的环境中step有5个返回值,无法在该DQN的模型中运行,后面如果想用5个返回值,该代码要重写。直接用 pip install stable-baselines3[extra],安装失败,换成以下命令安装。源代码为了测试方便,测试过程并不显示,代码为。笔者希望可以显示测试过程,代码改为。

weixin_48878618的博客 868

DEV-C++调试设置

       昨天用C/C++去考了CSP,结果用DEV-C++调试总是闪退,按照我的记忆打开了调试参数,迷迷糊糊搞了一通,还是没办法调试,难受了几个小时。所以今天痛下决心,一定要写下DEV-C++设置调试的过程,警示自己! 解决步骤 1.打开DevC++找到上方工具栏 2.点击选择编译选项,再按下图所示设置即可

懒羊羊的快乐小屋 1029

机械臂开发必备:KDL库正逆解与动力学实战指南

在机器人算法领域,运动学与动力学计算是机械臂控制、仿真与轨迹规划的核心基础。正运动学描述关节空间到笛卡尔空间的映射,逆运动学则需要求解复杂的非线性方程,工程实现时常面临数值稳定性与调试效率的挑战。KDL(Kinematics and Dynamics Library)作为ROS生态中广泛使用的开源库,提供了统一的模型描述与高效求解器,将正逆解、雅可比矩阵及动力学参数计算封装为简洁接口,大幅降低开发门槛。无论是机械臂的笛卡尔空间轨迹跟踪,还是基于动力学模型的前馈控制,KDL都展现出强大的工程价值。本文从运动学

weixin_33860528的博客 2509

【强化学习实战-04】DQN和Double DQN保姆级教程(2):以MountainCar-v0

【强化学习实战】DQN和Double DQN保姆级教程(2):以MountainCar-v0为什么用Deep Q Network (DQN)实战:用Double DQN求解MountainCar问题MountainCar问题详解MountainCar问题的源代码解释cartpole.pyMountainCar的状态(Observation)MountainCar的动作MountainCar的目的DQN 求解MountainCar问题:完整代码详解定义神经网络Q(w)Q(\mathbf{w})Q(w)神经网络

HsinglukLiu的博客 2759

深入剖析 Wenet 下 AISHELL-1 的 run.sh 脚本:从数据准备到模型训练

run.sh脚本用于处理 AISHELL-1 数据集的整个训练和测试流程。我们将逐步分析脚本中的每个部分,包括环境变量、参数设置、各个阶段的执行等。stage: 设置脚本的起始阶段(如数据准备)。stop_stage: 设置脚本的结束阶段。通过对 Wenet 下 AISHELL-1 的run.sh脚本的详细剖析,我们希望你能更好地理解每个步骤的功能及其背后的原理。此脚本不仅为模型训练提供了便利,也为用户自定义和扩展训练流程提供了基础。希望本教程能帮助你顺利完成语音识别项目!

帅小柏的博客 1634

用DQN算法玩转MountainCar-v0:从零实现到性能优化全记录

本文详细解析了如何利用DQN算法攻克OpenAI Gym中的MountainCar-v0环境,从基础实现到性能优化全流程。通过设计神经网络架构、优化经验回放机制、重塑奖励函数等策略,解决了稀疏奖励和延迟反馈等关键挑战。实战数据显示,经过调优的DQN算法能在387轮内实现平均98.2步的优异表现,为强化学习爱好者提供了可复现的解决方案。

xxx12的博客 1025

TPAMI 2024 | 基于外观的深度学习凝视估计:综述与基准测试

人类目光提供了关于人类焦点和意图的有价值信息,使其成为研究的关键领域。最近,深度学习彻底改变了基于外观的眼神估计。然而,由于眼神估计研究的独特特征,如2D眼神位置和3D眼神向量之间的不公平比较以及不同的预处理和后处理方法,缺乏开发基于深度学习的眼神估计算法的明确指导方针。在本文中,我们系统回顾了使用深度学习的眼神估计方法。首先,我们沿着典型的眼神估计流程调查现有的算法:深度特征提取、深度学习模型设计、个人校准和平台。

小白学视觉 345

9、储备池学习:从学习到学习的新范式

本文探讨了基于学习到学习(L2L)框架的储备池计算新范式,提出通过在外循环中优化储备池的超参数(如递归连接权重、输入权重和读出初始化),以提升其在多种任务中的内循环学习性能。研究展示了两种主要实验设置:一是优化储备池用于回归二阶Volterra滤波器任务,显著优于随机基线;二是实现无需调整读出权重、仅依赖内部动态学习非线性函数的能力,表明储备池可快速构建目标函数的内部模型并安装任务先验知识。结合流程图与表格,文章系统呈现了L2L的训练流程、技术细节及实验结果,并讨论了性能提升、泛化能力等开放问题,指出了未来

ujm56789012的博客 506

jupyter notebook远程服务器使用gym

jupyter notebook中使用gym jupyter notebook中使用gym 莫烦pytorch系列教程 4.5 DQN 强化学习 (PyTorch tutorial 神经网络 教学),使用到gym。 Gym是一个用于测试和比较强化学习算法的工具包,它不依赖强化学习算法结构,并且可以使用很多方法对它进行调用,像Tensorflow。 目前我使用Ubuntu远程服务器,配合Vscode的jupyter notebook进行远端调试。 安装gym !pip install -i https://p

irober的博客 1982

STM32F103(二十三)通用同步异步收发器(USART)

学习板:STM32F103ZET6 往期博客: STM32F103五分钟入门系列(一)跑马灯(库函数+寄存器)+加编程模板+GPIO总结 STM32F103五分钟入门系列(二)GPIO的七大寄存器+GPIOx_LCKR作用和配置 STM32F103五分钟入门系列(三)GPIO的常用库函数使用方法总结+一个网络上的误区 STM32F103五分钟入门系列(四)蜂鸣器实验(库函数+寄存器) STM32F103五分钟入门系列(五)按键实验(库函数+寄存器) STM32F103五分钟入门系列(六)时钟框图+相关寄存器

Curnane0_0的博客 1019

用DQN算法玩转MountainCar-v0:从零开始实现小车上山(附完整代码)

本文详细介绍了如何从零开始使用DQN算法解决经典的强化学习环境MountainCar-v0。通过剖析稀疏奖励与长期依赖的挑战,提供了完整的代码实现,包括经验回放、目标网络等核心组件,并分享了训练调试与可视化技巧,帮助开发者掌握DQN实战应用。

sky77的博客 187

使用HART Server PC软件进行HART设备的组态、调试和分析的完整指南

HART协议是一种用于工业自动化中的双向通信协议,能够在4-20mA模拟信号的基础上叠加数字信号,从而实现设备的远程监控和管理。HART协议兼具模拟和数字通信的优点,被广泛应用于过程控制系统中。设备组态:通过软件可以对HART设备进行组态,配置设备参数。设备调试:支持设备的在线调试和故障诊断,方便快速解决问题。数据分析:提供设备运行数据的实时监控和历史数据分析功能。报表生成:支持生成各类报表,便于数据记录和管理。

qq_38334677的博客 2475

【深度学习驱动流体力学】Python流体力学Ansys Fluent

PyFluent 是一个将 Python 编程语言与 Ansys Fluent 流体动力学 (CFD) 仿真软件集成的工具。它允许用户通过 Python 脚本来控制和自动化 Fluent 中的仿真任务,实现从预处理、求解到后处理的全流程控制。PyFluent 结合了 Python 的灵活性和 Fluent 的强大功能,提供了一种高效且灵活的 CFD 仿真方法。PyFluent 是一个强大而灵活的工具,使用户能够通过 Python 脚本全面利用 Ansys Fluent 的功能。

源代码杀手的博客 3126
上一篇: 将一个新的机器人模型导入最新版isaacLab进行训练(以unitree H1_2为例)
下一篇: 路径规划算法总结:从 Dijkstra 到 A* 与 Hybrid A
我要看无刺有刺
博客等级 码龄8年 292粉丝 543原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值