【问题标题】:KNN Classifier for simple digit recognition用于简单数字识别的 KNN 分类器
【发布时间】:2016-02-03 00:39:15
【问题描述】:

实际上,我有一个任务需要识别单个十进制数字作为文本识别过程的一部分。我已经得到了一组 JPEG 格式的一些数字图像。每个图像的大小为 160 x 160 像素。在这里检查了一些资源后,我设法编写了这段代码,但是:

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

【问题讨论】:

    标签: matlab image-processing computer-vision pattern-recognition


    【解决方案1】:

    因为你的问题是:

    1) 图像大小调整确实会影响整个过程的准确性。 回答:正如您在问题中提到的,您的图像已经是 160 x 160 的大小,imresize 不会影响它,但是如果您的图像尺寸太小,比如 60*60,它将执行插值以增加空间尺寸图像可能会影响数字的结构和形状,为了解决这种可变性,您的训练数据应该有更多的样本(每类至少 50 个样本),并且应该对数据进行一些预处理,例如 de-数字图像的倾斜。

    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 放入混淆矩阵(5,5)中;如果您的分类器将其预测为 3,则应在混淆矩阵(5,3)处 +1。最后添加confusion_mat的对角线元素并将其除以测试样本的总数。输出将是分类器的准确性。

    附:尝试每个类至少有 50 个样本,并在交叉验证期间将训练数据按 85:10 的比例划分,其中 90% 的样本应用于训练,其余 10% 应用于测试分类器。

    希望对您有所帮助。 随时分享您的想法。

    谢谢

    【讨论】:

      【解决方案2】:

      首先我认为 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
      

      【讨论】:

      • 感谢您的回答,但我只是想在不使用 Knnclassify 的情况下制作它,我如何将图像调整为更小的图像以及什么是 lab_train 或 lab_test?
      猜你喜欢
      • 2013-04-30
      • 1970-01-01
      • 2021-03-19
      • 2014-11-14
      • 2012-12-07
      • 2019-05-26
      • 2012-03-13
      • 2014-02-02
      • 2013-11-13
      相关资源
      最近更新 更多