Почему вы должны изменить входные данные в Keras / Tensorflow 2?

У меня простая сеть:

input_layer = Input(1)
inner_layer = Dense(4, activation='relu')(input_layer)
output_layer = Dense(1, activation='linear')(inner_layer)
model = Model(input_layer, output_layer)
optimizer = Adam(learning_rate=0.01)
model.compile(optimizer=optimizer, loss='mse')

Интуитивно model.predict(0) , что вывод для ввода 0 будет просто model.predict(0) . Однако это генерирует эту ошибку: expected input_2 to have 2 dimensions, but got array with shape ()

Я понимаю, что ожидается, что вход (который является одним числом) будет двухмерным, но я не понимаю, что Tensorflow принимает в качестве допустимого ввода. Я перепробовал много разных комбинаций входных данных, некоторые из них работают, а некоторые нет, это кажется довольно противоречивым, и предупреждения / ошибки обычно бесполезны:

При вызове model.predict() :

  • model.predict(0) - броски
  • model.predict([0]) - Работы
  • model.predict([[0]]) - Работы

При вызове model() ( здесь я увидел, что нужно получить градиенты):

  • model(0) - броски
  • model([0]) - броски
  • model([[0]]) - броски

При использовании np.reshape :

  • model(np.reshape(0,[1,1])) - Работы
  • model(np.reshape([0],[1,1])) - Работы
  • model(np.reshape([[0]],[1,1])) - Работы

То, что работает последовательно, использует функцию reshape numpy. он всегда работает как для model.predict() и для model() на всех входах, если они преобразуются в форму [1,1] .

Мои вопросы:

  1. Каковы рекомендации по вводу входных данных в модели тензорного потока в отношении форм / типов входных данных?
  2. Что означает « shape () »?
  3. Что значит " (None, 1) "?
  4. Почему reshape работает, но [[0]] нет? Оба создают 2-мерную коллекцию.
  5. Почему при вызове model(0) / model([0]) / model([[0]]) отображается это предупреждение: WARNING:tensorflow:Model was constructed with shape Tensor("input_1:0", shape=(None, 1), dtype=float32) for input (None, 1), but it was re-called on a Tensor with incompatible shape () ?

Всего 1 ответ


Форма тензора inputs = tf.keras.layers.Input(1) имеет вид (None, 1) (запустите inputs.get_shape().as_list() ). None означает любой размер, который определяется динамически (размер партии). 1 - это форма вашей точки данных. Например, это тензор формы (3, 1) :

[[1], [2], [1]]

Это тензор формы (3,)

[1, 2, 1]

Если вы определяете тензор формы (None, 1) вы должны передавать данные той же формы.

[[0]] имеет правильную форму (1, 1) и не будет выдавать никаких ошибок или предупреждений, если вы передадите его в виде массива ожидаемого типа данных:

import tensorflow as tf
import numpy as np

input_layer = tf.keras.layers.Input(1)
inner_layer = tf.keras.layers.Dense(4, activation='relu')(input_layer)
output_layer = tf.keras.layers.Dense(1, activation='linear')(inner_layer)
model = tf.keras.models.Model(input_layer, output_layer)
optimizer = tf.keras.optimizers.Adam(learning_rate=0.01)
model.compile(optimizer=optimizer, loss='mse')
print(model(np.array([[0.]], dtype=np.float32)).numpy()) # [[0.]]
print(model.predict(np.array([[0.], [1]], dtype=np.float32))) # [[0.        ]
                                                              # [0.08964952]]

np.reshape() работает, потому что он автоматически преобразует ваш список в массив numpy. Подробнее о np.reshape см. В официальной документации .

model.predict() также ожидает ту же форму, что и model.__call__() , но может выполнять автоматическое изменение формы (расширение размера слева, т.е. [1] -- > [[1]] ).


Есть идеи?

10000