我正在尝试用单层感知器进行手写识别,使用Java中的MNIST数据库。每个感知器被指定识别一个数字(所以10个感知器)。它们每个都在50,000个样本中的每一个上随机训练多个时期。测试时,选择具有最高速率的感知器(即最有信心的感知器)。
使用这种方法,我的准确率一直达到93.5%。但是,我认为要改进我需要添加隐藏层,并实现反向传播。当使用Sigmoid(压缩)功能来计算我的单层网络的前向传递时,它可以很好地工作。然而,当我改变我的向后传递(学习)功能以匹配反向传播时,我得到~70%的准确度。有人可以检查我的算法以确保这是正确的吗?
我从几个地方得到了算法,我认为它是一样的。例如,这一个:http://www.webpages.ttu.edu/dleverin/neural_network/neural_networks.html
注意我将最后一个体重视为偏见。输入学习函数的“错误”只是期望的结果减去实际结果。 example是与输入相同的数组 - 数字中每个像素的灰度。
Forward pass:
public final double apply( double[] input ) {
double ret = 0;
for (int i=0; i<wei.length-1; i++){
ret = ret + input[i]*wei[i];
}
ret+=wei[wei.length-1];
//apply squashing function
ret = 1/(1+Math.exp(-ret));
return ret;
}
Learning Function (backwards Pass)
public final void learn( double error, double result, double[] example, double alpha ) {
for (int i=0; i<wei.length-1; i++){
//wei[i] = wei[i] + alpha*error*example[i]; //This was original learning function - it gives 93.5% accuracy
wei[i]=wei[i]+ alpha* error * example[i]*result*(1-result); //This line gives ~70% accuracy
}
//wei[wei.length-1] += alpha*error; //this line works for bias
wei[wei.length-1]=wei[wei.length-1]+ alpha* error * 1*result*(1-result); //again, this makes results inaccurate
}
答案 0 :(得分:0)
今天早上我在这里http://visualstudiomagazine.com/articles/2013/03/01/pattern-recognition-with-perceptrons.aspx得到了关于算法和实现的最佳解释。它详细解释了C#中用于字符识别的逐个感知器源代码。