Keras でカスタム拡張レイヤーを作成しようとしていました。アイデアは、拡張を高速化することです (同じ関数を BATCH_SIZE 回実行する代わりに、バッチ全体で 1 回実行します)。
私は機能に行き詰まった:
__call__(inputs, training=False, **kwargs)
トレーニングでは、関数は(None, 128, 128, 3)
最後の 3 つの数字が画像の形状を示す形状の入力を取得します。私の理解では、最初None
は決定論的ではないバッチサイズでなければなりません(何らかの理由で)。
私の問題はここにあります。私の関数では、形状インジケーターとしてnp.random.ranf(inputs.shape)
満足していないものを使用しNone
、エラーをスローします。
TypeError: 'NoneType' object cannot be interpreted as an integer
一方、計算のバッチサイズを取得する方法がわかりません。カスタム Augmentation レイヤーのコードは次のとおりです。どんな助けでも大歓迎です!
class RandomHSV(Layer):
"""Adding Random Noise to HSV image. output is RGB
Input shape:
Arbitrary.
Output shape:
Same as input.
Arguments:
hsv_max_amp: list or tuple of the maximum amplitudes of the noise in range of [0, 1]
name: A string, the name of the layer.
"""
def __init__(self, hsv_max_amp=(0, 0, 0), name=None, **kwargs):
super(RandomHSV, self).__init__(name=name, **kwargs)
self.hsv_max_amp = np.array(list(hsv_max_amp), dtype='float32')
def build(self, input_shape):
self.batch_size = input_shape[0]
super(RandomHSV, self).build(input_shape) # Be sure to call this at the end
def call(self, inputs, training=True, **kwargs):
def hsv_noise():
hsv = tf.image.rgb_to_hsv(inputs)
# the random noise is a random matrix in shape (batch_size, img_w, img_h, depth)
# after creating the random matrix, multiply it (element wise) by the self.hsv_max_amp.
# that gets multiplied by random enabler (np.random.randint(0, 2, 3) -> 3 items, 0 or 1)
# then removing an offset.
random_noise = (np.random.ranf(inputs.shape) * (
np.random.random(1) * self.hsv_max_amp * np.random.randint(0, 2, 3)) - self.hsv_max_amp / 2) * 2
# those lines will cut any number which goes above 1 or goes below 0 (round it to 1 or 0 respectively).
hsv = tf.minimum(1., tf.maximum(0., hsv + random_noise))
batch = tf.image.hsv_to_rgb(hsv)
batch.set_shape(inputs.shape)
return batch
# applying hsv_noise if Training. if Testing then just passing batch forward unchanged
return control_flow_util.smart_cond(pred=training, true_fn=hsv_noise, false_fn=lambda: inputs)
編集: Input() レイヤーでバッチサイズを指定できることはわかっています。問題は解決しますが、入力レイヤーで形状を指定せずにそれを行う方法はありますか? したがって、より一般的なものになる可能性があります。