CPN神經網絡的一些資料:
http://wenku.baidu.com/link?url=JIhrQ5tpegz_KfBEV6TT9nPL6SYBq-Msc8GzHJYgAi2rM462hTZy2QU4G7qUQYXlOdVxxHKn-FRKS5Ok9Jkc02gM2B72ySRrf9SM-mqZrT7
CPN神經網絡設計步驟如下:
C代碼如下:(本代碼按照步驟完成,同時也對照MATLAB代碼修改,但是並沒有預測功能,只能判斷已輸入的樣本屬於哪一類。貼出代碼,希望大牛能幫幫忙)
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "time.h"
#include "vector"
using namespace std;
#define INF 99999
#define dimIn 4 //輸入樣本維數
#define dimOut 1 //期望輸出樣本維數
#define competeNum 40 //競爭神經元數
#define maxLoop 6000 //訓練次數
#define alpha 0.41 //輸入層到競爭層的學習率
#define delta 0.32 //競爭層到輸出層的學習率
typedef vector<double> doubleVector;
vector<doubleVector> dataIn; //輸入訓練樣本
vector<doubleVector> dataOut; //期望輸出樣本
vector<doubleVector> W; //輸入層到競爭層的權值
vector<doubleVector> V; //競爭層到輸出層的權值
doubleVector B; //二值輸出向量
vector<doubleVector> Y; //輸出層輸出向量
void getFileData(char *File1, char *File2); //獲取樣本
double EucDistance(doubleVector X); //計算歐式距離
void NormalizationX(); //輸入樣本歸一化
void NormalizationW(); //連接權值歸一化
void NormalizationV(); //輸出層權值歸一化
void Initialize(); //初始化權值
void CPN_Train(); //開始訓練
int chooseWg(doubleVector X); //選擇權重與X距離最近的向量
void Use_CPN(); //使用CPN網絡
doubleVector round(doubleVector src); //四捨五入
//主函數
void main()
{
int i, j;
char *File1 = "in.txt";
char *File2 = "out.txt";
getFileData(File1, File2); //獲取樣本
NormalizationX(); //輸入樣本歸一化
srand(time(NULL));
Initialize(); //初始化權值
CPN_Train(); //開始訓練
Use_CPN();
//使用CPN網絡
}
//使用CPN網絡
void Use_CPN()
{
int i, g;
double num, dis;
doubleVector test;
doubleVector out_sam;
while(1)
{
test.clear();
out_sam.clear();
printf("輸入測試樣本:\n");
for(i=0; i<dimIn; i++)
{
scanf("%lf", &num);
test.push_back(num);
}
dis = EucDistance(test);
for(i=0; i<dimIn; i++)
test[i] = test[i]/dis;
g = chooseWg(test);
for(i=0; i<dimOut; i++)
out_sam.push_back(V[i][g]);
out_sam = round(out_sam); //四捨五入
printf("測試結果:\n");
for(i=0; i<out_sam.size(); i++)
printf("%lf ", out_sam[i]);
printf("\n\n");
}
}
//開始訓練
void CPN_Train()
{
int i, g, k;
int t=0; //計步器
double dis;
Y = dataOut;
while(t<maxLoop)
{
for(i=0; i<dataIn.size(); i++)
{
NormalizationW();
g = chooseWg(dataIn[i]); //選擇權值
//權值修正W
for(k=0; k<dataIn[i].size(); k++)
W[g][k] = W[g][k]+alpha*(dataIn[i][k]-W[g][k]);
//歸一化
dis = EucDistance(W[g]);
for(k=0; k<dimIn; k++)
W[g][k] = W[g][k]/dis;
//修正權重V
for(k=0; k<dimOut; k++)
V[k][g] = V[k][g]+delta*(dataOut[i][k]-V[k][g]);
}
t++; //計步器加1
}
}
//四捨五入
doubleVector round(doubleVector src)
{
int i;
doubleVector dst;
for(i=0; i<src.size(); i++)
{
if(src[i]-(int)src[i]>=0.5)
dst.push_back((int)src[i]+1);
else
dst.push_back((int)src[i]);
}
return dst;
}
//選擇權重與X距離最近的向量
int chooseWg(doubleVector X)
{
int i, j, label;
double sum, max=0;
label = 0;
for(i=0; i<competeNum; i++)
{
sum = 0;
for(j=0; j<dimIn; j++)
sum += X[j]*W[i][j];
if(sum>max)
{
max = sum;
label = i;
}
}
return label;
}
//初始化權值
void Initialize()
{
int i, j;
doubleVector temp;
//輸入層到競爭層的權值
for(i=0; i<competeNum; i++)
{
temp.clear();
for(j=0; j<dimIn; j++)
temp.push_back((double)(rand()%RAND_MAX)/RAND_MAX);
W.push_back(temp);
}
//競爭層到輸出層的權值
for(i=0; i<dimOut; i++)
{
temp.clear();
for(j=0; j<competeNum; j++)
temp.push_back((double)(rand()%RAND_MAX)/RAND_MAX);
V.push_back(temp);
}
}
//連接權值歸一化
void NormalizationW()
{
int i, j;
double dis;
for(i=0; i<competeNum; i++)
{
dis = EucDistance(W[i]);
for(j=0; j<dimIn; j++)
W[i][j] = W[i][j]/dis;
}
}
//計算歐式距離
double EucDistance(doubleVector X)
{
int i;
double sum=0;
for(i=0; i<X.size(); i++)
sum += X[i]*X[i];
sum = sqrtf(sum);
return sum;
}
//輸入樣本歸一化
void NormalizationX()
{
int i, j;
double dis;
for(i=0; i<dataIn.size(); i++)
{
dis = EucDistance(dataIn[i]);
for(j=0; j<dimIn; j++)
dataIn[i][j] = dataIn[i][j]/dis;
}
}
//獲取樣本
void getFileData(char *File1, char *File2)
{
int i;
double num;
FILE *fp1 = fopen(File1, "r");
FILE *fp2 = fopen(File2, "r");
if(fp1==NULL || fp2==NULL)
{
printf("Open file error!!!\n");
exit(0);
}
doubleVector temp;
//輸入的樣本
i = 1;
temp.clear();
while(fscanf(fp1, "%lf", &num)!=EOF)
{
temp.push_back(num);
if(i%dimIn==0)
{
dataIn.push_back(temp);
temp.clear();
}
i++;
}
//輸出的樣本
i = 1;
temp.clear();
while(fscanf(fp2, "%lf", &num)!=EOF)
{
temp.push_back(num);
if(i%dimOut==0)
{
dataOut.push_back(temp);
temp.clear();
}
i++;
}
}