SVM прогнозирование изображений Python - PullRequest
0 голосов
/ 27 февраля 2019

Я извлек некоторые функции из изображений в своем наборе данных поезда, затем применил эти функции и разделил данные на поезда и проверил, используя train_test_split:

Train data  : (60, 772)
Test data   : (20, 772)
Train labels: (60,)
Test labels : (20,)

Что я хочу сделатьЗатем примените классификатор SVM к моим изображениям в наборе тестовых данных и посмотрите результаты.

# create the model - SVM
#clf = svm.SVC(kernel='linear', C=40)
clf = svm.SVC(kernel='rbf', C=10000.0, gamma=0.0001)

# fit the training data to the model
clf.fit(trainDataGlobal, trainLabelsGlobal)

# path to test data
test_path = "dataset/test"

# loop through the test images
for index,file in enumerate(glob.glob(test_path + "/*.jpg")):
    # read the image
    image = cv2.imread(file)

    # resize the image
    image = cv2.resize(image, fixed_size)

    # predict label of test image
    prediction = clf.predict(testDataGlobal)
    prediction = prediction[index]
    #print("Accuracy: {}%".format(clf.score(testDataGlobal, testLabelsGlobal) * 100 ))

    # show predicted label on image
    cv2.putText(image, train_labels[prediction], (20,30), cv2.FONT_HERSHEY_TRIPLEX, .7 , (0,255,255), 2)

    # display the output image
    plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    plt.show()

У меня не очень хорошая точность, хотя я вижу, что это говорит о точности 60%.Тем не менее, большинство изображений помечены неправильно.Я передал неправильный аргумент в prediction?

Что я могу сделать, чтобы улучшить это?

РЕДАКТИРОВАТЬ : Я пробовал то, что вы сказали, с помощью следующего кода, но я получаю сообщение об ошибке, в котором говорится, что я должен изменить свою feature_vector.Поэтому я делаю это, и затем я получаю следующую ошибку.

(Для справки: feature_extraction_method(image).shape - это (772,).)

for filename in test_images:

    # read the image and resize it to a fixed-size
    img = cv2.imread(filename)
    img = cv2.resize(img, fixed_size)

    feature_vector = feature_extraction_method(img)
    prediction = clf.predict(feature_vector.reshape(-1, 1))
    cv2.putText(img, prediction, (20, 30), cv2.FONT_HERSHEY_TRIPLEX, .7 , (0, 255, 255), 2)
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.show()   

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-71-2b8ff4146d8e> in <module>()
     19 
     20     feature_vector = feature_extraction_method(img)
---> 21     prediction = clf.predict(feature_vector.reshape(-1, 1))
     22     cv2.putText(img, prediction, (20, 30), cv2.FONT_HERSHEY_TRIPLEX, .7 , (0, 255, 255), 2)
     23     plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

/anaconda3/lib/python3.6/site-packages/sklearn/svm/base.py in predict(self, X)
    546             Class labels for samples in X.
    547         """
--> 548         y = super(BaseSVC, self).predict(X)
    549         return self.classes_.take(np.asarray(y, dtype=np.intp))
    550 

/anaconda3/lib/python3.6/site-packages/sklearn/svm/base.py in predict(self, X)
    306         y_pred : array, shape (n_samples,)
    307         """
--> 308         X = self._validate_for_predict(X)
    309         predict = self._sparse_predict if self._sparse else self._dense_predict
    310         return predict(X)

/anaconda3/lib/python3.6/site-packages/sklearn/svm/base.py in _validate_for_predict(self, X)
    457             raise ValueError("X.shape[1] = %d should be equal to %d, "
    458                              "the number of features at training time" %
--> 459                              (n_features, self.shape_fit_[1]))
    460         return X
    461 

ValueError: X.shape[1] = 1 should be equal to 772, the number of features at training time 

1 Ответ

0 голосов
/ 28 февраля 2019

Есть две основные проблемы с вашим кодом.

Во-первых, вам не нужно классифицировать весь набор тестов в каждом взаимодействии цикла for.Предсказания метки класса для одного изображения за раз будет достаточно:

    prediction = svm.clf.predict([testDataGlobal[index, :]])

Обратите внимание, что testDataGlobal[index, :] должен быть заключен в квадратные скобки [ ], так как метод predict() ожидает двухмерную переменную, похожую на массив.

Во-вторых, и самое главное, давайте предположим, что функция glob выдает список из трех файлов изображений, а именно imgA.jpg, imgB.jpg и imgC.jpg, и обозначим их соответствующие векторы признаков какfeatsA, featsB и featsC.Для правильной работы вашего кода важно, чтобы testDataGlobal располагался следующим образом:

[featsA, 
 featsB, 
 featsC]

Если векторы элементов расположены в другом порядке, вы, вероятно, получите неправильные результаты.

Вы можете правильно пометить изображения с помощью следующего фрагмента (не проверено):

test_images = glob.glob("dataset/test/*.jpg")

for filename in test_images:
    img = cv2.imread(filename)
    img = cv2.resize(img, fixed_size)
    feature_vector = your_feature_extraction_method(img)
    prediction = svm.clf.predict([feature_vector])
    cv2.putText(img, prediction[0], (20, 30), 
                cv2.FONT_HERSHEY_TRIPLEX, .7 , (0, 255, 255), 2)
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.show()    

, где your_feature_extraction_method() обозначает функцию, которая использует изображение и возвращает его вектор объектов (в виде 1D-массива).

Примечание : не забудьте заключить feature_vector в квадратные скобки [ ].Вы также можете использовать любой из следующих подходов, чтобы увеличить размерность feature_vector в еще одном измерении:

    prediction = svm.clf.predict(feature_vector[None, :])
    prediction = svm.clf.predict(feature_vector[np.newaxis, :])
    prediction = svm.clf.predict(np.atleast_2d(feature_vector))
...