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

how do I implement Gaussian blurring layer in Keras?

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

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

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 层来实现,但它不起作用。

如报错:AttributeError: 'float' object has no attribute 'dtype',只需将K.sqrt改为math.sqrt即可。

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

但是,如果您专门寻找 Gaussian blur filters in image processing, then you can simply use a depth-wise convolution layer (to apply the filter on each input channel independently) with fixed weights to get the desired output (Note that you need to generate the weights of Gaussian kernel to set them as the weights of DepthwiseConv2D layer. For that you can use the function introduced in this 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...

在尝试弄清楚如何使用@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()。您可以向函数添加参数以使其更具动态性,例如形状、内核大小、通道。根据我的发现,只有在将层添加到模型后才能应用权重。