Как назначить класс tf.keras.layers.layer без его инициализации? - PullRequest
1 голос
/ 03 мая 2019

Я работаю над классом для создания всевозможных симметричных АЕ. Сейчас я портирую этот класс на TF 2.0, и он сложнее, чем я думал. Тем не менее, я использую подклассы слоев и моделей для достижения этой цели. Поэтому я хочу сгруппировать несколько слоев керас в один слой керас. Но если я хочу написать что-то вроде этого:

def __init__(self, name, keras_layer, **kwargs):
    self.keras_layer = tf.keras.layer.Conv2D
    super(CoderLayer, self).__init__(name=name, **kwargs)

Я получаю следующую ошибку, потому что tf хочет использовать этот неинициализированный слой:

TypeError: _method_wrapper() missing 1 required positional argument: 'self'

Я также пытался обернуть это в список, но это тоже не сработало.

EDIT

Вот работающий минимальный пример и полный возврат:

import tensorflow as tf
print(tf.__version__) # 2.0.0-alpha0

class CoderLayer(tf.keras.layers.Layer):

    def __init__(self, name, keras_layer):
        self.keras_layer = keras_layer
        self.out = keras_layer(12, [3, 3])
        super(CoderLayer, self).__init__(name=name)

    def call(self, inputs):
        return self.out(inputs)

inputs = tf.keras.Input(shape=(200, 200, 3), batch_size=12)
layer = CoderLayer("minimal_example", tf.keras.layers.Conv2D)

layer(inputs)

Traceback:

Traceback (most recent call last):
  File "..\baseline_cae.py", line 24, in <module>
    layer(inputs)
  File "..\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 581, in __call__
    self._clear_losses()
  File "..\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\training\tracking\base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "..\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 818, in _clear_losses
    layer._clear_losses()
TypeError: _method_wrapper() missing 1 required positional argument: 'self'

1 Ответ

1 голос
/ 03 мая 2019

Проблема в том, что в качестве атрибута для подкласса tf.keras.layers.Layer задан не экземплярный экземпляр класса. Если удалить следующую строку

self.keras_layer = keras_layer

код будет работать:

import tensorflow as tf

class CoderLayer(tf.keras.layers.Layer):
    def __init__(self, name, keras_layer):
        super(CoderLayer, self).__init__(name=name)
        self.out = keras_layer(12, [3, 3])

    def call(self, inputs):
        return self.out(inputs)

inputs = tf.keras.Input(shape=(200, 200, 3), batch_size=12)
layer = CoderLayer("minimal_example", tf.keras.layers.Conv2D)
print(layer(inputs))
# Tensor("minimal_example_3/conv2d_12/BiasAdd:0", shape=(12, 198, 198, 12), dtype=float32)

Вероятно, это ошибка. Эта - похожая проблема, которая была поднята (если вы поместите свой неинстанцированный класс в список и попытаетесь __setattr__(), вы получите то же исключение).

Это может быть возможным обходным решением, если вы хотите использовать несколько слоев:

class CoderLayer(tf.keras.layers.Layer):
    def __init__(self, name, layername):
        super(CoderLayer, self).__init__(name=name)
        self.layer = layername
        self.out = tf.keras.layers.__dict__[layername](1, 2)

    def call(self, inputs):
        return self.out(inputs)

inputs = tf.random.normal([1, 3, 3, 1])
layer = CoderLayer("mylayer", 'Conv2D')
layer(inputs).numpy()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...