AI 神经网络错误的手写数字预测由于反色。 Octave/Matlab?

AI Neural Network Wrong Handwritten Digit Prediction due to inverted color. Octave/Matlab?

我在 Octave 中的程序使用神经网络来识别手写数字。问题是如果颜色改变,它将无法正确识别数字。但如果颜色反转,则预测不正确。例如:


上面的图片包含相同的数字和相同的图案。但是他们有反色。

我已经在使用 RGB 到 GrayScale 的转换。如何克服这个问题?有没有比对倒置彩色图像使用单独的训练示例更好的选择?

边缘提取

如果您从图像中提取边缘,您会发现它在这方面基本上是不变的,图像的两个版本在转换后看起来几乎相同

下面我展示了使用拉普拉斯边缘检测提取边缘时图像的外观,对于 "white on black" 和 "black on white" 图像:

这个想法是在边缘训练你的网络,以获得关于你描述的变化的一些不变性。

以下是 MATLAB/OCtave 用于边缘提取的一些资源:

https://mathworks.com/discovery/edge-detection.html https://octave.sourceforge.io/image/function/edge.html

我已经使用 Python 和 OpenCV 使用 edges_image = cv2.Laplacian(original_image, cv2.CV_64F) 完成了边缘提取。如果我可以修复我的安装,我可能会 post 一个 MATLAB/Octave 示例 :)

检测主色并在需要时反转

另一种方法是决定您要使用一个版本,假设您已经在 "Black text on white background" 变体上训练了网络。

现在当您输入图像时,首先检测主色/背景是黑色还是白色,然后根据需要进行反转。

特征提取

为了概括@bakkal 关于使用边缘的建议,可以提取多种类型的 image features. These include edges, corners, blobs, ridges, etc.. There is actually a page on mathworks with a few examples, including number recognition using HOG features(定向梯度直方图)。

此类技术也适用于更复杂的图像,因为边缘并不总是最好的特征。使用 matlab extractHOGFeatures:

从你的两个图像中提取 HOG 特征

我相信如果你有 Octave,你可以使用 vlfeat 来获得 HOG 特征。

另一件需要牢记的重要事情是,您希望所有图像都具有相同的大小。我已将您的两张图片调整为 500x500,但这是任意的。

上面生成图片的代码

close all; clear; clc;

% reading in
img1 = rgb2gray(imread('img1.png'));
img2 = rgb2gray(imread('img2.png'));

img_size = [500 500]; % 

% all images should have the same size
img1_resized = imresize(img1, img_size);
img2_resized = imresize(img2, img_size);

% extracting features
[hog1, vis1] = extractHOGFeatures(img1_resized);
[hog2, vis2] = extractHOGFeatures(img2_resized);

% plotting
figure(1);
subplot(1, 2, 1);
plot(vis1);
subplot(1, 2, 2);
plot(vis2);

您不必局限于 HOG 功能。也可以赶紧试试SURF features

同样,颜色反转并不重要,因为特征匹配。但是你可以看到 HOG 特征在这里可能是更好的选择,因为绘制的 20 points/blobs 并不能很好地代表数字 6.. 在 matlab 中获得上面的代码。

% extracting SURF features
points1 = detectSURFFeatures(img1_resized);
points2 = detectSURFFeatures(img2_resized);

% plotting SURF Features
figure(2);
subplot(1, 2, 1);
imshow(img1_resized);
hold on;
plot(points1.selectStrongest(20));
hold off;
subplot(1, 2, 2);
imshow(img2_resized);
hold on;
plot(points2.selectStrongest(20));
hold off;

总而言之,根据问题,您可以选择不同类型的特征。大多数时候选择原始像素值并不够好,正如您从自己的经验中看到的那样,除非您有一个包含所有可能情况的非常大的数据集。