ML_Karasik
@ML_Karasik
Люблю нейросети и что с ними связанно

Не работают кастомные tf.keras слои, что делаю не так?

Вопрос людям разбирающимся в Tensorflow/Keras. Пытаюсь создать модель со своими классами наследованными от tf.keras.layers.Layer:
Код кастомных слоев

class UnetEncoderBlock(tf.keras.layers.Layer):
    def __init__(
            self,
            num_filters,
            use_pooling=True
    ):
        super().__init__()

        self.num_filters = num_filters
        self.use_pooling = use_pooling

    def build(self, input_shape):
        self.conv_1 = tf.keras.layers.Conv2D(
            self.num_filters,
            (3, 3),
            kernel_initializer='he_normal',
            padding='same',
            use_bias=False
        )
        self.activation_1 = tf.keras.layers.ReLU()

        self.conv_2 = tf.keras.layers.Conv2D(
            self.num_filters,
            (3, 3),
            kernel_initializer='he_normal',
            padding='same',
            use_bias=False
        )
        self.activation_2 = tf.keras.layers.ReLU()

        self.batch_norm = tf.keras.layers.BatchNormalization()
        self.pooling = tf.keras.layers.MaxPooling2D((2, 2))
        self.dropout = tf.keras.layers.Dropout(0.1)

        super().build(input_shape)

    def call(self, inputs, *args, **kwargs):
        conv = self.conv_1(inputs)
        conv = self.activation_1(conv)

        conv = self.conv_2(conv)
        conv = self.activation_2(conv)

        if self.use_pooling:
            pool = self.pooling(conv)
            pool = self.dropout(pool)
        else:
            pool = None

        return conv, pool


class UnetDecoderBlock(tf.keras.layers.Layer):
    def __init__(self, num_filters, concatenate_with=None):
        super().__init__()

        self.num_filters = num_filters
        self.concatenate_with = concatenate_with if concatenate_with else []

    def build(self, input_shape):
        self.conv_transpose = tf.keras.layers.Conv2DTranspose(
            self.num_filters,
            (3, 3),
            padding='same',
            strides=(2, 2),
            kernel_initializer='he_normal',
            use_bias=False
        )
        self.weights_concat = tf.keras.layers.Concatenate()
        self.dropout = tf.keras.layers.Dropout(0.1)

        self.conv_1 = tf.keras.layers.Conv2D(
            self.num_filters,
            (3, 3),
            kernel_initializer='he_normal',
            padding='same',
            use_bias=False
        )
        self.activation_1 = tf.keras.layers.ReLU()

        self.conv_2 = tf.keras.layers.Conv2D(
            self.num_filters,
            (3, 3),
            kernel_initializer='he_normal',
            padding='same',
            use_bias=False
        )
        self.activation_2 = tf.keras.layers.ReLU()

        self.batch_norm = tf.keras.layers.BatchNormalization()

        super().build(input_shape)

    def call(self, inputs, *args, **kwargs):
        unfl = self.conv_transpose(inputs)
        unfl = self.weights_concat([unfl, *self.concatenate_with])
        unfl = self.dropout(unfl)

        conv = self.conv_1(unfl)
        conv = self.activation_1(conv)

        conv = self.conv_2(conv)
        conv = self.activation_2(conv)

        conv = self.batch_norm(conv)

        return conv



Однако, при создании модели с этими слоями выдает ошибку:
model_input = tf.keras.layers.Input(input_shape)

conv_1, pool_1 = UnetEncoderBlock(16)(model_input)  # 256x256 -> 128x128
conv_2, pool_2 = UnetEncoderBlock(32)(pool_1)  # 128x128 -> 64x64
conv_3, pool_3 = UnetEncoderBlock(64)(pool_2)  # 64x64 -> 32x32
conv_4, pool_4 = UnetEncoderBlock(128)(pool_3)  # 32x32 -> 16x16

conv_5, _ = UnetEncoderBlock(256, use_pooling=False)(pool_4)

conv_6 = UnetDecoderBlock(128, concatenate_with=[conv_4])(conv_5)  # 16x16 -> 32x32
conv_7 = UnetDecoderBlock(64, concatenate_with=[conv_3])(conv_6)  # 32x32 -> 64x64
conv_8 = UnetDecoderBlock(32, concatenate_with=[conv_2])(conv_7)  # 64x64 -> 128x128
conv_9 = UnetDecoderBlock(16, concatenate_with=[conv_1])(conv_8)  # 128x128 -> 256x256

model_output = tf.keras.layers.Conv2D(1, (1, 1))(conv_9)
model_output = tf.keras.layers.Activation('sigmoid')(model_output)

model = tf.keras.models.Model(inputs=[model_input], outputs=[model_output], name='Unet')

TypeError: Could not build a TypeSpec for KerasTensor(type_spec=TensorSpec(shape=(None, 32, 32, 128), dtype=tf.float32, name=None), name='batch_normalization/FusedBatchNormV3:0', description="created by layer 'batch_normalization'") of unsupported type <class 'keras.engine.keras_tensor.KerasTensor'>.

Full traceback

Traceback (most recent call last):
  File "C:\Users\yahry\PycharmProjects\lesa_niisva\tests\tests.py", line 48, in <module>
    model = build_unet()
  File "C:\Users\yahry\PycharmProjects\lesa_niisva\lesa\models\models.py", line 263, in build_unet
    conv_6 = UnetDecoderBlock(128, concatenate_with=[conv_4])(conv_5)  # 16x16 -> 32x32
  File "C:\Users\yahry\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\utils\traceback_utils.py", line 61, in error_handler
    return fn(*args, **kwargs)
  File "C:\Users\yahry\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\base_layer.py", line 1058, in __call__
    return self._functional_construction_call(
  File "C:\Users\yahry\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\base_layer.py", line 2572, in _functional_construction_call
    outputs = self._keras_tensor_symbolic_call(
  File "C:\Users\yahry\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\base_layer.py", line 2419, in _keras_tensor_symbolic_call
    return self._infer_output_signature(
  File "C:\Users\yahry\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\base_layer.py", line 2484, in _infer_output_signature
    outputs = tf.nest.map_structure(
  File "C:\Users\yahry\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\tensorflow\python\util\nest.py", line 917, in map_structure
    structure[0], [func(*x) for x in entries],
  File "C:\Users\yahry\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\tensorflow\python\util\nest.py", line 917, in <listcomp>
    structure[0], [func(*x) for x in entries],
  File "C:\Users\yahry\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\keras_tensor.py", line 663, in keras_tensor_from_tensor
    out = keras_tensor_cls.from_tensor(tensor)
  File "C:\Users\yahry\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\keras\engine\keras_tensor.py", line 199, in from_tensor
    type_spec = tf.type_spec_from_value(tensor)
  File "C:\Users\yahry\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\tensorflow\python\framework\type_spec.py", line 958, in type_spec_from_value
    raise TypeError(f"Could not build a TypeSpec for {value} of "
TypeError: Could not build a TypeSpec for KerasTensor(type_spec=TensorSpec(shape=(None, 32, 32, 128), dtype=tf.float32, name=None), name='batch_normalization/FusedBatchNormV3:0', description="created by layer 'batch_normalization'") of unsupported type <class 'keras.engine.keras_tensor.KerasTensor'>.



Не понимаю что не так, вроде делал всё по официальному гайду (https://www.tensorflow.org/guide/keras/making_new_...).
  • Вопрос задан
  • 118 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы