Формы ввода Tensorflow несовместимы

#python #tensorflow

#python #tensorflow

Вопрос:

Пытаюсь построить модель Tensorflow, в которой мои данные содержат 70 функций. Вот настройка моего первого слоя:

tf.keras.layers.Dense(units=50, activation='relu', input_shape=(None,70)),

Установка формы ввода на (None,70) показалась мне лучшей, поскольку я использую нейронную сеть прямой связи, где каждая «строка» данных уникальна. Я использую размер пакета (на данный момент) размером 10. Должна ли моя форма ввода измениться на (10,70) ??

Я пробовал с оригиналом (None, 70) и получил ошибку:

 WARNING:tensorflow:Model was constructed with shape (None, None, 70) for input Tensor("dense_33_input:0", shape=(None, None, 70), dtype=float32), but it was called on an input with incompatible shape (10, 70).

TypeError: Input 'y' of 'Mul' Op has type float64 that does not match type float32 of argument 'x'.
  

Совершенно запутался в том, что именно происходит не так с input_shape as (None, 70) , похоже, подходит лучше всего. Любая помощь очень ценится.

Редактировать: хотел добавить воспроизводимый пример для большего контекста. Извините за длину. Это воспроизведение [этого примера] [1], чтобы лучше соответствовать моим текущим данным (не изображениям).

Вариационная модель автоэнкодера

 class VAE(tf.keras.Model):
    
    def __init__(self, latent_dim):
        super(VAE, self).__init__()
        self.latent_dim = latent_dim
        self.encoder = tf.keras.Sequential(
        [
            tf.keras.layers.Dense(units=50, activation='relu', input_shape=(70,)),
            tf.keras.layers.Dense(latent_dim   latent_dim), #No activation
        ])
        
        self.decoder = tf.keras.Sequential(
        [
            tf.keras.layers.Dense(units=50, activation='relu', input_shape=(latent_dim,)),
            tf.keras.layers.Dense(units=70),
        ])
        
    @tf.function
    def sample(self, eps=None):
        if eps is None:
            eps = tf.random.normal(shape=(100, self.latent_dim))
        return self.decode(eps, apply_sigmoid=True)

    def encode(self, x):
        mean, logvar = tf.split(self.encoder(x), num_or_size_splits=2, axis=1)
        return mean, logvar

    def reparameterize(self, mean, logvar):
        eps = tf.random.normal(shape=mean.shape)
        return eps * tf.exp(logvar * .5)   mean

    def decode(self, z, apply_sigmoid=False):
        logits = self.decoder(z)
        if apply_sigmoid:
            probs = tf.sigmoid(logits)
            return probs
        return logits


  [1]: https://www.tensorflow.org/tutorials/generative/cvae
  

Функция оптимизации и потери

 optimizer = tf.keras.optimizers.Adam(1e-4)

def log_normal_pdf(sample, mean, logvar, raxis=1):
    log2pi = tf.math.log(2. * np.pi)
    return tf.reduce_sum(
        -.5 * ((sample - mean) ** 2. * tf.exp(-logvar)   logvar   log2pi), axis=raxis)

def compute_loss(model, x):
    mean, logvar = model.encode(x)
    z = model.reparameterize(mean, logvar)
    x_logit = model.decode(z)
    cross_ent = tf.nn.sigmoid_cross_entropy_with_logits(logits=x_logit, labels=x)
    logpx_z = -tf.reduce_sum(cross_ent, axis=[1])
    logpz = log_normal_pdf(z, 0, 0)
    logqz_x = log_normal_pdf(z, mean, logvar)
    return -tf.reduce_mean(logpx_z   logpz - logqz_x)

@tf.function
def train_step(model, x, optimizer):
    with tf.GradientTape() as tape:
        loss = compute_loss(model, x)
    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  

Поезд

 X = tf.random.uniform((100,70))
y = tf.random.uniform((100,))

ds_train = tf.data.Dataset.from_tensor_slices((X, y))

tf.random.set_seed(1)

train = ds_train.shuffle(buffer_size=len(X))
train = train.batch(batch_size=10, drop_remainder=False)

epochs = 5
latent_dim = 2

model = VAE(2)

for epoch in range(1, epochs 1):
    start_time = time.time()
    for i, (train_x, train_y) in enumerate(train):
        train_step(model, train_x, optimizer)
    end_time = time.time()
    
    loss = tf.keras.metrics.Mean()
    for i, (test_x, test_y) in enumerate(ds_test):
        loss(compute_loss(model, test_x))
    elbo = -loss.result()
    display.clear_output(wait=False)
    print('Epoch: {}, Test set ELBO: {}, time elapse for current epoch: {}'
         .format(epoch, elbo, end_time - start_time))
  

Комментарии:

1. Не могли бы вы, пожалуйста, определить X_train и y_train ?

2. Извините … должно быть исправлено сейчас. y в этом примере нет необходимости.

3. Я не могу воспроизвести эту ошибку в вашем примере, и я столкнулся с другими ошибками. Не могли бы вы исправить свой пример? Попробуйте запустить его в новом интерпретаторе Python (переменные еще не определены). Без примера будет сложно помочь.

4. @jakub только что внес незначительные изменения в y и ось в reduce_sum. Должно быть с той же ошибкой, что и у меня

5. Спасибо. Можете ли вы попробовать изменить logpz = log_normal_pdf(z, 0., 0.) на logpz = log_normal_pdf(z, 0., 0.) ? Это приведет к тому, что эти нули будут плавающими вместо целых чисел. Я столкнулся с ошибкой, которая tf.exp не может принять int32.

Ответ №1:

input_shape Не должно включать измерение пакета. Используйте input_shape=(70,) .

 tf.keras.layers.Dense(units=50, activation='relu', input_shape=(70,))
  

Вы можете установить размер пакета при вызове model.fit(..., batch_size=10) . Смотрите документацию по tf.keras.Model.fit .

В исходном сообщении была еще одна ошибка из-за передачи int32 значения tf.math.exp . Эта строка должна гласить

 logpz = log_normal_pdf(z, 0., 0.)
  

чтобы устранить эту ошибку. Обратите внимание на 0. значения, которые оцениваются как значения с плавающей точкой вместо целых чисел.

Комментарии:

1. Все еще получаю последнюю ошибку: TypeError: Input 'y' of 'Mul' Op has type float64 that does not match type float32 of argument 'x'. Могу поделиться дополнительным кодом, если это полезно…

2. Да, пожалуйста, обновите свой пост минимальным, воспроизводимым примером.

3. Только что сделал … дайте мне знать ваши мысли. Спасибо