簡體   English   中英

Tensorflow 中每個 class 的 F1 得分指標

[英]F1 Score metric per class in Tensorflow

我已經實現了以下指標來查看我認為相關的類的精度和召回率。

metrics=[tf.keras.metrics.Recall(class_id=1, name='Bkwd_R'),tf.keras.metrics.Recall(class_id=2, name='Fwd_R'),tf.keras.metrics.Precision(class_id=1, name='Bkwd_P'),tf.keras.metrics.Precision(class_id=2, name='Fwd_P')]

How can I implement the same in Tensorflow 2.5 for F1 score (ie specifically for class 1 and class 2, and not class 0, without a custom function.


更新

使用此指標設置:

tfa.metrics.F1Score(num_classes = 3, average = None, name = f1_name)

我在培訓期間得到以下信息:

13367/13367 [==============================] 465s 34ms/step - loss: 0.1683 - f1_score: 0.5842 - val_loss: 0.0943 - val_f1_score: 0.3314

當我做 model.evaluate 時:

224/224 [==============================] - 11s 34ms/step - loss: 0.0665 - f1_score: 0.3325

和得分=

Score: [0.06653735041618347, array([0.99740255, 0.        , 0.        ], dtype=float32)]

問題是這是基於平均值的訓練,但我想訓練合理平均的 F1 分數/數組中最后兩個值/類中的每一個(在這種情況下為 0)


編輯

Will accept a non tensorflow specific function that gives the desired result (with full function and call during fit code) but was really hoping for something using the exisiting tensorflow code if it exists)

您可以查看 tensorflow-addons ZEFE90A8E604A7C840E88D03A78 中的https://www.tensorflow.org/addons/api_docs/python/tfa/metrics/F1Score 具體來說,如果您需要每個班級的分數,則需要將平均參數設置為Nonemacro

正如 David Harris 的評論中提到的,神經網絡 model 是在損失函數上訓練的,而不是在度量分數上訓練的 損失有助於推動model 尋求通過反向傳播提供准確標簽的解決方案。 指標有助於對該模型的性能進行可比較的評估,這種評估更易於人類閱讀。

因此,話雖如此,我覺得您在問題中所說的是“有三個班級,我希望 model 更關心三個班級中的最后兩個” 我想要

如果是這種情況,您可以采取的一種方法是按label對樣本進行加權。 假設您在數組y_train中有標簽。

# Which classes are you wanting to focus on
classes_i_care_about = [1, 2]
# Initialize all weights to 1.0
sample_weights = np.ones(shape=(len(y_train),))
# Give the classes you care about 50% more weight
sample_weight[np.isin(y_train, classes_i_care_about)] = 1.5

...

model.fit(
    x=X_train,
    y=y_train,
    sample_weight=sample_weight,
    epochs=5
)

這是我在不知道更多信息的情況下能提供的最好建議。 如果您正在尋找有關如何讓 model 在某些課程上做得更好的其他信息,其他信息可能會有用,例如:

  • 您的數據集中標簽的比例是多少?
  • 您的 model 架構的最后一層是什么? Dense(3, activation="softmax")
  • 你用的是什么損失?

這是一個更完整、可重現的示例,它顯示了我所說的樣本權重:

import numpy as np

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder

from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam
import tensorflow_addons as tfa

iris_data = load_iris() # load the iris dataset

x = iris_data.data
y_ = iris_data.target.reshape(-1, 1) # Convert data to a single column

# One Hot encode the class labels
encoder = OneHotEncoder(sparse=False)
y = encoder.fit_transform(y_)

# Split the data for training and testing
train_x, test_x, train_y, test_y = train_test_split(x, y, test_size=0.20)

# Build the model
def get_model():
    model = Sequential()

    model.add(Dense(10, input_shape=(4,), activation='relu', name='fc1'))
    model.add(Dense(10, activation='relu', name='fc2'))
    model.add(Dense(3, activation='softmax', name='output'))

    # Adam optimizer with learning rate of 0.001
    optimizer = Adam(lr=0.001)
    model.compile(
        optimizer,
        loss='categorical_crossentropy',
        metrics=[
            'accuracy',
            tfa.metrics.F1Score(
                num_classes=3,
                average=None,
            )
        ]
    )
    return model

model = get_model()
model.fit(
    train_x,
    train_y,
    verbose=2,
    batch_size=5,
    epochs=25,
)

results = model.evaluate(test_x, test_y)

print('Final test set loss: {:4f}'.format(results[0]))
print('Final test set accuracy: {:4f}'.format(results[1]))
print('Final test F1 scores: {}'.format(results[2]))
Final test set loss: 0.585964
Final test set accuracy: 0.633333
Final test F1 scores: [1.         0.15384616 0.6206897 ]

現在,我們給第 1 類和第 2 類添加權重:

sample_weight = np.ones(shape=(len(train_y),))
sample_weight[
    (train_y[:, 1] == 1) | (train_y[:, 2] == 1)
] = 1.5

model = get_model()
model.fit(
    train_x,
    train_y,
    sample_weight=sample_weight,
    verbose=2,
    batch_size=5,
    epochs=25,
)

results = model.evaluate(test_x, test_y)

print('Final test set loss: {:4f}'.format(results[0]))
print('Final test set accuracy: {:4f}'.format(results[1]))
print('Final test F1 scores: {}'.format(results[2]))
Final test set loss: 0.437623
Final test set accuracy: 0.900000
Final test F1 scores: [1.        0.8571429 0.8571429]

在這里,model 着重學習了這些,並提高了它們各自的性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM