Input 0 is incompatible with layer when using dataset.batch

问题描述 投票:0回答:2

我给出了以下运行良好的代码。

import tensorflow as tf
import numpy as np
from tensorflow.keras.layers import Input, Dense, Reshape, Dropout, \
    BatchNormalization, Activation, Conv2D, Conv2DTranspose, LeakyReLU
from tensorflow.keras.models import Model

AUTOTUNE = tf.data.experimental.AUTOTUNE
HEIGHT = 39
WIDTH = 39
CHANNELS = 2
SCALE_FACTOR = 4
VAL_SPLIT = 0.1
TRAIN_SPLIT = 0.8
TEST_SPLIT = 0.1
SEED = 1
BUFFER_SIZE = 100
LR = 1e-4
BATCH_SIZE = 2

INP_LOW = (HEIGHT, WIDTH, CHANNELS)

gpus = tf.config.experimental.list_physical_devices('GPU')
for gpu in gpus:
    tf.config.experimental.set_memory_growth(gpu, True)
    
    
def resize_and_rescale(low, high):

    high = tf.image.resize(high, 
                           (HEIGHT, WIDTH),
                           preserve_aspect_ratio=False)
    return low, high


def split_train_test_val(ds,
                         seed,
                         train_split=TRAIN_SPLIT, 
                         val_split=VAL_SPLIT, 
                         test_split=TEST_SPLIT,
                         shuffle=True, 
                         shuffle_size=BUFFER_SIZE):                       
    assert (train_split + test_split + val_split) == 1
    
    ds_size = len(ds)
    if shuffle:
        ds = ds.shuffle(shuffle_size, 
                        reshuffle_each_iteration=False,
                        seed=seed)
    
    train_size = int(train_split * ds_size)
    val_size = int(val_split * ds_size)
    test_size = int(test_split * ds_size)
    
    train_ds = ds.take(train_size)
    test_ds = ds.skip(train_size)
    val_ds = test_ds.skip(test_size)
    test_ds = test_ds.take(test_size)
    
    return train_ds, val_ds, test_ds

def prepare(ds, shuffle=False):
    
    ds = ds.map(resize_and_rescale, num_parallel_calls=AUTOTUNE)
    ds = ds.cache()
    if shuffle:
        ds = ds.shuffle(buffer_size=BUFFER_SIZE)
  
    #ds = ds.batch(BATCH_SIZE)
    #ds = ds.prefetch(buffer_size=AUTOTUNE)
   
    return ds

def data_gen(low_res, high_res):
    
    dataset_low = tf.data.Dataset.from_tensor_slices(low_res)
    dataset_high = tf.data.Dataset.from_tensor_slices(high_res)
    
    dataset = tf.data.Dataset.zip((dataset_low, dataset_high))
    
    train_ds, val_ds, test_ds = split_train_test_val(dataset,
                                                     SEED,
                                                     train_split=TRAIN_SPLIT, 
                                                     val_split=VAL_SPLIT, 
                                                     test_split=TEST_SPLIT,
                                                     shuffle=True, 
                                                     shuffle_size=BUFFER_SIZE)

   
    train_ds = prepare(train_ds, shuffle=True)
    val_ds = prepare(val_ds)
    test_ds = prepare(val_ds)
    return train_ds, val_ds, test_ds


def build_model(lr):
    inp = Input(lr)
    x = Dense(16)(inp)
    x = Conv2DTranspose(CHANNELS, kernel_size=3, strides=1, padding='same')(x)
    output = Activation('tanh')(x)
    model = Model(inp, output)
    return model


low = np.load('low.npy')
high = np.load('high.npy')

train_ds, val_ds, test_ds = data_gen(low, high)

model = build_model(INP_LOW)
model.compile(loss=['mse'],
              optimizer= tf.keras.optimizers.Adam(learning_rate=LR))

train_low, train_high = tf.data.experimental.get_single_element(train_ds.batch(len(train_ds)))

history = model.fit(train_low,
                    train_high,
                    epochs=2,
                    batch_size=BATCH_SIZE)
              

但是当我尝试使用时:

 ds = ds.batch(BATCH_SIZE)
  ds = ds.prefetch(buffer_size=AUTOTUNE)

prepare
函数中,同时,我省略了
batch_size
in fit:

history = model.fit(train_low,
                    train_high,
                    epochs=2)

我收到:

ValueError: Input 0 is incompatible with layer model_2: expected shape=(None, 39, 39, 2), found shape=(32, 2, 39, 39, 2)

你可以在这里找到数据

我希望,因为我从 fit 中删除了批量大小,所以可以工作。

python-3.x tensorflow deep-learning tensorflow2.0
2个回答
1
投票

tf.data.Dataset
中使用
model.fit
时,您应该仅提供
x
model.fit
参数,假设您的
tf.data.Dataset
返回一个元组
(input_features, targets)
.

您可以在keras.Model.fit

文档中阅读更多内容。以下是相关信息的摘录:

Args

  • x
    :输入数据。可能是:

    • tf.data
      数据集。应该返回 (inputs, targets) 或 (inputs, targets, sample_weights) 的元组。
  • y
    :如果 x 是数据集、生成器或
    keras.utils.Sequence
    实例,则
    y
    不应指定(因为目标将从
    x
    获得)。

假设

train_high
是你的输入特征,
train_low
是你的目标,你应该简单地调用
model.fit(train_ds, epochs=2)
,并跳过这行

train_low, train_high = tf.data.experimental.get_single_element(train_ds.batch(len(train_ds)))

0
投票

您遇到的问题是由于输入数据与模型预期的形状不匹配。当您在准备函数中使用 ds.batch(BATCH_SIZE) 和 ds.prefetch(buffer_size=AUTOTUNE) 时,数据集的形状会发生变化。在您的情况下,形状变为 (32, 2, 39, 39, 2) 而不是预期的 (None, 39, 39, 2)。 要解决此问题,您需要修改 prepare 函数以正确批处理数据集。用以下内容替换注释行:

ds = ds.batch(BATCH_SIZE, drop_remainder=True)
ds = ds.prefetch(buffer_size=AUTOTUNE)

drop_remainder=True 参数确保数据集以正确的形状进行批处理。

© www.soinside.com 2019 - 2024. All rights reserved.