Kaiwu

学习期

  • 熟悉平台以及了解项目
1
mkdir -p /data/projects/gorge_walk_v2/log/learner

初赛:

任务

训练智能体,在地图中不断探索中学习移动策略,减少碰撞障碍物,以最少的步数从起点走到终点,可能会有附属任务——收集宝箱

场景介绍

峡谷漫步使用64*64的网格化的地图(智能体每步移动的距离是一网格),地图中包含起点终点道路障碍物宝箱等元素。

元素 说明
英雄 环境中存在英雄单位,智能体可以控制英雄在地图中进行移动。本环境采用鲁班作为英雄角色。
起点 任务开始时,英雄单位在起点出现。
终点 任务设置的目的地,当英雄抵达终点时,任务结束。
道路 英雄可以在道路中通过前、后、左、右四个方向移动进行试探,每次移动的距离是一个网格。
障碍物 英雄遇到障碍物时无法继续前进,需要调整方向开启新的探索。
宝箱 如果用户给任务配置了宝箱,则智能体可以通过控制英雄拾取宝箱增加积分,每个宝箱获得100积分,地图中共有10个可配置宝箱的点位。
视野范围 智能体的视野范围是以自己为中心,5*5范围内的所有格子。

规则介绍

总积分 = 终点积分 + 步数积分 + 宝箱积分

  • 终点积分:到达终点即获得150积分。
  • 步数积分(最大步数 - 完成步数) * 奖励系数0.2。任务设置有最大步数,当智能体到达终点时,根据最大步数和任务完成步数计算步数积分。
  • 宝箱积分:每获得一个宝箱,即可增加100积分。

注意:若在最大步数内没有走到终点(包括最大步数),则判定为任务超时。超时任务的总积分为0

本赛题需选手自备算力,下载客户端后在本地进行训练。为提升体验,学习期阶段支持单机和分布式训练模式。

注意事项

训练启动时,可选择如下算法:

  • dynamic_programming
  • monte_carlo
  • sarsa
  • q_learning
  • diy

可选训练模式:

  • 单机
  • 分布式

整体训练思路参考:

  1. 第一阶段,让agent学会走路,到达终点(宝箱奖励为0,终点奖励在引导智能体决策);
  2. 第二阶段,在智能体学会走路的基础上,尝试收集宝箱(靠近宝箱的奖励,获取宝箱的奖励,终点奖励减少)
  3. 第三阶段,强化智能体收集宝箱的能力(奖励中设置在未全部收集到宝箱时终点奖励为0)

实现分阶段训练的方法:

训练的整体流程是在train_workflow.py中控制的,可以利用workflow函数中的epoch来划分训练的各个阶段(具体如何划分大家自行确定)

奖励设计思路:
1.针对上面的三个阶段设计了三个不同的奖励体系
2.宝箱奖励的设计非常重要(宝箱奖励的变化不仅反映是否拿到宝箱,还可以反映出闪现的使用情况,buff的使用情况),好的宝箱奖励设计决定了智能体是否是个优秀的迷宫探索者
3.在设计宝箱奖励时重点要关注奖励边界变化(重点:收集到宝箱的瞬间一定要考虑周全,pluto佬也提到这点)

训练设置:常规的八个随机宝箱,收敛时间在16个小时以上

可以参考的一些指南:
学习期峡谷漫步开发指南的注解(一)(前两部分) - 腾讯开悟社区平台
学习期峡谷漫步开发指南的注解(二)(后两部分) - 腾讯开悟社区平台

实现:

  1. 首先先实现在没有宝箱的情况下的DQN算法,同时补充完代码
  2. 然后在1的基础上进行优化,让机器人学会找宝箱
  3. 最后优化找宝箱

实现Step1
重新理解一下代码结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
📦 根目录
├── 📂 agent
│ ├── 📂 algorithm
│ └── 📄 __init__.py
│ └── 📄 algorithm.py
│ ├── 📂 conf
│ └── 📄 __init__.py
│ └── 📄 conf.py
│ └── 📄 train_env_conf.toml
│ ├── 📂 feature
│ └── 📄 __init__.py
│ └── 📄 definition.py
│ └── 📄 preprocessor.py
│ ├── 📂 model
│ └── 📄 __init__.py
│ └── 📄 model.py
│ ├── 📂 workflow
│ └── 📄 __init__.py
│ └── 📄 train_workflow.py
│ ├── 📄 __init__.py
│ └── 📄 agent.py
├── 📂 conf
│ ├── 📄 __init__.py
│ ├── 📄 configure_app.toml
├── 📂 log
└── 📄 train_test.py

algorithm主要是agent的实现,包含训练和预训练。
官方解释:算法开发 - 腾讯开悟
其中learn方法是实现强化学习优化算法的核心方法。函数的输入是训练样本数据,我们要基于不同的算法完成相关实现,包括优化方法、损失计算等。

feature 特征相关,主要包含用户自定义的数据结构和数据处理方法,以及特征和奖励的计算,详情见实现特征处理和样本处理
特征处理 - 腾讯开悟
model模型相关,由于峡谷漫步的4个算法都未使用到神经网络模型,故文件夹为空
config.py该算法下的配置,用户可以任意增加配置或修改配置,但注意:SAMPLE_DIM是开悟框架使用配置,不允许删除

train_workflow.py(强化学习的训练流程,详情见强化学习训练流程开发)
工作流开发 - 腾讯开悟
可能这里可以设置其他笔记里提到的分阶段开发?

conf:配置文件,感觉还是有点不知道怎么修改配置
train_test.py 测试代码正确性,保证先通过这里再去提交模型

开发流程:
part1:环境
环境接受到智能体的行动,然后给出反馈
part2:智能体
智能体接受到新的环境信息,通过神经网络或者计算做出决策,把动作给到环境
part3:样本池和算法
每次的环境信息变化和智能体行动都会被打包成帧数据,存储起来,一局游戏是一个样本,组成样本池后供应给算法来计算奖励,修正智能体的行为

(至于多久修正一次智能体,一次用多少样本,一个样本用多少次这是基础设置负责的(也就是conf);怎么修正,修正多大程度是由算法决定的)

首先我在model里实现一个model类,也就是实现神经网络。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
###########################################################################
# Copyright © 1998 - 2025 Tencent. All Rights Reserved.
###########################################################################
"""
Author: Tencent AI Arena Authors
"""

import torch
import numpy as np
from torch import nn
import torch.nn.functional as F
from kaiwu_agent.utils.common_func import attached


class MLPBlock(nn.Module):
def __init__(self, input_dim, hidden_dims, output_dim):
super().__init__()
layers = []
last_dim = input_dim
for h in hidden_dims:
layers.append(nn.Linear(last_dim, h))
layers.append(nn.ReLU())
last_dim = h
layers.append(nn.Linear(last_dim, output_dim))
self.model = nn.Sequential(*layers)

def forward(self, x):
return self.model(x)

class Model(nn.Module):
def __init__(self, image_shape=(6, 51, 51), flat_dim=64, action_shape=8):
super().__init__()
c, h, w = image_shape

# 卷积层部分(提取地图图像特征)
self.conv = nn.Sequential(
nn.Conv2d(c, 32, kernel_size=5, stride=2, padding=2), # -> [32, 26, 26]
nn.BatchNorm2d(32),
nn.ReLU(),

nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1), # -> [64, 13, 13]
nn.BatchNorm2d(64),
nn.ReLU(),

nn.Conv2d(64, 64, kernel_size=3, stride=2, padding=1), # -> [64, 7, 7]
nn.ReLU()
)

conv_out_dim = 64 * 7 * 7

# 全连接部分(融合 conv + 其他一维特征)
self.q_net = nn.Sequential(
nn.Linear(conv_out_dim + flat_dim, 512),
nn.ReLU(),
nn.Linear(512, 256),
nn.ReLU(),
nn.Linear(256, action_shape)
)

self.target_q_net = nn.Sequential(
nn.Linear(conv_out_dim + flat_dim, 512),
nn.ReLU(),
nn.Linear(512, 256),
nn.ReLU(),
nn.Linear(256, action_shape)
)

self.update_target()

def forward(self, image, flat_feature):
batch = image.shape[0]
conv_feat = self.conv(image).view(batch, -1) # 展平
x = torch.cat([conv_feat, flat_feature], dim=1) # 拼接上其他特征
return self.q_net(x)

def target(self, image, flat_feature):
with torch.no_grad():
batch = image.shape[0]
conv_feat = self.conv(image).view(batch, -1)
x = torch.cat([conv_feat, flat_feature], dim=1)
return self.target_q_net(x)

def update_target(self):
self.target_q_net.load_state_dict(self.q_net.state_dict())

然后实现agent.py
基础Agent类的五个接口,按照具体代码示例的顺序,我做个逻辑的简单解释。

  1. learn:挨个提取各个值之后计算 Q 值的更新量 delta,使用学习率和更新量来改变对应Q值表的对应值(二重索引)
  2. predict:就是存了一下状态,然后用一个函数处理,引入一个随机概率,最后返回行动的列表。
  3. exploit:依然存一下状态,直接处理,然后返回行动列表。
  4. save_model:定义一个路径,保存self的Q函数,日志记录一下保存成功。
  5. load_model:定义个路径,加载模型,存个日志,没加载成功就存个日志并退出整个程序。

初赛

参考了精华帖中提到的一些优化,先看看能不能写出一版新的。
【精华贴】海选阶段性总结 - 腾讯开悟社区平台
首先修改model.py,修改其中的神经网络,根据精华帖中提到的,加入maxpool,batchnorm,残差连接等使得训练更稳定

复赛

典型修改流程

  1. 先修正配置文件:
    修改 conf.py,保证奖励权重字典正确。
    调试环境数据入口

  2. 修改/调试 feature_process.py、agent.py,保证观测数据结构和内容正确。
    调试reward_process

  3. 修改 reward_process.py,加日志、异常处理,保证 reward_sum 正确计算。
    检查reward传递链路

  4. 修改 algorithm.py、learner.py,保证 reward 字段被正确采样、传递到训练流程、上报监控。
    监控代码检查

  5. 修改 monitor_proxy_process.py、prometheus_utils.py,保证 reward 字段正确上报。


Kaiwu
https://pqcu77.github.io/2025/07/12/kaiwu/
作者
linqt
发布于
2025年7月12日
许可协议