使用keras bert进行分类时loss为NaN
loss is NaN when using keras bert for classification
我正在使用 keras-bert 进行分类。在某些数据集上,它 运行 很好并计算了损失,而在其他数据集上,损失是 NaN
.
不同数据集的相似之处在于它们是原始数据集的增强版本。使用 keras-bert,原始数据和一些增强版本的数据 运行 很好,而其他增强版本的数据不 运行 很好。
当我在数据的增强版本上使用常规的一层 BiLSTM
时,运行 与 keras-bert 的效果不佳,效果很好,这意味着我可以排除数据有错误或包含可能影响损失计算方式的虚假值的可能性。
处理中的数据有三个类.
我正在使用基于 bert 的 uncased
!wget -q https://storage.googleapis.com/bert_models/2018_10_18/uncased_L-12_H-768_A-12.zip
任何人都可以告诉我为什么损失是 nan 吗?
inputs = model.inputs[:2]
dense = model.layers[-3].output
outputs = keras.layers.Dense(3, activation='sigmoid', kernel_initializer=keras.initializers.TruncatedNormal(stddev=0.02),name = 'real_output')(dense)
decay_steps, warmup_steps = calc_train_steps(train_y.shape[0], batch_size=BATCH_SIZE,epochs=EPOCHS,)
#(decay_steps=decay_steps, warmup_steps=warmup_steps, lr=LR)
model = keras.models.Model(inputs, outputs)
model.compile(AdamWarmup(decay_steps=decay_steps, warmup_steps=warmup_steps, lr=LR), loss='sparse_categorical_crossentropy',metrics=['sparse_categorical_accuracy'])
sess = tf.compat.v1.keras.backend.get_session()
uninitialized_variables = set([i.decode('ascii') for i in sess.run(tf.compat.v1.report_uninitialized_variables ())])
init_op = tf.compat.v1.variables_initializer([v for v in tf.compat.v1.global_variables() if v.name.split(':')[0] in uninitialized_variables])
sess.run(init_op)
model.fit(train_x,train_y,epochs=EPOCHS,batch_size=BATCH_SIZE)
Train on 20342 samples
Epoch 1/10
20342/20342 [==============================] - 239s 12ms/sample - loss: nan - sparse_categorical_accuracy: 0.5572
Epoch 2/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 3/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2081
Epoch 4/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 5/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 6/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 7/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 8/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2081
Epoch 9/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 10/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
<tensorflow.python.keras.callbacks.History at 0x7f1caf9b0f90>
此外,我正在 运行与 tensorflow 2.3.0
和 keras 2.4.3
在 Google Colab 上进行此操作
UPDATE
我再次查看了导致此问题的数据,发现其中一个目标标签丢失了。我可能错误地编辑了它。一旦我修复了它,损失就是 NaN 问题消失了。但是,我会为我得到的答案打 50 分,因为它让我更好地思考我的代码。谢谢。
我注意到您的代码中存在一个问题,但我不确定这是否是主要原因;如果您能提供一些可重现的代码就更好了。
在上面的代码片段中,您在最后一层激活中设置了 sigmoid
unit < 1
,这表明问题数据集可能是 multi-label 并且这就是为什么损失函数应该是 binary_crossentropy
但你设置 sparse_categorical_crossentropy
这是典型的使用 multi-class 问题和 integer标签.
outputs = keras.layers.Dense(3, activation='sigmoid',
kernel_initializer=keras.initializers.TruncatedNormal(stddev=0.02),
name = 'real_output')(dense)
model = keras.models.Model(inputs, outputs)
model.compile(AdamWarmup(decay_steps=decay_steps,
warmup_steps=warmup_steps, lr=LR),
loss='sparse_categorical_crossentropy',
metrics=['sparse_categorical_accuracy'])
所以,如果你的问题数据集是一个多标签,最后一层unit = 3
,那么设置应该更像
outputs = keras.layers.Dense(3, activation='sigmoid',
kernel_initializer=keras.initializers.TruncatedNormal(stddev=0.02),
name = 'real_output')(dense)
model.compile(AdamWarmup(decay_steps=decay_steps,
warmup_steps=warmup_steps, lr=LR),
loss='binary_crossentropy',
metrics=['accuracy'])
但是如果问题集是一个多class问题并且你的目标标签是整数(unit = 3
) 那么设置应该更像如下:
outputs = keras.layers.Dense(3, activation='softmax',
kernel_initializer=keras.initializers.TruncatedNormal(stddev=0.02),
name = 'real_output')(dense)
model.compile(AdamWarmup(decay_steps=decay_steps,
warmup_steps=warmup_steps, lr=LR),
loss='sparse_categorical_crossentropy',
metrics=['sparse_categorical_accuracy'])
我正在使用 keras-bert 进行分类。在某些数据集上,它 运行 很好并计算了损失,而在其他数据集上,损失是 NaN
.
不同数据集的相似之处在于它们是原始数据集的增强版本。使用 keras-bert,原始数据和一些增强版本的数据 运行 很好,而其他增强版本的数据不 运行 很好。
当我在数据的增强版本上使用常规的一层 BiLSTM
时,运行 与 keras-bert 的效果不佳,效果很好,这意味着我可以排除数据有错误或包含可能影响损失计算方式的虚假值的可能性。
处理中的数据有三个类.
我正在使用基于 bert 的 uncased
!wget -q https://storage.googleapis.com/bert_models/2018_10_18/uncased_L-12_H-768_A-12.zip
任何人都可以告诉我为什么损失是 nan 吗?
inputs = model.inputs[:2]
dense = model.layers[-3].output
outputs = keras.layers.Dense(3, activation='sigmoid', kernel_initializer=keras.initializers.TruncatedNormal(stddev=0.02),name = 'real_output')(dense)
decay_steps, warmup_steps = calc_train_steps(train_y.shape[0], batch_size=BATCH_SIZE,epochs=EPOCHS,)
#(decay_steps=decay_steps, warmup_steps=warmup_steps, lr=LR)
model = keras.models.Model(inputs, outputs)
model.compile(AdamWarmup(decay_steps=decay_steps, warmup_steps=warmup_steps, lr=LR), loss='sparse_categorical_crossentropy',metrics=['sparse_categorical_accuracy'])
sess = tf.compat.v1.keras.backend.get_session()
uninitialized_variables = set([i.decode('ascii') for i in sess.run(tf.compat.v1.report_uninitialized_variables ())])
init_op = tf.compat.v1.variables_initializer([v for v in tf.compat.v1.global_variables() if v.name.split(':')[0] in uninitialized_variables])
sess.run(init_op)
model.fit(train_x,train_y,epochs=EPOCHS,batch_size=BATCH_SIZE)
Train on 20342 samples
Epoch 1/10
20342/20342 [==============================] - 239s 12ms/sample - loss: nan - sparse_categorical_accuracy: 0.5572
Epoch 2/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 3/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2081
Epoch 4/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 5/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 6/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 7/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 8/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2081
Epoch 9/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
Epoch 10/10
20342/20342 [==============================] - 225s 11ms/sample - loss: nan - sparse_categorical_accuracy: 0.2082
<tensorflow.python.keras.callbacks.History at 0x7f1caf9b0f90>
此外,我正在 运行与 tensorflow 2.3.0
和 keras 2.4.3
UPDATE
我再次查看了导致此问题的数据,发现其中一个目标标签丢失了。我可能错误地编辑了它。一旦我修复了它,损失就是 NaN 问题消失了。但是,我会为我得到的答案打 50 分,因为它让我更好地思考我的代码。谢谢。
我注意到您的代码中存在一个问题,但我不确定这是否是主要原因;如果您能提供一些可重现的代码就更好了。
在上面的代码片段中,您在最后一层激活中设置了 sigmoid
unit < 1
,这表明问题数据集可能是 multi-label 并且这就是为什么损失函数应该是 binary_crossentropy
但你设置 sparse_categorical_crossentropy
这是典型的使用 multi-class 问题和 integer标签.
outputs = keras.layers.Dense(3, activation='sigmoid',
kernel_initializer=keras.initializers.TruncatedNormal(stddev=0.02),
name = 'real_output')(dense)
model = keras.models.Model(inputs, outputs)
model.compile(AdamWarmup(decay_steps=decay_steps,
warmup_steps=warmup_steps, lr=LR),
loss='sparse_categorical_crossentropy',
metrics=['sparse_categorical_accuracy'])
所以,如果你的问题数据集是一个多标签,最后一层unit = 3
,那么设置应该更像
outputs = keras.layers.Dense(3, activation='sigmoid',
kernel_initializer=keras.initializers.TruncatedNormal(stddev=0.02),
name = 'real_output')(dense)
model.compile(AdamWarmup(decay_steps=decay_steps,
warmup_steps=warmup_steps, lr=LR),
loss='binary_crossentropy',
metrics=['accuracy'])
但是如果问题集是一个多class问题并且你的目标标签是整数(unit = 3
) 那么设置应该更像如下:
outputs = keras.layers.Dense(3, activation='softmax',
kernel_initializer=keras.initializers.TruncatedNormal(stddev=0.02),
name = 'real_output')(dense)
model.compile(AdamWarmup(decay_steps=decay_steps,
warmup_steps=warmup_steps, lr=LR),
loss='sparse_categorical_crossentropy',
metrics=['sparse_categorical_accuracy'])