资讯专栏INFORMATION COLUMN

基于BP神经网络的人脸识别

izhuhaodev / 1143人阅读

摘要:有研究证明,三层的人工神经网络可以模拟各种函数。三神经网络神经网络是一种按误差反向传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一。

一.阈值逻辑单元

 阈值逻辑单元(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)


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

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


通过将多个阈值逻辑单元组合,形成网络,用来模拟非线性的问题。有研究证明,三层的人工神经网络可以模拟各种函数。
三.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张,一半正例一半反例。
具体的实现,我感觉代码写的比较清楚,我就不赘述了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/19604.html

相关文章

  • 基于BP神经网络人脸识别

    摘要:有研究证明,三层的人工神经网络可以模拟各种函数。三神经网络神经网络是一种按误差反向传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一。 一.阈值逻辑单元 阈值逻辑单元(threshold logic unit ,TLU),它可以输入一组加权系数的量,对它们进行求和,如果这个和达到或者超过了某个阈值,输出一个量。例如,输入为a1, a2, ..., an和权值 w1, w2...

    罗志环 评论0 收藏0
  • Ruff Chain 双周报 | 5月13日-5月24日

    摘要:据悉,上海的人工智能和物联网实验室是微软全球的第四个实验室。微软实验室致力于为来自各个行业的企业创造价值,全球已累计服务企业余个,超过半数的企业有多个项目在不同时段获得了微软实验室的指导。 showImg(https://segmentfault.com/img/bVbrOPB?w=1280&h=719);在过去的两周,RuffChain 完成了测试网络的代码审计工作,目前正在进行主网...

    shiina 评论0 收藏0
  • 浅析 Hinton 最近提出 Capsule 计划

    摘要:近几年以卷积神经网络有什么问题为主题做了多场报道,提出了他的计划。最初提出就成为了人工智能火热的研究方向。展现了和玻尔兹曼分布间惊人的联系其在论文中多次称,其背后的内涵引人遐想。 Hinton 以深度学习之父 和 神经网络先驱 闻名于世,其对深度学习及神经网络的诸多核心算法和结构(包括深度学习这个名称本身,反向传播算法,受限玻尔兹曼机,深度置信网络,对比散度算法,ReLU激活单元,Dropo...

    Donald 评论0 收藏0
  • 浅谈人脸识别技术方法和应用

    摘要:人脸识别技术所独具的活性判别能力保证了他人无法以非活性的照片木偶蜡像来欺骗识别系统。人脸识别技术所采用的依据是人脸照片或实时摄取的人脸图像,因而无疑是最容易获得的。 人脸识别是近年来模式识别、图像处理、机器视觉、神经网络以及认知科学等领域研究的热点课题之一,被广泛应用于公共安全(罪犯识别等)...

    Charles 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<