如何在Tensorflow / Keras中为包含多个标签的字典形式的数据集定义损失?

我有一个包含多个标签的数据集,我希望定义一个依赖于这些标签的损失。数据集中的标签是以字典形式存储的,例如:

y = tf.data.Dataset.from_tensor_slices({'values': [1, 2, 3], 'symbols': [4, 5, 6]})

然后我想为每个标签定义一个损失,以便之后对这些损失进行某种组合。我尝试这样定义损失:

def model_loss(y, y_):    return tf.losses.SparseCategoricalCrossentropy(from_logits=False, name='values_xent')(y['values'], y_)

然而,当我拟合模型时,它会给我以下错误:

TypeError: Only integers, slices (`:`), ellipsis (`...`), tf.newaxis (`None`) and scalar tf.int32/tf.int64 tensors are valid indices, got 'values'

所以似乎我不能这样做y['values']。我该如何在损失函数中访问这些值呢?提前感谢。

编辑

我想实现的目标是这样的:

import tensorflow as tfimport numpy as np# 样本ds_x = tf.data.Dataset.from_tensor_slices(np.random.randn(5, 5))# 标签ds_y = tf.data.Dataset.from_tensor_slices({'l1': np.arange(5), 'l2':np.arange(5)})# 样本 + 标签ds = tf.data.Dataset.zip((ds_x, ds_y))# 模型input_ = tf.keras.Input(shape=(5,))x = tf.keras.layers.Dense(30, activation='relu')(input_)x1 = tf.keras.layers.Dense(5, activation='softmax')(x)x2 = tf.keras.layers.Dense(5, activation='softmax')(x)model = tf.keras.Model(inputs=input_, outputs={'l1':x1, 'l2':x2})# 损失def model_loss(y, y_):    res = 3 * tf.losses.SparseCategoricalCrossentropy()(y['l1'], y_['l1'])    res += tf.losses.SparseCategoricalCrossentropy()(y['l2'], y_['l2'])    return res# 编译和训练model.compile(optimizer='adam', loss=model_loss)model.fit(ds.batch(5), epochs=5)

回答:

一旦你做了一些对Keras来说不完全正常的事情,我建议使用自定义训练循环。这样你就可以控制训练过程的每一个步骤。

我这样做了,并且不需要改变你的损失函数。

import tensorflow as tfimport numpy as npds_x = tf.data.Dataset.from_tensor_slices(np.random.randn(5, 5).astype(np.float32))ds_y = tf.data.Dataset.from_tensor_slices({'l1': np.arange(5), 'l2':np.arange(5)})ds = tf.data.Dataset.zip((ds_x, ds_y)).batch(2)input_ = tf.keras.Input(shape=[5])x = tf.keras.layers.Dense(30, activation='relu')(input_)x1 = tf.keras.layers.Dense(5, activation='softmax')(x)x2 = tf.keras.layers.Dense(5, activation='softmax')(x)model = tf.keras.Model(inputs=input_, outputs={'l1':x1, 'l2':x2})def model_loss(y, y_):    res = 3 * tf.losses.SparseCategoricalCrossentropy()(y['l1'], y_['l1'])    res += tf.losses.SparseCategoricalCrossentropy()(y['l2'], y_['l2'])    return restrain_loss = tf.keras.metrics.Mean()optimizer = tf.keras.optimizers.Adam()for i in range(25):    for x, y in ds:        with tf.GradientTape() as tape:            out = model(x)            loss = model_loss(y, out)                    gradients = tape.gradient(loss, model.trainable_variables)        optimizer.apply_gradients(zip(gradients, model.trainable_variables))        train_loss(loss)    print(f'Epoch {i} Loss: {train_loss.result():=4.4f}')    train_loss.reset_states()
Epoch 0 Loss: 6.4170Epoch 1 Loss: 6.3396Epoch 2 Loss: 6.2737Epoch 11 Loss: 5.7191Epoch 12 Loss: 5.6608Epoch 19 Loss: 5.2646Epoch 24 Loss: 4.9896

Related Posts

TypeError: 无法将符号化的Keras输入/输出转换为numpy数组

尝试升级在这里找到的gumble-softmax-va…

在使用train_test_split之前和之后应用SMOTETomek时的不同得分

我正在尝试将文本分类到6个不同的类别。由于我的数据集不…

随机森林:缺失值

我的随机森林模型中的一个特征存在缺失值。我知道数据缺失…

Torch argmax用于获取N个最高值 [重复]

此问题已有答案: 如何高效地检索Torch张量中最大值…

在向MobileNet模型添加分类器时遇到问题

我有以下代码,在尝试添加自己的分类器时遇到了错误。 i…

如何在测试数据中选择与训练数据相同的特征?

我在参加Kaggle的房价竞赛。我有一个数据准备函数,…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注