Accurate Image Super-Resolution Using Very Deep Convolutional Networks
https://cv.snu.ac.kr/research/VDSR/VDSR_CVPR2016.pdf
摘要:
这是一种单张图像超分辨率(SISR)重建方法,采用极深网络结构,想法来源于在ImageNet分类中的VGG网络。
提出增加网络深度可提高SR效果。
采用多次级联小滤波器,有效利用了整张图像的上下文信息,即不仅仅是单个像素之间的相似。
采用以高学习率只训练残差的方式训练,减缓因增加layers至20造成的时间负担。(ResNet 2015年被提出,本文是2016年的文章)
也就是计算真实图像I与生成图像之间的残差。
本文方法是面向多尺寸图像的超分辨率重建。
网络结构:
每一层是64个filter 3*3*64
最后一层是单个filter 3*3*64
for i in range(18):
#conv_w = tf.get_variable("conv_%02d_w" % (i+1), [3,3,64,64],
initializer=tf.contrib.layers.xavier_initializer())
conv_w = tf.get_variable("conv_%02d_w" % (i+1), [3,3,64,64],
initializer=tf.random_normal_initializer(stddev=np.sqrt(2.0/9/64)))
conv_b = tf.get_variable("conv_%02d_b" % (i+1), [64],
initializer=tf.constant_initializer(0))
weights.append(conv_w)
weights.append(conv_b)
tensor = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(tensor, conv_w, strides=[1,1,1,1], padding='SAME'), conv_b))
训练的输入是先用插值方法放大图像,再进行非线性映射。关于这种插值的方法目前仍有方法使用,但个人觉得这个插值过程可能引入噪声,还是看图像。
边缘填充0
本文讨论了每次应用卷积导致feature map减少的问题。因为需要用surrounding pixel推断center pixel,所以the pixel near the image boundary需要被裁剪,就是每次经过卷积核都会裁剪一圈边缘像素,这样图像会变得越来越小,显然我们不想这样。
文中指出VDSR在每次卷积之前进行0填充,保证feature map数量一致,并对边界有了有效的超分辨率预测。
梯度裁剪 (Clipping Gradient) :
为了防止梯度爆炸 https://blog.csdn.net/qq_29340857/article/details/70574528
既然在BP过程中会产生梯度消失(就是偏导无限接近0,导致长时记忆无法更新),那么最简单粗暴的方法,设定阈值,当梯度小于阈值时,更新的梯度为阈值,如下图所示:
优点:简单粗暴
缺点:很难找到满意的阈值
梯度裁剪在pytorch和tensorflow中已经是封装好的函数。
pytorch:nn.utils.clip_grad_norm(parameters, max_norm, norm_type=2)
tensorflow:
clip_by_norm
这里的clip_by_norm是指对梯度进行裁剪,通过控制梯度的最大范式,防止梯度爆炸的问题,是一种比较常用的梯度规约的方式。通过注解可以清晰的明白其作用在于将传入的梯度张量t
的L2范数进行了上限约束,约束值即为clip_norm
,如果t
的L2范数超过了clip_norm
,则变换为t * clip_norm / l2norm(t)
,如此一来,变换后的t
的L2范数便小于等于clip_norm
了。
多尺度模型
训练多尺度模型,参数共享在所有预定义的尺度中。
就是每个批次中有不同scale的图像,每个mini-batch有64张图
由本图可知,在VDSR中采用多种放大尺度图像训练,得到多种尺度放大模型。
VDSR结果: