TensorFlow 2.0 - Создание подкласса модели: без входного измерения
Я читал учебник TensorFlow 2.0 и наткнулся на создание подклассов моделей для создания моделей TensorFlow 2.0.
Код, который я нашел, был:
class MyModel(Model):
def __init__(self):
super(MyModel, self).__init__()
self.conv1 = Conv2D(32, 3, activation='relu')
self.flatten = Flatten()
self.d1 = Dense(128, activation='relu')
self.d2 = Dense(10, activation='softmax')
def call(self, x):
x = self.conv1(x)
x = self.flatten(x)
x = self.d1(x)
return self.d2(x)
# Create an instance of the model
model = MyModel()
В этом коде меня беспокоит то, что автор кода не определяет входы?
Здесь нет-
self.input_layer = Input(
shape = (28, 28)
)
# OR-
self.conv1 = Conv2D(32, 3, activation='relu', input_dim = (28, 28)
Каким образом определенная модель узнает, сколько атрибутов / функций ожидать от обучающих данных?
Спасибо
2 ответа
По словам Франсуа Шоле, ответ на ваш вопрос следующий (при сравнении (функциональный + последовательный и модельный API):
Вы можете делать все это (печатать фигуры ввода / вывода) в функциональной или последовательной модели, потому что эти модели представляют собой статические графики слоев.
Напротив, модель с подклассом - это часть кода Python (метод вызова). Графики слоев здесь нет. Мы не можем знать, как слои связаны друг с другом (потому что это определено в теле вызова, а не как явная структура данных), поэтому мы не можем вывести формы ввода / вывода
Более подробное объяснение этих трех типов доступно здесь: https://medium.com/tensorflow/what-are-symbolic-and-imperative-apis-in-tensorflow-2-0-dfccecb01021
Пример того, как вы все еще можете достичь этого, смешивая API функционального + модельного подкласса, находится здесь (кредиты ixez на GitHub):
import tensorflow as tf
from tensorflow.keras.layers import Input
class MyModel(tf.keras.Model):
def __init__(self):
super().__init__()
self.dense = tf.keras.layers.Dense(1)
def call(self, inputs, **kwargs):
return self.dense(inputs)
def model(self):
x = Input(shape=(1))
return Model(inputs=[x], outputs=self.call(x))
MyModel().model().summary()
В tensorflow/keras модель представляет собой последовательность слоев, которая может служить подблоком для более сложных сетей. Основное понятие здесь — повторение.
Однако для большинства библиотек машинного обучения модель — это алгоритм, который принимает входные данные, обрабатывает их и генерирует выходные данные (ну, это алгоритм!), которые должны быть связаны с входными данными посредством теории принятия решений. По существу, его можно обучить и протестировать на заданном наборе данных или, по крайней мере, с использованием предписаний для набора данных (например, размера и типа данных). Основная идея заключается в рендеринге статического кода.
Таким образом, эти две концепции (рекуррентное построение и статическое построение) в каком-то смысле несовместимы, но можно найти обходной путь. То, как я это сделал, обобщено в приведенном ниже примере.
class MultiLayerPerceptron(Model):
def __init__(
self,
d_input: int = 32,
d_hidden: int = 64,
d_output: int = 16,
dropout: float = 0.0):
self.d_input = int(d_input)
self.d_hidden = int(d_hidden)
self.d_output = int(d_output)
self.dropout = float(dropout)
inputs = Input(shape=(self.d_input,), name='input')
x = Dense(self.d_hidden, activation='relu', name='hidden')(inputs)
x = Dropout(self.dropout, name='dropout')(x)
outputs = Dense(self.d_output, activation='sigmoid', name='output')(x)
super().__init__(inputs=inputs, outputs=outputs)
loss_function = tf.keras.losses.BinaryCrossentropy(from_logits=False)
optimizer = tf.keras.optimizers.Adam()
super().compile(
optimizer=optimizer, loss=loss_function, metrics=['accuracy'])
return None
def predict(self, x):
y = super().predict(x)
return tf.round(y).numpy().astype(int)
def transform(self, x):
return self(x)
что, я надеюсь, достаточно ясно. Я просто отложил звонок
Тем не менее, обратите внимание, что
- здесь утеряна рекуррентная стратегия, потому что Вход дан раз и навсегда
- можно использовать большинство основных
методы, как подходят, оценивают, прогнозируют,... но не сохраняют, это уже другая история
В любом случае, для простых моделей (в терминологии keras/recurrent) проще использовать функциональный API. Если вам нужно настроить слои, просто создайте собственные слои , а не модель , которые все равно можно создать на функциональном уровне API.