如何使用批处理的 tf 数据集对象训练 keras 函数 API 模型? (批处理数据集)

How to I train a keras functional API model with batched tf Dataset objects? (BatchDataset)

我正在使用函数 API 构建一个 tf keras 模型。该模型将在大内存映射数组上进行良好的训练。然而,出于多种原因,使用 tensorflow 数据集对象可能是有利的。因此,我使用 from_tensor_slices() 将我的数组转换为 Dataset 对象。 问题是模型将不再训练。

keras 文档:Model training APIs 表明数据集对象是可接受的。

我正在关注的有关如何训练的指南可在此处找到:Using tf.data with tf keras

关于如何使用 keras 功能 API 的指南是 here。但是,未概述使用 tf 数据集对象训练功能性 API 模型。

此处提供了一个 MWE:

import numpy as np
import tensorflow as tf
from tensorflow import keras
from keras import layers

print('numpy version: {}'.format(np.__version__))
print('keras version: {}'.format(keras.__version__))
print('tensorflow version: {}'.format(tf.__version__))

numpy version: 1.21.4
keras version: 2.6.0
tensorflow version: 2.6.0

X = np.random.uniform(size=(1000,75))
Y = np.random.uniform(size=(1000))

data = tf.data.Dataset.from_tensor_slices((X, Y))
print(data.cardinality().numpy())

1000

data.batch(batch_size=100, drop_remainder=True)

<BatchDataset shapes: ((100, 75), (100,)), types: (tf.float64, tf.float64)>

def API_Model(input_shape, name="test_model"):

    inputs = layers.Input(shape=input_shape)
    x = layers.Dense(1)(inputs)
    outputs = layers.Activation('relu')(x)

    return keras.Model(inputs=inputs, outputs=outputs, name=name)

api_model = API_Model(input_shape=(X.shape[1],))
api_model.compile()
api_model.summary()
Model: "test_model"
_________________________________________________________________  
Layer (type)                 Output Shape              Param #     
=================================================================  
input_2 (InputLayer)         [(None, 75)]              0           
_________________________________________________________________  
dense_1 (Dense)              (None, 1)                 76          
_________________________________________________________________  
activation_1 (Activation)    (None, 1)                 0           
=================================================================  
Total params: 76  
Trainable params: 76  
Non-trainable params: 0  
_________________________________________________________________
api_model.fit(data, epochs=10)

Epoch 1/10 WARNING:tensorflow:Model was constructed with shape (None, 75) for input KerasTensor(type_spec=TensorSpec(shape=(None, 75), dtype=tf.float32, name='input_2'), name='input_2', description="created by layer 'input_2'"), but it was called on an input with incompatible shape (75, 1).

我收到的错误是:ValueError: Input 0 of layer dense_1 is incompatible with the layer: expected axis -1 of input shape to have value 75 but received input with shape (75, 1)

此外,我尝试训练的实际模型的错误略有不同,但似乎在相同的原理下出现故障。如下:

ValueError: Input 0 is incompatible with layer pfn_base: expected shape=(None, 1086, 5), found shape=(1086, 5)

在 BatchDataset 对象上训练 keras 函数 API 模型的正确方法是什么?

您需要将批处理数据集分配给一个变量,并且您还应该在 model.compile 中使用损失函数,因为默认值为 None 并且您无法使用它学习任何东西。这是一个工作示例:

import numpy as np
import tensorflow as tf
from tensorflow import keras
from keras import layers

print('numpy version: {}'.format(np.__version__))
print('keras version: {}'.format(keras.__version__))
print('tensorflow version: {}'.format(tf.__version__))
X = np.random.uniform(size=(1000,75))
Y = np.random.uniform(size=(1000))

data = tf.data.Dataset.from_tensor_slices((X, Y))
print(data.cardinality().numpy())
data = data.batch(batch_size=100, drop_remainder=True)

def API_Model(input_shape, name="test_model"):

    inputs = layers.Input(shape=input_shape)
    x = layers.Dense(1)(inputs)
    outputs = layers.Activation('relu')(x)

    return keras.Model(inputs=inputs, outputs=outputs, name=name)

api_model = API_Model(input_shape=(X.shape[1],))
api_model.compile(loss='mse')
api_model.summary()
api_model.fit(data, epochs=10)