我如何在 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()))
Traceback (most recent call last):
File "", line 125, in
decoded_noise=SaltAndPepper(0.5)(decoded)
File
"D:\software\Anaconda3\envs\py36\lib\site-packages\keras\engine\base_layer.py",
line 457, in call
output = self.call(inputs, **kwargs)
File "", line 57, in call
return K.in_train_phase(noised(), inputs, training=training)
File "", line 52, in noised
n = int( s * r/10 )
TypeError: unsupported operand type(s) for /: 'Dimension' and 'int'
更新:
我使用了@today的解决方案并编写了以下代码:
decoded_noise=call(0.05,bncv11)#16
哪个bncv11是它之前的batch normalization层的输出。
但是它会产生这个错误,为什么会这样?
Traceback (most recent call last):
File "", line 59, in
decoded_noise=call(0.05,bncv11)#16
File "", line 34, in call
return K.in_train_phase(noised(), inputs, training=training)
File "", line 29, in noised
mask_select = K.random_binomial(shape=shp, p=self.ratio)
AttributeError: 'float' object has no attribute '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, 编译)
文件
"D:\software\Anaconda3\envs\py36\lib\site-packages\keras\engine\saving.py",
第 225 行,在 _deserialize_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
return反序列化(配置,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
列表(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)。虽然,除了图像处理之外,我们还可以在其他领域使用相同的想法。所以你必须首先指定三件事:
- 应更改多少像素? (噪声比)
- 应该选择和更改哪些像素?
- 应该对这些选定像素中的哪些像素加盐(以及对其他像素加胡椒)?
由于 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
对一批中的所有样本应用相同的噪声模式(但是,批与批之间会有所不同)。
我需要像高斯噪声一样在 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()))
Traceback (most recent call last):
File "", line 125, in decoded_noise=SaltAndPepper(0.5)(decoded)
File "D:\software\Anaconda3\envs\py36\lib\site-packages\keras\engine\base_layer.py", line 457, in call output = self.call(inputs, **kwargs)
File "", line 57, in call return K.in_train_phase(noised(), inputs, training=training)
File "", line 52, in noised n = int( s * r/10 )
TypeError: unsupported operand type(s) for /: 'Dimension' and 'int'
更新:
我使用了@today的解决方案并编写了以下代码:
decoded_noise=call(0.05,bncv11)#16
哪个bncv11是它之前的batch normalization层的输出。
但是它会产生这个错误,为什么会这样?
Traceback (most recent call last):
File "", line 59, in decoded_noise=call(0.05,bncv11)#16
File "", line 34, in call return K.in_train_phase(noised(), inputs, training=training)
File "", line 29, in noised mask_select = K.random_binomial(shape=shp, p=self.ratio)
AttributeError: 'float' object has no attribute '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, 编译)
文件 "D:\software\Anaconda3\envs\py36\lib\site-packages\keras\engine\saving.py", 第 225 行,在 _deserialize_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 return反序列化(配置,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 列表(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)。虽然,除了图像处理之外,我们还可以在其他领域使用相同的想法。所以你必须首先指定三件事:
- 应更改多少像素? (噪声比)
- 应该选择和更改哪些像素?
- 应该对这些选定像素中的哪些像素加盐(以及对其他像素加胡椒)?
由于 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
对一批中的所有样本应用相同的噪声模式(但是,批与批之间会有所不同)。