Я работаю над моделью глубокого обучения, которая будет выводить различные помеченные заболевания. Входными данными являются как текст (заметки врача), так и скалярные клинические данные. Выходы являются метками. У любого пациента может быть несколько заболеваний. Следовательно, это проблема с несколькими метками.
Выход также очень редкий. Наивный тест на точность (просто генерирование матрицы нулей, равной по форме истинным меткам) дал около 92% точности. Поэтому одной из метрик, которые я использую для оценки производительности, является потеря Хемминга (количество неверных меток, деленное на общее количество меток). Чтобы проверить, правильно ли я написал функцию, я использую tf.print в процессе обучения, чтобы увидеть, соответствует ли то, что я вычисляю вручную, тому, что рассчитывается в коде.
Вот функция hamming_loss (на основе этой функции здесь: https://github.com/tensorflow/addons/blob/v0.7.1/tensorflow_addons/metrics/hamming.py#L56 -L130 ).
def hamming_loss(y, y_hat, thresh=0.8, use_thresh=True, mode='multilabel'):
if use_thresh is False:
threshold = tf.reduce_max(y_hat, axis=-1, keepdims=True)
# make sure [0, 0, 0] doesn't become [1, 1, 1]
# Use abs(x) > eps, instead of x != 0 to check for zero
y_pred = tf.logical_and(y_hat >= threshold, tf.abs(y_hat) > 1e-12)
else:
y_pred = y_hat > thresh
y_true = tf.cast(y, tf.int32)
y_pred = tf.cast(y_pred, tf.int32)
shape = tf.cast(tf.shape(y)[-1], tf.int32)
#tf.print(y, summarize = -1)
#tf.print('\n')
#tf.print(y_pred, summarize = -1)
#tf.print(shape)
#tf.print(y_hat, summarize = -1)
if mode == 'multiclass':
nonzero = tf.cast(
tf.math.count_nonzero(y_true * y_pred, axis=-1), tf.float32)
return 1.0 - nonzero
else:
nonzero = tf.cast(
tf.math.count_nonzero(y_true - y_pred, axis=-1), tf.int32)
#tf.print(nonzero, summarize=-1)
tf.print(nonzero/shape, summarize=-1)
return nonzero/shape
Вот моя сеть (и да, это вероятно, излишне глубокий / большой, но я нахожусь в стадии создания прототипа и просто пробую различные структуры):
nlp_input = Input(shape=(1024,), name='nlp_input')
lr = LeakyReLU(alpha=0.1)
meta_input = Input(shape=(24,), name='meta_input')
hidden_m1 = Dense(2000, activation=lr,kernel_regularizer = L1L2(l1=0.0001)
)(meta_input)
hidden_m2 = Dense(200, activation=lr,
)(hidden_m1)
hidden_m3 = Dense(100, activation=lr,
)(hidden_m2)
hidden_m4 = Dense(10, activation='relu',
)(hidden_m3)
hidden1 = Dense(5000, activation=lr,kernel_regularizer = L1L2(l1=0.0001)
)(nlp_input)
hidden2 = Dense(3000, activation=lr
)(hidden1)
hidden3 = Dense(3000, activation=lr,
)(hidden2)
hidden4 = Dense(768, activation=lr,
)(hidden3)
hidden5 = Dense(500, activation=lr,
)(hidden4)
hidden6 = Dense(100, activation='relu')(hidden5)
conc = concatenate([hidden6, hidden_m4])
conch1 = Dense(1000, activation =lr, kernel_regularizer = L1L2(l1=0.0001))(conc)
conch2 = Dense(500, activation =lr)(conch1)
conch3 = Dense(500, activation =lr)(conch2)
conch4 = Dense(100, activation ='relu')(conch3)
acti = Dense(15, 'sigmoid')(conch4)
model = Model(inputs=[nlp_input, meta_input], outputs=[acti])
opt = tf.keras.optimizers.Adam(learning_rate=1e-4)
model.compile(loss=focal_loss(), optimizer=opt,metrics=[tf_prec,tf_rec, hamming_loss])
print(model.summary())
Для простоты, просто для отладки моей функции hamming_loss, я запускаю с размером пакета, равным 1 и распечатайте hamming_loss каждый шаг. Вот несколько шагов:
Train on 1315 samples, validate on 328 samples
0.066666666666666666
1/1315 [..............................] - ETA: 12:54 - loss: 6.6111 - tf_prec: 0.2000 - tf_rec: 1.0000 - hamming_loss: 0.06670.066666666666666666
2/1315 [..............................] - ETA: 8:16 - loss: 6.5891 - tf_prec: 0.2000 - tf_rec: 1.0000 - hamming_loss: 0.0667 0.13333333333333333
0.13333333333333333
4/1315 [..............................] - ETA: 4:27 - loss: 6.5504 - tf_prec: 0.2500 - tf_rec: 1.0000 - hamming_loss: 0.10000.26666666666666666
0.2
6/1315 [..............................] - ETA: 3:10 - loss: 6.5065 - tf_prec: 0.3000 - tf_rec: 1.0000 - hamming_loss: 0.14440.066666666666666666
0.2
8/1315 [..............................] - ETA: 2:31 - loss: 6.4611 - tf_prec: 0.3187 - tf_rec: 1.0000 - hamming_loss: 0.14170.2
0.066666666666666666
10/1315 [..............................] - ETA: 2:08 - loss: 6.4265 - tf_prec: 0.2800 - tf_rec: 0.9000 - hamming_loss: 0.14000.066666666666666666
0.066666666666666666
12/1315 [..............................] - ETA: 1:52 - loss: 6.3848 - tf_prec: 0.2542 - tf_rec: 0.8333 - hamming_loss: 0.12780.066666666666666666
0.066666666666666666
Я полностью озадачен тем, почему значение Hamming_loss, возвращаемое функцией, не совпадает с потерей Хемминга, выводимой вручную на каждом шаге? Я все еще новичок в TensorFlow-Keras, так что за кулисами происходит что-то, чего я просто не знаю?