码迷,mamicode.com
首页 > 编程语言 > 详细

感知器算法

时间:2017-12-23 23:07:15      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:void   pac   分享图片   错误   stream   add   输出   space   程序   


title: 感知器算法做模式识别
date: 2017-12-23 21:04:54
tags: 模式识别
categories: c++


感知器算法是线性分类器中的一种。
这种算法的基本思想是:
对于初始的或者迭代中的增广权矢量W,用训练模式检验其合理性。当不合理时,对其进行校正,利用梯度下降法。梯度下降法也是人工神经网络中线性阈值神经元的学习算法。

感知器算法的基本步骤:

  1. 给定一个增广的训练模式集合{x1, x2, …, xN},其中每个模式类别已知,分别属于?1类和?2类。
  2. 输入训练模式xk,计算判别函数值WT(k)xk
  3. 训练样本分量增广化和符号规范化。
  4. 按照判别规则调整增广权矢量
    技术分享图片
  5. 如果在用全部模式训练完一轮后,如果仍有模式被错分,则需要进行第二轮、第三轮迭代,直到所有模式都能够正确分类为止

样例输入文件
in.txt

2 2 2
0 0 0 1
1 0 1 1

样例输出


输入样本维度,第一类样本个数,第二类样本个数: 
输入第一类样本:
输入第二类样本:
k = 1     x = 1     d = 1
k = 2     x = 2     d = 2
k = 3     x = 3     d = -2
更新增广权矢量:      w = (0,1,0)
k = 4     x = 4     d = -1
更新增广权矢量:      w = (-1,0,-1)
k = 5     x = 1     d = -1
更新增广权矢量:      w = (-1,0,0)
k = 6     x = 2     d = 0
更新增广权矢量:      w = (-1,1,1)
k = 7     x = 3     d = 0
更新增广权矢量:      w = (-2,1,0)
k = 8     x = 4     d = 1
k = 9     x = 1     d = 0
更新增广权矢量:      w = (-2,1,1)
k = 10    x = 2     d = 2
k = 11    x = 3     d = 1
k = 12    x = 4     d = 0
更新增广权矢量:      w = (-3,0,0)
k = 13    x = 1     d = 0
更新增广权矢量:      w = (-3,0,1)
k = 14    x = 2     d = 1
k = 15    x = 3     d = 2
k = 16    x = 4     d = 2
k = 17    x = 1     d = 1
k = 18    x = 2     d = 1
k = 19    x = 3     d = 2
k = 20    x = 4     d = 2
最终所求解向量为:   -3 0 1 

C++程序

#include "iomanip"
#include "iostream"

using namespace std;

/*
感知器算法:

1. 录入样本,每个样本属于类别c1 OR c2
2. 将训练样本增加一个分量1
3. 属于c2的样本*(-1)
4. 给增广权矢量赋值w[1]=(1,1,1),取增量p=1,迭代步数k=1
*/

int c[100][100];  //存储样本
int w[100];       //增广权矢量
int p = 1;  //增量
int k = 1;  //迭代步数
int D;        //样本维度
int n;        //第一类样本个数
int m;        //第二类样本个数

//计算w'(k)X
int d(int x[]) {
    int sum = 0;
    for (int i = 0; i <= D; i++) sum += (w[i] * x[i]);
    return sum;
}

//更新增广权矢量
void add(int x[]) {
    for (int i = 0; i <= D; i++) w[i] += x[i];
}

int main() {
    freopen("in.txt", "r", stdin);
    int i, j, t;
    cout << "输入样本维度,第一类样本个数,第二类样本个数: \n";
    cin >> D >> n >> m;

    //初始化增广权矢量全为1
    for (i = 0; i <= D; i++) w[i] = 1;

    cout << "输入第一类样本:\n";
    for (i = 0; i < n; i++)
    for (j = 0; j < D; j++) cin >> c[i][j];

    cout << "输入第二类样本:\n";
    for (i = 0; i < m; i++)
    for (j = 0; j < D; j++) cin >> c[i + n][j];

    int N = n + m;

    //训练样本分量增广化
    for (i = 0; i < N; i++) c[i][D] = 1;

    //训练样本符号规范化
    for (i = n; i < N; i++)
    for (j = 0; j <= D; j++) c[i][j] = -c[i][j];

    //感知器算法训练
    while (1) {
    bool flag = false;  //标记是否有正常分类
    for (i = 0; i < N; i++) {
        cout << "k = " << setiosflags(ios::left) << setw(6) << k++;
        cout << "x = " << setiosflags(ios::left) << setw(6) << i + 1;

        t = d(c[i]);
        cout << "d = " << t << endl;
        if (t <= 0) {  //错误分类
        //更新增广权矢量
        add(c[i]);
        cout << "更新增广权矢量:      w = (";
        // cout << "w = (" << i + 1 << endl;
        for (j = 0; j <= D; j++) {
            cout << w[j];
            if (j < D) cout << ',';
        }
        cout << ")\n";
        flag = true;
        }
    }
    if (!flag) break;
    }

    //输出解向量
    cout << "最终所求解向量为:   ";
    for (i = 0; i <= D; i++) cout << w[i] << ' ';
    cout << endl;

    return 0;
}

感知器算法

标签:void   pac   分享图片   错误   stream   add   输出   space   程序   

原文地址:http://www.cnblogs.com/lepeCoder/p/8094465.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!