用于光学标记识别的神经网络?

人工智能 神经网络 机器学习 深度学习 卷积神经网络 计算机视觉
2021-11-10 10:30:19

我使用具有 3 个完全连接的隐藏层的 ConvNetSharp 库创建了一个神经网络。第一个有 35 个神经元,另外两个每个有 25 个神经元,每层都有一个 ReLU 层作为激活函数层。

我正在使用这个网络进行图像分类 - 有点。基本上,它将输入作为输入图像的原始灰度像素值并猜测输出。我使用随机梯度下降来训练模型,学习率为 0.01。输入图像是一行或一列 OMR“气泡”,网络必须猜测哪个“气泡”被标记(即填充)并显示该气泡的索引。

我认为这是因为网络很难在众多泡沫中识别出单个填充的泡沫。

这是 OMR 部分的示例图像: OMR 气泡示例

使用图像预处理给网络提供上述图像的单行或单列来评估标记的图像。

这是网络看到的预处理图像的示例:

OMR 气泡柱 - 网络所见

以下是标记输入的示例:

标记的 OMR 列

我尝试使用卷积网络,但我无法让他们使用它。

基本上,我的问题是我应该使用哪种类型的神经网络和网络架构来完成此类任务?将不胜感激这种带有代码的网络的示例。

我尝试了许多预处理技术,例如使用 EmguCv 中的 AbsDiff 函数和 MOG2 算法的背景减法,我还尝试了阈值二进制函数,但图像中仍然存在足够的噪声,这使得神经网络难以学习.

我认为这个问题并不特定于将神经网络用于 OMR,而是针对其他问题。如果有一个解决方案可以使用相机存储背景/模板,然后当相机再次看到该图像时,它会透视转换它以与模板完全匹配

我能够做到这一点 - 然后找到它们的差异或进行某种预处理,以便神经网络可以从中学习。如果这不太可能,那么是否有一种神经网络可以检测图像中非常小的特征并从中学习。我已经尝试过卷积神经网络,但这也不是很好,或者我没有有效地应用它们。

3个回答

据我了解,不要为 CNN 烦恼,你的图像结构基本上是完美的。

您可以手动代码检测器来测量一个圆圈中填充了多少。

基本上做模板对齐,然后搜索圆圈。

例如,一个简单的检测器将测量圆形的平均黑度,然后您可以对其进行阈值处理。

我不熟悉 ConvNetSharp 库,标签convolutional-neural-networks让我有点困惑,但来自:

因此,我使用具有 3 个全连接隐藏层的 ConvNetSharp 库创建了一个神经网络。第一个有 35 个神经元,另外两个有 25 个神经元,每个神经元都有一个 ReLU 层作为激活函数层。

我假设您正在构建一个密集连接的神经网络。如我错了请纠正我。


您需要的神经网络类型是卷积神经网络

对于图像识别(这是你的情况),卷积网络几乎总是答案。

有很多类型的 CNN,只需选择一个看起来合适的并尝试。

在我看来,您的任务似乎很简单,您不需要真正深入/复杂的架构。


如果有一个解决方案可以使用相机存储背景/模板,然后当相机再次看到该图像时,那就太好了

我不知道有什么模型可以满足您的要求。

但是您要问的并不是真正的“神经网络”思维方式。构建神经网络的目标是不指定任何内容。神经网络将为您学习并找到特征。所以你只需要给他很多数据,他就能识别你的模式。

看看这个 CNN 过滤器的可视化:

在此处输入图像描述

在这里,没有人给神经网络提供鼻子的模板、眼睛的模板或脸的模板。CNN 通过大量图像了解了这一点。

如果填写其中一个数字是不是这样?如果是这样,具有 10 个输出的 CNN 应该可以正常工作。只需选择概率最高的输出即可。如果您的数据不允许填写任何数字,则有 11 个输出,其中第十一个输出表示未填写任何数字。我建议使用 MobileNet 模型进行迁移学习。文档在这里这是使 MobileNet 适应您的问题的代码:

image_size=128
no_of_classes=10  # set to 11 if in some cases no numbers are filled in
lr_rate=.001
dropout=.4
mobile = tf.keras.applications.mobilenet.MobileNet( include_top=False,
                                                           input_shape=(image_size,image_size,3),
                                                           pooling='avg', weights='imagenet',
                                                           alpha=1, depth_multiplier=1)
x=mobile.layers[-1].output
x=keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
x=Dense(128, kernel_regularizer = regularizers.l2(l = 0.016),activity_regularizer=regularizers.l1(0.006),
                bias_regularizer=regularizers.l1(0.006) ,activation='relu')(x)
x=Dropout(rate=dropout, seed=128)(x)
x=keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
predictions=Dense (no_of_classes, activation='softmax')(x)
model = Model(inputs=mobile.input, outputs=predictions)    
for layer in model.layers:
    layer.trainable=True
model.compile(Adam(lr=lr_rate), loss='categorical_crossentropy', metrics=['accuracy']) 

我还将创建一个训练、测试和验证集,其中测试集中有大约 150 张图像,验证集中有 150 张图像,剩下 1700 张图像用于训练。我还建议您使用两个有用的回调。文档在这里使用 ReduceLROnPlateau 回调来监控验证损失并将学习率向下调整一个因子。使用 ModelCheckpoint 监控验证损失并保存具有最低验证损失的模型以用于对测试集进行预测。