如何使用深度学习为图像添加局部(例如修复)转换?

数据挖掘 机器学习 神经网络 深度学习
2022-02-23 04:06:40

我想训练一个从图片中去除划痕的神经网络。我选择了一个带有生成器 (G) 和鉴别器 (D) 的 GAN 架构,以及具有相似动机的两组粗糙和不粗糙的图像。G 在我的设置中主要使用卷积和反卷积层ReLU作为输入,它使用粗糙的图像。D 区分 G 的输出和非划痕图像。

例如,生成器将执行以下转换:

(128, 128, 3) > (128, 128, 128) > (128, 128, 3)

元组包含(宽度、高度、通道)的位置。输入和输出需要具有相同的格式。

但是为了获得与输入具有相同全局结构的输出(即街道、房屋等),我似乎必须使用过滤器大小和步幅为 1,并且基本上通过网络传递完整的图片。

但是,我正在查看的功能相当小且本地化。对卷积使用最大 20 像素大小的过滤器就足够了。然后将网络应用到输入图片的所有部分。

对于这样的任务,什么是好的生成器架构?您是否同意生成器的结构,或者您是否希望不同的设计在局部更改上表现更好?

这是我在 tensorflow 中使用的生成器的代码。

def generator(x, batch_size, reuse=False):
    with tf.variable_scope('generator') as scope:
        if (reuse):
            tf.get_variable_scope().reuse_variables()

        s = 1
        f = 1

        assert ((WIDTH + f - 1) / s) % 1 == 0

        keep_prob = 0.5

        n_ch1 = 32
        w = init_weights('g_wc1', [f, f, CHANNELS, n_ch1])
        b = init_bias('g_bc1', [n_ch1])
        h = conv2d(x, w, s, b)
        h = bn(h, 'g_bn1')
        h = tf.nn.relu(h)
        h = tf.nn.dropout(h, keep_prob)
        h1 = h

        n_ch2 = 128
        w = init_weights('g_wc2', [f, f, n_ch1, n_ch2])
        b = init_bias('g_bc2', [n_ch2])
        h = conv2d(h, w, s, b)
        h = bn(h, "g_bn2")                
        h = tf.nn.relu(h)
        h = tf.nn.dropout(h, keep_prob)
        h2 = h

        n_ch3 = 256
        w = init_weights('g_wc3', [f, f, n_ch2, n_ch3])
        b = init_bias('g_bc3', [n_ch3])
        h = conv2d(h, w, s, b)
        h = bn(h, "g_bn3")                
        h = tf.nn.relu(h)
        h = tf.nn.dropout(h, keep_prob)      

        output_shape = [batch_size, HEIGHT//s//s, WIDTH//s//s, n_ch2]
        w = init_weights('g_wdc3', [f, f, n_ch2, n_ch3])
        b = init_bias('g_bdc3', [n_ch2])
        h = deconv2d(h, w, s, b, output_shape)        
        h = bn(h, "g_bnd3")                
        h = tf.nn.relu(h)
        h = h + h2

        output_shape = [batch_size, HEIGHT//s, WIDTH//s, n_ch1]
        w = init_weights('g_wdc2', [f, f, n_ch1, n_ch2])
        b = init_bias('g_bdc2', [n_ch1])
        h = deconv2d(h, w, s, b, output_shape)        
        h = bn(h, "g_bnd2")                
        h = tf.nn.relu(h)
        h = h + h1

        output_shape = [batch_size, HEIGHT, WIDTH, CHANNELS]
        w = init_weights('g_wdc1', [f, f, CHANNELS, n_ch1])
        b = init_bias('g_bdc1', [CHANNELS])
        h = deconv2d(h, w, s, b, output_shape)

    return tf.nn.sigmoid(h+x)

当你使用跨步时s>1,你会得到一个沙漏,其中层变得更小但更深。深度由n_ch变量独立控制。

顺便说一句,我在 Google colab 笔记本上运行它。免费拥有这样的引擎并能够尝试深度学习,真是太棒了!极好的!

2个回答

Max Jaderberg 等人了一篇名为Spatial Transformer Networks的论文。它所做的是试图通过减少转换(如平移和旋转)甚至减少输入的失真来找到其输入的规范形状。它引入了一个帮助卷积网络空间不变的模块。该模块的一项重大成就是它试图增强失真输入。看看这里


由于我们一位朋友的要求,我编辑了答案。首先,我引用了 Pr 写的通俗书籍中的一些内容。冈萨雷斯,我希望版权没有问题。然后我建议我的建议。

图 2.40,我附上的那个,显示了图 2.39 中的步骤示例。在这种情况下,使用的变换是傅里叶变换,我们将在本节后面简要提及并在第 4 章详细讨论。图 2.40(a) 是正弦干扰破坏的图像,图 2.40(b) 是幅度其傅里叶变换,即图 2.39 中第一级的输出。正如您将在第 4 章中了解到的,空间域中的正弦干扰表现为变换域中的明亮强度爆发。在这种情况下,脉冲串呈圆形,如图 2.40(b) 所示。图 2.40(c) 显示了一个蒙版图像(称为过滤器),白色和黑色分别代表 1 和 0。对于这个例子,图 2.39 的第二个框中的操作是将掩码乘以变换,从而消除造成干扰的突发。图 2.40(d) 显示了最终结果,通过计算修改变换的逆获得。干扰不再可见,重要细节非常清晰。事实上,您甚至可以看到用于图像对齐的基准标记(微弱的十字)。

在此处输入图像描述

好的!在这些引用之后,我参考了我的建议。ST网络中,作者声称他们的可微模块可以学习仿射变换以外的不同类型的变换。关键是我们通常应用两种转换。一种变换应用于图像的强度,这通过过滤器很流行。另一种称为图像变形,我们改变强度的位置,强度值不会改变,除非它们位于图像条目的离散网格之间,也称为像素,图片元素空间转换器适用于第二个任务,但它们也可用于第一个任务。有关于使用CNN的研究用于在其频域而不是在空间域中评估图像。您可以在这些网络中使用这些可微分模块。

最后,关于您的具体任务,我在您的图片中看到的内容,您的噪音具有相同的行为。我想如果这适用于所有情况,那么您的任务不是学习,可以使用通常的图像处理技术来解决。

您是否研究过 ResNet 在像素级别上修改图像,而不是整体修改图像内容,保留全局结构和注释?

此外,您的应用程序听起来很像deep image prior