感知器算法+C代碼

感知算法的訓練過程就是對判斷好的樣本集求解權矢量W,這實際是一個線性聯立不等式的求解問題。

具體算法如下:

1. 初始權矢量 W = 0

2. 第k次輸入一個樣本X(K), 計算第k次迭代的過爲:

      d[X(k)] = W'[k] * X(k),

3. 根據欲劃分類和d值進行權值修正:

     當d<=0時: W[k+1] = W[k] + X[k]

     當d>0時:   W[k+1] = W[k] - X[k]

4. 循環執行第二步,直到輸入所有樣本後,權重都不需要修改爲止。


本代碼的測試用例爲,胃病和非胃病測試樣例(1爲胃病,-1爲非胃病)

228 134 20 11 1 1
245 134 10 40 1 1
200 167 12 27 1 1
170 150 7 8 1 1
100 167 20 14 1 1
150 117 7 6 1 -1
165 142 5 3 1 -1
185 108 2 12 1 -1
120 133 10 26 1 -1
160 100 5 10 1 -1
185 115 5 19 1 -1
170 125 6 4 1 -1

待測樣品爲:

225 125 7 14 1 0
100 117 7 2 1 0
130 100 6 12 1 0


c代碼如下:(訓練會需要一些時間)

#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "vector"
using namespace std;


typedef vector<double> doubleVector;


#define alpha 0.2
#define dimNum 6   //樣本的維數
vector<doubleVector>  getSample(char *File);  //獲取樣本
double matMul(doubleVector Mat1, doubleVector Mat2);  //矩陣相乘
doubleVector matAdd(doubleVector Mat1, doubleVector Mat2);  //矩陣相加
void Perceptron(vector<doubleVector> sample);   //感知算法開始引擎
doubleVector matSub(doubleVector Mat1, doubleVector Mat2);  //矩陣相減


void main()
{
char *File = "胃病.txt";
vector<doubleVector> sample;

  sample = getSample(File);
 
Perceptron(sample);
}




//感知算法開始引擎
void Perceptron(vector<doubleVector> sample)
{
doubleVector W(dimNum-1, 0);  //權重
double mulResult;
int i;
bool flag = false;




while(!flag)  //輸入所有樣本後權重都不改變
{
flag = true;


for(i=0; i<sample.size(); i++)
{
mulResult = matMul(W, sample[i]);  //計算權值


if(sample[i][dimNum-1]==1)
{
if(mulResult<=0)
{
W = matAdd(W, sample[i]);
flag = false;
}


}


else
{
if(mulResult>0)
{
W = matSub(W, sample[i]);
flag = false;
}
}


}
}


vector<doubleVector> test;
char *File = "待判樣品.txt";
test = getSample(File);


for(i=0; i<test.size(); i++)
{
mulResult = matMul(W, test[i]);
if(mulResult>0)
printf("胃病\n");


else
printf("非胃病\n");


}





}




//獲取樣本
vector<doubleVector> getSample(char *File)
{
int i=1;
vector<doubleVector> dst;
doubleVector temp;

FILE *fp = fopen(File, "r");

if(fp == NULL)
{
printf("Open file error!!!\n");
return dst;
}

double num;
while(fscanf(fp, "%lf", &num)!=EOF)
{
temp.push_back(num);
if(i%dimNum==0)
{
dst.push_back(temp);
temp.clear();
}
i++;
}

return dst;
}




//矩陣相乘
double matMul(doubleVector Mat1, doubleVector Mat2)
{
int i;
double sum=0;

for(i=0; i<dimNum-1; i++)
sum += Mat1[i]*Mat2[i];
return sum;
}




//矩陣相加
doubleVector matAdd(doubleVector Mat1, doubleVector Mat2)
{
int i;
doubleVector dstMat;

for(i=0; i<dimNum-1; i++)
dstMat.push_back(Mat1[i]+Mat2[i]*alpha);


return dstMat;
}




//矩陣相減
doubleVector matSub(doubleVector Mat1, doubleVector Mat2)
{
int i;
doubleVector dstMat;

for(i=0; i<dimNum-1; i++)
dstMat.push_back(Mat1[i]-Mat2[i]*alpha);

return dstMat;
}

發佈了38 篇原創文章 · 獲贊 34 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章