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

时间:2019-04-12 14:30:24

标签: python tensorflow image-processing keras noise

我需要像高斯噪声一样在喀拉拉邦实现盐和胡椒层,我尝试使用以下代码,但会产生一些错误。你能告诉我是什么问题吗?您对实施S&P层还有其他建议吗?谢谢。

from keras.engine.topology import Layer

class SaltAndPepper(Layer):

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

    def call(self, inputs, training=None):
        def noised():
            r = self.ratio*10
            s = inputs.shape[1]
            n = int( s * r/10 )
            perm = np.random.permutation(r)[:n]
            inputs[perm] = (np.random.rand(n) > 0.5)
            return inputs

        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()))
  

回溯(最近通话最近一次):

     

文件“”,第125行,在       encoded_noise = SaltAndPepper(0.5)(已解码)

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ engine \ base_layer.py”,   第457行,致电       输出= self.call(输入,** kwargs)

     

文件“”,第57行,正在通话中       返回K.in_train_phase(noised(),输入,training = training)

     

文件“”,第52行,有噪点       n = int(s * r / 10)

     

TypeError:/:“ Dimension”和“ int”的不受支持的操作数类型

更新

我使用@today的解决方案并编写了以下代码:

decoded_noise=call(0.05,bncv11)#16

哪个bncv11是之前的批处理规范化层的输出。

但是会产生此错误,为什么会发生?

  
    

回溯(最近通话最近一次):

         

文件“”,第59行,在         encoded_noise = call(0.05,bncv11)#16

         

文件“”在呼叫的第34行         返回K.in_train_phase(noised(),输入,training = training)

         

文件“”,第29行,有噪点         mask_select = K.random_binomial(shape = shp,p = self.ratio)

         

AttributeError:“浮动”对象没有属性“比率”

  
     

保存模型并使用它后,会产生此错误:

     

回溯(最近通话最近一次):

     

文件“”,第1行,在       b = load_model('Desktop / los4x4_con_tile_convolw_FBN_SigAct_SandPAttack05.h5',custom_objects = {'tf':tf})

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ engine \ saving.py”,   第419行,在load_model中       模型= _deserialize_model(f,custom_objects,compile)

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ engine \ saving.py”,   _deserialize_model中的第225行       模型= model_from_config(model_config,custom_objects = custom_objects)

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ engine \ saving.py”,   第458行,在model_from_config中       返回反序列化(config,custom_objects = custom_objects)

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ layers__init __。py”,   第55行,反序列化       printable_module_name ='图层')

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ utils \ generic_utils.py”,   第145行,在deserialize_keras_object中       list(custom_objects.items()))

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ engine \ network.py”,   第1022行,位于from_config中       process_layer(layer_data)

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ engine \ network.py”,   第1008行,在process_layer中       custom_objects = custom_objects)

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ layers__init __。py”,   第55行,反序列化       printable_module_name ='图层')

     

文件   “ D:\ software \ Anaconda3 \ envs \ py36 \ lib \ site-packages \ keras \ utils \ generic_utils.py”,   第138行,在deserialize_keras_object中       ':'+ class_name)

     

ValueError:未知层:SaltAndPepper

我将此代码放入定义网络结构的程序中

from keras.engine.topology import Layer

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=True):
        def noised():
            shp = K.shape(inputs)[1:]
            mask_select = K.random_binomial(shape=shp, p=self.ratio)
            mask_noise = K.random_binomial(shape=shp, p=0.5) # salt and pepper have the same chance
            out = inputs * (1-mask_select) + mask_noise * mask_select
            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()))

2 个答案:

答案 0 :(得分:1)

在图像处理中,盐和胡椒粉噪声基本上会将随机选择的像素比率的值更改为盐(即白色,根据图像值的范围通常为1或255)或胡椒粉(即黑色,通常为0)。虽然,我们可以在图像处理之外的其他领域使用相同的想法。因此,您必须首先指定三件事:

  1. 应更改多少个像素? (噪声比)
  2. 应该选择和更改哪些像素?
  3. 应该选择其中哪些像素进行腌制(并添加其他像素)?

由于Keras后端中有一个函数,可以根据给定的概率从二项式分布(即0或1)生成随机值,因此我们可以通过生成两个掩码轻松完成上述所有步骤:一个用于选择具有给定比率的像素,另一个用于将盐或胡椒粉应用于这些选定像素。这是操作方法:

from keras import backend as K

# NOTE: this is the definition of the call method of custom layer class (i.e. SaltAndPepper)
def call(self, inputs, training=None):
    def noised():
        shp = K.shape(inputs)[1:]
        mask_select = K.random_binomial(shape=shp, p=self.ratio)
        mask_noise = K.random_binomial(shape=shp, p=0.5) # salt and pepper have the same chance
        out = inputs * (1-mask_select) + mask_noise * mask_select
        return out

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

请注意,上面的代码中我假设了几件事:

  • 给定的噪声比值在[0,1]范围内。
  • 如果您使用该层将其直接应用于图像,则必须注意它假定图像是灰度的(即单色通道)。要将其用于RGB图像(即三个颜色通道),您可能需要对其进行一些修改,以便选择具有所有通道的像素以添加噪声(尽管这取决于您定义和使用盐和胡椒噪声的方式) )。
  • 它假定盐的值为1,而胡椒的值为0。不过,通过更改定义,您可以轻松地将盐的值更改为x,将胡椒的值更改为y mask_noise中的内容,如下所示:

    mask_noise = K.random_binomial(shape=shp, p=0.5) * (x-y) + y
    
  • 相同的噪声模式应用于批次中的所有样本(但是,批次之间会有所不同)。

答案 1 :(得分:0)

我认为不可能在模型中使用图层,但是在深度学习中,总会有一个称为图像预处理的过程,其中包括去除噪声,调整图像大小等,因此您可以在馈入图像之前对其进行预处理进入神经。

开放式简历库最适合解决此类问题

检查:https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_filtering/py_filtering.html