使用Python 3.8.3和tensorflow版本2.4.1
想class_id在tensorflow.metrics諸如Recall(參見檔案)中使用引數
這是復制問題的最小代碼段。下面的代碼崩潰了class_id=1
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.layers import SimpleRNN
from sklearn.model_selection import train_test_split
from tensorflow.keras import metrics
import numpy as np
#generate data
max_length = 200
width = 3
n_samples = 100
data = np.random.rand(n_samples, max_length, width)
label = np.random.randint(0, high =2, size = n_samples)
train_size = 0.8
x_train, x_test, y_train, y_test = train_test_split(data, label, train_size = train_size)
#create a model
rnn_size = 16
sequence_input = Input(shape=(max_length,width,), dtype='float32')
x = SimpleRNN(rnn_size)(sequence_input)
preds = Dense(1, activation='sigmoid')(x)
model = Model(sequence_input, preds)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=[metrics.Recall(class_id=1)])
#fit
BATCH_SIZE = 32
history = model.fit(x_train, y_train, epochs=1, batch_size=BATCH_SIZE)
投擲 ValueError
ValueError: slice index 1 of dimension 1 out of bounds. for '{{node strided_slice_1}} = StridedSlice[Index=DT_INT32, T=DT_FLOAT, begin_mask=0, ellipsis_mask=1, end_mask=0, new_axis_mask=0, shrink_axis_mask=2](Cast_1, strided_slice_1/stack, strided_slice_1/stack_1, strided_slice_1/stack_2)' with input shapes: [?,1], [2], [2], [2] and with computed input tensors: input[1] = <0 1>, input[2] = <0 2>, input[3] = <1 1>.
但它適用于 metrics.Recall(class_id=0)
metrics.Precision(class_id=1)使用的所有其他指標都可能出現相同的錯誤class_id(我還沒有全部嘗試過)。
我無法解讀錯誤訊息的含義,也無法在網上找到任何相關內容來回答我的問題。
uj5u.com熱心網友回復:
檔案指出:
class_id(可選):我們想要二進制指標的整數類 ID。這必須在半開區間 [0, num_classes) 中,其中 num_classes 是預測的最后一個維度。
當您使用sigmoid您的輸出時,它包含導致此錯誤的形狀:(1, )。如果你修改你的網路進行二元分類,輸出將是 1 類的 sigmoid 概率。
因此,對于二元分類情況,默認情況下您將獲得類別 1 的精度和召回率,如果您想獲得類別 0,則需要定義自己的指標。可以在此處找到示例。
相對錯誤來自這里(源代碼):
if class_id is not None:
y_true = y_true[..., class_id]
y_pred = y_pred[..., class_id]
在您的示例中,標簽應該是單熱編碼的:
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.layers import SimpleRNN
from sklearn.model_selection import train_test_split
from tensorflow.keras import metrics
from tensorflow.keras.utils import to_categorical
import numpy as np
#generate data
max_length = 200
width = 3
n_samples = 100
data = np.random.rand(n_samples, max_length, width)
label = np.random.randint(0, high =2, size = n_samples)
label = to_categorical(label, 2)
train_size = 0.8
x_train, x_test, y_train, y_test = train_test_split(data, label, train_size = train_size)
#create a model
rnn_size = 16
sequence_input = Input(shape=(max_length,width), dtype='float32')
x = SimpleRNN(rnn_size)(sequence_input)
preds = Dense(2, activation='softmax')(x)
model = Model(sequence_input, preds)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=[metrics.Precision(class_id=1),
metrics.Recall(class_id=1)])
#fit
BATCH_SIZE = 32
history = model.fit(x_train, y_train, epochs=16, batch_size=BATCH_SIZE,
validation_data = (x_test, y_test))
Epoch 16/16
3/3 [==============================] - 0s 86ms/step - loss: 0.6771 - precision: 0.5676 -
recall: 0.5250 - val_loss: 0.6419 - val_precision: 0.2222 - val_recall: 0.6667
通過sklearn驗證結果:
from sklearn.metrics import classification_report
print(classification_report(np.argmax(y_test, axis = -1),
np.argmax(model.predict(x_test, batch_size = 1),
axis= -1), digits = 4))
precision recall f1-score support
0 0.9091 0.5882 0.7143 17
1 0.2222 0.6667 0.3333 3
accuracy 0.6000 20
macro avg 0.5657 0.6275 0.5238 20
weighted avg 0.8061 0.6000 0.6571 20
如果您class_id = 0在最后一個示例中進行更改,它將計算 0 類的指標。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/391920.html
