061、自定义数据集训练:如何将自己的图像和视频数据用于超分模型 📅 2026/7/6 5:41:06 061、自定义数据集训练如何将自己的图像和视频数据用于超分模型上周帮一个做遥感图像的朋友调试超分模型他兴冲冲地拿来一堆卫星图结果训练到一半loss直接炸了——NaN满天飞。我一看数据好家伙16位TIFF直接喂给模型像素值范围0-65535模型压根没见过这种阵仗。这种坑我踩过不止一次今天就把自定义数据集训练超分模型的完整流程掰开揉碎讲清楚。数据准备别让格式坑了你先说说图像数据。很多人以为超分训练就是拿一堆高清图扔进去然后模型自动学会放大。天真了。超分训练的核心是构造低分辨率-高分辨率对模型学的是从低到高的映射关系不是凭空变出细节。你手头的图像不管是从相机拍的、网上爬的还是专业设备采集的第一步要做的是统一格式。我习惯把所有图像转成PNG或BMP避免JPEG压缩带来的块效应污染训练数据。如果你非要用JPEG至少保证质量因子在95以上不然模型学到的全是压缩伪影的修复技巧不是真正的超分能力。这里有个血泪教训别用8位图像训练超分模型然后指望输出16位结果。模型输出的位深和输入是一致的你想做HDR超分训练数据就得是HDR格式。我见过有人拿普通8位图训练然后要求模型输出16位结果就是颜色断层严重跟水彩画似的。数据预处理双三次下采样不是唯一选择构造LR-HR对时最常用的方法是双三次下采样。但如果你做的是真实场景超分比如监控图像、老照片修复双三次下采样出来的LR图像和真实低分辨率图像差距很大。真实低分辨率图像包含传感器噪声、光学模糊、压缩失真等多种退化单纯的双三次下采样太干净了。我自己的做法是根据应用场景设计退化模型。做遥感超分我会加入高斯模糊和泊松噪声做视频超分我会考虑运动模糊和压缩伪影。代码实现时可以用OpenCV的退化函数组合也可以直接用BasicSR框架里的退化模块后者封装得比较完善。# 这里踩过坑直接用cv2.resize做下采样然后发现模型在真实低分辨率图上效果很差# 后来改成模拟真实退化importcv2importnumpyasnpdefdegrade_image(hr_img,scale4,noise_level0.05):# 先加模糊模拟光学退化kernel_sizeint(scale*2)1blurredcv2.GaussianBlur(hr_img,(kernel_size,kernel_size),0)# 下采样lrcv2.resize(blurred,(hr_img.shape[1]//scale,hr_img.shape[0]//scale),interpolationcv2.INTER_CUBIC)# 加噪声模拟传感器噪声noisenp.random.randn(*lr.shape)*noise_level*255lrnp.clip(lrnoise,0,255).astype(np.uint8)returnlr别这样写直接把HR图resize成小尺寸就当LR用除非你确定你的应用场景就是理想退化。视频数据的特殊处理视频超分和图像超分最大的区别在于时序一致性。你单独对每一帧做超分然后拼回去会发现画面闪烁、抖动因为模型对每一帧的处理不一致。处理视频数据时我通常先做关键帧提取。不是所有帧都需要相邻帧之间信息冗余太大。一般每秒取10-15帧就够了动作快的场景可以多取一些。然后以关键帧为中心前后各取2-3帧构成一个clip作为训练样本。# 视频帧提取别用opencv的默认参数它会把帧读成BGR# 超分模型一般用RGB记得转换capcv2.VideoCapture(input_video.mp4)fpscap.get(cv2.CAP_PROP_FPS)frame_intervalmax(1,int(fps/12))# 每秒取12帧frames[]count0whileTrue:ret,framecap.read()ifnotret:breakifcount%frame_interval0:frame_rgbcv2.cvtColor(frame,cv2.COLOR_BGR2RGB)frames.append(frame_rgb)count1视频超分训练时clip的长度很关键。太短了学不到时序信息太长了显存放不下。我一般用5帧前2后2加中间帧。训练时随机从视频中截取clip而不是固定位置这样数据多样性更好。数据增强别只做水平翻转很多人做数据增强就是水平翻转、垂直翻转、旋转90度完事。对于超分任务这些远远不够。超分模型对纹理细节敏感你需要让模型见过各种尺度和方向的纹理。我常用的增强策略随机裁剪从HR图上随机裁patch然后生成对应的LR patch。patch大小根据模型感受野定EDSR这类大模型需要96x96以上轻量模型64x64就够了。随机旋转0, 90, 180, 270度加上随机翻转。注意旋转后要同步处理LR和HR别只转一个。颜色抖动轻微调整亮度、对比度、饱和度。别调太狠不然模型学的是颜色映射不是超分。混合分辨率同一个batch里混入不同下采样倍数的样本让模型学会处理多种尺度。这个技巧在真实场景超分中特别有用。# 这里踩过坑颜色抖动参数设太大模型输出颜色漂移# 现在只用很小的幅度fromtorchvisionimporttransforms color_jittertransforms.ColorJitter(brightness0.1,# 别超过0.2contrast0.1,saturation0.05,hue0.02)训练策略学习率调度是门玄学自定义数据集训练超分模型最怕的就是过拟合。你的数据集可能只有几百张图而模型参数量动辄几百万。这时候需要一些trick。先用预训练权重初始化。不管你的数据多特殊先在DIV2K或Flickr2K上预训练过的权重基础上微调效果远好于从头训练。我试过用EDSR在遥感图像上从头训练跑了三天PSNR还不如预训练模型微调两小时。学习率要小。微调时初始学习率设1e-4每10个epoch衰减0.5。如果loss震荡说明学习率大了降到5e-5试试。别用固定学习率超分模型训练后期需要精细调整。验证集要模拟真实场景。不要用双三次下采样的验证集那会给你虚假的自信。用真实的低分辨率图像验证或者用你设计的退化模型生成验证集。我习惯在验证集上同时看PSNR和SSIM但更看重主观效果——PSNR高但图像模糊的情况太常见了。数据加载别让IO成为瓶颈很多人训练超分模型时GPU利用率只有30-40%一看CPU和磁盘IO已经100%了。这是因为超分训练需要频繁读取大尺寸图像而且每次都要做下采样、裁剪等预处理。解决方案预处理成patch把HR图像预先裁成小patch存成npy或h5文件。训练时直接读取patch省去实时裁剪的开销。使用LMDB数据库把图像序列化存入LMDB读取速度比文件系统快一个数量级。BasicSR框架默认支持LMDB格式。多进程数据加载PyTorch的DataLoader设置num_workers4或8但别超过CPU核心数。我试过设成16结果系统卡死。# 别这样写每次训练都从原始大图裁剪IO开销巨大# 应该预处理成patchimporth5pydefpreprocess_to_patches(hr_dir,lr_dir,patch_size96,scale4):# 遍历所有HR图像裁成patch并保存# 同时生成对应的LR patch# 保存为h5文件训练时直接读取pass# 具体实现略思路最重要个人经验性建议数据质量比数量重要。100张高质量、多样性的图像效果远好于1000张重复、模糊的图像。我见过有人从视频里抽了10000帧训练结果模型学到的全是相同场景的不同角度泛化能力极差。别迷信PSNR。PSNR高不代表超分效果好尤其是自定义数据集上。我做过一个实验用GAN训练的超分模型PSNR比ESRGAN低0.5dB但人眼看起来细节更真实。如果做应用建议同时用NIQE、PIQE等无参考评价指标。视频超分先做对齐。如果你的视频有运动帧与帧之间没有对齐直接训练时序模型会学到运动模糊。建议先用光流法或特征匹配做帧对齐再送入模型。EDVR和BasicVSR都内置了对齐模块但需要你提供对齐后的数据。混合精度训练要小心。超分模型对精度敏感混合精度训练容易导致梯度消失或爆炸。我一般先用FP32训练几个epoch确认loss稳定后再切到AMP。如果发现loss异常立刻切回FP32。保存中间结果。每训练一个epoch在验证集上跑一次保存超分结果。肉眼观察比看loss曲线更直观。我经常发现loss在下降但超分结果越来越模糊——这是过拟合的征兆。最后说一句自定义数据集训练超分模型80%的时间花在数据准备上10%花在调参只有10%是真正的训练。别急着跑模型先把数据搞清楚后面会省很多事。