超分辨率:卷积在边缘留下痕迹

时间:2018-10-14 17:46:18

标签: image machine-learning neural-network keras conv-neural-network

因此,我一直在研究超分辨率模型,并取得了不错的成绩。但是,我在输出图像中留下了网络的剩余部分:由于内存原因,我无法将整个图像作为输入提供,这意味着我不得不将图像切成多个较小的部分(在我的情况下,128x128 )。

由于某些原因,这些印章的边缘正在产生线条。我的问题是:原因是什么以及如何防止?

我首先想到的是,边缘上的卷积没有剩下的其他信息,因为尺寸超过1x1的过滤器需要填充,因此在没有后处理的情况下使用此类行是正常且不可避免的。什么是好的后处理方法?

还是需要更多培训才能最终解决该问题?

我的另一种想法是将图像的重叠区域馈送到网络,并用重叠输出的相应非边缘部分替换一个输出的边缘。

这是我使用的模型:

def setUpModel(x_train, y_train):

    filters = 256
    kernel_size = 3
    strides = 1
    scale_fact = 4
    res_blocks = 3
    img_depth = 3


    # Head module
    input = Input(shape=(None, None, img_depth))  # None = can take inputs of different sizes
    conv0 = Conv2D(filters, kernel_size, strides=strides, padding='same')(input)

    # Body module
    res = Conv2D(filters, kernel_size, strides=strides, padding='same')(conv0)
    act = ReLU()(res)
    res = Conv2D(filters, kernel_size, strides=strides, padding='same')(act)
    res_rec = Add()([conv0, res])

    for i in range(res_blocks):
        res1 = Conv2D(filters, kernel_size, strides=strides, padding='same')(res_rec)
        act  = ReLU()(res1)
        res2 = Conv2D(filters, kernel_size, strides=strides, padding='same')(act)
        res_rec = Add()([res_rec, res2])

    conv = Conv2D(filters, kernel_size, strides=strides, padding='same')(res_rec)
    add  = Add()([conv0, conv])

    # Tail module
    conv = Conv2D(filters, kernel_size, strides=strides, padding='same')(add)
    act  = ReLU()(conv)
    up   = UpSampling2D(size=scale_fact if scale_fact != 4 else 2)(act)  # TODO: try "Conv2DTranspose"

    # When it's a 4X factor, we want the upscale split in two procedures
    if(scale_fact == 4):
        conv = Conv2D(filters, kernel_size, strides=strides, padding='same')(up)
        act  = ReLU()(conv)
        up   = UpSampling2D(size=2)(act)  # TODO: try "Conv2DTranspose"

    output = Conv2D(filters=3,
                    kernel_size=1,
                    strides=1,
                    padding='same')(up)

    model = Model(inputs=input, outputs=output)

    return model

这里有两个例子:

HR1

traces1

HR2

traces2

编辑:根据要求,下面是train代码:

def train(model, x_train, y_train):
    print("Training is starting.")

    if load_model == False:
        print("Compiling the model since it wasn't loaded from memory.")
        optimizer = Adadelta(lr=1.0,
                             rho=0.95,
                             epsilon=None,
                             decay=0.0)
        model.compile(optimizer=optimizer,
                      loss='mean_squared_error')

    model.fit(x_train,
              y_train,
              epochs=6,  # TODO: is it multi-fold testing?
              verbose=verbosity,
              shuffle=False,
              validation_split=0.1,
              batch_size=7,
              callbacks=get_callbacks())

我以前的batch_size为1,并且会在128x128的样本上进行训练(较大的样本会破坏我的记忆),但是这给了我很长的训练时间。我最终选择了7的批量大小和64x64的训练输入大小。

数据集太大,我不得不将其拆分为多个子部分,因为我无法将其全部加载到内存中,因此历元值较低(我手动更改了输入的源文件夹,然后再次在保存的模型)。

get_callbacks()返回[],因为我想尝试使用的某些回调会导致内存问题,并极大地减慢了训练时间(例如,TensorBoad)。

如果您有兴趣查看更多要理解的代码,这里是repo

0 个答案:

没有答案