在具有多个输入的模型中使用每个项目具有多个张量的数据集

Use dataset with multiple tensors per item in model with multiple inputs

我有一个 Tensorflow 数据集,其中包含以下格式的项目

(
    <tf.Tensor: shape=(14,), dtype=int64, numpy=array([ 1,  2,  3,  4,  5,  4,  6,  7,  8,  9, 10, 11,  9, 12])>, 
    <tf.Tensor: shape=(12,), dtype=int64, numpy=array([ 1,  2,  3,  4,  5,  4,  6,  7,  8,  9, 10, 11])>, 
    <tf.Tensor: shape=(), dtype=int64, numpy=0>
)

由此代码创建

encoder = tfds.deprecated.text.TokenTextEncoder(token_counts)

def encode(text0, text1, label):
    return encoder.encode(text0.numpy()), encoder.encode(text1.numpy()), label

def encode_map_fn(text, text2, label):
    return tf.py_function(encode,
                          inp=[text, text2, label],
                          Tout=[tf.int64, tf.int64, tf.int64])

ds_train = ds_raw_train.map(encode_map_fn)
ds_train_valid = ds_raw_train_valid.map(encode_map_fn)

它通过以下代码进行批处理,但这应该不会对问题产生任何影响

train_data_batch = ds_train.padded_batch( 32, padded_shapes=([-1],[-1],[]))

valid_data_batch = ds_train_valid.padded_batch( 32, padded_shapes=([-1],[-1],[]))

它产生以下输出

(
    <tf.Tensor: shape=(32, 29), dtype=int64, numpy=array([[ 1,  2,  3,  4,  5,  4,  6,  7,  8,  9, 10, 11,  9, 12],...])>, 
    <tf.Tensor: shape=(32, 29), dtype=int64, numpy=array([[ 1,  2,  3,  4,  5,  4,  6,  7,  8,  9, 10, 11],...])>, 
    <tf.Tensor: shape=(32,), dtype=int64, numpy=array([0,...]>
)

使用

创建模型后
lstm_layer = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64, return_sequences = False))

size_dic = len(token_counts) + 2

emb = Embedding(size_dic, 100, input_length=300)

input1 = tf.keras.Input(shape=(300,))
input2 = tf.keras.Input(shape=(300,))

e1 = emb(input1)
e2 = emb(input2)
x1 = lstm_layer(e1)
x2 = lstm_layer(e2)

mhd = lambda x: tf.keras.backend.abs(x[0] - x[1])
merged = tf.keras.layers.Lambda(function=mhd, output_shape= lambda x: x[0])([x1, x2])
preds = tf.keras.layers.Dense(1)(merged)
model = tf.keras.Model(inputs=(input1, input2), outputs=preds)
model.compile(optimizer=tf.keras.optimizers.Adam(1e-3),
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=False),
              metrics=['accuracy'])

我尝试用

拟合模型
history = model.fit(train_data_batch, validation_data=valid_data_batch, epochs=5)

这会导致以下错误

ValueError: Layer "model_1" expects 2 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, None) dtype=int64>]

我认为数据集的项目应该采用 ([tf.int64, tf.int64], tf.int64) 格式,但尝试将其设置为 Tout 会导致错误。

有没有办法将数据集更改为所需的格式,更改模型以按原样接受数据集,或者为数据集中每个项目的第一个、第二个和第三个属性获取单独的迭代器?

尝试:

train_data_batch = train_data_batch.map(lambda x1, x2, y: ((x1, x2), y))