1

實際上,我有一個作業,它需要識別單獨的十進制數字作爲文本識別過程的一部分。我已經給出了一組數字的JPEG格式圖像。每個圖像的大小爲160 x 160像素。在檢查了一些資源後,我設法編寫了這段代碼,但是:用於簡單數字識別的KNN分類器

1)我不確定是否讀取圖像並在矩陣中調整它們的大小以保持它們是正確的。

2)假設我有30個火車數據圖像的數字[0-9]每個數字有三個圖像,我有10個圖像測試每個圖像只有一個數字。如何計算每個測試和火車之間的距離在一個循環?因爲在我的計算歐幾里得的代碼中,它給出了一個輸出零。

3)如何使用混淆矩陣計算精度?

% number of train data 
Train = 30; 
%number of test data 
Test =10; 
% to store my images 
tData = uint8(zeros(160,160,30)); 
tTest = uint8(zeros(160,160,10)); 


for k=1:Test 
    s1='im-'; 
    s2=num2str(k); 
    t = strcat('testy/im-',num2str(k),'.jpg'); 
    im=rgb2gray(imread(t)); 
    I=imresize(im,[160 160]); 
    tTest(:,:,k)=I; 


    %case testing if it belongs to zero  

    for l=1:3 

    ss1='zero-'; 
    ss2=num2str(l); 
    t1 = strcat('data/zero-',num2str(l),'.jpg'); 
    im1=rgb2gray(imread(t1)); 

    I1=imresize(im1,[160 160]); 
    tData(:,:,l)=I1; 

    % Euclidean distance 
distance= sqrt(sum(bsxfun(@minus, tData(:,:,k), tTest(:,:,l)).^2, 2)); 
    [d,index] = sort(distance); 
    %k=3 
    % index_close(l) = index(l:3); 
    %x_close = I(index_close,:); 

    end  
end 

回答

0

首先,我認爲10個測試數據是不夠的。 只需使用下面的函數,data_test是您的訓練數據(),data_label是它們的標籤。重新調整您的圖像尺寸以縮小尺寸! 我認爲默認距離度量是歐幾里德距離,但您可以選擇其他方式,例如城市塊方法。

Class = knnclassify(data_test, data_train, lab_train, 11); 
fprintf('11-NN Accuracy: %f\n', sum(Class == lab_test')/length(lab_test)); 


Class = knnclassify(data_test, data_train, lab_train, 1, 'cityblock'); 
fprintf('1-NN Accuracy (cityblock): %f\n', sum(Class == lab_test')/length(lab_test)); 

好了,現在你有整體精度,但是這不是一個好辦法,最好是單獨計算精度爲每個類,然後計算其平均值。 就可以計算出一個特定的類(ID)的精度這樣,,

idLocations = (lab_test == id); 
    NumberOfId = sum(idLocations); 
    NumberOfCurrect =sum (lab_test (idLocations) == Class(idLocations)); 
    NumberOfCurrect/NumberOfId %Class id accuracy 
+0

謝謝您的回答,但我只是想讓它不使用Knnclassify也是,我怎麼能調整我的圖像轉換成小的什麼都lab_train或lab_test? – Suzy

0

爲你的問題是:

1)圖像尺寸調整不會影響整個過程的精度。 Ans:正如你在你的問題中提到的你的圖像的尺寸已經是160的160,imresize不會影響它,但是如果你的圖像尺寸太小,例如60 * 60,它會執行插值以增加空間尺寸圖像可能影響數字的結構和形狀,爲了應對這種變化,您的訓練數據應該有更多的樣本(每個類至少有50個樣本),並且一些預處理應該應用於數據,如去偏斜的數字圖像。 2)歐幾里得距離是一種很好的測量方法,但不是處理這類問題的最佳方法,因爲它的分佈是一個球形分佈,它可以給予不同的數字相同的距離。如果你在MATLAB工作中注意變量轉換,那麼你需要改變,所以這兩個變量本質上應該是雙重的。這可能是計算錯誤距離的原因之一。在這一行distance= sqrt(sum(bsxfun(@minus, tData(:,:,k), tTest(:,:,l)).^2, 2));你是矩陣明智的總結矩陣,所以這個輸出將是一個行向量(1 X 160),其中有每個角落的總和。我認爲它應該是這樣的:distance= sqrt(sum(sum(bsxfun(@minus, tData(:,:,k), tTest(:,:,l)).^2, 2)));我剛剛增加了一個額外的總和來獲得整個矩陣的差異總和嘗試它是否有幫助。

3)爲了準確檢查分類器的準確性,您必須擁有一個大型訓練數據集,順便說一句,在交叉驗證過程中創建混淆矩陣,將訓練數據分爲訓練樣本和測試樣本,所以你知道兩個樣本中的輸出類,現在執行分類過程,爲num_classe X num_classes(在你的情況下爲10 X 10)準備一個矩陣,其中行與實際類相似,而列屬於預測。從測試中取樣並預測輸出類別,假設你的分類器預測5和樣本的實際類別也是5把+1置於confusion_matrix(5,5)中;如果你的分類器預測它爲3,你應該在confusion_matrix(5,3)處做+1。最後添加confusion_mat的對角線元素並將其除以測試樣本的總數。輸出將是您的分類器的準確性。

P.S.試着每班至少有50個樣本,在交叉驗證過程中,將訓練數據85:10比例分爲90%樣本用於訓練,其餘10%用於測試分類器。

希望它能幫助你。 隨時分享您的想法。

謝謝