我给出了以下运行良好的代码。
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 中删除了批量大小,所以可以工作。
在
tf.data.Dataset
中使用 model.fit
时,您应该仅提供 x
的 model.fit
参数,假设您的 tf.data.Dataset
返回一个元组 (input_features, targets)
.
您可以在keras.Model.fit
Args
:输入数据。可能是:x
数据集。应该返回 (inputs, targets) 或 (inputs, targets, sample_weights) 的元组。tf.data
:如果 x 是数据集、生成器或y
实例,则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)))
您遇到的问题是由于输入数据与模型预期的形状不匹配。当您在准备函数中使用 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 参数确保数据集以正确的形状进行批处理。