簡體   English   中英

如何在 Keras 中實現 Salt&Pepper 層?

[英]how do I implement Salt& Pepper layer in Keras?

我需要像高斯噪聲一樣在 keras 中實現鹽和胡椒層,我嘗試使用以下代碼,但它產生了幾個錯誤。 你能告訴我有什么問題嗎? 您對實施 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 行,在 decoded_noise=SaltAndPepper(0.5)(decoded)

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

文件“”,第 57 行,在調用中返回 K.in_train_phase(noised(), inputs, training=training)

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

類型錯誤:不支持 / 的操作數類型:'Dimension' 和 'int'

更新:

我使用了@today 的解決方案並編寫了以下代碼:

decoded_noise=call(0.05,bncv11)#16

其中 bncv11 是它之前的批歸一化層的輸出。

但它會產生這個錯誤,為什么會發生?

回溯(最近一次調用最后一次):

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

文件“”,第 34 行,在調用中返回 K.in_train_phase(noised(), inputs, training=training)

文件“”,第 29 行,噪聲掩碼選擇 = K.random_binomial(shape=shp, p=self.ratio)

AttributeError: 'float' 對象沒有屬性 'ratio'

保存模型並使用它后會產生此錯誤:

回溯(最近一次調用最后一次):

文件“”,第 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”,第225行,_deserialize_model model = 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 返回 deserialize(config, custom_objects=custom_objects)

文件“D:\\software\\Anaconda3\\envs\\py36\\lib\\site-packages\\keras\\layers__init__.py”,第55行,反序列化printable_module_name='layer')

文件“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='layer')

文件 "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()))

在圖像處理中,鹽和胡椒粉噪聲基本上將隨機選擇的像素比率的值更改為鹽(即白色,根據圖像值的范圍通常為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圖像(即三個顏色通道),您可能需要對其進行一些修改,以便選擇具有所有通道的像素以添加噪聲(盡管這取決於您定義和使用鹽和胡椒噪聲的方式) )。
  • 假設salt的值為1,胡椒的值為0。不過,可以通過如下更改mask_noise的定義,輕松地將salt的值更改為x ,將胡椒的值更改為y

     mask_noise = K.random_binomial(shape=shp, p=0.5) * (xy) + y 
  • 相同的噪聲模式將應用於批次中的所有樣本(但是,批次之間會有所不同)。

我認為不可能在模型中使用這些圖層,但是在深度學習中,總會有一個稱為圖像預處理的過程,其中包括消除噪聲,調整圖像大小等,因此您可以在將圖像輸入神經元之前進行預處理。

開放式簡歷庫最適合解決此類問題

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM