精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品原创,禁止全文或局部转载,禁止任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创内容。
锐英源软件前些年从事过语音识别项目开发,对于神经网络认识非常深刻,网络节点上也是分层的,这个非常重要。本文翻译自codeproject,看不懂codeproject,找锐英源。
介绍
如今,人工神经网络已广泛应用于人类生活的许多领域。然而,为像手写识别系统这样的大型分类器创建一个高效的网络仍然是科学家面临的一大挑战。在我的上一篇题为“使用UNIPEN数据库的在线手写识别系统库”的文章中,我为手写识别系统提供了一个高效的库,它可以简单地创建、更改神经网络。演示程序对数字集(97%)和字母集(93%)显示出良好的识别结果。本文我将继续介绍一个解决方案,用于一般的大模式分类和手写识别
用于识别系统的神经网络
在传统的模式识别模型中,手工设计的特征提取器从输入中收集相关信息,并消除不相关的变量。训练器分类器(通常,标准的、完全连接的多层神经网络可以用作分类器)然后将生成的特征向量分类为类。然而,它可能存在一些影响识别结果的问题。卷积神经网络(CNN)解决了传统神经网络的这一缺点,以在模式识别任务中获得最佳性能。
CNN是多层神经网络的一种特殊形式。与其他网络一样,CNN由反向传播算法训练。区别在于他们的架构。卷积网络结合了三种架构思想,以确保一定程度的移位、尺度和失真不变性:局部感受野、共享权重(或权重复制)空间或时间子采样。它们被特别设计为以最少的预处理操作直接从数字图像中识别图案。Yahn LeCun博士和Patrice Simard博士的文章对CNN的架构细节进行了全面描述(参见我之前的文章)。
上述网络的识别结果对于小型模式集合(如数字、大写字母或小写字母等)来说确实很高。然而,当我们想创建一个更大的神经网络,它可以识别更大的集合,如数字和英文字母(62个字符)时,问题就开始出现了。找到一个优化的、足够大的网络变得更加困难,通过大的输入模式训练网络需要更长的时间。网络的收敛语音较慢,尤其是由于较大的不良书写字符、许多相似和易混淆的字符等,假设我们可以创建一个足够好的网络,它可以准确地识别英文字符,但它肯定不能正确地识别超出其输出集的特殊字符(俄语或中文字符),因为它没有扩展能力。因此,为非常大的模式分类器创建一个独特的网络是非常困难的,而且可能是不可能的。
针对上述问题提出的解决方案是,我们可以使用多个较小的网络,而不是使用唯一的大网络,这些网络对这些自己的输出集具有非常高的识别率。除了官方输出集(数字、字母…),这些网络还有一个未知输出(未知字符)。这意味着,如果输入模式未被识别为官方输出的字符,则它将被理解为未知字符。然后,输入模式将被传送到下一个网络,直到系统能够正确识别它。
该解决方案几乎克服了传统模型的限制。新系统包括几个小网络,这些网络很容易优化以获得最佳识别结果。与庞大的网络相比,训练这些小型网络所需的时间更少。特别是,新模型非常灵活和可扩展。根据需要,我们可以加载一个或多个网络;我们还可以在系统中添加新的网络来识别新的模式,而无需更改或重建模型。所有这些小网络对于其他多神经网络系统都具有可重用的能力。
实验
演示程序旨在展示识别系统的所有阶段,包括:创建组件网络、训练网络、在UNIPEN数据集上测试网络以及在鼠标绘图控件上测试网络。这是一些教程,可以帮助每个人理解识别系统。所有功能都可以在程序GUI上实现。因此,您可以在运行时创建、训练和测试网络,而无需更改任何代码或重新启动程序。
创建新的神经网络完全基于GUI。创建网络取决于输入模式大小、层数、数据集…。在输出层,我们可以选择“未知输出”复选框来为网络创建额外的未知输出,或者忽略它来创建正常网络。
当然,我们仍然可以通过代码创建网络:
void CreateNetwork() { network = new ConvolutionNetwork(); //layer 0: inputlayer network.Layers = new Layer[6]; network.LayerCount = 6; InputLayer inputlayer = new InputLayer("00-Layer Input", new Size(29, 29)); network.InputDesignedPatternSize = new Size(29, 29); inputlayer.Initialize(); network.Layers[0] = inputlayer; ConvolutionLayer convlayer = new ConvolutionLayer("01-Layer ConvolutionalSubsampling", inputlayer, new Size(13, 13), 10, 5); convlayer.Initialize(); network.Layers[1] = convlayer; convlayer = new ConvolutionLayer("02-Layer ConvolutionalSubsampling", convlayer, new Size(5, 5), 60, 5); convlayer.Initialize(); network.Layers[2] = convlayer; FullConnectedLayer fulllayer = new FullConnectedLayer("03-Layer FullConnected", convlayer, 200); fulllayer.Initialize(); network.Layers[3] = fulllayer; fulllayer = new FullConnectedLayer("04-Layer FullConnected", fulllayer, 100); fulllayer.Initialize(); network.Layers[4] = fulllayer; OutputLayer outputlayer = new OutputLayer("05-Layer Output", fulllayer, Letters3.Count, true); outputlayer.Initialize(); network.Layers[5] = outputlayer; network.TagetOutputs = Letters3; network.UnknownOuput = '?'; }
训练网络
使用“创建网络”功能创建神经网络后,将使用UNIPEN数据库对网络进行训练。
根据网络大小,我们可以在UNIPENdata文件夹中选择训练集1a、1b或1c。训练过程的统计可以显示许多有用的信息,如:历元数、MSE、每个历元的训练时间、成功率…
UNIPEN数据浏览器和识别测试<o:p>
演示程序中的UNIPEN数据浏览器控件可以显示所有UNIPEN的数据文件。我们还可以通过加载经过训练的网络参数文件,在这些文件上测试经过训练的神经网络。图像10
鼠标绘图控件基于Alex Fr的优秀文章“DrawTools”。我只是修改了一些代码以符合我的要求。图像中的草书文本通过以下相同算法被分成行、字和孤立字符:
private void btRecognition_Click(object sender, EventArgs e)
<pre> {
//recognition all characters in the drawArea
if (bitmap != null)
{
bitmap.Dispose();
bitmap = null;
}
bitmap = new Bitmap(drawArea.Width, drawArea.Height);
drawArea.DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
drawBitmap =(Bitmap) bitmap.Clone();
if (bitmap != null)
{
lbRecognizedText.Items.Clear();
List<InputPattern> lineList=null;
List<InputPattern> wordList=null;
InputPattern parentPt=new InputPattern(bitmap,255,new Rectangle(0,0,bitmap.Width,bitmap.Height));
lineList = GetPatternsFromBitmap(parentPt,500,1,true,10,10);
if (lineList.Count > 0)
{
if (characterList != null)
{
characterList.Clear();
characterList = null;
}
characterList = new List<InputPattern>();
foreach (var line in lineList)
{
String text = "";
wordList = GetPatternsFromBitmap(line, 50, 10,false, 10, 10);
if (wordList != null)
{
if (wordList.Count > 0)
{
foreach (var word in wordList)
{
List<InputPattern> charList = GetPatternsFromBitmap(word, 5, 5, false, 10, 10);
//check if have part bitmaps
if (charList != null)
{
if (charList.Count > 0)
{
panelNavigation.Visible = true;
foreach (var c in charList)
{
characterList.Add(c);
c.GetPatternBoundaries(5,5,false,10,10);
Char accChar = new Char();
PatternRecognition(c.OriginalBmp,out accChar);
if (accChar != '\0')
{
text = String.Format("{0}{1}", text, accChar.ToString());
drawBitmap = c.DrawChildPatternBoundaries(drawBitmap);
}
}
}
}
text = String.Format("{0} ", text);
}
}
}
lbRecognizedText.Items.Add(text);
}
}
pbPreview.Image = drawBitmap;
lblNavigation.Text = characterList.Count.ToString();
index = 0;
}
}
为了激活识别功能,我只需加载经过训练的网络参数文件。根据我的识别要求,我可以加载一个、两个或所有文件。如果我只加载一个网络来识别其输出字符,识别结果真的很好(90%以上)。然而,当我加载多个网络时,系统的准确率会变低。主要原因是草书文本中有许多易混淆的字符;训练集不够大等等。
对于像手写字符这样的大型模式集合,有这么多相似的字符,在某些情况下,它们不仅会让机器感到困惑,还会让人感到困惑,例如:O、0和O;9、4、g、q等。这些字符会使网络误认。因此,该解决方案正在升级,通过在系统输出端使用额外的拼写检查器/投票模块,显著提高了识别率。输入模式将被所有组件网络识别。这些输出(未知输出除外)将被设置为拼写检查器/投票模块的输入。该模块将根据以前识别的字符、内部字典和其他因素来决定哪一个将是最准确的识别字符。
结论
所提出的识别模型解决了大型识别系统的许多问题:识别大型伙伴集合的能力、灵活的设计和部署、可扩展和可重用的能力等。通过提高组件网络的识别率、使用拼写检查器/投票模块等,提高系统的准确率也更容易。演示程序还证明了该库的容量,该库应用于许多其他应用程序,如预测应用程序、人脸识别。。。
未来工作和升级
某些功能将被添加到库中:
-LeNET模型的卷积和采样层。
-拼写检查器/投票模块
-字符分割。
目前,这个项目占用了我很多空闲时间。在我能够重新安排一切和/或找到一个新的好的赞助商之前,这应该是减速或暂时停止。然而,对文章的投票/评论将决定项目是否继续。我非常感谢收到对文章的评论和建议,特别是对模型、拼写检查模块和字符分割算法的评论和意见。。。