bp神经网络人脸识别c语言,基于BP神经网络的人脸识别

本文探讨了阈值逻辑单元如何处理线性加权求和问题,并介绍人工神经网络,特别是BP神经网络在模拟非线性问题上的作用。通过实例展示了BP网络的学习过程,包括权重初始化、误差反向传播和训练迭代。Java代码实例演示了如何用神经网络进行人脸识别。
摘要由CSDN通过智能技术生成

一.阈值逻辑单元

阈值逻辑单元(threshold logic unit ,TLU),它可以输入一组加权系数的量,对它们进行求和,如果这个和达到或者超过了某个阈值,输出一个量。例如,输入为a1, a2, ..., an和权值 w1, w2, ..., wn。接着是求和计算出的 ai x wi ,产生了激发层 t,换一种方法表示:

t = f((a1 x w1)+(a2 x w2)+...+(aI x wI)+...+ (an x wn)+b)

bVvpl0

我理解的阈值逻辑单元就是用于解决多维线性加权求和问题的工具,那么遇到复杂问题该如何做呢?

二.人工神经网络

人工神经网络(Artificial Neural Networks,简写为ANNs)也简称为神经网络(NNs)或称作连接模型(Connection Model),它是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。

bVvpmu

通过将多个阈值逻辑单元组合,形成网络,用来模拟非线性的问题。有研究证明,三层的人工神经网络可以模拟各种函数。

三.BP神经网络

BP(Back Propagation)神经网络是一种按误差反向传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一。BP网络能学习和存贮大量的输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。它的学习规则是使用梯度下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小。

这里利用了偏导数的知识去推导计算公式,具体我没有列出,我自己在理解的时候是读了《人工智能》(机械工业出版社),感兴趣的朋友可以自己看一下。

BP神经网络调整权值的过程更像是一种函数图像逼近的过程,首先猜测一个函数,然后读入一个数据点,根据数据点和函数图像之间的差距调整函数,使得函数图像更符合数据。不断迭代,使得整个数据样本都较为符合我们估计得函数。

四.步骤:

1.对权系数置初值

2.输入一组样本及它的希望输出

3.计算实际输出值

4.计算误差值

5.反向传播误差值并调整权值

6.不断训练(重复步骤2~5)

7.利用完成后的神经网络进行预测

五.Java代码:

import java.io.File;

import java.io.RandomAccessFile;

import java.util.Random;

public class FaceRecognition {

private int picSize = 19 * 19;// 图像大小

private int hiddenSize = 12;// 隐藏层节点个数

private byte[] imageinfor = new byte[374];// 存放图像信息

private double[] input = new double[picSize + 1];// 归一化后的图像信息

private double[][] inputWeight = new double[hiddenSize][picSize + 1];// 输入层参数

private double[] alpha1 = new double[hiddenSize];// 隐藏层调整的梯度

private double[] hiddenWeight = new double[hiddenSize + 1];// 隐藏层参数

private double[] hiddenOutput = new double[hiddenSize + 1];// 隐藏层输出

private double alpha2;// 输出层调整的梯度

private double output;// 输出层

private double ci = 0.3;// 学习率

private double opt;// 期望输出

Random random = new Random();

private double [] pro;

public FaceRecognition() {

}

// 初始化

public void init() {

for (int i = 0; i < hiddenSize; i++) {

for (int j = 0; j < picSize + 1; j++)

inputWeight[i][j] = random.nextDouble() * 2 - 1;

// inputWeight[i][j] =0;

}

for (int i = 0; i < hiddenSize + 1; i++) {

hiddenWeight[i] = random.nextDouble() * 2 - 1;

// hiddenWeight[i]=0;

}

}

// sigmoid

private double Sigmoid(double x) {

return 1.0d / (1.0d + Math.exp(-x));

}

// 图像文件读入

public void PGMReader(String filename) {

File file = new File(filename);

try {

RandomAccessFile in = new RandomAccessFile(file, "r");

in.read(imageinfor);

in.close();

} catch (Exception e) {

e.printStackTrace();

}

for (int i = 0; i < picSize; i++) {

int temp = (int) imageinfor[i + 13];

input[i] = (double) (temp + 128) / 255;

}

input[picSize] = 1.0;

}

public void PGMReader(File file) {

try {

RandomAccessFile in = new RandomAccessFile(file, "r");

in.read(imageinfor);

in.close();

} catch (Exception e) {

e.printStackTrace();

}

for (int i = 0; i < picSize; i++) {

int temp = (int) imageinfor[i + 13];

input[i] = (double) (temp + 128) / 255;

}

input[picSize] = 1.0;

}

public void setOpt(double opt) {

this.opt = opt;

}

private void forward() {

for (int i = 0; i < hiddenSize; i++) {

double temp = 0;

for (int j = 0; j < picSize + 1; j++) {

temp += input[j] * inputWeight[i][j];

}

hiddenOutput[i] = Sigmoid(temp);

}

hiddenOutput[hiddenSize] = 1.0;

double temp = 0;

for (int i = 0; i < hiddenSize + 1; i++) {

temp += hiddenOutput[i] * hiddenWeight[i];

}

output = Sigmoid(temp);

}

public void BP() {

// 计算各层的梯度

alpha2 = (opt - output) * output * (1 - output);

for (int i = 0; i < hiddenSize; i++) {

alpha1[i] = hiddenOutput[i] * (1 - hiddenOutput[i]) * alpha2 * hiddenWeight[i];

}

// 反向传播

for (int i = 0; i < hiddenSize; i++) {

hiddenWeight[i] += ((hiddenOutput[i] * alpha2 * ci) );

for (int j = 0; j < picSize + 1; j++) {

inputWeight[i][j] +=((input[j] * alpha1[i] * ci));

}

}

hiddenWeight[hiddenSize]+=(hiddenOutput[hiddenSize] * alpha2 * ci);

}

public void train() {

String non_facePath = "D://人工智能//face.train//train//non-face";

File non_facFile = new File(non_facePath);

File[] non_faceList = non_facFile.listFiles();

String facePath = "D://人工智能//face.train//train/face";

File faceFile = new File(facePath);

File[] faceList = faceFile.listFiles();

init();

pro =new double [151];

for(int i =0;i<151;i++){

int right = 0;

int facenumber =0;

int nonfacenumber =0;

for (int j = 0; j < 4000; j++) {

int temp = random.nextInt();

if(temp%2 ==0)

{ // 正例训练

this.setOpt(1.0);

this.PGMReader(faceList[facenumber]);

this.forward();

this.BP();

facenumber++;

}

else{ // 反例训练

this.setOpt(0.0);

this.PGMReader(non_faceList[nonfacenumber]);

this.forward();

this.BP();

nonfacenumber++;

}

}

for (int j = 2000; j <2400; j++) {

{ // 正例测试

this.PGMReader(faceList[j]);

this.forward();

if (output > 0.5)

right++;

}

{ // 反例测试

this.PGMReader(non_faceList[j]);

this.forward();

if (output < 0.5)

right++;

}

}

pro[i] = (double) right / 800;

if(i%10==0)

{

System.out.println("第"+i+"次迭代估算正确率为:" + pro[i]);

}

if(pro[i]>=0.95){

System.out.println("第"+i+"次迭代估算正确率为:" + pro[i]);

break;

}

}

}

}

这里我采用的数据的格式是PGM,19*19大小的,训练集一共有4800张,一半正例一半反例。

具体的实现,我感觉代码写的比较清楚,我就不赘述了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值