相关文章推荐
纯真的熊猫  ·  javascript convert ...·  12 月前    · 
风度翩翩的伤疤  ·  datatable select like ...·  1 年前    · 
曾经爱过的领结  ·  c - How to change ...·  1 年前    · 

源码来自github: https://github.com/JuheonYi/VESPCN-tensorflow 中 ESPCN部分

首先简单的来看ESPCN的网络结构搭建 conv--conv--conv--ps

    def network(self, LR):
        feature_tmp = tf.layers.conv2d(LR, 64, 5, strides=1, padding='SAME', name='CONV_1',
                                kernel_initializer=tf.contrib.layers.xavier_initializer(), reuse=tf.AUTO_REUSE)
        feature_tmp = tf.nn.relu(feature_tmp)
        feature_tmp = tf.layers.conv2d(feature_tmp, 32, 3, strides=1, padding='SAME', name='CONV_2',
                                kernel_initializer=tf.contrib.layers.xavier_initializer(), reuse=tf.AUTO_REUSE)
        feature_tmp = tf.nn.relu(feature_tmp)
        feature_out = tf.layers.conv2d(feature_tmp, self.channels*self.scale*self.scale, 3, strides=1, padding='SAME', 
                            name='CONV_3', kernel_initializer = tf.contrib.layers.xavier_initializer())
        feature_out = PS(feature_out, self.scale, color=False)
        feature_out = tf.layers.conv2d(feature_out, 1, 1, strides=1, padding='SAME', 
                        name = 'CONV_OUT', kernel_initializer=tf.contrib.layers.xavier_initializer(), reuse=tf.AUTO_REUSE)
        return feature_out

其中PS操作便是pixel shuffle

PS操作:其实就是将H * W * C * r * r  ==>  rH * rW * C  将其从H * W 放大为 rH * rW

def PS(X, r, color=False):
    #print("Input X shape:",X.get_shape(),"scale:",r)
    if color:
        Xc = tf.split(X, 3, 3)
        X = tf.concat([_phase_shift(x, r) for x in Xc], 3)   #each of x in Xc is r * r channel 分别每一个通道变为r*r
    else:
        X = _phase_shift_1dim(X, r)
    #print("output X shape:",X.get_shape())
    return X

tf.split方法请移步tensorflow API: https://www.tensorflow.org/api_docs/python/tf/split 或者直接google

总之结果就是得到一个Xc(三通道,每一通道为H * W * r * r) 随后分辨遍历每一个通道 将r 与H W混合(shuffle)

具体操作:

def _phase_shift(I, r):
    bsize, w, h, c = I.get_shape().as_list()
    bsize = tf.shape(I)[0]
    X = tf.reshape(I, (bsize, w, h, r, r))
    X = tf.split(X, w, 1)   #在w通道上分成了w份, 将每一维分成了1
    #tf.squeeze删除axis上的1,然后在第三通道 即r通道上 将w个小x重新级联变成r * w
    X = tf.concat([tf.squeeze(x, axis=1) for x in X], 2)  #最终变成 bsize, h, r * w, r
    X = tf.split(X, h, 1)
    X = tf.concat([tf.squeeze(x, axis=1)for x in X], 2)
    return tf.reshape(X, (bsize, w * r, h * r, 1))  #最后变成这个shape
def _phase_shift_1dim(I, r):
    bsize, h, w, c = I.shape
    bsize = I.shape[0]
    X = tf.reshape(I, (bsize, h, w, r, r))
    X = tf.split(X, w, 1)
    X = tf.concat([tf.squeeze(x, axis=1) for x in X], 2)
    X = tf.split(X, h, 1)
    X = tf.concat([tf.squeeze(x, axis=1) for x in X], 2)
    return tf.reshape(X, (bsize, w * r, h * r, 1))

其中重点 在split和concat中,这两步进行了pixel的拆分与重组 将a变为r * a ,b同理。

来自:https://github.com/drakelevy/ESPCN-TensorFlow

shuffle操作如下:

def shuffle(input_image, ratio):
    shape = input_image.shape
    height = int(shape[0]) * ratio
    width = int(shape[1]) * ratio
    channels = int(shape[2]) // ratio // ratio
    shuffled = np.zeros((height, width, channels), dtype=np.uint8)
    for i in range(0, height):
        for j in range(0, width):
            for k in range(0, channels):
                #每一个像素 都是三通道叠加
                shuffled[i,j,k] = input_image[i // ratio, j // ratio, k * ratio * ratio + (i % ratio) * ratio + (j % ratio)]
    return shuffled

简单粗暴 直接打乱重组 直接根据原图拼接一张新图片(使用python的思想来理解,一个三维数组,分别对每一维度,即每一个数组进行处理),每一个像素点分别控制。

而在pytorch在中:官方提供了pixel shuffle方法:

CLASS torch.nn.PixelShuffle(upscale_factor)
pixelshuffle定义: 算法思路:图像转张量(NxCxWxH)–增加C的维度–调用pixelshuffle 博主最近在做图像超分辨率重建,复现了SRCNN,RDN一些卷积之后concat再进行上采样的算法,今天做了一下简单的pixelshuffle。 import torch from torch import nn import cv2 import numpy as np from torchvision import transforms img1 = cv2.imread('./107.p 推荐项目:PixelCNN++ - 高性能像素预测模型 项目地址:https://gitcode.com/pclucas14/pixel-cnn-pp PixelCNN++ 是一个基于 PyTorch 实现的深度学习模型,用于图像像素级别的建模和预测。这个项目灵感来源于 OpenAI 的官方实现,并对其进行了优化,提供更高的预测性能。 PixelCNN++ 设计的核心是递归神经网络结构,... 简单来说,例如nn.Pixelshuffle(2),他会将前4个通道,拼在第一个通道的空间,然后将接下来4个通道拼在输出的第二个通道的空间,依次类推,见下面的实验就懂了 实验代码 import torch import torch.nn as nn ps = nn.PixelShuffle(2) input = torch.range(1,c*h*w).view(1,c,h,w) print(input.shape) output = ps(input) print("ou PixelUnshuffle就是PixelShuffle的逆操作。如下图可以看到,PixelShuffle是把输入通道按照缩放因子。PixelShuffle是一种上采样方法,它将形状为。功能: 是PixelShuffle的逆操作,把大小为。输入的第二组(后4个通道)的元素,每次间隔。,PixelShuffle的 缩放因子是。交错排列,合并成输出的第一个通道维度。交错排列,合并成输出通道的第二个维度。是 0 或者batch大小。的张量重新排列转换为形状为。通道)的元素,每次间隔。的张量重新排列为大小为。 这里介绍一下PyTorchtorch.nn.PixelShuffle()这个层的背景介绍和相关用法。 参考文档: ①PyTorchPixelShuffle PixelShuffle层1 背景介绍2 用法简介2.1 实战代码2.2 效果展示 1 背景介绍 PixelShuffle层又名亚像素卷积层,是论文Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural . cuda 9.2 python 3.6 github: [https://github.com/leftthomas/ESPCN](https://github.com/leftthomas/ESPCN) 上面github应该是官方代码,但是用的pytorch0.4以前的版本应该是,cuda是8.0,python是2.7 原文链接:https://blog.csdn.net/u014636245/article/details/98071626 PixelShuffle是一种上采样方法,可以对缩小后的特征图进行有效的放大。可以替代插值或解卷积的方法实现upscale PixelShuffle PixelShuffle(像素重组)的主要功能是将低分辨的特征图,通过卷积和多通道间的重组得到高分辨率的特征图。这一方法最... torch.nn.PixelShuffle(upscale_factor): 将 shape 为[N,C∗r2,H,W][N, C*r^2, H, W][N,C∗r2,H,W]的 Tensor 重新排列为 shape 为[N,C,H∗r,W∗r][N, C, H*r, W*r][N,C,H∗r,W∗r]的 Tensor。 当使用stride=1/r 的 sub-pixel 卷积的时候,这个方法是非常有用的。 (1)upscale_factor (int):增加空间分辨率因子 模型输入:原始低分辨率图片 核心:亚像素卷积。在网络的最末端实现LR到HR的分辨率 背景:之前的SRCNN,通过双三次插值得到的高分辨率的图像,直接从低分辨率LR得到了高分辨率的图片。(输入是双三次插值的高分辨率图像(类似于粗糙的高分辨率图像)),那么在网络卷积就会造成,粗糙的高分辨率图和标签进行计算。这样计算时间复杂度较大。 ESPCN网络模型 # 网络模型代码 import math import torch 去年曾经使用过FCN(全卷积神经网络)及其派生Unet,再加上在爱奇艺的时候做过一些超分辨率重建的内容,其用到了毕业于帝国理工的华人博士Shi Wenzhe(在Twitter任职)发表的PixelShuffle《Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network》的论文。 PyTorch 0.4.1将这些上采样的方式定义为Vision Laye