Расчет точности, отзыва и F1 в Keras v2, я делаю это правильно? - PullRequest
0 голосов
/ 28 апреля 2018

Уже есть вопрос о том, как получить точность, отзыв и оценки F1 в Keras v2, вот метод, который я использую, но вопрос: правильно ли я делаю?

Прежде всего, Ф. Чоллет говорит , что он удалил эти три метрики из версии 2 Keras, потому что они основывались на пакетах и, следовательно, не надежны. Я следую идее basque21 , используя Callback с методом on_epoch_end, разве это обычно не зависит от партии, так как рассчитывается в конце эпохи (= после того, как все партии завершены)?

Вот код, который я использую. В метод model.fit я добавляю аргумент callbacks=[metrics] и определяю словарь myhistory и класс Metrics следующим образом (код адаптирован из basque21 ):

myhistory={}
myhistory['prec']=[]
myhistory['reca']=[]
myhistory['f1']=[]

class Metrics(keras.callbacks.Callback):
    def on_epoch_end(self, batch, logs={}):
        predict = numpy.asarray(self.model.predict(self.validation_data[0]))
        predict = a=numpy.array(predict.flatten()>=0.5,dtype=int)
        targ = self.validation_data[1]
        targ=numpy.array(targ.flatten()>=0.5,dtype=int)
        self.prf=precision_recall_fscore_support(targ, predict)
        print("Precision/recall/f1 class 0 is {}/{}/{}, precision/recall/f1 class 1 is {}/{}/{}".format(self.prf[0][0], self.prf[1][0], self.prf[2][0], self.prf[0][1], self.prf[1][1], self.prf[2][1]))
        myhistory['prec'].append(self.prf[0][1])
        myhistory['reca'].append(self.prf[1][1])
        myhistory['f1'].append(self.prf[2][1])
        return
metrics = Metrics()

Как только примерка закончена, я отображаю все на общем графике следующим образом:

import matplotlib.pyplot as plt

loss = history.history['loss']
val_loss = history.history['val_loss']
precision = [1-x for x in myhistory['prec']]
recall = [1-x for x in myhistory['reca']]
f_one = [1-x for x in myhistory['f1']]

epochs = range(1, len(loss) + 1)

# "bo" is for "blue dot"
plt.plot(epochs, loss, 'bo', label='Training loss')
# b is for "solid blue line"
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.plot(epochs, precision, 'r', label='One minus precision')
plt.plot(epochs, recall, 'g', label='One minus recall')
plt.plot(epochs, f_one, 'm', label='One minus f1')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()

plt.show()

Я использую «один минус точность» и т. Д., Чтобы все в диапазоне было близко к нулю. Что я не понимаю, так это то, что, как вы можете видеть на графике, enter image description here, хотя потери при проверке увеличиваются (из-за переоснащения), точность, отзыв, кажется, меняется, так что F1 остается относительно постоянным. Что я делаю не так?

Пример взят из главы 3 книги Ф. Чолле , речь идет о классификации текстов IMDB, и я показываю баллы только для класса 1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...