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

时间:2019-04-12 02:32:24

标签: python tensorflow keras keras-layer gaussianblur

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

如果要在以下代码的调用部分中实现上述等式,该怎么办?

import random
from PyQt5 import QtCore, QtGui, QtWidgets


class GraphicsButton(QtWidgets.QGraphicsPixmapItem):
    def __init__(self, name, pixmap, parent=None):
        super(GraphicsButton, self).__init__(pixmap, parent)
        self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True)
        self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
        self._name = name

    @property
    def name(self):
        return self._name

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            print("mouse left press")
        elif event.button() == QtCore.Qt.RightButton:
            print("mouse right press")
        elif event.button() == QtCore.Qt.MidButton:
            print("mouse middle press")
        print(self.name)
        super(GraphicsButton, self).mousePressEvent(event)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        scene = QtWidgets.QGraphicsScene()
        view = QtWidgets.QGraphicsView(scene)
        self.setCentralWidget(view)
        # coordinates of the pentagon
        datas = [
            ("name1", "img0.png", QtCore.QPointF(0, -200)),
            ("name2", "img1.png", QtCore.QPointF(-190, -62)),
            ("name3", "img2.png", QtCore.QPointF(-118, 162)),
            ("name4", "img3.png", QtCore.QPointF(118, 162)),
            ("name5", "img0.png", QtCore.QPointF(190, -62)),
        ]
        for name, path, position in datas:
            item = GraphicsButton(name, QtGui.QPixmap(path))
            scene.addItem(item)
            item.setPos(position)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

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

3 个答案:

答案 0 :(得分:1)

如果您正在寻找加法可乘高斯噪声,那么它们已经在Keras中实现为层:GuassianNoise(加法)和{ {3}}(可乘)。

但是,如果要在图像处理中像GuassianDropout滤镜中那样专门寻找模糊效果,则可以简单地使用深度卷积层(将滤镜独立应用于每个输入通道)与< strong> fixed 权重以获取所需的输出(请注意,您需要生成高斯内核的权重以将其设置为DepthwiseConv2D层的权重。为此,您可以使用此Gaussian blur中引入的函数):

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...

答案 1 :(得分:0)

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

答案 2 :(得分:0)

一段时间后,我想弄清楚如何使用@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()创建了一个非常简单的模型,仅具有输入和一个卷积层,该卷积层提供了高斯模糊,并具有函数{{1 }}。您可以向函数添加参数以使其更具动态性,例如形状,仁大小,通道。根据我的发现得出的权重只有在将图层添加到模型后才能应用。