在完成第一个纪元后,Tensorflow 无法将批次附加在一起
Tensorflow can't append batches together after doing the first epoch
我 运行 在删除 compile
步骤的损失函数(将其设置为 loss=None
)并添加一个以添加的目的后,我的代码出现了问题另一个,通过add_loss
方法损失函数。我可以调用 fit
并训练一个时期,但随后出现此错误:
ValueError: operands could not be broadcast together with shapes (128,) (117,) (128,)
我的批量大小是 128。看起来 117
在某种程度上取决于我使用的示例数量。当我改变示例的数量时,我从 117
得到不同的数字。它们都是我的示例数量 mod 我的批量大小。我不知道如何解决这个问题。我正在使用 tf.data.TFRecordDataset
作为输入。
我有以下简化的 model:
class MyModel(Model):
def __init__(self):
super(MyModel, self).__init__()
encoder_input = layers.Input(shape=INPUT_SHAPE, name='encoder_input')
x = encoder_input
x = layers.Conv2D(64, (3, 3), activation='relu', padding='same', strides=2)(x)
x = layers.BatchNormalization()(x)
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same', strides=2)(x)
x = layers.BatchNormalization()(x)
x = layers.Flatten()(x)
encoded = layers.Dense(LATENT_DIM, name='encoded')(x)
self.encoder = Model(encoder_input, outputs=[encoded])
self.decoder = tf.keras.Sequential([
layers.Input(shape=LATENT_DIM),
layers.Dense(32 * 32 * 32),
layers.Reshape((32, 32, 32)),
layers.Conv2DTranspose(32, kernel_size=3, strides=2, activation='relu', padding='same'),
layers.Conv2DTranspose(64, kernel_size=3, strides=2, activation='relu', padding='same'),
layers.Conv2D(3, kernel_size=(3, 3), activation='sigmoid', padding='same')])
def call(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
# Loss function. Has to be here because I intend to add another, more layer-interdependent, loss function.
r_loss = tf.math.reduce_sum(tf.math.square(x - decoded), axis=[1, 2, 3])
self.add_loss(r_loss)
return decoded
def read_tfrecord(example):
example = tf.io.parse_single_example(example, CELEB_A_FORMAT)
image = decode_image(example['image'])
return image, image
def load_dataset(filenames, func):
dataset = tf.data.TFRecordDataset(
filenames
)
dataset = dataset.map(partial(func), num_parallel_calls=tf.data.AUTOTUNE)
return dataset
def train_autoencoder():
filenames_train = glob.glob(TRAIN_PATH)
train_dataset_x_x = load_dataset(filenames_train[:4], func=read_tfrecord)
autoencoder = Autoencoder()
# The loss function used to be defined here and everything worked fine before.
def r_loss(y_true, y_pred):
return tf.math.reduce_sum(tf.math.square(y_true - y_pred), axis=[1, 2, 3])
optimizer = tf.keras.optimizers.Adam(1e-4)
autoencoder.compile(optimizer=optimizer, loss=None)
autoencoder.fit(train_dataset_x_x.batch(AUTOENCODER_BATCH_SIZE),
epochs=AUTOENCODER_NUM_EPOCHS,
shuffle=True)
如果您只想消除错误而不关心数据集的最后“剩余”批次,则可以在 train_dataset_x_x.batch()
中使用关键字参数 drop_remainder=True
,这样你所有的批次都会有相同的大小。
仅供参考,通常更好的做法是在 fit
:
的函数调用之外对数据集进行批处理
data = data.batch(32)
model.fit(data)
调用方法中不能设置损失函数。
call 方法旨在进行前向传递而不是计算损失。
你需要在编译方法中或之后添加损失函数
我 运行 在删除 compile
步骤的损失函数(将其设置为 loss=None
)并添加一个以添加的目的后,我的代码出现了问题另一个,通过add_loss
方法损失函数。我可以调用 fit
并训练一个时期,但随后出现此错误:
ValueError: operands could not be broadcast together with shapes (128,) (117,) (128,)
我的批量大小是 128。看起来 117
在某种程度上取决于我使用的示例数量。当我改变示例的数量时,我从 117
得到不同的数字。它们都是我的示例数量 mod 我的批量大小。我不知道如何解决这个问题。我正在使用 tf.data.TFRecordDataset
作为输入。
我有以下简化的 model:
class MyModel(Model):
def __init__(self):
super(MyModel, self).__init__()
encoder_input = layers.Input(shape=INPUT_SHAPE, name='encoder_input')
x = encoder_input
x = layers.Conv2D(64, (3, 3), activation='relu', padding='same', strides=2)(x)
x = layers.BatchNormalization()(x)
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same', strides=2)(x)
x = layers.BatchNormalization()(x)
x = layers.Flatten()(x)
encoded = layers.Dense(LATENT_DIM, name='encoded')(x)
self.encoder = Model(encoder_input, outputs=[encoded])
self.decoder = tf.keras.Sequential([
layers.Input(shape=LATENT_DIM),
layers.Dense(32 * 32 * 32),
layers.Reshape((32, 32, 32)),
layers.Conv2DTranspose(32, kernel_size=3, strides=2, activation='relu', padding='same'),
layers.Conv2DTranspose(64, kernel_size=3, strides=2, activation='relu', padding='same'),
layers.Conv2D(3, kernel_size=(3, 3), activation='sigmoid', padding='same')])
def call(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
# Loss function. Has to be here because I intend to add another, more layer-interdependent, loss function.
r_loss = tf.math.reduce_sum(tf.math.square(x - decoded), axis=[1, 2, 3])
self.add_loss(r_loss)
return decoded
def read_tfrecord(example):
example = tf.io.parse_single_example(example, CELEB_A_FORMAT)
image = decode_image(example['image'])
return image, image
def load_dataset(filenames, func):
dataset = tf.data.TFRecordDataset(
filenames
)
dataset = dataset.map(partial(func), num_parallel_calls=tf.data.AUTOTUNE)
return dataset
def train_autoencoder():
filenames_train = glob.glob(TRAIN_PATH)
train_dataset_x_x = load_dataset(filenames_train[:4], func=read_tfrecord)
autoencoder = Autoencoder()
# The loss function used to be defined here and everything worked fine before.
def r_loss(y_true, y_pred):
return tf.math.reduce_sum(tf.math.square(y_true - y_pred), axis=[1, 2, 3])
optimizer = tf.keras.optimizers.Adam(1e-4)
autoencoder.compile(optimizer=optimizer, loss=None)
autoencoder.fit(train_dataset_x_x.batch(AUTOENCODER_BATCH_SIZE),
epochs=AUTOENCODER_NUM_EPOCHS,
shuffle=True)
如果您只想消除错误而不关心数据集的最后“剩余”批次,则可以在 train_dataset_x_x.batch()
中使用关键字参数 drop_remainder=True
,这样你所有的批次都会有相同的大小。
仅供参考,通常更好的做法是在 fit
:
data = data.batch(32)
model.fit(data)
调用方法中不能设置损失函数。 call 方法旨在进行前向传递而不是计算损失。
你需要在编译方法中或之后添加损失函数