簡體   English   中英

當使用來自 sklearn.neighbors.KNeighborsClassifier 的 predict 和 kneighbors 時,KNN 分類器給出不同的結果

[英]KNN classifier gives different results when using predict and kneighbors from sklearn.neighbors.KNeighborsClassifier

我想使用來自 sklearn.neighbors.KNeighborsClassifier 的 k 最近鄰分類器對從 CNN 提取的特征進行分類。 但是當我在測試數據上使用 predict() 函數時,它給出的類與 kneighbors() 可以找到的多數票不同。 我正在使用以下 Resnet50 預訓練模型來提取作為連體網絡分支的特征。 可以在此處找到連體網絡的詳細信息。

def embedding_model():
    
    baseModel = ResNet50(weights="imagenet", include_top=False,input_tensor=Input(shape=(IMAGE_SIZE, IMAGE_SIZE, 3)))
    for layer in baseModel.layers[:165]:
        layer.trainable = False
    
    headModel = baseModel.output
    headModel = GlobalAveragePooling2D()(headModel)
    model = Model(inputs=baseModel.input, outputs=headModel, name = 'embedding_model')

    return model

#get embedding model weights from saved weights
embeddings_weights = siamese_test.get_layer('embedding_model').get_weights()
embeddings_branch = siamese_test.get_layer('embedding_model')

input_shape = (224,224,3)

input = Input(shape=input_shape)
x = embeddings_branch(input)

model = Model(input, x)
model.set_weights(embeddings_weights )
out_shape = model.layers[-1].output_shape

模型摘要可以在這里找到。 我使用以下函數來使用模型提取特征。

def create_features(dataset, pre_model,out_shape,batchSize=16):
    features = pre_model.predict(dataset, batchSize)
    features_flatten = features.reshape((features.shape[0], out_shape[1] ))
    return features, features_flatten
train_features, train_features_flatten = create_features(x_train,model,out_shape, batchSize)
test_features, test_features_flatten = create_features(x_test,model,out_shape, batchSize)

然后我使用 KNN 分類器來預測測試特征

from sklearn.neighbors import KNeighborsClassifier

KNN_classifier = KNeighborsClassifier(n_neighbors=3)
KNN_classifier.fit(train_features_flatten, y_train)

y_pred = KNN_classifier.predict(test_features_flatten)

我使用 keighbors() 函數來查找最近鄰居的距離及其相應的索引。 但它給了我與預期不同的結果。

neighbors_dist, neighbors_index = KNN_classifier.kneighbors(test_features_flatten)

#replace the index with actual class 
data2 = np.zeros(neighbors_index.shape, dtype=object)
for i in range(neighbors_index.shape[0]):
  for j in range(neighbors_index.shape[1]):
    data2[i,j] = str(y_test[neighbors_index[i][j]])

#get the majority class 
from collections import Counter
majority_class = np.array([Counter(sorted(row, reverse=True)).most_common(1)[0][0] for row in data2])

如您所見,預測的類與前 10 個樣本的多數類不同

for i, pred in enumerate(y_pred):
  print(i,pred)

for i, c in enumerate(majority_class):
  print(i,c)

前 10 個樣品的預測輸出: 0 燈芯絨 1 羊毛 2 羊毛 3 brown_bread 4 木材 5 燈芯絨 6 燈芯絨 7 燈芯絨 8 羊毛 9 木材 10 燈芯絨

前 10 個樣品的多數類: 0 燈芯絨 1 軟木 2 軟木 3 lettuce_leaf 4 亞麻 5 燈芯絨 6 羊毛 7 燈芯絨 8 brown_bread 9 亞麻 10 羊毛

有什么我做錯了嗎? 任何幫助,將不勝感激。 謝謝你。

這是不正確的:

    data2[i,j] = str(y_test[neighbors_index[i][j]])

kneighbors方法(以及predict )找到最接近輸入的訓練點,因此您應該在此處引用y_train

暫無
暫無

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

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