Reputation: 5878
I wanted to create my own Keras noise layer, so I started from the Keras GaussianNoise code. The call method is:
def call(self, inputs, training=None):
def noised():
return inputs + K.random_normal(shape=K.shape(inputs), mean=0., stddev=self.stddev)
return K.in_train_phase(noised, inputs, training=training)
I wanted the random noise to be applied only to X% of the pixels, not all of them. So I need to generate an other random binary tensor (with random 0 and 1). Following this discussion, the solution seems to use a constant tensor and do something like that:
randomtensor = K.random_uniform(shape=K.shape(inputs), minval=0.0, maxval=100.0)
constensor = K.constant(0.0, shape=K.shape(inputs))
cond = K.less(randomvalues, constensor)
randomtensor = K.switch(cond, 1, randomtensor)
cond = K.greater_equal(randomvalues, constensor)
randomtensor = K.switch(cond, 0, randomtensor)
Unfortunately, there is an issue with the constant tensor, and I get the following error:
File "/Users/firetiti/NN/Keras/Contributions_Noise.py", line 50, in noised
constensor = K.constant(0.0, shape=K.shape(inputs))
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py", line 358, in constant
return tf.constant(value, dtype=dtype, shape=shape, name=name)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tensorflow/python/framework/constant_op.py", line 102, in constant
tensor_util.make_tensor_proto(value, dtype=dtype, shape=shape, verify_shape=verify_shape))
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tensorflow/python/framework/tensor_util.py", line 416, in make_tensor_proto
shape = [int(dim) for dim in shape]
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/tensorflow/python/framework/ops.py", line 541, in iter
raise TypeError("'Tensor' object is not iterable.")
TypeError: 'Tensor' object is not iterable.
What am I doing wrong?
Is there a better way to generate a random binary tensor?
Upvotes: 2
Views: 1683
Reputation: 18675
K.switch()
takes a zero dimension expression (i.e. is not an element-wise if
)
Does the following do what you want ?
from keras import backend as K
import numpy as np
a = np.asarray([[3,4,2,44,22,4,5,6,77,86,3,2,3,23,44,21],
[3,4,22,44,2,4,54,6,77,8,3,2,36,23,4,2]], dtype=np.float)
inputs = K.variable(a)
# probability per pixel to add noise
prob_noise = 0.2
# standard deviation of noise
noise_stddev = 0.1
# noise_mask will be a tensor of floats which are one
# if and only if the corresponding random value falls into the interval
# [0..prob_noise)
noise_mask = K.cast(
K.less(
K.random_uniform(shape=inputs.shape, minval=0.0, maxval=1.0),
prob_noise),
'float32')
noise = K.random_normal(shape = inputs.shape , mean=0., stddev = noise_stddev)
noised = inputs + noise * noise_mask
print K.eval(noised)
Note that this does not guarantee that for each image exactly prob_noise
of the pixels will be smeared with noise, this holds only on average.
Upvotes: 3