github链接:https://github.com/ckkelvinchan/RealBasicVSR
参考:https://zhuanlan.zhihu.com/p/482656858
https://blog.csdn.net/weixin_42130300/article/details/116604351?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163688913616780265481616%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163688913616780265481616&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-3-116604351.first_rank_v2_pc_rank_v29&utm_term=BasicVSR%E5%A4%8D%E7%8E%B0%E2%80%98%E2%80%99&spm=1018.2226.3001.4187
https://blog.csdn.net/qq_39967751/article/details/124292824
https://zhuanlan.zhihu.com/p/347776747
https://zhuanlan.zhihu.com/p/466999485
一、背景:超分训练分为两大类:基于图片的模型,基于视频的(带有时序性,类似rnn的结构)。超分训练也是有监督训练。准备一些真实+清晰的视频,然后通过一些退化的手段得到不清晰的视频,在一定程度上可以泛化到真实场景当中。组成监督训练对,作为训练数据。
RealBasicVSR 使用的是 Real-ESRGAN 的二阶退化模型,包括的方法主要有Blur, resize, noise 等,唯一不同的是为了针对视频退化,多路一个种退化方法: JPEG 压缩后加上视频压缩。
二、数据处理
早期的超分辨率模型假设退化是固定的(例如 bicubic 下采样),因为不需要考虑泛他性的问题,我们只需要对于高清图片作出对应的退化得到低清图片然后保存,再在训练期间直接读取高清和低清的图片对。
但是使用二阶退化模型时,为了提高泛化性,退化的参数是随机选取的。因此,我们不能先生成图片对再直接读取。所以,我们要对数据处理作出修改:只读取高清图片,在 再加上随机退化得到低清图片。我们再来看看配置文件。从 52 行到 195 行都是我们的随机退化,我们接下来看看不同退化的设置
首先我们会对图片加上模糊, 我们需要设置不同模糊的参数。
RandomBlur
RandomResize
RandomNoise
视频压缩DegradationsWithShuffle
resd数据集下载:https://seungjunnah.github.io/Datasets/reds.html
1.应用:
图片超分;
视频超分;
2.背景
非盲超分 (non-blind super-resolution):超分辨率的子领域。在这个任务中假设下采样的方式已知(例如 bicubic 下采样),因此可以人工生成无限训练数据。
真实视频超分 (real-world video super-resolution):指在对于真实视频的超分,难点在于真实视频的退化是未知且多样化的,因此很难采集适当的数据进行训练。
长期传播 (long-term propagation):指 Recurrent Network 中的传播方式。该方法把当前帧的信息传到下一帧, 从而把长期信息累积起来。代表方法有 BasicVSR,IconVSR,和 BasicVSR++。
3.训练
让我们来先了解一下 RealBasicVSR 是如何训练的。 RealBasicVSR 是通过大量生成退化(例如Gaussian blur, Poisson noise, JPEG compression)的不同组合用作监督训练。通过不同退化的组合,RealBasicVSR 在一定程度上可以泛化到真实场景当中。 RealBasicVSR 使用的是 Real-ESRGAN 的二阶退化模型,下图是 Real-ESRGAN 原文中的图解:
在作用到高清图片中得到低清图片。 RealBasicVSR 的退化大致跟上图一样。唯一不同的是为了针对视频退化,我们在 JPEG 压缩后加上视频压缩。
4.模型
三、模型训练
训练分为两个阶段:
使用 realbasicvsr_wogan_c64b20_2x30x8_lr1e-4_300k_reds.py 训练一个没有感知损失和对抗性损失的模型。
使用感知损失和对抗性损失 realbasicvsr_c64b20_1x30x8_lr5e-5_150k_reds.py 微调模型。
数据处理,我这是2个1080 ti的gpu,
直接训练
mim train mmedit configs/realbasicvsr_wogan_c64b20_2x30x8_lr1e-4_300k_reds.py --gpus 8 --launcher pytorch
显存不够报错,cuda out of memory
data = dict(
workers_per_gpu=10, ##改成4
train_dataloader=dict(
samples_per_gpu=2, drop_last=True, persistent_workers=False),
val_dataloader=dict(samples_per_gpu=1, persistent_workers=False),
test_dataloader=dict(samples_per_gpu=1, workers_per_gpu=1),
# train
train=dict(
type='RepeatDataset',
times=150,
dataset=dict(
type=train_dataset_type,
lq_folder='data/REDS/train_sharp_sub',
gt_folder='data/REDS/train_sharp_sub',
num_input_frames=15, ##改成5
pipeline=train_pipeline,
scale=4,
test_mode=False)),
能正常训练,但是训到4000多时,loss=nan了。怀疑是数据太少,因为只用了其中一小部分训练数据。
后来用了全部的数据2400*100=24万张图片进行训练。但是程序里打印的输入数据是36万,可能是增强到了1.5倍。还是nan。
又把学习率从1e-4改成1e-5,还是nan。
看有人说是可能是数据问题,但是每次loss为nan的iters不是一样的。大概率排除这个原因。
参考:https://blog.csdn.net/weixin_44145782/article/details/123782895
利用torch.isnan判断是否NaN,如果NaN了就不回传优化
试试
在mmedit/models/restorers/real_basicvsr.py
# optimize
# optimizer['generator'].zero_grad()
# loss_g.backward()
# optimizer['generator'].step()
# optimize
if (losses['loss_pix'].cpu().detach().numpy()<1000.0 or losses['loss_clean'].cpu().detach().numpy()<1000.0):
optimizer['generator'].zero_grad()
loss_g.backward()
optimizer['generator'].step()
按道理这样是没有问题的,但是这样改完之后,一旦loss大于1000.0又报cuda out of memory,改之前可以正常运行。
还试了用了4个gpu,报错数据太少不能训练。把数据集复制成2倍还是不行。还是2个gpu报错cuda out of memory,3个及以上就报数据太少不能训练。
暂时放弃这个网络训练了。
考虑是不是val数据集太少了导致的?