Skill: limax666/paper-research-assistant (version 1.0.0)

--- name: paper-research-assistant description: 科研论文研读与复现自动化助手。使用当用户需要：(1) 研读论文 PDF 并提取核心内容，(2) 生成结构化研读报告，(3) 查找官方代码/数据集，(4) 编写复现代码框架，(5) 设计实验方案复现论文结果 --- # Paper Research Assistant - 科研论文研读与复现助手 ## 核心工作流 ### 1. 论文接收与解析 - 接收用户提供的论文 PDF 文件路径或 arXiv/期刊链接 - 使用 `scripts/parse_paper.py` 提取论文元数据（标题、作者、摘要、关键词） - 识别论文类型：理论研究/实验研究/综述/方法论文 ### 2. 深度研读与报告生成 - 提取核心贡献（通常位于 Introduction 最后一段或 Conclusion） - 识别方法论框架（模型架构、算法流程、关键公式） - 整理实验配置（数据集、基线方法、评估指标、超参数） - 生成结构化研读报告（使用 `references/report_template.md`） ### 3. 资源收集 - 搜索官方代码仓库（GitHub、GitLab、项目主页） - 查找配套数据集（HuggingFace、Kaggle、论文中提到的数据源） - 验证资源可用性与许可证 ### 4. 复现代码生成 - 根据论文方法描述生成代码骨架（PyTorch/TensorFlow） - 实现核心算法模块 - 配置训练循环与评估流程 - 生成可运行的实验脚本 ### 5. 实验方案设计 - 列出环境依赖（Python 版本、关键库） - 设计对比实验（消融实验、基线对比） - 配置超参数搜索空间 - 预估计算资源需求 ## 脚本使用 ### parse_paper.py ```bash python scripts/parse_paper.py --pdf /path/to/paper.pdf --output /tmp/paper_metadata.json ``` 提取论文结构化元数据 ### generate_report.py ```bash python scripts/generate_report.py --metadata /tmp/paper_metadata.json --template references/report_template.md --output /tmp/research_report.md ``` 生成研读报告 ### scaffold_code.py ```bash python scripts/scaffold_code.py --paper-json /tmp/paper_metadata.json --framework pytorch --output-dir /tmp/repo ``` 生成复现代码骨架 ## 参考文档 - `references/report_template.md` - 研读报告标准模板 - `references/code_style.md` - 复现代码规范 - `references/experiment_design.md` - 实验设计指南 ## 输出规范 ### 研读报告结构 ```markdown # 论文研读报告 ## 基本信息 - 标题： - 作者/机构： - 发表 venue： - 日期： ## 核心贡献 1. ... 2. ... ## 方法论 - 问题定义： - 核心思路： - 关键公式： ## 实验配置 - 数据集： - 基线方法： - 评估指标： - 超参数： ## 复现可行性 - 官方代码：[有/无] [链接] - 数据集：[公开/需申请] [链接] - 计算需求： - 预计复现难度：[低/中/高] ## 待澄清问题 - ... ``` ## 注意事项 1. **PDF 解析限制**：复杂公式可能识别不准确，需人工核对 2. **代码复现范围**：生成骨架代码，完整实现需根据实际调试 3. **资源验证**：所有链接需验证有效性，标注最后访问时间 4. **许可证合规**：注明原论文/代码的许可证类型 ## 工具依赖 - PyMuPDF / pdfplumber - PDF 解析 - arxiv API - 论文元数据查询 - GitHub API - 代码仓库搜索 - HuggingFace API - 数据集查询

path: code_style.md
content: # 复现代码规范

## 目录结构

```
paper-implementation/
├── README.md           # 项目说明
├── requirements.txt    # 依赖列表
├── setup.py           # 安装脚本（可选）
│
├── configs/           # 配置文件
│   ├── default.yaml
│   └── experiment_*.yaml
│
├── src/               # 源代码
│   ├── __init__.py
│   ├── model.py       # 模型定义
│   ├── layers.py      # 自定义层
│   ├── losses.py      # 损失函数
│   └── utils.py       # 工具函数
│
├── datasets/          # 数据加载
│   ├── __init__.py
│   ├── base.py        # 基类
│   └── custom.py      # 自定义数据集
│
├── scripts/           # 脚本
│   ├── train.py       # 训练脚本
│   ├── evaluate.py    # 评估脚本
│   └── visualize.py   # 可视化脚本
│
├── checkpoints/       # 模型权重（.gitignore）
├── logs/              # 训练日志（.gitignore）
└── results/           # 实验结果（可选）
```

## 代码规范

### 1. 模型定义

```python
import torch
import torch.nn as nn


class PaperModel(nn.Module):
    """
    论文方法的核心模型实现。
    
    Reference:
        [论文标题](论文链接)
    
    Args:
        config: 配置字典，包含模型超参数
        **kwargs: 其他参数
    
    Examples:
        >>> model = PaperModel(config)
        >>> output = model(input_tensor)
    """
    
    def __init__(self, config, **kwargs):
        super().__init__()
        self.config = config
        
        # 明确标注每个组件对应的论文章节/公式
        # Example: "对应论文公式 (3)"
        self.encoder = nn.Linear(config.input_dim, config.hidden_dim)
        
    def forward(self, x):
        """
        前向传播。
        
        Args:
            x: 输入张量 [batch_size, input_dim]
            
        Returns:
            output: 输出张量 [batch_size, output_dim]
        """
        # 添加注释说明每步对应的算法步骤
        x = self.encoder(x)  # 公式 (3): 编码
        return x
```

### 2. 配置管理

```yaml
# configs/default.yaml

# 模型配置
model:
  name: "PaperModel"
  input_dim: 784
  hidden_dim: 512
  output_dim: 10
  
# 训练配置
training:
  epochs: 100
  batch_size: 32
  learning_rate: 0.001
  weight_decay: 1e-5
  
# 数据配置
data:
  name: "mnist"
  data_dir: "./data"
  num_workers: 4
  
# 实验配置
experiment:
  seed: 42
  log_interval: 10
  save_dir: "./checkpoints"
```

### 3. 训练循环

```python
def train_epoch(model, dataloader, optimizer, criterion, device, epoch):
    """
    单个训练 epoch。
    
    Args:
        model: 模型
        dataloader: 数据加载器
        optimizer: 优化器
        criterion: 损失函数
        device: 计算设备
        epoch: 当前 epoch 编号
        
    Returns:
        avg_loss: 平均损失
    """
    model.train()
    total_loss = 0
    
    for batch_idx, (data, target) in enumerate(dataloader):
        data, target = data.to(device), target.to(device)
        
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()
        
        total_loss += loss.item()
        
        if batch_idx % args.log_interval == 0:
            print(f'Epoch {epoch} [{batch_idx}/{len(dataloader)}] Loss: {loss.item():.4f}')
    
    return total_loss / len(dataloader)
```

### 4. 评估函数

```python
@torch.no_grad()
def evaluate(model, dataloader, criterion, device):
    """
    评估模型性能。
    
    Args:
        model: 模型
        dataloader: 数据加载器
        criterion: 损失函数
        device: 计算设备
        
    Returns:
        metrics: 评估指标字典
    """
    model.eval()
    total_loss = 0
    correct = 0
    total = 0
    
    for data, target in dataloader:
        data, target = data.to(device), target.to(device)
        output = model(data)
        
        total_loss += criterion(output, target).item()
        pred = output.argmax(dim=1)
        correct += pred.eq(target).sum().item()
        total += target.size(0)
    
    metrics = {
        'loss': total_loss / len(dataloader),
        'accuracy': correct / total
    }
    
    return metrics
```

## 注释规范

1. **关键公式引用：** 在实现论文公式的代码处添加注释
   ```python
   # 公式 (5): 注意力权重计算
   attention = softmax(q @ k.transpose(-2, -1) / sqrt(d_k))
   ```

2. **超参数说明：** 说明关键超参数的选择依据
   ```python
   # 论文 Section 4.2: hidden_dim=512 在大多数任务上表现最佳
   self.hidden_dim = 512
   ```

3. **与官方实现差异：** 如有不同，明确标注
   ```python
   # 注意：官方代码使用 LayerNorm，这里用 BatchNorm 替代
   # 原因：小 batch size 下 LayerNorm 更稳定
   ```

## Git 规范

### .gitignore
```
__pycache__/
*.pyc
checkpoints/
logs/
*.log
.env
.DS_Store
```

### Commit Message
```
feat: 实现论文核心注意力机制
fix: 修复梯度计算错误
docs: 添加 API 文档
test: 添加单元测试
```

## 文档规范

### README.md 必含内容

1. 论文信息（标题、作者、链接）
2. 环境要求
3. 快速开始
4. 复现结果对比
5. 与官方实现的差异说明

---

*参考：https://github.com/ossu/computer-science*


path: experiment_design.md
content: # 实验设计指南

## 实验类型

### 1. 主实验（Main Results）

复现论文的核心实验结果，用于验证方法有效性。

**设计要点：**
- 使用与论文相同的数据集划分
- 使用与论文相同的评估指标
- 报告平均值±标准差（多次运行）
- 与论文报告的基线方法对比

**输出格式：**
```markdown
| 方法 | 准确率 (%) | F1 Score | AUC |
|------|-----------|----------|-----|
| Baseline 1 | 85.2 | 83.1 | 0.89 |
| Baseline 2 | 87.5 | 85.4 | 0.91 |
| **Ours** | **89.3** | **87.2** | **0.93** |
```

### 2. 消融实验（Ablation Study）

分析各组件对整体性能的贡献。

**常见类型：**
- **组件移除：** 逐个移除模型组件
- **组件替换：** 用替代方案替换关键组件
- **超参数敏感性：** 测试关键超参数的影响

**设计示例：**
```markdown
| 变体 | 准确率 (%) | 说明 |
|------|-----------|------|
| Full Model | 89.3 | 完整模型 |
| -Component A | 86.1 | 移除组件 A |
| -Component B | 87.5 | 移除组件 B |
| Replace X with Y | 85.8 | 替换组件 X |
```

### 3. 对比实验（Comparative Study）

与 SOTA 方法进行公平对比。

**注意事项：**
- 确保实验设置一致（数据预处理、增强等）
- 使用相同的训练/测试划分
- 报告统计显著性检验（如 t-test）

### 4. 定性分析（Qualitative Analysis）

可视化展示方法效果。

**常见形式：**
- 注意力可视化
- 特征空间 t-SNE 图
- 成功/失败案例分析
- 生成结果展示

## 实验记录模板

### 实验日志

```markdown
## 实验 ID: exp_001

**日期：** 2024-01-15

**目的：** 复现论文 Table 1 主实验

**配置：**
- 模型：PaperModel
- 数据集：CIFAR-10
- 批次大小：32
- 学习率：0.001

**结果：**
- 训练损失：0.342
- 验证准确率：87.5%
- 测试准确率：86.8%

**与论文对比：**
- 论文报告：89.3%
- 差距：-2.5%

**分析：**
可能原因：
1. 数据预处理差异
2. 超参数未完全调优
3. 随机种子影响

**下一步：**
- [ ] 检查数据预处理流程
- [ ] 尝试学习率调优
- [ ] 多次运行取平均
```

## 超参数搜索空间

### 网格搜索示例

```yaml
hyperparameter_search:
  learning_rate:
    - 0.0001
    - 0.001
    - 0.01
  batch_size:
    - 16
    - 32
    - 64
  hidden_dim:
    - 256
    - 512
    - 1024
  dropout:
    - 0.1
    - 0.3
    - 0.5
```

### 贝叶斯优化配置

```python
from optuna import Trial

def suggest_hyperparams(trial: Trial):
    return {
        'lr': trial.suggest_float('lr', 1e-5, 1e-2, log=True),
        'batch_size': trial.suggest_categorical('batch_size', [16, 32, 64]),
        'hidden_dim': trial.suggest_int('hidden_dim', 128, 1024, step=128),
        'dropout': trial.suggest_float('dropout', 0.1, 0.5),
    }
```

## 统计显著性检验

```python
from scipy import stats

def t_test(results_a, results_b):
    """
    执行配对 t 检验。
    
    Args:
        results_a: 方法 A 的多次运行结果
        results_b: 方法 B 的多次运行结果
        
    Returns:
        t_statistic, p_value
    """
    t, p = stats.ttest_rel(results_a, results_b)
    return t, p

# 示例
ours = [89.1, 89.5, 88.9, 89.3, 89.0]
baseline = [87.2, 87.5, 87.0, 87.8, 87.3]
t, p = t_test(ours, baseline)
print(f"t={t:.3f}, p={p:.4f}")
# p < 0.05 表示差异显著
```

## 计算资源估算

### GPU 内存估算

```python
def estimate_gpu_memory(model, batch_size, input_shape):
    """
    估算 GPU 内存需求（近似）。
    
    Args:
        model: PyTorch 模型
        batch_size: 批次大小
        input_shape: 输入形状
        
    Returns:
        estimated_memory_mb: 估算内存 (MB)
    """
    # 模型参数
    param_memory = sum(p.numel() * p.element_size() for p in model.parameters())
    
    # 梯度
    grad_memory = param_memory
    
    # 激活（粗略估算）
    # 需要根据具体模型架构计算
    
    total = param_memory + grad_memory
    return total / (1024 * 1024)  # MB
```

### 训练时间估算

```
训练时间 ≈ (数据集大小 / 批次大小) × 每批次时间 × 训练轮数

示例：
- 数据集：50,000 样本
- 批次大小：32
- 每批次时间：0.1 秒
- 训练轮数：100

训练时间 ≈ (50000/32) × 0.1 × 100 ≈ 15,625 秒 ≈ 4.3 小时
```

## 实验检查清单

### 实验前

- [ ] 确认数据集已正确下载和预处理
- [ ] 确认环境配置与论文一致
- [ ] 确认随机种子已设置
- [ ] 确认基线方法可正常运行

### 实验中

- [ ] 记录所有超参数配置
- [ ] 保存训练日志和 checkpoints
- [ ] 监控训练曲线（损失、准确率）
- [ ] 记录异常情况和解决方案

### 实验后

- [ ] 整理实验结果表格
- [ ] 生成可视化图表
- [ ] 与论文结果对比分析
- [ ] 撰写实验报告

---

*参考：https://www.cs.cmu.edu/~aarti/Class/10701/experiment_design.pdf*


path: generate_report.py
content: #!/usr/bin/env python3
"""
研读报告生成脚本
根据论文元数据生成结构化研读报告
"""

import argparse
import json
from pathlib import Path
from datetime import datetime


def load_template(template_path: str) -> str:
    """加载报告模板"""
    with open(template_path, 'r', encoding='utf-8') as f:
        return f.read()


def generate_report(metadata: dict, template: str) -> str:
    """生成研读报告"""
    
    # 提取核心贡献（从摘要和引言推断）
    contributions = []
    abstract = metadata.get('abstract', '')
    if 'propose' in abstract.lower():
        contributions.append(abstract.split('propose')[1].split('.')[0].strip() + '.')
    if 'introduce' in abstract.lower():
        contributions.append(abstract.split('introduce')[1].split('.')[0].strip() + '.')
    if not contributions:
        contributions = ['待详细分析论文内容']
    
    # 复现可行性评估
    reproducibility = {
        'code_available': '待确认',
        'dataset_access': '待确认',
        'complexity': '中',
        'estimated_time': '1-2 周'
    }
    
    report = f"""# 论文研读报告

**生成时间：** {datetime.now().strftime('%Y-%m-%d %H:%M')}

## 基本信息

| 项目 | 内容 |
|------|------|
| 标题 | {metadata.get('title', 'N/A')} |
| 类型 | {metadata.get('paper_type', 'N/A')} |
| 关键词 | {', '.join(metadata.get('keywords', [])) or 'N/A'} |

## 摘要

{metadata.get('abstract', 'N/A')}

## 核心贡献

{''.join([f'{i+1}. {c}\\n' for i, c in enumerate(contributions)])}

## 方法论

### 问题定义
待详细分析...

### 核心思路
待详细分析...

### 关键公式
{chr(10).join([f"- 公式 ({f['number']}): {f['content']}" for f in metadata.get('key_formulas', [])]) or '待提取'}

## 实验配置

| 配置项 | 详情 |
|--------|------|
| 数据集 | 待确认 |
| 基线方法 | 待确认 |
| 评估指标 | 待确认 |
| 超参数 | 待确认 |

## 复现可行性评估

- **官方代码：** {reproducibility['code_available']}
- **数据集：** {reproducibility['dataset_access']}
- **计算需求：** GPU (建议 RTX 3090 或更高)
- **预计难度：** {reproducibility['complexity']}
- **预计时间：** {reproducibility['estimated_time']}

## 论文章节结构

{chr(10).join([f"- {s}" for s in metadata.get('sections', [])]) or '待提取'}

## 待澄清问题

1. 论文中是否有未明确说明的实现细节？
2. 是否有未公开的关键超参数？
3. 数据集预处理步骤是否完整描述？

## 下一步行动

- [ ] 查找官方代码仓库
- [ ] 确认可用的数据集来源
- [ ] 搭建基础实验环境
- [ ] 实现核心算法模块
- [ ] 复现关键实验结果

---
*本报告由 paper-research-assistant 自动生成*
"""
    return report


def main():
    parser = argparse.ArgumentParser(description='研读报告生成工具')
    parser.add_argument('--metadata', required=True, help='论文元数据 JSON 文件')
    parser.add_argument('--template', default='references/report_template.md', help='报告模板文件')
    parser.add_argument('--output', required=True, help='输出报告文件路径')
    
    args = parser.parse_args()
    
    # 加载元数据
    with open(args.metadata, 'r', encoding='utf-8') as f:
        metadata = json.load(f)
    
    # 加载模板（如果存在）
    template_path = Path(args.template)
    if template_path.exists():
        template = load_template(str(template_path))
    else:
        template = ""
    
    # 生成报告
    report = generate_report(metadata, template)
    
    # 输出
    output_path = Path(args.output)
    output_path.parent.mkdir(parents=True, exist_ok=True)
    
    with open(output_path, 'w', encoding='utf-8') as f:
        f.write(report)
    
    print(f"报告生成完成：{output_path}")


if __name__ == '__main__':
    main()


path: parse_paper.py
content: #!/usr/bin/env python3
"""
论文 PDF 解析脚本
提取论文元数据、摘要、核心章节内容
"""

import argparse
import json
import re
from pathlib import Path

try:
    import fitz  # PyMuPDF
except ImportError:
    print("请安装 PyMuPDF: pip install pymupdf")
    exit(1)


def extract_text_from_pdf(pdf_path: str) -> str:
    """从 PDF 提取全文文本"""
    doc = fitz.open(pdf_path)
    text = ""
    for page in doc:
        text += page.get_text()
    doc.close()
    return text


def extract_metadata(text: str) -> dict:
    """提取论文元数据"""
    lines = text.split('\n')
    metadata = {
        'title': '',
        'authors': [],
        'abstract': '',
        'keywords': [],
        'sections': []
    }
    
    # 提取标题（通常是第一行非空文本）
    for line in lines:
        line = line.strip()
        if line and len(line) > 10:
            metadata['title'] = line
            break
    
    # 提取摘要
    abstract_match = re.search(r'Abstract\s*\n(.*?)(?=\n\s*\n|\n\s*[A-Z]|\Z)', text, re.DOTALL | re.IGNORECASE)
    if abstract_match:
        metadata['abstract'] = abstract_match.group(1).strip()
    
    # 提取关键词
    keywords_match = re.search(r'(?:Keywords?|Index Terms)\s*[:\-]?\s*(.*?)(?=\n\s*\n|\n\s*[A-Z])', text, re.DOTALL | re.IGNORECASE)
    if keywords_match:
        keywords_str = keywords_match.group(1)
        metadata['keywords'] = [k.strip() for k in re.split(r'[;,]', keywords_str) if k.strip()]
    
    # 提取章节标题
    section_pattern = re.compile(r'^\d+\.\s+([A-Z][^\n]+)$', re.MULTILINE)
    metadata['sections'] = section_pattern.findall(text)
    
    return metadata


def identify_paper_type(metadata: dict) -> str:
    """识别论文类型"""
    title = metadata['title'].lower()
    abstract = metadata['abstract'].lower()
    
    if 'survey' in title or 'review' in title or '综述' in title:
        return 'survey'
    elif 'method' in title or 'approach' in title or 'framework' in title:
        return 'method'
    elif 'experiment' in abstract or 'empirical' in abstract:
        return 'experimental'
    else:
        return 'theoretical'


def extract_key_formulas(text: str) -> list:
    """提取关键公式（简单启发式）"""
    formulas = []
    formula_pattern = re.compile(r'\((\d+)\)\s*([^\n]{10,200})', re.MULTILINE)
    for match in formula_pattern.finditer(text):
        formulas.append({
            'number': match.group(1),
            'content': match.group(2).strip()[:100]
        })
    return formulas[:10]


def main():
    parser = argparse.ArgumentParser(description='论文 PDF 解析工具')
    parser.add_argument('--pdf', required=True, help='PDF 文件路径')
    parser.add_argument('--output', required=True, help='输出 JSON 文件路径')
    
    args = parser.parse_args()
    
    pdf_path = Path(args.pdf)
    if not pdf_path.exists():
        print(f"错误：文件不存在 {pdf_path}")
        return
    
    print(f"正在解析：{pdf_path}")
    full_text = extract_text_from_pdf(str(pdf_path))
    metadata = extract_metadata(full_text)
    metadata['paper_type'] = identify_paper_type(metadata)
    metadata['key_formulas'] = extract_key_formulas(full_text)
    metadata['full_text_preview'] = full_text[:5000]
    
    output_path = Path(args.output)
    output_path.parent.mkdir(parents=True, exist_ok=True)
    
    with open(output_path, 'w', encoding='utf-8') as f:
        json.dump(metadata, f, ensure_ascii=False, indent=2)
    
    print(f"解析完成：{output_path}")
    print(f"标题：{metadata['title']}")
    print(f"类型：{metadata['paper_type']}")


if __name__ == '__main__':
    main()


path: report_template.md
content: # 论文研读报告模板

**生成时间：** {{timestamp}}

---

## 基本信息

| 项目 | 内容 |
|------|------|
| 标题 | {{title}} |
| 作者 | {{authors}} |
| 机构 | {{institutions}} |
| 发表 Venue | {{venue}} |
| 发表日期 | {{date}} |
| arXiv/DOI | {{link}} |
| 论文类型 | {{type}} |

---

## 核心贡献

> 用 1-3 句话概括论文的核心创新点

1. **贡献 1：** ...
2. **贡献 2：** ...
3. **贡献 3：** ...

---

## 问题定义

**研究问题：** 论文试图解决什么问题？

**动机：** 为什么这个问题重要？现有方法的局限性是什么？

**形式化定义：** （如有）用数学语言描述问题

---

## 方法论

### 核心思路

> 用通俗语言解释方法的核心思想

### 技术细节

#### 整体架构

（模型架构图/算法流程图描述）

#### 关键组件

1. **组件 1：** ...
2. **组件 2：** ...

#### 关键公式

$$
\text{公式 1: } ...
$$

$$
\text{公式 2: } ...
$$

### 算法流程

```
Algorithm 1: 论文核心算法
Input: ...
Output: ...
1: ...
2: ...
```

---

## 实验配置

### 数据集

| 数据集 | 用途 | 规模 | 获取方式 |
|--------|------|------|----------|
| ... | ... | ... | ... |

### 基线方法

- Baseline 1: ...
- Baseline 2: ...

### 评估指标

- **主要指标：** ...
- **次要指标：** ...

### 实现细节

| 超参数 | 值 |
|--------|-----|
| 学习率 | ... |
| Batch Size | ... |
| Optimizer | ... |
| 训练轮数 | ... |

### 计算资源

- **GPU：** ...
- **训练时间：** ...

---

## 实验结果

### 主要结果

| 方法 | 指标 1 | 指标 2 | 指标 3 |
|------|--------|--------|--------|
| Baseline 1 | ... | ... | ... |
| Baseline 2 | ... | ... | ... |
| **Ours** | **...** | **...** | **...** |

### 消融实验

（关键组件的消融分析）

### 定性分析

（可视化结果、案例分析）

---

## 复现可行性评估

### 资源可用性

- [ ] **官方代码：** 有/无/部分公开
  - 链接：...
  - 许可证：...
  
- [ ] **数据集：** 公开/需申请/私有
  - 链接：...
  - 规模：...

### 复现难度

| 维度 | 评估 | 说明 |
|------|------|------|
| 方法复杂度 | ⭐⭐⭐☆☆ | ... |
| 实现难度 | ⭐⭐⭐☆☆ | ... |
| 数据获取 | ⭐⭐☆☆☆ | ... |
| 计算需求 | ⭐⭐⭐⭐☆ | ... |

**总体难度：** 中

**预计时间：** 1-2 周

### 关键风险点

1. **未明确细节：** 论文中是否有未说明的实现细节？
2. **数据预处理：** 是否有未公开的数据处理步骤？
3. **超参数敏感：** 方法是否对超参数高度敏感？

---

## 复现计划

### Phase 1: 环境搭建（1-2 天）

- [ ] 搭建基础实验环境
- [ ] 准备数据集
- [ ] 跑通基线方法

### Phase 2: 核心实现（3-5 天）

- [ ] 实现模型架构
- [ ] 实现训练流程
- [ ] 调试基础功能

### Phase 3: 实验验证（3-5 天）

- [ ] 复现主要实验结果
- [ ] 进行消融实验
- [ ] 对比基线方法

### Phase 4: 文档整理（1-2 天）

- [ ] 整理代码仓库
- [ ] 编写技术报告
- [ ] 记录复现心得

---

## 待澄清问题

1. ...
2. ...
3. ...

---

## 参考资料

- 论文链接：...
- 官方代码：...
- 相关论文：...
- 背景资料：...

---

*本报告由 paper-research-assistant 自动生成*


path: scaffold_code.py
content: #!/usr/bin/env python3
"""
复现代码骨架生成脚本
根据论文描述生成 PyTorch/TensorFlow 代码框架
"""

import argparse
import json
from pathlib import Path


def generate_pytorch_scaffold(metadata: dict) -> dict:
    """生成 PyTorch 代码骨架"""
    title = metadata.get('title', 'Model').replace(' ', '_').replace('-', '_')
    
    files = {
        f'{title}/README.md': f"""# {metadata.get('title', 'Paper Implementation')}

Unofficial PyTorch implementation based on the paper.

## Setup

```bash
pip install -r requirements.txt
```

## Usage

```bash
python train.py --config configs/default.yaml
```

## Structure

- `model.py` - Core model architecture
- `train.py` - Training loop
- `evaluate.py` - Evaluation script
- `datasets/` - Dataset loaders
- `configs/` - Configuration files
""",
        
        f'{title}/requirements.txt': """torch>=2.0.0
torchvision>=0.15.0
numpy>=1.24.0
pandas>=2.0.0
tqdm>=4.65.0
yaml>=6.0
""",
        
        f'{title}/model.py': f'''"""
Core model architecture for {metadata.get("title", "Paper")}
"""

import torch
import torch.nn as nn


class {title.replace("_", "")}(nn.Module):
    """
    Main model class implementing the paper method.
    
    TODO: Fill in the architecture based on paper details
    """
    
    def __init__(self, config):
        super().__init__()
        self.config = config
        
        # TODO: Define model layers based on paper
        # Example:
        # self.encoder = nn.Linear(config.input_dim, config.hidden_dim)
        # self.decoder = nn.Linear(config.hidden_dim, config.output_dim)
        
    def forward(self, x):
        """
        Forward pass.
        
        Args:
            x: Input tensor
            
        Returns:
            Output tensor
        """
        # TODO: Implement forward pass based on paper method
        # x = self.encoder(x)
        # x = self.decoder(x)
        return x


def build_model(config):
    """
    Build model from config.
    
    Args:
        config: Configuration dict
        
    Returns:
        Model instance
    """
    return {title.replace("_", "")}(config)
''',
        
        f'{title}/train.py': '''"""
Training loop for paper reproduction.
"""

import argparse
import torch
from torch.utils.data import DataLoader
from tqdm import tqdm
import yaml

from model import build_model
from datasets import get_dataset


def train_epoch(model, dataloader, optimizer, criterion, device):
    """Single training epoch."""
    model.train()
    total_loss = 0
    
    for batch in tqdm(dataloader, desc="Training"):
        x, y = batch
        x, y = x.to(device), y.to(device)
        
        optimizer.zero_grad()
        output = model(x)
        loss = criterion(output, y)
        loss.backward()
        optimizer.step()
        
        total_loss += loss.item()
    
    return total_loss / len(dataloader)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--config', type=str, default='configs/default.yaml')
    parser.add_argument('--epochs', type=int, default=100)
    parser.add_argument('--batch-size', type=int, default=32)
    parser.add_argument('--lr', type=float, default=1e-3)
    args = parser.parse_args()
    
    # Load config
    with open(args.config, 'r') as f:
        config = yaml.safe_load(f)
    
    # Setup device
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    
    # Build model
    model = build_model(config).to(device)
    
    # Setup data
    train_dataset = get_dataset(config, split='train')
    train_loader = DataLoader(train_dataset, batch_size=args.batch_size, shuffle=True)
    
    # Setup optimizer
    optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)
    criterion = torch.nn.CrossEntropyLoss()
    
    # Training loop
    for epoch in range(args.epochs):
        loss = train_epoch(model, train_loader, optimizer, criterion, device)
        print(f"Epoch {epoch+1}/{args.epochs}, Loss: {loss:.4f}")
    
    # Save model
    torch.save(model.state_dict(), 'checkpoints/final.pth')
    print("Training completed!")


if __name__ == '__main__':
    main()
''',
        
        f'{title}/configs/default.yaml': f"""# Default configuration for {metadata.get('title', 'Model')}

model:
  input_dim: 784
  hidden_dim: 512
  output_dim: 10

training:
  epochs: 100
  batch_size: 32
  learning_rate: 0.001

data:
  dataset: 'mnist'
  data_dir: './data'
""",
        
        f'{title}/datasets/__init__.py': '''"""
Dataset loaders.
"""

from torch.utils.data import Dataset


def get_dataset(config, split='train'):
    """
    Get dataset based on config.
    
    TODO: Implement dataset loading based on paper requirements
    """
    # Example:
    # if config['data']['dataset'] == 'mnist':
    #     return MNISTDataset(config, split)
    return PlaceholderDataset(config, split)


class PlaceholderDataset(Dataset):
    """Placeholder dataset - replace with actual implementation."""
    
    def __init__(self, config, split):
        self.config = config
        self.split = split
        
    def __len__(self):
        return 1000
    
    def __getitem__(self, idx):
        # TODO: Replace with actual data loading
        return torch.zeros(10), torch.tensor(0)
'''
    }
    
    return files


def main():
    parser = argparse.ArgumentParser(description='代码骨架生成工具')
    parser.add_argument('--paper-json', required=True, help='论文元数据 JSON 文件')
    parser.add_argument('--framework', choices=['pytorch', 'tensorflow'], default='pytorch')
    parser.add_argument('--output-dir', required=True, help='输出目录')
    
    args = parser.parse_args()
    
    # 加载元数据
    with open(args.paper_json, 'r', encoding='utf-8') as f:
        metadata = json.load(f)
    
    # 生成代码
    if args.framework == 'pytorch':
        files = generate_pytorch_scaffold(metadata)
    else:
        # TODO: Add TensorFlow scaffold
        print("TensorFlow scaffold not yet implemented")
        return
    
    # 写入文件
    output_dir = Path(args.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)
    
    for filepath, content in files.items():
        full_path = output_dir / filepath
        full_path.parent.mkdir(parents=True, exist_ok=True)
        with open(full_path, 'w', encoding='utf-8') as f:
            f.write(content)
        print(f"Created: {full_path}")
    
    print(f"\n代码骨架生成完成：{output_dir}")


if __name__ == '__main__':
    main()


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)