DANN 无监督域适应教程:从零跑通 PyTorch 域对抗训练
2026/8/21 22:46:24 网站建设 项目流程

DANN 无监督域适应教程:从零跑通 PyTorch 域对抗训练

【免费下载链接】DANNpytorch implementation of Domain-Adversarial Training of Neural Networks项目地址: https://gitcode.com/gh_mirrors/da/DANN

DANN 是一个基于 PyTorch 1.0 实现的无监督领域自适应(domain adaptation)训练框架:它不需要目标域的任何标签,就能把源域上学到的分类能力迁移到新分布的数据上。本教程以官方的 MNIST 到 mnist_m 迁移示例为线索,带你先看懂原理,再完成环境配置、数据集准备和首次训练。跑通全流程只需要三条命令:克隆、解压、运行。

🔍 DANN 原理 3 分钟看懂:梯度反转层如何实现无监督域适应

先看问题:你有一个带标签的源域(MNIST 线条手写数字),还有一个目标域(mnist_m,彩色手写数字照片),两者分布不一致,而目标域没有标签,没法用常规监督方式直接训练。

DANN 的解法是域对抗训练:在网络里加一个域分类器,让它猜测特征来自源域还是目标域;同时用梯度反转层让特征提取器"欺骗"这个分类器——分类器越分不出来源,特征就越接近与域无关。

梯度反转层实现在 models/functions.py:正向传播时特征原样通过、数据不被改动,反向传播时取负梯度再乘以强度 α。这就像记账:付款时金额照实记一笔(正向不变),月底对账时却把这笔从"收入"改记到"支出"(反向翻号),数字没变,影响方向反了。α 不是常数,它随训练进度 p 按 S 曲线从接近 0 逐渐升到 2,即域适应压力前期轻、后期强。

结构上整体是双分支:特征提取器(两层卷积加批归一化与池化)的输出,一路送进类别分类器(10 个数字类别),另一路经梯度反转层送进域分类器(源/目标 2 类),三路损失相加后一起反向传播。

🚀 从零跑通 DANN:环境准备与 mnist_m 数据集配置

  1. 准备环境:Python 2.7 加 PyTorch 1.0,可选 CUDA 加速。代码使用了 xrange、print 语句等 Python 2 语法,Python 3 无法运行。
  2. 克隆仓库,然后进入 DANN 目录:
git clone https://gitcode.com/gh_mirrors/da/DANN
  1. 配置数据集:源域 MNIST 会被代码自动下载,无需操作;目标域 mnist_m 需按 README 中的地址手动下载,放入 dataset 目录后在 mnist_m 子目录中解压:
cd dataset mkdir mnist_m cd mnist_m tar -zxvf mnist_m.tar.gz

解压后该目录内应包含 mnist_m_train、mnist_m_test 两个子目录和 mnist_m_train_labels.txt、mnist_m_test_labels.txt 两个标签文件。 4. 运行训练:

cd train && python main.py

控制台每个 batch 会打印 err_s_label(源域分类损失)与 err_s_domain、err_t_domain(两项域分类损失);每轮结束模型保存为 models 下的 mnist_mnistm_model_epoch_N.pth,并评估两个数据集的准确率,随时可检查进度或从存档断点续训。

🎚️ 关键参数怎么调:学习率、批次与训练轮数调参建议

可调项集中在 train/main.py 顶部:

参数默认值调整建议
学习率(Adam 优化器)1e-3损失震荡时降到 5e-4;收敛过慢可试 2e-3
批次大小 batch size128显存紧张时降到 64;显存充裕可升到 256 提速
训练轮数 n_epoch100目标域准确率仍在上升则延长到 150~200;提前平台期可减到 50
α 域适应强度0→2 随进度调度由 S 曲线公式自动计算,一般无需改;想加压或减压可调公式中的指数系数 -10

🧰 出错时先查这里:Python 版本与数据集配置

现象可能原因解决办法
启动即报 SyntaxError,指向 xrange 或 print用了 Python 3 运行,项目仅支持 2.7换 Python 2.7 加 PyTorch 1.0 环境重跑
抛出 FileNotFoundError / IOErrormnist_m 未放在 dataset/mnist_m,或标签文件缺失检查两个数据集子目录与两份 labels txt 是否齐全
训练明显偏慢未使用 CUDA,或数据读取线程不足用 GPU 环境训练;适当调整 DataLoader 的 num_workers

🧩 改造成你的场景:数据、结构与多领域

自定义数据集:改动 dataset/data_loader.py 中目标域的读取逻辑。GetLoader 从文本列表里读取每张图片的相对路径与标签,你只需按同样格式准备图片与列表文件;源域也可以在 main.py 中换成任意带标签数据集。

调整网络层:特征提取器与两个分类器都定义在 models/model.py,可增删卷积层与全连接层。注意类别分类器输入是 50×4×4,若改动特征层输出尺寸,需同步修改全连接层的输入维度。

扩展到多领域:当前域分类器输出 2 类,只区分源与目标。要支持 K 个领域,把它的最后一层改为 K 类,为每个领域分配独立标签,并在同一训练循环中并入各领域数据即可。

最快的上手路径是先跑通这个 MNIST 到 mnist_m 的示例:看 train/main.py 确认超参设置,读 models/functions.py 弄清梯度反转层的工作原理,之后换成自己的数据时从数据加载部分入手修改即可。

【免费下载链接】DANNpytorch implementation of Domain-Adversarial Training of Neural Networks项目地址: https://gitcode.com/gh_mirrors/da/DANN

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询