Saya mencoba mendefinisikan fungsi metrik khusus (Skor-F1) di Keras (backend Tensorflow) menurut yang berikut:
def f1_score(tags, predicted):
tags = set(tags)
predicted = set(predicted)
tp = len(tags & predicted)
fp = len(predicted) - tp
fn = len(tags) - tp
if tp>0:
precision=float(tp)/(tp+fp)
recall=float(tp)/(tp+fn)
return 2*((precision*recall)/(precision+recall))
else:
return 0
Sejauh ini, sangat bagus, tetapi ketika saya mencoba menerapkannya dalam kompilasi model:
model1.compile(loss="binary_crossentropy", optimizer=Adam(), metrics=[f1_score])
itu memberikan kesalahan:
TypeError Traceback (most recent call last)
<ipython-input-85-4eca4def003f> in <module>()
5 model1.add(Dense(output_dim=10, activation="sigmoid"))
6
----> 7 model1.compile(loss="binary_crossentropy", optimizer=Adam(), metrics=[f1_score])
8
9 h=model1.fit(X_train, Y_train, batch_size=500, nb_epoch=5, verbose=True, validation_split=0.1)
/home/buda/anaconda2/lib/python2.7/site-packages/keras/models.pyc in compile(self, optimizer, loss, metrics, sample_weight_mode, **kwargs)
522 metrics=metrics,
523 sample_weight_mode=sample_weight_mode,
--> 524 **kwargs)
525 self.optimizer = self.model.optimizer
526 self.loss = self.model.loss
/home/buda/anaconda2/lib/python2.7/site-packages/keras/engine/training.pyc in compile(self, optimizer, loss, metrics, loss_weights, sample_weight_mode, **kwargs)
664 else:
665 metric_fn = metrics_module.get(metric)
--> 666 self.metrics_tensors.append(metric_fn(y_true, y_pred))
667 if len(self.output_names) == 1:
668 self.metrics_names.append(metric_fn.__name__)
<ipython-input-84-b8a5752b6d55> in f1_score(tags, predicted)
4 #tf.convert_to_tensor(img.eval())
5
----> 6 tags = set(tags)
7 predicted = set(predicted)
8
/home/buda/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/ops.pyc in __iter__(self)
493 TypeError: when invoked.
494 """
--> 495 raise TypeError("'Tensor' object is not iterable.")
496
497 def __bool__(self):
TypeError: 'Tensor' object is not iterable.
Apa masalah yang terjadi di sini? Fakta bahwa input fungsi f1_score saya bukan array Tensorflow? Jika demikian, di mana / bagaimana saya bisa mengubahnya dengan benar?
tensorflow
keras
evaluation
Hendrik
sumber
sumber
eval
saat yang Anda maksudeval()
Jawaban:
Anda harus menggunakan fungsi backend Keras . Sayangnya mereka tidak mendukung
&
-operator, sehingga Anda harus membangun solusi: Kami menghasilkan matriks dimensibatch_size x 3
, di mana (misalnya untuk true positive) kolom pertama adalah vektor kebenaran dasar, yang kedua adalah prediksi aktual dan yang ketiga adalah semacam label-helper kolom, yang berisi dalam kasus yang benar-benar positif saja. Kemudian kami memeriksa contoh mana yang positif, diprediksi positif dan label-helpernya juga positif. Itu adalah hal positif yang sebenarnya.Kita dapat membuat analog ini dengan positif palsu, negatif palsu dan negatif asli dengan beberapa kalkulasi terbalik label.
Metrik f1 Anda mungkin terlihat sebagai berikut:
Karena kalkulator Keras-backend mengembalikan nan untuk pembagian dengan nol, kita tidak memerlukan pernyataan if-else-untuk pernyataan pengembalian.
Sunting: Saya telah menemukan ide yang cukup bagus untuk implementasi yang tepat. Masalah dengan pendekatan pertama kami adalah, bahwa itu hanya "diperkirakan", karena dihitung secara batch dan kemudian dirata-rata. Satu juga bisa menghitung ini setelah setiap zaman dengan
keras.callback
s. Silakan temukan idenya di sini: https://github.com/fchollet/keras/issues/5794Contoh implementasi adalah:
Untuk membuat jaringan memanggil fungsi ini, Anda cukup menambahkannya seperti panggilan balik
Maka Anda cukup mengakses anggota
metrics
variabel.sumber