• 感知器算法



    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 << "输入样本维度,第一类样本个数,第二类样本个数: 
    ";
        cin >> D >> n >> m;
    
        //初始化增广权矢量全为1
        for (i = 0; i <= D; i++) w[i] = 1;
    
        cout << "输入第一类样本:
    ";
        for (i = 0; i < n; i++)
    	for (j = 0; j < D; j++) cin >> c[i][j];
    
        cout << "输入第二类样本:
    ";
        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 << ")
    ";
    		flag = true;
    	    }
    	}
    	if (!flag) break;
        }
    
        //输出解向量
        cout << "最终所求解向量为:   ";
        for (i = 0; i <= D; i++) cout << w[i] << ' ';
        cout << endl;
    
        return 0;
    }
    
    
  • 相关阅读:
    C/C++ 公有函数无法返回私有的类对象解决方案
    C/C++ ShowWindow()
    Windows 隐藏控制台
    Windows 关闭win32 控制台
    Windows 开启win32 控制台
    CSS中可以和不可以继承的属性
    css3实现炫酷的文字效果_空心/立体/发光/彩色/浮雕/纹理等文字特效
    CSS position 属性_css中常用position定位属性介绍
    无间歇文字滚动_ 原生js实现新闻无间歇性上下滚动
    好看css搜索框样式_分享8款纯CSS搜索框
  • 原文地址:https://www.cnblogs.com/lepeCoder/p/8094465.html
Copyright © 2020-2023  润新知