Files
MAGAIL4AutoDrive/问题解决记录.md

317 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 问题解决记录
## 运行 `train_magail.py` 遇到的问题及解决方案
---
### ❌ 问题1: 模块导入错误
**错误信息:**
```python
ImportError: attempted relative import with no known parent package
```
**原因:**
- `Algorithm/` 文件夹中的文件使用了不一致的导入方式
- 有些文件使用相对导入(`.ppo`, `.utils`),有些使用绝对导入
**解决方案:**
1. 修改所有导入语句为兼容模式try相对导入except绝对导入
2. 创建 `Algorithm/__init__.py``Env/__init__.py` 使其成为Python包
**修改的文件:**
-`Algorithm/ppo.py` - 添加try-except导入
-`Algorithm/policy.py` - 添加try-except导入
-`Algorithm/disc.py` - 添加try-except导入
-`Algorithm/magail.py` - 添加try-except导入
-`Algorithm/__init__.py` - 新建包初始化文件
-`Env/__init__.py` - 新建包初始化文件
---
### ❌ 问题2: `action_shape` 参数缺失
**错误信息:**
```python
TypeError: MAGAIL.__init__() got an unexpected keyword argument 'action_shape'
```
**原因:**
- `MAGAIL` 类的 `__init__()` 方法没有定义 `action_shape` 参数
- 但训练脚本传递了这个参数
**解决方案:**
`MAGAIL.__init__()` 中添加 `action_shape` 参数并传递给父类
**修改代码:**
```python
# 修改前
class MAGAIL(PPO):
def __init__(self, buffer_exp, input_dim, device, ...):
super().__init__(state_shape=input_dim, device=device)
# 修改后
class MAGAIL(PPO):
def __init__(self, buffer_exp, input_dim, device, action_shape=(2,), **kwargs):
super().__init__(state_shape=input_dim, device=device,
action_shape=action_shape, **kwargs)
```
---
### ❌ 问题3: 维度类型不匹配
**错误信息:**
```python
TypeError: empty(): argument 'size' must be tuple of ints,
but found element of type tuple at pos 2
```
**原因:**
- `input_dim` 传入时是元组 `(108,)`
-`Bert``nn.Linear(input_dim, embed_dim)` 期望 `input_dim` 是整数
**根本原因:**
```python
# 训练脚本中
magail = MAGAIL(
input_dim=(108,), # 传入的是元组
...
)
# 在 PPO.__init__ 中
self.critic = Bert(
input_dim=state_shape, # state_shape = (108,) 仍是元组
output_dim=1
)
# 在 Bert.__init__ 中
self.projection = nn.Linear(input_dim, embed_dim) # 期望 input_dim=108
```
**解决方案:**
在使用 `state_shape``input_dim` 创建 `Bert` 时,提取整数值
**修改代码:**
1. **在 `Algorithm/ppo.py` 中:**
```python
# 修改前
self.critic = Bert(
input_dim=state_shape,
output_dim=1
).to(device)
# 修改后
state_dim = state_shape[0] if isinstance(state_shape, tuple) else state_shape
self.critic = Bert(
input_dim=state_dim,
output_dim=1
).to(device)
```
2. **在 `Algorithm/magail.py` 中:**
```python
# 修改前
self.disc = GAILDiscrim(input_dim=input_dim)
# 修改后
state_dim = input_dim[0] if isinstance(input_dim, tuple) else input_dim
self.disc = GAILDiscrim(input_dim=state_dim)
```
3. **在 `Algorithm/magail.py` 的Normalizer中**
```python
# 修改前
self.normalizer = Normalizer(self.state_shape[0]*2)
# 修改后
state_dim = self.state_shape[0] if isinstance(self.state_shape, tuple) else self.state_shape
self.normalizer = Normalizer(state_dim*2)
```
---
## 所有修改总结
### 修改的文件列表
| 文件 | 修改内容 |
|------|----------|
| `Algorithm/ppo.py` | 1. 添加try-except导入<br>2. 添加action_shape参数<br>3. 修复state_shape元组问题 |
| `Algorithm/magail.py` | 1. 添加try-except导入<br>2. 添加action_shape参数<br>3. 修复input_dim元组问题 |
| `Algorithm/policy.py` | 添加try-except导入 |
| `Algorithm/disc.py` | 添加try-except导入 |
| `Algorithm/__init__.py` | 新建包初始化文件 |
| `Env/__init__.py` | 新建包初始化文件 |
### 新增的文件
| 文件 | 用途 |
|------|------|
| `train_magail.py` | 完整的MAGAIL训练脚本 |
| `MAGAIL算法应用指南.md` | 详细的使用文档 |
| `快速测试.sh` | 快速测试脚本 |
| `问题解决记录.md` | 本文件 |
---
## 如何运行
### 方法1: 直接运行(推荐)
```bash
# 确保在conda环境中
conda activate metadrive
# 运行训练少量episode测试
python train_magail.py --episodes 5 --horizon 100
# 带可视化
python train_magail.py --episodes 5 --render
# 完整训练
python train_magail.py --episodes 1000 --horizon 300
```
### 方法2: 使用测试脚本
```bash
conda activate metadrive
bash 快速测试.sh
```
### 方法3: 查看帮助
```bash
python train_magail.py --help
```
---
## 验证是否修复成功
运行以下命令测试:
```bash
# 测试1: 验证导入
python -c "from Algorithm.magail import MAGAIL; print('✅ 导入成功!')"
# 测试2: 验证初始化
python -c "
from Algorithm.magail import MAGAIL
import torch
class DummyBuffer:
def __init__(self, device):
self.device = device
def sample(self, batch_size):
return torch.randn(batch_size, 108, device=self.device), \
torch.randn(batch_size, 108, device=self.device)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
buffer = DummyBuffer(device)
magail = MAGAIL(
buffer_exp=buffer,
input_dim=(108,),
device=device,
action_shape=(2,)
)
print('✅ MAGAIL初始化成功!')
"
# 测试3: 运行1个episode
python train_magail.py --episodes 1 --horizon 50
```
---
### ❌ 问题4: 保存模型时目录不存在
**错误信息:**
```python
FileNotFoundError: [Errno 2] 没有那个文件或目录: './outputs/magail_xxx/models/best_model/model.pth'
```
**原因:**
- `save_models()` 方法直接保存文件,但没有创建目录
**解决方案:**
在保存前使用 `os.makedirs(path, exist_ok=True)` 创建目录
**修改代码:**
```python
# 修改前
def save_models(self, path):
torch.save({...}, os.path.join(path, 'model.pth'))
# 修改后
def save_models(self, path):
os.makedirs(path, exist_ok=True) # 确保目录存在
torch.save({...}, os.path.join(path, 'model.pth'))
```
---
## 剩余的已知问题
### 1. 专家数据加载未实现
**现象:**
```
⚠️ 警告: 未找到专家数据
```
**原因:**
`ExpertBuffer._extract_trajectories()` 方法是空的需要根据实际Waymo数据格式实现
**TODO**
- 分析Waymo pkl文件的实际结构
- 实现轨迹提取逻辑
### 2. 多智能体buffer存储
**现象:**
当前buffer是为单智能体设计的
**TODO**
- 实现多智能体经验存储逻辑
- 或者修改为将所有智能体作为一个batch处理
### 3. 环境奖励为0
**现象:**
环境返回的奖励全是0
**TODO**
- 设计合理的任务奖励函数
- 或者完全依赖GAIL的内在奖励
---
## 下一步计划
1.**已完成**: 修复导入问题
2.**已完成**: 修复参数问题
3.**已完成**: 修复维度问题
4.**已完成**: 修复保存模型目录问题
5.**已完成**: 测试完整训练流程 - **训练脚本可以正常运行!**
5. 📝 **待办**: 实现专家数据加载
6. 📝 **待办**: 完善多智能体buffer
7. 📝 **待办**: 设计奖励函数
8. 📝 **待办**: 超参数调优
---
## 参考文档
- `技术说明文档.md` - 完整的技术实现细节
- `MAGAIL算法应用指南.md` - 使用指南和示例
- `README.md` - 项目概述
---
**最后更新**: 2024
**状态**: ✅ 主要问题已解决,可以开始训练