0

我在使用中的steps_per_epoch参数时遇到问题model.fit。据我所知,steps_per_epoch 用于在多次迭代后(即向模型提供多个批次后)记录指标,如损失函数。因此,在训练时,我们能够在几次迭代后看到损失,而不必等到 epoch 结束才能显示损失。因此,如果我有一个小数据,那么我的模型将从几个时期学习一个模式。因此,我有兴趣查看模型在 n 次迭代后的行为。

首先,请注意我有 tensorflow 版本 2.3.0

这是数据预处理逻辑(这是为时间序列数据定制的)。

window_size = 42
batch_size  = 32
forecast_period = 3

def _sub_to_batch(sub):
    return sub.batch(window_size, drop_remainder=True)

def _return_input_output(tensor):
    _input  = tensor[:, :-forecast_period, :]
    _output = tensor[:, forecast_period:, :]
    return _input, _output

def _reshape_tensor(tensor):
    tensor = tf.expand_dims(tensor, axis=-1)
    tensor = tf.transpose(tensor, [1, 0, 2])
    return tensor

# total elements after unbatch(): 3813
train_ts_dataset = tf.data.Dataset.from_tensor_slices(train_ts)\
                            .window(window_size, shift=1)\
                            .flat_map(_sub_to_batch)\
                            .map(_reshape_tensor)\
                            .unbatch().shuffle(buffer_size=500).batch(batch_size)\
                            .map(_return_input_output)

valid_ts_dataset = tf.data.Dataset.from_tensor_slices(valid_ts)\
                            .window(window_size, shift=1)\
                            .flat_map(_sub_to_batch)\
                            .map(_reshape_tensor)\
                            .unbatch().shuffle(buffer_size=500).batch(batch_size)\
                            .map(_return_input_output)


for i, (x, y) in enumerate(train_ts_dataset):
    print(i, x.numpy().shape, y.numpy().shape)

和输出:

0 (32, 39, 1) (32, 39, 1)
1 (32, 39, 1) (32, 39, 1)
2 (32, 39, 1) (32, 39, 1)
3 (32, 39, 1) (32, 39, 1)
4 (32, 39, 1) (32, 39, 1)
5 (32, 39, 1) (32, 39, 1)
6 (32, 39, 1) (32, 39, 1)
7 (32, 39, 1) (32, 39, 1)
8 (32, 39, 1) (32, 39, 1)
9 (32, 39, 1) (32, 39, 1)
10 (32, 39, 1) (32, 39, 1)
11 (32, 39, 1) (32, 39, 1)
12 (32, 39, 1) (32, 39, 1)
13 (32, 39, 1) (32, 39, 1)
14 (32, 39, 1) (32, 39, 1)
15 (32, 39, 1) (32, 39, 1)
16 (32, 39, 1) (32, 39, 1)
17 (32, 39, 1) (32, 39, 1)
18 (32, 39, 1) (32, 39, 1)
19 (32, 39, 1) (32, 39, 1)
20 (32, 39, 1) (32, 39, 1)
21 (32, 39, 1) (32, 39, 1)
22 (32, 39, 1) (32, 39, 1)
23 (32, 39, 1) (32, 39, 1)
24 (32, 39, 1) (32, 39, 1)
25 (32, 39, 1) (32, 39, 1)
26 (29, 39, 1) (29, 39, 1)

因此,我可以看出我的数据集总共包含 27 个批次,每个批次包含 29-32 个形状为 (32, 39, 1), (32, 39, 1) 的元素。

至于型号:

import datetime

tf.keras.backend.clear_session()

time_steps = x_train.shape[1]

def _custom_mae(y_pred, y_true):
    _y_pred = y_pred[-forecast_period:, :]
    _y_true = y_true[-forecast_period:, :]
    mae = tf.losses.MAE(_y_true, _y_pred)
    return mae

model = k.models.Sequential([
#     k.layers.Bidirectional(k.layers.LSTM(units=100, return_sequences=True), input_shape=(None, 1)),
    k.layers.Conv1D(256, 16, strides=1, padding='same', input_shape=(None, 1)),
    k.layers.Conv1D(128, 16, strides=1, padding='same'),
    k.layers.TimeDistributed(k.layers.Dense(1))
])

_datetime = datetime.datetime.now().strftime("%Y%m%d-%H-%M-%S")
_log_dir = os.path.join(".", "logs", "fit4", _datetime)

tensorboard_cb = k.callbacks.TensorBoard(log_dir=_log_dir)

model.compile(loss="mae", optimizer=tf.optimizers.Adam(learning_rate=0.01), metrics=[_custom_mae])

# , validation_data=valid_ts_dataset
history = model.fit(train_ts_dataset, steps_per_epoch=12, epochs=1, callbacks=[tensorboard_cb])

我得到以下输出:

所以,我可以说我在一个真实的纪元中有 12 个虚拟纪元。

在此处输入图像描述

但是,经过调查,history.history我得到了以下信息:

在此处输入图像描述

但是,我希望看到每个 theloss和 the的 12 个值的列表_custom_mae

最后,我很想在 tensorboard 中看到结果。

请让我知道我缺少什么以及如何解决我的问题。

提前感谢您的支持!

4

1 回答 1

0

来自 keras 文档

steps_per_epoch:整数或无。在宣布一个时期完成并开始下一个时期之前的步骤总数(样本批次)。当使用输入张量(例如 TensorFlow 数据张量)进行训练时,默认的 None 等于数据集中的样本数除以批量大小,如果无法确定,则为 1。如果 x 是 tf.data 数据集,并且 'steps_per_epoch' 为 None,则 epoch 将运行直到输入数据集耗尽。传递无限重复数据集时,您必须指定 steps_per_epoch 参数。数组输入不支持此参数。

所以我认为你正在寻找的是回调,就像 tensorard_cb 一样,我为你写了一个回调,它将在每批之间运行,你可以在这里找到回调的全部可能性https://keras.io/指南/writing_your_own_callbacks/#a-basic-example

logdir = "logs/scalars/" + datetime.now().strftime("%Y%m%d-%H%M%S")
file_writer = tf.summary.create_file_writer(logdir + "/metrics")
file_writer.set_as_default()

class CustomCallback(tf.keras.callbacks.Callback):
    def on_train_batch_end(self, batch, logs=None):
        print("For batch {}, _custom_mae is {:7.2f}.".format(batch, logs["_custom_mae"]))
        tf.summary.scalar('_custom_mae rate', data=logs["_custom_mae", step=epoch)


可以这样使用

tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir)


history = model.fit(train_ts_dataset,
 steps_per_epoch=12,
 epochs=1,
 callbacks=[tensorboard_callback, CustomCallback()])

然后运行张量板

%tensorboard --logdir logs/scalars

更多信息在这里

于 2020-11-05T16:48:41.983 回答