如何在 Keras 中实现高斯模糊层?

Posted

技术标签:

【中文标题】如何在 Keras 中实现高斯模糊层?【英文标题】:how do I implement Gaussian blurring layer in Keras? 【发布时间】:2019-09-02 17:59:10 【问题描述】:

我有一个自动编码器,我需要在输出后添加一个高斯噪声层。我需要一个自定义层来执行此操作,但我真的不知道如何生成它,我需要使用张量来生成它。

如果我想在下面代码的调用部分实现上面的等式怎么办?

class SaltAndPepper(Layer):

    def __init__(self, ratio, **kwargs):
        super(SaltAndPepper, self).__init__(**kwargs)
        self.supports_masking = True
        self.ratio = ratio

    # the definition of the call method of custom layer
    def call(self, inputs, training=None):
        def noised():
            shp = K.shape(inputs)[1:]

         **what should I put here????**            
                return out

        return K.in_train_phase(noised(), inputs, training=training)

    def get_config(self):
        config = 'ratio': self.ratio
        base_config = super(SaltAndPepper, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

我也尝试使用 lambda 层来实现,但它不起作用。

【问题讨论】:

你可以简单地考虑 GaussianNoise 或 GaussianDropout:***.com/a/65504785/10375049 【参考方案1】:

如果您正在寻找 additivemultiplicative 高斯噪声,那么它们已经在 Keras 中作为一个层实现:GuassianNoise(additive)和GuassianDropout (乘法)。

但是,如果您在图像处理中专门寻找 Gaussian blur 过滤器中的模糊效果,那么您可以简单地使用具有 的深度卷积层(在每个输入通道上独立应用过滤器)固定权重以获得所需的输出(注意,您需要生成高斯核的权重以将其设置为 DepthwiseConv2D 层的权重。为此,您可以使用answer 中介绍的函数):

import numpy as np
from keras.layers import DepthwiseConv2D

kernel_size = 3  # set the filter size of Gaussian filter
kernel_weights = ... # compute the weights of the filter with the given size (and additional params)

# assuming that the shape of `kernel_weighs` is `(kernel_size, kernel_size)`
# we need to modify it to make it compatible with the number of input channels
in_channels = 3  # the number of input channels
kernel_weights = np.expand_dims(kernel_weights, axis=-1)
kernel_weights = np.repeat(kernel_weights, in_channels, axis=-1) # apply the same filter on all the input channels
kernel_weights = np.expand_dims(kernel_weights, axis=-1)  # for shape compatibility reasons

# define your model...

# somewhere in your model you want to apply the Gaussian blur,
# so define a DepthwiseConv2D layer and set its weights to kernel weights
g_layer = DepthwiseConv2D(kernel_size, use_bias=False, padding='same')
g_layer_out = g_layer(the_input_tensor_for_this_layer)  # apply it on the input Tensor of this layer

# the rest of the model definition...

# do this BEFORE calling `compile` method of the model
g_layer.set_weights([kernel_weights])
g_layer.trainable = False  # the weights should not change during training

# compile the model and start training...

【讨论】:

非常感谢您的完整解释,让我的问题变得简单。这正是我一直在寻找的。你真的很专家:) 它只在训练阶段或测试阶段也有效吗? @david 欢迎您。该层的权重是固定的,将在训练和测试阶段应用。 今天你好,你能帮我解决这个问题吗?***.com/questions/55713523/… 您好,您对这个问题有什么建议吗?没有人知道这件事:(***.com/questions/55871023/…【参考方案2】:

经过一段时间试图弄清楚如何使用@today 提供的代码来执行此操作后,我决定与将来可能需要它的任何人分享我的最终代码。我创建了一个非常简单的模型,它只对输入数据应用模糊:

import numpy as np
from keras.layers import DepthwiseConv2D
from keras.layers import Input
from keras.models import Model


def gauss2D(shape=(3,3),sigma=0.5):

    m,n = [(ss-1.)/2. for ss in shape]
    y,x = np.ogrid[-m:m+1,-n:n+1]
    h = np.exp( -(x*x + y*y) / (2.*sigma*sigma) )
    h[ h < np.finfo(h.dtype).eps*h.max() ] = 0
    sumh = h.sum()
    if sumh != 0:
        h /= sumh
    return h

def gaussFilter():
    kernel_size = 3
    kernel_weights = gauss2D(shape=(kernel_size,kernel_size))
    
    
    in_channels = 1  # the number of input channels
    kernel_weights = np.expand_dims(kernel_weights, axis=-1)
    kernel_weights = np.repeat(kernel_weights, in_channels, axis=-1) # apply the same filter on all the input channels
    kernel_weights = np.expand_dims(kernel_weights, axis=-1)  # for shape compatibility reasons
    
    
    inp = Input(shape=(3,3,1))
    g_layer = DepthwiseConv2D(kernel_size, use_bias=False, padding='same')(inp)
    model_network = Model(input=inp, output=g_layer)
    model_network.layers[1].set_weights([kernel_weights])
    model_network.trainable= False #can be applied to a given layer only as well
        
    return model_network

a = np.array([[[1, 2, 3], [4, 5, 6], [4, 5, 6]]])
filt = gaussFilter()
print(a.reshape((1,3,3,1)))
print(filt.predict(a.reshape(1,3,3,1)))

出于测试目的,数据仅具有1,3,3,1 的形状,函数gaussFilter() 创建了一个非常简单的模型,该模型只有输入和一个卷积层,该模型提供高斯模糊,其权重在函数gauss2D() 中定义。您可以向函数添加参数以使其更具动态性,例如形状,内核大小,通道。根据我的发现,权重只能在图层添加到模型后应用。

【讨论】:

【参考方案3】:

由于错误:AttributeError: 'float' object has no attribute 'dtype',只需将K.sqrt更改为math.sqrt即可。

【讨论】:

不,我更改了代码,但它产生了一个错误,我把它放在上面。我不确定是否要实现高斯模糊我该怎么做??

以上是关于如何在 Keras 中实现高斯模糊层?的主要内容,如果未能解决你的问题,请参考以下文章

高斯模糊效果

如何在 Keras 中实现 Salt&Pepper 层?

如何在 iOS6 中的 UIView 上获得高斯模糊效果

MKMapKit 上的高斯模糊

【iOS开发】生成高斯模糊效果背景

如何高斯过滤(模糊)浮点numpy数组