`
ljl_xyf
  • 浏览: 636009 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

神经网络和遗传算法应用在字符识别

    博客分类:
  • c#
阅读更多
using System;
using System.Collections.Generic;
using System.Text;


public class CharNet
{
public List lay = new List();
public int outputlen, inputlen, laylen;

public CharNet(int outputcount, int inputcout, int laylen)
{
output = new double[outputcount, outputcount];
for (int i = 0; i < outputcount; i++)
{
output[outputcount, outputcount] = 1.0;
}
}

protected void CreateNet(int outputcount, int inputcout, int laylen)
{
lay.Clear();

}

}


///
/// 包括返回的第几个字符和差值
///
public class OutputError
{
public int index = -1;
public double ErrorValue = double.MaxValue;
public const OutputError MaxValue = new OutputError();
public OutputError()
{
index = -1;
ErrorValue = double.MaxValue;
}

public OutputError(int idx,double err)
{
index = idx;
ErrorValue = err;
}

///
/// 判断是否错误时出现的最大值
///
///
public bool isMaxValue()
{
if (index == -1 && ErrorValue = double.MaxValue)
{
return true;
}
return false;
}
}


///
/// 最后输出标准
///
public class Output
{
public static double[,] data = null;
public static int datalen = 0;
public Output(int len)
{
datalen = len;
data = new double[len, len];
GetDefaultValue();
}


///
/// 检查input与哪个最像
///
///
///
public OutputError GetLike(double[] input)
{
if (input == null || input.Length != datalen)
{
return new OutputError();
}
double minError = double.MaxValue;
double nowErr=0.0;
int nowidx = -1;
for (int i = 0; i < datalen; i++)
{
nowErr=0.0;
for (int j = 0; i < datalen; i++)
{
if (minError < nowErr)
{//说明当前不可能是最小的
break;
}
nowErr += Math.Abs(input[j] - data[i, j]);
}
if (minError < nowErr)
{
nowidx = i;
minError = nowErr;
}
}
return new OutputError(nowidx, nowErr);
}


///
/// 取得默认的输出参数
///
///
public Output GetDefaultValue()
{
data.Initialize();
for (int i = 0; i < datalen; i++)
{
data[i, i] = 1.0;
}
return this;
}


}




///
/// 输入输出值
///
public class LayData
{
///
/// 输入参数
///
public double[] data;
///
/// 输入参数长度
///
public int datalen;

///
/// 当前输入是第几个字符
///
public int charindex = -1;

public LayData(int len)
{
datalen = len;
data = new double[len];
}
}






///
/// 层之间的权值
///
public class Lay
{
///
/// 本层的权限
///
public double[,] weights = null;

///
/// 本层的输入层数量
///
public int inputlen = 0;

///
/// 本层的输出层数量
///
public int outputlen = 0;


///
/// 交换最少基因
///
public uint changeCountMin = 3;

///
/// 交换最大基因
///
public uint chnageCountMax = 10;

///
/// 变异系数0-1之间,如果是1表示每次都要变异,0,表示不变异
///
public double bianyi = 0.001;


///
/// 当前层参数的评价值
///
public double Value = 0.0;


///
///
///
///
///
public Lay(int ilen, int olen)
{
weights = new double[ilen, olen];
inputlen = ilen;
outputlen = olen;
}





///
/// 使用权限计算,输入内容为input时,对应的output是什么
///
///
public double[] changeOutput(double[] input)
{
double[] output = new double[outputlen];
output.Initialize();
for (int j = 0; j < outputlen; j++)
{
for (int i = 0; i < inputlen; i++)
{
output[j] += weights[i, j] * input[i];
}
}
return output;
}



public static System.Random rnd = new Random((int)DateTime.Now.Ticks);

///
/// 随机生成
///
///
public void Random()
{
for (int i = 0; i < inputlen; i++)
{
for (int j = 0; j < outputlen; j++)
{
weights[i, j] = GetRndValue();
}
}
}

///
/// 初始化随机数
///
public static void ResetRnd()
{
rnd = new Random((int)DateTime.Now.Ticks);
}

///
/// 取得权限值
///
///
public static double GetRndValue()
{
return rnd.NextDouble() - rnd.NextDouble();
}




///
/// 复制本身
///
///
public Lay Copy()
{
Lay lay = new Lay();
lay.inputlen = this.inputlen;
lay.outputlen = this.outputlen;
lay.changeCountMin = this.changeCountMin;
lay.chnageCountMax = this.chnageCountMax;
lay.bianyi = this.bianyi;
weights.CopyTo(lay.weights, 0);
return lay;
}


///
/// 按当前参数,以本身为父,p1为母,生成新代NewCount*2个
///
///
///
///
public List ChangeNew(Lay p1, int NewCount)
{
if (p1.datalen != this.datalen)
{//p1和this不能生成后代
return null;
}
List list = new List();
int nowcount = 0;
int posi = 0;
int poso = 0;
double temp = 0.0;
Lay ch1, ch2;
for (int i = 0; i < NewCount; i++)
{
nowcount = rnd.Next(this.changeCountMin, this.chnageCountMax);
for (int j = 0; j < nowcount; j++)
{//交换j个参数
ch1 = this.Copy();
ch2 = p1.Copy();
posi = rnd.Next(0, this.inputlen);//要交换的位置
poso = rnd.Next(0, this.outputlen);//要交换的位置
temp = ch1.data[posi, poso];
ch1.weights[posi, poso] = ch2.data[posi, poso];
ch2.weights[posi, poso] = temp;
}
temp = rnd.NextDouble();
if (temp > this.bianyi)
{//要变异
int ccount = rnd.Next(1, datalen);//变异数量
for (int j = 0; j < ccount; j++)
{//对ch1变异
posi = rnd.Next(0, this.inputlen);//要交换的位置
poso = rnd.Next(0, this.outputlen);//要交换的位置
ch1.data[pos] = GetRndValue();
}
ccount = rnd.Next(1, datalen);//变异数量
for (int j = 0; j < ccount; j++)
{//对ch2变异
posi = rnd.Next(0, this.inputlen);//要交换的位置
poso = rnd.Next(0, this.outputlen);//要交换的位置
ch2.weights[posi, poso] = GetRndValue();
}
}
list.Add(ch1);
list.Add(ch2);
}
return list;
}



}





namespace Alibaba
{
public class NeuralNet
{
//相关系数
const double momentum = 0;
//最小均方误差
const double minex = 0.001;
//BP网络隐层结点的数目
const int hidden = 10;
//训练步长
const double eta = 0.015;
//网络输出层结点的个数
const int output = 4;
//输入层结点个数,,待识别图片的像素点个数
const int input = 156;


public static double[,] targetoutput = null;
public NeuralNet(int charcount)
{
targetoutput = new double[charcount, charcount];
targetoutput.Initialize();
for (int i = 0; i < charcount; i++)
{
targetoutput[i, i] = 1.0;
}
}




//理想输出模板
static double[] output0 = { 0.1, 0.1, 0.1, 0.1 };
static double[] output1 = { 0.1, 0.1, 0.1, 0.9 };
static double[] output2 = { 0.1, 0.1, 0.9, 0.1 };
static double[] output3 = { 0.1, 0.1, 0.9, 0.9 };
static double[] output4 = { 0.1, 0.9, 0.1, 0.1 };
static double[] output5 = { 0.1, 0.9, 0.1, 0.9 };
static double[] output6 = { 0.1, 0.9, 0.9, 0.1 };
static double[] output7 = { 0.1, 0.9, 0.9, 0.9 };
static double[] output8 = { 0.9, 0.1, 0.1, 0.1 };
static double[] output9 = { 0.9, 0.1, 0.1, 0.9 };

static double[][] outnumber = { output0, output1, output2, output3, output4, output5, output6, output7, output8, output9 };

//指向输入层于隐层之间权值的指针
static double[][] input_weights;
//指向隐层与输出层之间的权值的指针
static double[][] hidden_weights;
//指向上一此输入层于隐层之间权值的指针
static double[][] input_prev_weights;
//指向上一此隐层与输出层之间的权值的指针
static double[][] hidden_prev_weights;

static NeuralNet()
{
ran = new Random();
input_weights = new double[input + 1][];
hidden_weights = new double[hidden + 1][];
input_prev_weights = new double[input + 1][];
hidden_prev_weights = new double[hidden + 1][];

//对各种权值进行初始化
randomize_weights(input_weights, input, hidden);
randomize_weights(hidden_weights, hidden, output);
zero_weights(input_prev_weights, input, hidden);
zero_weights(hidden_prev_weights, hidden, output);
}



static double squash(double x)
{
return (1.0 / (1.0 + Math.Exp(-x)));
}

//生成-1~1的随机数
static Random ran;
static double getrandom()
{
double a = ran.NextDouble();
double b = ran.NextDouble();
return a - b;
}

///
/// 随机初始化权值
///
///
///
///
static void randomize_weights(double[][] w, int m, int n)
{
for (int i = 0; i <= m; i++)
{
double[] temp = new double[n + 1];
for (int j = 0; j <= n; j++)
temp[j] = getrandom();
w[i] = temp;
}
}
///
/// 0初始化权值
///
///
///
///
static void zero_weights(double[][] w, int m, int n)
{
for (int i = 0; i <= m; i++)
{
double[] temp = new double[n + 1];
for (int j = 0; j <= n; j++)
temp[j] = 0.0;
w[i] = temp;
}
}

///
/// 前向传输
///
///
///
///
///
///
static void LayerForward(double[] curr, double[] next, double[][] weights, int n1, int n2)
{
double sum;
/*** 设置偏置对应输入层值 ***/
curr[0] = 1.0;
/*** 对于第二层的每个神经元 ***/
for (int j = 1; j <= n2; j++)
{
/*** 计算输入的加权总和 ***/
sum = 0.0;
for (int k = 0; k <= n1; k++)
sum += weights[k][j] * curr[k];
next[j] = squash(sum);
}
}

///
/// 输出误差
///
///
///
///
///
static void OutputError(double[] delta, double[] target, double[] output, int nj)
{
double o, t;
for (int j = 1; j <= nj; j++)
{
o = output[j];
t = target[j];
delta[j] = o * (1.0 - o) * (t - o);
}
}

///
/// 隐含层误差
///
///
///
///
///
///
///
static void HiddenError(double[] delta_h, int nh, double[] delta_o, int no, double[][] weights, double[] hidden)
{
double h, sum;
for (int j = 1; j <= nh; j++)
{
h = hidden[j];
sum = 0.0;
for (int k = 1; k <= no; k++)
sum += delta_o[k] * weights[j][k];
delta_h[j] = h * (1.0 - h) * sum;
}
}



/* 调整权值 */
static void AdjustWeights(double[] delta, int ndelta, double[] ly, int nly, double[][] w, double[][] oldw, double eta, double momentum)
{
double new_dw;
ly[0] = 1.0;
for (int j = 1; j <= ndelta; j++)
{
for (int k = 0; k <= nly; k++)
{
new_dw = ((eta * delta[j] * ly[k]) + (momentum * oldw[k][j]));
w[k][j] += new_dw;
oldw[k][j] = new_dw;
}
}
}

///
/// 根据输入的特征向量和期望的理想输出向量对BP网络尽行训练,训练结束后将权值保存
///
/// 输入的特征向量
/// 理想输出特征向量
public static bool Train(List> data_in, List data_out)
{
//循环变量
int i, l, k, flag;
//指向输入层数据的指针
double[] input_layer = new double[input + 1];
//指向隐层数据的指针
double[] hidden_layer = new double[input + 1];
//指向输出层数据的指针
double[] output_layer = new double[hidden + 1];
//指向隐层误差数据的指针
double[] hidden_deltas = new double[hidden + 1];
//指向输出层误差数剧的指针
double[] output_deltas = new double[output + 1];
//指向理想目标输出的指针
double[] target = new double[output + 1];
//每次循环后的均方误差误差值
double ex = double.MaxValue;

//开始进行BP网络训练
//这里设定最大的迭代次数为15000次
for (l = 0; l < 15000; l++)
{
//对均方误差置零
ex = 0;
for (k = 0; k < data_in.Count; k++)
{
//将提取的样本的特征向量输送到输入层上
for (i = 1; i <= input; i++)
input_layer[i] = data_in[k][i - 1];

flag = data_out[k];
//将预定的理想输出输送到BP网络的理想输出单元
for (i = 1; i <= output; i++)
target[i] = outnumber[flag][i - 1];

//前向传输激活
//将数据由输入层传到隐层
LayerForward(input_layer, hidden_layer, input_weights, input, hidden);
//将隐层的输出传到输出层
LayerForward(hidden_layer, output_layer, hidden_weights, hidden, output);
//误差计算
//将输出层的输出与理想输出比较计算输出层每个结点上的误差
OutputError(output_deltas, target, output_layer, output);
//根据输出层结点上的误差计算隐层每个节点上的误差
HiddenError(hidden_deltas, hidden, output_deltas, output, hidden_weights, hidden_layer);
//权值调整
//根据输出层每个节点上的误差来调整隐层与输出层之间的权值
AdjustWeights(output_deltas, output, hidden_layer, hidden, hidden_weights, hidden_prev_weights, eta, momentum);
//根据隐层每个节点上的误差来调整隐层与输入层之间的权值
AdjustWeights(hidden_deltas, hidden, input_layer, input, input_weights, input_prev_weights, eta, momentum);
//误差统计
for (i = 1; i <= output; i++)
ex = (output_layer[i] - outnumber[flag][i - 1]) * (output_layer[i] - outnumber[flag][i - 1]);
}
ex = ex / Convert.ToDouble(data_in.Count*output);
if (ex < minex) break;
}

if (ex <= minex)
return true;
else
return false;
}

///
///读入输入样本的特征相量并根据训练所得的权值,进行识别
///
///
public static int Recognize(List data_in)
{
int i, result;

result = 0;
//指向输入层数据的指针
double[] input_layer = new double[input + 1];
//指向隐层数据的指针
double[] hidden_layer = new double[input + 1];
//指向输出层数据的指针
double[] output_layer = new double[hidden + 1];


//将提取的样本的特征向量输送到输入层上
for (i = 1; i <= input; i++)
input_layer[i] = data_in[i - 1];

//前向输入激活
LayerForward(input_layer, hidden_layer, input_weights, input, hidden);
LayerForward(hidden_layer, output_layer, hidden_weights, hidden, output);

//考察每一位的输出
//如果大于0.5判为1
for (i = 1; i <= output; i++)
{
if (output_layer[i] > 0.5)
result += (int)Math.Pow(2, Convert.ToDouble(4 - i));
}
return result;
}

}
}
 

 

分享到:
评论

相关推荐

    遗传算法神经网络,遗传算法神经网络区别,matlab

    遗传算法神经网络是一种结合了遗传算法(Genetic Algorithm, GA)与神经网络(Neural Network, NN)的优化技术,广泛应用于复杂问题的求解,如模式识别、预测分析、函数优化等。在MATLAB环境中,可以利用其强大的...

    汉英文字图片识别(神经网络,遗传算法)

    汉英文字图片识别技术是计算机视觉领域的一个重要分支,它主要涉及神经网络和遗传算法的应用。这项技术的主要目的是从图像中自动识别并提取出文本信息,对于自动化处理、信息检索和翻译等领域具有重要意义。 神经...

    几篇遗传算法的论文 神经网络的车牌识别系统 单亲遗传算法

    总的来说,这个压缩包提供的资料涵盖了遗传算法在多个领域的应用,包括优化问题的求解、神经网络驱动的图像识别以及能源管理和交通规划。这些论文展示了遗传算法的灵活性和广泛适用性,为相关领域的研究和实践提供了...

    C#模拟神经网络和遗传算法(示例工程).rar

    标题中的"C#模拟神经网络和遗传算法(示例工程)"表明这是一个使用C#编程语言实现的项目,旨在演示神经网络和遗传算法的应用。这个工程可能包含可运行的代码示例,帮助开发者理解这两种算法的工作原理及其在实际问题中...

    基于遗传算法的BP神经网络优化算法

    - **编码与解码:** 在遗传算法中,个体通常用二进制字符串表示,这些字符串代表BP神经网络的权重和阈值。解码过程则将这些字符串转化为实际的数值用于神经网络。 - **种群初始化:** 创建一个包含多个随机权重和...

    基于遗传算法的神经网络在露天矿卡车调度系统优化中的应用研究

    基于遗传算法的神经网络作为一种新兴的优化技术,在露天矿卡车调度系统中的应用越来越受到关注。 首先,让我们来探讨遗传算法的基础知识。遗传算法(Genetic Algorithm, GA)是一种模仿生物进化过程的搜索启发式...

    GASARBF.rar_RBF_RBF 遗传算法_rbf神经网络_遗传rbf_遗传算法 RBF

    遗传算法与RBF神经网络的结合应用在许多领域都有广泛的应用,如模式识别、系统辨识、控制工程和数据预测等。其优势在于能够自动搜索和调整网络结构,适应复杂问题的解决,且具有较强的全局优化能力。 总的来说,...

    基于遗传算法和Hopfield神经网络的字符识别方法

    分析了Hopfield神经网络和遗传算法的基本原理,探讨了Hopfield神经网络在字符识别中的应用,针对Hopfield神经网络易陷入局部最优的问题,提出了基于遗传算法的Hopfield神经网络的字符识别方法,利用遗传算法的全局...

    【验证码识别】基于遗传算法优化OUST结合BP神经网络实现数字验证码识别含Matlab源码.zip

    遗传算法可以对BP神经网络的权重和阈值进行优化,从而提高其泛化能力和识别准确性。OUST是一种优化方法,它用于改进卡尔曼滤波器的估计精度,可以更有效地处理非线性问题,与遗传算法结合能更好地调整神经网络参数。...

    基于遗传算法优化BP神经网络的弹体结构载荷识别.pdf

    在本研究中,遗传算法被用来优化BP神经网络的权重,以提高网络的收敛速度和识别精度。 3. **载荷识别**:在结构动力学中,载荷识别是根据结构的输出响应(如应变、位移)来估计输入激励的过程。这是一个非线性问题...

    基于神经网络的手写字符识别优化研究.pdf

    综上所述,本研究提出的优化策略,通过预处理、遗传算法优化的BP神经网络模型和Otsu阈值分割技术的综合应用,为小样本、噪声环境下的手写字符识别提供了一种有效解决方案。该方法不仅减轻了对大量训练数据的依赖,...

    【字符识别】基于BP神经网络实现字符识别含Matlab源码.zip

    【字符识别】基于BP神经网络实现字符识别含Matlab源码.zip这个压缩包文件主要包含了一个使用BP神经网络进行字符识别的项目,其中涉及到的知识点非常丰富,涵盖了多个IT领域,特别是机器学习和图像处理方面。...

    遗传算法与机器学习

    - **参数优化**: 在神经网络训练过程中,遗传算法可以用于优化网络结构的设计或调整权重和偏置等参数。 - **特征选择**: 遗传算法能够帮助识别出最具区分力的特征子集,从而减少模型复杂度并提高泛化能力。 - **分类...

    基于改进BP网络的车牌字符识别方法研究

    BP神经网络是人工神经网络的一种,广泛应用于模式识别和函数逼近等问题。传统的BP网络存在学习速度慢、易陷入局部最优以及过拟合等缺点。因此,对BP网络进行改进显得尤为必要。在本研究中,可能的改进策略包括但不...

    遗传算法课件 人工智能 算法设计

    《遗传算法在人工智能中的应用与理解》 遗传算法,作为一种模拟生物进化原理的全局优化方法,是人工智能领域...在未来的研究中,遗传算法的改进和与其他技术的结合,如深度学习和神经网络,有望带来更多的创新和突破。

    遗传算法(经典算法)

    在神经网络中,遗传算法可用于优化权重参数,提升网络性能。 总结,遗传算法作为一种经典算法,以其独特的优化机制和广泛的应用前景,对解决实际问题提供了有力的工具。通过不断迭代和改进,遗传算法能够在复杂的...

    神经网络入门级教材,简单易懂

    反馈网络,Hopfield网络及其在字符识别中的应用,支持向量机及其故障诊断,小波神经网络及其在控制与辨识中的应用。 本书内容全面,重点突出,以讲明基本概念和方法为主,尽量减少繁琐的数学推导,并给出一些结合...

    基于人工神经网络的车牌识别.pdf

    总结:基于人工神经网络的车牌识别技术通过预处理、字符分割和识别等步骤,利用神经网络和深度学习的强大识别能力,再结合遗传算法优化,提高了识别的准确性和速度,是现代交通系统中不可或缺的一部分。这种技术的...

Global site tag (gtag.js) - Google Analytics