ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ViT图像去雾实践:原理、PyTorch实现与训练优化指南

ViT图像去雾实践:原理、PyTorch实现与训练优化指南 简介一套基于视觉Transformer的图像去雾算法研究与实现源码及文档说明面向图像去雾与低层视觉方向的学生和开发者提供从数据预处理、模型训练到结果评估的完整可运行项目涵盖数据切分、模型搭建、训练调用等环节。资源共338个文件包含204个Python源码、yaml配置文件、csv数据记录、ipynb探索笔记、md与txt说明文档等压缩包整体约156.36MB目录按预处理、训练、测试等模块划分便于快速定位代码与实验记录。目前已吸引291人学习下载适合作为Transformer架构在图像去雾任务中的落地参考。内容提供NH-HAZE训练图像切分为256×256小图的预处理脚本以及基于Uformer的My_train.py训练代码支持配置训练轮数如270轮、批大小32、输入块尺寸128等超参数并可通过指定GPU执行训练配套文档对数据集存放路径、依赖环境与训练流程做了说明可帮助快速搭建实验环境、复现基础去雾效果。1. 图像去雾这几年绕不开 Vision Transformer 这张牌雾天拍出来的监控画面、行车记录仪、无人机巡检图灰蒙蒙一片对比度低到没法看。传统暗通道先验DCP那种规则式方法在均匀雾霾下好用一旦遇到逆光、夜间、浓雾透射率估计就失准出来的图要么偏色、要么有 halo 伪影。后来 CNN 去雾模型DehazeNet、AOD-Net、FFA-Net把端到端映射这条路走通了但卷积的感受野始终是局部窗口对雾这种低频全局分布信息传递效率不高。Vision TransformerViT把图像切成 patch 做全局自注意力天然擅长建模长距离依赖把 VIT 结构搬到去雾任务上成了这几年算法研究和个人毕设、课程设计里最热门的方向之一。这个标题对应的项目就是一套典型的「ViT 图像去雾研究与实现」有完整 python 源码、有文档说明能训练、能评估、能出对比图适合想做深度学习算法入门、或者要交图像处理方向项目的人直接拿来复现和改造。2. 去雾任务先立住模型到底在学什么ViT 相比 CNN 强在哪2.1 大气散射模型与透射率估计先看懂物理先验图像去雾经典建模是大气散射模型Atmospheric Scattering Model一图胜千言这里用公式表达I(x) J(x) * t(x) A * (1 - t(x))I(x) 是观测到的有雾图像J(x) 是我们要恢复的无雾清晰图A 是全局大气光t(x) 是透射率表示场景辐射经过雾衰减后到达相机的比例。去雾的本质就是反解这个方程估计出 A 和 t(x)就能反推 J(x)。早期方法用暗通道先验直接算 t(x)算完再抠图guided filter细化工程上能跑但太依赖统计先验的成立条件。深度学习方法不显式建模 A 和 t而是让网络学一个 J F(I) 的端到端映射把透射率、大气光和噪声一起隐式打包在特征里。这样做的优点是鲁棒性和泛化能力远好于传统方法缺点是模型成了一个黑匣子解释性差。我自己的经验是不管用什么结构先跑通 DCP 作为 baseline 是值得的它给你一个「可接受的低标」后续 ViT 模型涨了多少个 dB 的 PSNR用 DCP 一比就清楚了。2.2 Vision Transformer 的核心机制patch embedding、多头自注意力与位置编码ViT 的起点是把图像拆成语义块。一张 256x256 的图像patch_size16会切成 (256/16)^2256 个 patch每个 patch 展平成 16x16x3768 维序列。然后过一个线性投影层变成隐层维度 d再加上位置编码learnable positional embedding一起送入 Transformer Encoder。Encoder 里最核心的就是多头自注意力Multi-Head Self-Attention每个 patch 都能跟全图其他 patch 计算相关度这正是雾这种全局退化因素需要的感受野。去雾任务上我用 ViT 而不是纯 CNN 的关键理由有两条。第一雾在大气中分布是平滑且全局的远处区域对近处像素的透射率估计有影响CNN 得堆十几层卷积才能把感受野推到全图ViT 第一层就能做全局交互。第二自注意力里的 attention map 可以拿来做可视化直接看到模型在哪些区域「集中注意力去雾」这个对写文档说明、做论文级图表都是加分项。代价是计算量和显存比 CNN 大ViT 的假设是数据量足够但在去雾这种需要在域内微调的课题上数据量不大时容易过拟合后面会谈到对应的 trick。2.3 与 AOD-Net、FFA-Net 等 CNN 去雾模型的对比与选型CNN 系去雾模型里AOD-Net 把大气散射模型折叠进网络直接回归清晰图参数少、速度快适合视频实时去雾FFA-Net 用了 feature attention 多个 attention module 混合在 RESIDE 榜单上 PSNR 领先了一段时间。FFA-Net 胜在特征层面的注意力但 attention 是通道和像素级别的和 ViT 的全局空间自注意力不同。ViT 去雾模型目前主流做法是让 Transformer 作为骨干网络配合 CNN 的归纳偏置做解码器比如在 encoder 阶段用 Swin-Transformer block 提取多尺度特征。这样全局关系和局部纹理两不误。选型建议如果你的部署环境是边缘设备算力受限优先考虑轻量 CNN 或 CNNTransformer 混合结构如果目标是刷指标、出高质量论文效果图、或者课程设计要展现研究和对比深度那直接用纯 ViT 做 backbone 是稳妥选择。源码工程里一般会把几种结构做成可配置的模型入口用参数切换 backbone跑实验时方便做消融。3. 用 PyTorch 搭一套 ViT 图像去雾最小工程数据管线与模型骨架3.1 项目目录怎么组织一个能跑通训练的最小文件结构拿到这类源码包第一件事不是看模型定义而是把文件结构过一遍。一个规范的 ViT 去雾项目目录应该是这样的dehaze_vit/ ├── dataset/ │ ├── hazy/ # 有雾图像 │ └── clear/ # 对应无雾 GT ├── configs/ │ └── train.yaml # 训练超参 ├── models/ │ ├── vit_backbone.py │ └── dehaze_model.py ├── losses/ │ ├── l1_loss.py │ └── ssim_loss.py ├── utils/ │ ├── metrics.py # PSNR / SSIM │ └── visualization.py ├── train.py ├── test.py └── README.md这个结构的好处是数据集、配置、模型、损失、评估各司其职。我给接手项目的学生一个习惯先打开 configs/train.yaml 看默认参数再打开 README 看作者训练环境。如果 README 没写环境版本就先用pip install torch torchvision opencv-python scikit-image tensorboard把这套最常用的环境装上python 版本建议 3.8 及以上torch 1.8 基本就能兼容绝大多数写法。3.2 Dataset 类写法有雾/无雾图像对怎么配对训练时才不会翻车图像去雾是监督学习任务训练数据是成对的同一场景一张有雾一张干净。公开数据集最常用的是 RESIDE 系列特别是 RESIDE-Standard 里的 ITSIndoor Training Set子集。自己造数据时常见做法是用大气散射模型合成有雾图像把无雾图当 GT。下面这段是我常用的 Dataset 代码关键写在注释里import os import cv2 import torch from torch.utils.data import Dataset import numpy as np class DehazeDataset(Dataset): def __init__(self, hazy_dir, clear_dir, patch_size128, trainTrue): self.hazy_dir hazy_dir self.clear_dir clear_dir # 按文件名配对要求 hazy 和 clear 文件同名只有在文件名一致时才配对 self.hazy_names sorted(os.listdir(hazy_dir)) self.clear_names sorted(os.listdir(clear_dir)) self.patch_size patch_size self.train train def __len__(self): return len(self.hazy_names) def __getitem__(self, idx): hazy_path os.path.join(self.hazy_dir, self.hazy_names[idx]) clear_path os.path.join(self.clear_dir, self.clear_names[idx]) hazy cv2.imread(hazy_path) # BGR clear cv2.imread(clear_path) # BGR hazy cv2.cvtColor(hazy, cv2.COLOR_BGR2RGB) clear cv2.cvtColor(clear, cv2.COLOR_BGR2RGB) if self.train: # 随机裁剪到 patch_size保持 hazy 和 clear 的裁剪位置一致 h, w, _ hazy.shape top np.random.randint(0, h - self.patch_size 1) left np.random.randint(0, w - self.patch_size 1) hazy hazy[top:top self.patch_size, left:left self.patch_size] clear clear[top:top self.patch_size, left:left self.patch_size] # 归一化到 [0,1]注意这里先除以 255后续网络层不需要额外规范化 hazy hazy.astype(np.float32) / 255.0 clear clear.astype(np.float32) / 255.0 # (H,W,C) - (C,H,W)并转 torch.Tensor hazy torch.from_numpy(hazy).permute(2, 0, 1) clear torch.from_numpy(clear).permute(2, 0, 1) return hazy, clear逻辑说明随机裁剪时两张图必须用同一个 top 和 left这是配对数据训练的基本前提很多人数据处理在这一步各裁各的训练出来的模型输出位置对不上网络学不出东西。归一化放在这里而不是用 torchvision.transforms.Normalize是因为去雾输出范围天然是 [0,1]如果套用 ImageNet 的 mean/std 归一化网络输出要再反归一化回 [0,1] 才能算 PSNR多一道转换就多一个出错点。参数说明里最值得调的就是 patch_size显存受限于 8G 时用 1282080Ti 或以上可以用 160 或 192patch 越大训练越稳但同一张图能裁的 patch 数变少相当于数据集变小。3.3 ViT 骨干模型用最小代码搭一个可训练的 encoder-decoder纯 ViT 输出序列特征但去雾要求输出逐像素图像所以常规做法是 U 型结构ViT encoder 提取特征 CNN decoder 还原空间分辨率。这里给一个简化但完整的模型定义适合先跑通再升级import torch import torch.nn as nn from einops import rearrange class PatchEmbed(nn.Module): def __init__(self, in_ch3, patch_size16, embed_dim256): super().__init__() self.patch_size patch_size # 一个卷积就能完成 patch 切块 线性投影 self.proj nn.Conv2d(in_ch, embed_dim, kernel_sizepatch_size, stridepatch_size) def forward(self, x): x self.proj(x) # (B, embed_dim, H/P, W/P) x rearrange(x, b c h w - b (h w) c) return x class TransformerBlock(nn.Module): def __init__(self, dim, num_heads4, mlp_ratio4.0, dropout0.1): super().__init__() self.norm1 nn.LayerNorm(dim) self.attn nn.MultiheadAttention(dim, num_heads, dropoutdropout, batch_firstTrue) self.norm2 nn.LayerNorm(dim) self.mlp nn.Sequential( nn.Linear(dim, int(dim * mlp_ratio)), nn.GELU(), nn.Linear(int(dim * mlp_ratio), dim), nn.Dropout(dropout) ) def forward(self, x): x x self.attn(self.norm1(x), self.norm1(x), self.norm1(x))[0] x x self.mlp(self.norm2(x)) return x class ViTDehaze(nn.Module): def __init__(self, patch_size8, embed_dim256, depth4, num_heads4): super().__init__() self.patch_embed PatchEmbed(in_ch3, patch_sizepatch_size, embed_dimembed_dim) # 简化版位置编码直接用可学习的参数 self.pos_embed nn.Parameter(torch.zeros(1, (256 // patch_size) ** 2, embed_dim)) self.blocks nn.Sequential(*[ TransformerBlock(dimembed_dim, num_headsnum_heads) for _ in range(depth) ]) self.norm nn.LayerNorm(embed_dim) # 解码器转置卷积逐级放大 卷积修正 self.decoder nn.Sequential( nn.ConvTranspose2d(embed_dim, 128, kernel_size2, stride2), nn.ReLU(), nn.ConvTranspose2d(128, 64, kernel_size2, stride2), nn.ReLU(), nn.ConvTranspose2d(64, 3, kernel_size2, stride2), nn.Sigmoid() # 输出限定在 [0,1] ) def forward(self, x): B, C, H, W x.shape x self.patch_embed(x) # (B, N, C) x x self.pos_embed x self.blocks(x) x self.norm(x) # 还原成图像形状进解码器 p int((H * W / x.shape[1]) ** 0.5) x rearrange(x, b (h w) c - b c h w, hH // p, wW // p) x self.decoder(x) return x参数说明patch_size 在去雾任务里不建议用 ViT 原论文的 16 或 32雾的分布虽然全局但细节纹理恢复需要相对密集的 patch 划分patch_size8 在 256x256 输入下会产生 1024 个 patch计算量适中效果明显好于 16。depth 代表 Transformer block 数量这个简化版用了 depth4数据集不大时 4 层足够加深到 8~12 层要看数据量和显存。num_heads 用 4 或 8 都行embed_dim 用 256 在这个规模下是性价比较高的选择。4. 训练闭环损失函数组合、超参配置与 PSNR/SSIM 评估4.1 损失函数不要只用 L1SSIM 损失和感知损失的取舍去雾任务最直接的损失是 L1 和 L2L2MSE容易让输出变模糊因为它在惩罚大误差时把边缘也抹平了。L1 比 L2 锐利但在平坦区域依然缺乏结构约束。行业内训练去雾模型最常见的组合是 L1 SSIM 损失SSIM 损失定义为 1 - SSIM(output, target)它能强制输出在局部结构上与 GT 保持一致抑制色彩偏移。下面是我使用多次的复合损失实现import torch import torch.nn.functional as F from pytorch_msssim import ssim # pip install pytorch-msssim class DehazeLoss(nn.Module): def __init__(self, alpha0.6): super().__init__() self.alpha alpha # L1 权重 def forward(self, output, target): l1 F.l1_loss(output, target) ssim_loss 1.0 - ssim(output, target, data_range1.0, size_averageTrue) return self.alpha * l1 (1 - self.alpha) * ssim_loss逻辑说明alpha 控制 L1 和 SSIM 的权重比例。alpha 越大输出越接近逐像素拟合细节更硬但可能出现局部不均匀alpha 越小结构保持更好但收敛变慢。实际调参我一般从 alpha0.6 起步最常用的区间是 0.5~0.8。pytorch_msssim 库的 ssim 函数需要 data_range1.0 匹配归一化范围这是最容易出错的地方。感知损失Perceptual Loss在去雾里可以加用 VGG16 的 relu1_2 和 relu2_2 特征做 L1 约束能提升视觉自然度但 PSNR 不一定会涨而且在显存有限时训练速度变慢我一般先不加。4.2 训练脚本关键配置优化器、学习率、warmup 和梯度裁剪ViT 和 CNN 的训练习惯有一个显著区别ViT 对学习率更敏感初始学习率过大直接 loss 震荡。常规做法如下optimizer torch.optim.AdamW(model.parameters(), lr0.0002, weight_decay0.01) scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max50, eta_min1e-6) # warmup: 前 5 个 epoch 线性升学习率避免 ViT 早期训练不稳定 for epoch in range(warmup_epochs): lr base_lr * (epoch 1) / warmup_epochs for param_group in optimizer.param_groups: param_group[lr] lr # --- 正常训练循环 --- # 梯度裁剪防止透射率估计极端值导致的梯度爆炸 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm1.0)参数说明AdamW 比 Adam 多一个解耦的 weight decay在 ViT 上收敛更稳weight_decay0.01 是一个安全的默认值。lr 从 2e-4 起步基本不会翻车如果 loss 前期不降可以调到 5e-4 试一次但不要一上来就用 1e-3。warmup 对 ViT 几乎是必选项因为 patch embedding 和位置编码刚开始都是随机初始化梯度信号弱且不稳定前几个 epoch 用线性升温让位置编码预热到合理范围。梯度裁剪 max_norm1.0 是我在去雾这个任务上的血泪经验透射率接近 0 的暗区会产生极大梯度不裁剪会看到 loss 突然跳到无穷大。训练参数建议表参数推荐值备注optimizerAdamWpytorch 1.8 内置base_lr2e-4不收敛时可试 5e-4weight_decay0.01解耦权重衰减warmup_epochs5线性升到 base_lrbatch_size8~16由显存决定patch_size128~192输入裁剪尺寸总 epoch50~100早停监控 PSNR4.3 评估脚本PSNR 和 SSIM 计算外加去雾前后对比图评估脚本要分开写不能在训练循环里随缘算。推理时把网络切到 eval 模式关掉 dropout 和 layer_norm 的 batch 统计。去雾任务上这两个指标是硬通货PSNR 反映像素还原精度SSIM 反映结构相似度学术报告里两个必须同时给。import cv2 import numpy as np import torch from skimage.metrics import peak_signal_noise_ratio as psnr_fn from skimage.metrics import structural_similarity as ssim_fn model.eval() with torch.no_grad(): hazy, clear next(iter(test_loader)) output model(hazy.cuda()).cpu() psnr_list [] ssim_list [] for i in range(output.shape[0]): out_img output[i].permute(1, 2, 0).numpy() gt_img clear[i].permute(1, 2, 0).numpy() # 注意PSNR 计算前必须 clip 到 [0,1]否则数值会偏低 out_img np.clip(out_img, 0.0, 1.0) psnr_list.append(psnr_fn(gt_img, out_img, data_range1.0)) ssim_list.append(ssim_fn(gt_img, out_img, data_range1.0, channel_axis-1)) print(fPSNR: {np.mean(psnr_list):.2f} dB, SSIM: {np.mean(ssim_list):.4f})逻辑说明输出层用了 Sigmoid理论上输出已经在 [0,1] 内但浮点误差会产生 0.999999 和 0.000001 这类值skimage 计算 PSNR 时如果 data_range1.0 且图像超出这个范围结果会异常偏大或计算出 nan所以 clip 是防御性操作。SSIM 的 channel_axis-1 表示输入是 (H,W,C) 格式很多人在这一步忘了通道轴设置导致计算出来的 SSIM 远低于真实值。test_loader 的 batch 建议设 1 或 2因为推理时不需要反传大 batch 会造成不必要的显存占用。5. 图像去雾训练五大翻车现场现象、原因与排查方法5.1 输出黑图或灰图去雾结果像是盖了一层毛玻璃现象训练到中途验证集输出的图像整体偏亮或偏暗严重的直接输出全黑或全灰PSNR 掉到 10 dB 以下。原因排查顺序第一看归一化最常见的是数据加载时用了 ImageNet 的均值方差做 Normalize但网络输出层接 Sigmoid 输出 [0,1]两者范围不匹配反归一化做错位置就会全屏灰第二看最后一层激活函数如果输出层没接 Sigmoid网络输出可能是任意值即便输入归一化正确输出的像素分布也在 [-2, 2] 之间乱跑第三看透射率预测分支是否单独存在有些模型结构是显式预测 t(x) 和 A再用公式前向计算去雾图此时如果 t(x) 的激活函数用的不是 Sigmoid值域可能超出 [0,1]导致反推出负值。解决统一方案是数据侧只做 [0,1] 缩放模型输出层固定接 Sigmoid评估和可视化前 clip 一次。如果是显式预测透射率的模型t(x) 分支单独接 SigmoidA 分支接 Sigmoid 乘常数也可以。我自己的习惯是直接让模型回归清晰图不显式拆解透射率少一个环节就少一个坑。5.2 PSNR 涨了 SSIM 不掉但人眼看着不行色彩整体发灰现象训练 loss 一直在降PSNR 从 20 dB 涨到 28 dB但输出的图肉眼看起来雾没去掉多少只是颜色变淡了像被漂过一遍。原因这是 L1/L2 损失的典型通病。像素级损失鼓励模型输出和目标逐像素接近统计上平均值接近最优时模型会趋向于保守预测——也就是每个像素取一个中间值边缘不锐利、纹理被抹平。雾的图像分布本身低频占主导模型学到的最优策略可能是降低对比度而不是恢复细节。解决引入结构类损失把 SSIM loss 权重拉高alpha 从 0.6 调到 0.4再加一个高频增强分支比如在 loss 里加上拉普拉斯算子的 L1 误差或者在网络解码器用子像素卷积替代普通转置卷积让细节恢复能力更强。我实测把 SSIM 损失权重从 0.4 提到 0.6视觉上逼真度提升明显PSNR 可能掉 0.2 dB 左右但人眼观感好很多。5.3 小数据集上 ViT 训不上去val PSNR 平台期来得特别早现象只有几百对训练图像ViT 在 10 个 epoch 内就过拟合train PSNR 逼近 40 dBval PSNR 停在 20 dB 附近不动。原因ViT 全局注意力参数多适合大数据。去雾公开数据集 ITS 有上万个样本但自己做课程设计经常只有几百张。数据量不够时位置编码和注意力矩阵会记住训练集的 patch 分布模式而非学习真实的去雾映射。解决一是数据增强加满随机旋转、水平翻转、色彩抖动hue/saturation 微调对去雾有帮助因为雾对不同光照条件应该有不变性二是降低模型容量depth 从 8 降到 4embed_dim 从 512 降到 256模型会更快收敛且不容易过拟合三是加 dropout 和 weight decayTransformerBlock 里的 dropout 从 0.1 提到 0.2训练时间长一点但泛化更好。这里要注意不要一上来就用 ImageNet 预训练权重如果预训练权重是在清晰自然图像上训的直接迁移到雾图域会带着源域 bias先让模型在去雾数据上从零训一个小规模版本再看是否值得加预训练。5.4 去雾结果出现紫色/绿色彩色伪影尤其是天空区域现象天空、白色墙壁等平坦区域输出出现一块块不自然的颜色斑块PSNR 不高SSIM 表现也差。原因这是注意力机制的边界产物。ViT 把图像分 patch 计算注意力平坦区域的 patch 之间相似度极高注意力矩阵接近均匀分布但 patch 边缘的不连续会导致解码器在恢复逐像素输出时产生振铃效应另一种情况是训练数据里天空区域较少模型对高频平滑区域的先验不足输出偏绿偏紫是网络在没有约束时选择了错误的色彩组合。解决在 loss 里加一个颜色一致性惩罚项计算输出和 GT 在饱和度HSV 空间的 S 通道上的 L1 损失能有效抑制伪影另外在训练数据增强里对天空占比大的样本做局部 Gamma 校正提高模型对亮区平坦纹理的鲁棒性。如果伪影只在个别测试图上出现可以考虑推理时做 Test-Time Augmentation对图像做水平翻转各跑一次再平均伪影通常能被抹掉。5.5 显存 OOMbatch_size 降到 4 还是炸现象ViT 模型在 11G 的 2080Ti 上训练batch_size4 patch_size128 就显存不足报 CUDA out of memory。原因ViT 的自注意力复杂度随 patch 数平方增长patch_size 越小 token 数越多显存消耗越大256x256 输入且 patch_size8 时 token 数是 1024自注意力的 attention map 是 1024x1024batch_size4 时这部分的显存占用就非常大。解决第一优先梯度累积batch_size2 累积 4 步等效 batch_size8代码改动极小显存压力直接减半第二检查是否有中间变量没 detach比如 loss 里用了 VGG 感知损失又没关梯度也会扩大显存占用第三考虑混合精度训练torch.cuda.amp在 2080Ti 上能省 30%~40% 显存而且去雾这类任务对精度损失不敏感。如果还不行就把 patch_size 从 8 改成 16token 数降为 256显存压力指数下降PSNR 损失 1~2 dB但至少能训起来。6. 最后再往前一步消融实验与自注意力可视化验证项目能跑通只是及格线要让这个方向真正站得住还得把「为什么有效」讲清楚。消融实验是让评审老师和面试官信服的核心手段。以这个 ViT 去雾项目为例三组必做的消融是去掉 SSIM 损失、把 ViT 换成同参数量 ResNet、把 patch_size 从 8 改成 16。每组跑同样的 epoch 数记录 PSNR/SSIM列成一张三行对比表。你会发现去掉 SSIM 损失后PSNR 可能不降或微降但 SSIM 明显掉换成 ResNet 后两个指标都掉这就证明了 ViT 的结构不是花架子。可视化验证方面用自注意力图最直观。取出最后一个 Transformer block 的 attention map对每个 head 取均值叠加到原图上能看到模型在雾气浓的区域分配更多注意力权重。把这个图写到论文或项目文档的「注意力可视化分析」小节里分量比十段文字都大。做法也很简单forward 的时候把 attention 层的输出保存下来不需要改模型结构。我自己做这类项目最大的教训是前期太迷信模型结构总在改注意力模块结果后来发现数据配对质量才是上限。项目里如果有合成有雾图像的数据生成脚本严格检查透射率 t 和大气光 A 的取值范围t 小于 0.2 的像素太多会导致训练样本里噪声占主导模型学出来透射率过暗看起来像蒙了一层烟。还有训练中断后想恢复最好把 optimizer、scheduler、epoch 一起存成一个 checkpoint而不是只存 model_dict否则恢复训练的学习率状态全乱了这也是很多人「续训反而变差」的原因。这个方向我建议你按「先跑通最小模型、再补消融、最后做可视化」的顺序推进每一步都留好实验结果和中间输出图文档说明的价值就在这些过程记录里。希望帮到你。本文还有配套的精品资源点击获取
返回列表