弄了一段时间,效果很差! 感觉对其理解不够!看了一些论文, 感觉有点前后矛盾,写了一段时间代码,感觉无法完成!
这里做一个总结,说明为什么完成不了!
1. 隶属度 我是用 高其隶属度函数, 感觉公式,导数计算,偏导计算,都已经完成,但误差传播,与,修正时候,总是出错!
2. 对我的项目感觉没有增益! 我是想用在麻醉深度的CSI训练上,但,深度, 需要用,4个特征量,六个深度,如果按模糊的方式,会有 6*6*6*6的专家规则,超过预期!
3. 看了很多论文模糊神经的最经常用的是控制,及 电机控制,无功补偿,洗衣机时间控制之类,有明确的专家规则,有明确的输出,这样训练时候,可以很好的控制。
4. 麻醉深度,无法固定规则可以遵寻,训练也就无重谈起。
下面是代码:注(运行不成功)
#include <math.h>
/
// 五层结构/ #define InputN (2)#define HideN_0 (2)
#define HideN_1 (4)#define HideN_2 (4)#define OutN (1)
typedef struct __FuzzyBP_DATA__{ double Input[InputN]; double Teach[OutN];}FuzzyBP_DATA_t;
typedef struct __FuzzyBP_t__
{ double y[OutN];double xOut[InputN];
double hOut_0[HideN_0]; double hOut_1[HideN_1]; double hOut_2[HideN_2]; double yOut[OutN];double h0_delta[HideN_0];
double h1_delta[HideN_1]; double h2_delta[HideN_2]; double y_delta[OutN]; double wh0[InputN][HideN_0]; // 权值 double wh1[HideN_0][HideN_1]; // 权值 double wh2[HideN_1][HideN_2]; // 权值 double v[HideN_2][OutN]; //double deltawh0[InputN][HideN_0]; // 权值
double deltawh1[HideN_0][HideN_1]; // 权值 double deltawh2[HideN_1][HideN_2]; // 权值 double deltav[HideN_2][OutN]; // double FuzzyC[HideN_0]; //--- double FuzzyU[HideN_0]; //---double deltaFuzzyC[HideN_0];
double deltaFuzzyU[HideN_0]; double RuleC[HideN_2]; double RuleU[HideN_2];double deltaRuleC[HideN_2];
double deltaRuleU[HideN_2];
double err;
double errLimit;double alpha;
double beta;int maxLoopNum;
}FuzzyBP_t;double fuction_lishu(double x, double c,double u) // 高斯隶属函数{ double tmp ; tmp = exp( -(x - c)*(x - c) /(u*u) ); return tmp;}double fuction_dao_lishu(double x, double c,double u) // 高斯隶属函数导数{ double tmp ; tmp = exp( -(x - c)*(x - c) /(u*u) ); tmp *= -2*(x - c) /(u*u); return tmp;}double fuction_lishuC(double x, double c,double u) // 高斯隶属函数偏导数 -- c{ double tmp ; tmp = exp( -(x - c)*(x - c) /(u*u) ); tmp *= 2*(x - c)/(u*u); return tmp;}
double fuction_lishuU(double x, double c,double u) // 高斯隶属函数偏导数 -- u
{ double tmp ; tmp = exp( -(x - c)*(x - c) /(u*u) ); tmp *= -2*(x - c)*(x - c)/(u*u*u); return tmp;}
double fuction_sigmod(double val)
{ return 1/(1 + exp(-val));}
void FuzzyBP_XunLian(FuzzyBP_t *pBp, FuzzyBP_DATA_t *pData, int dataNum)
{for (int i=0; i<HideN_0; i++)
{ pBp->FuzzyC[i] = (rand()/32767.0)*2 - 1; pBp->FuzzyU[i] = (rand()/32767.0)*2 - 1; pBp->deltaFuzzyC[i] = 0.0; pBp->deltaFuzzyU[i] = 0.0;}
for (int i=0; i<HideN_2; i++) { pBp->RuleC[i] = (rand()/32767.0)*2 - 1; pBp->RuleU[i] = (rand()/32767.0)*2 - 1; pBp->deltaRuleC[i] = 0.0; pBp->deltaRuleU[i] = 0.0;}
for (int i=0; i<InputN; i++)
{ for (int j = 0; j<HideN_0; j++) { pBp->wh0[i][j] = (rand()/32767.0)*2 - 1; pBp->deltawh0[i][j] = 0.0; } } for (int i=0; i<HideN_0; i++) { for (int j = 0; j<HideN_1; j++) { pBp->wh1[i][j] = (rand()/32767.0)*2 - 1; pBp->deltawh1[i][j] = 0.0; } }for (int i=0; i<HideN_1; i++)
{ for (int j = 0; j<HideN_2; j++) { pBp->wh2[i][j] = (rand()/32767.0)*2 - 1; pBp->deltawh2[i][j] = 0.0; } } for (int i=0; i<HideN_2; i++) { for (int j = 0; j<OutN; j++) { pBp->v[i][j] = (rand()/32767.0)*2 - 1; pBp->deltav[i][j] = 0.0; } } int loop = 0; while( loop < pBp->maxLoopNum) {pBp->err = 0.0;
for (int m = 0; m<dataNum; m++)
{for (int i=0; i<OutN; i++)
{ pBp->y[i] = pData[m].Teach[i]; } / // 正向传播 / // 输入层 for (int i=0; i<InputN; i++) { pBp->xOut[i] = pData[m].Input[i]; }// 隐藏层
// for (int i=0; i<HideN_0; i++)// { // double sumTemp = 0.0;// for (int j=0; j<InputN; j++)// { // sumTemp += pBp->wh0[j][i] * pBp->xOut[j];// }// pBp->hOut_0[i] = tanh(sumTemp);// }for (int i=0; i<HideN_0; i++)
{ pBp->hOut_0[i] = fuction_lishu(pBp->xOut[i], pBp->FuzzyC[i],pBp->FuzzyU[i]); } for (int i=0; i<HideN_1; i++) { double sumTemp = 0.0; for (int j=0; j<HideN_0; j++) { sumTemp += pBp->wh1[j][i] * pBp->hOut_0[j]; } pBp->hOut_1[i] = tanh(sumTemp); } for (int i=0; i<HideN_2; i++) { double sumTemp = 0.0; for (int j=0; j<HideN_1; j++) { sumTemp += pBp->wh2[j][i] * pBp->hOut_1[j]; } pBp->hOut_2[i] = tanh(sumTemp); } // 输出层 for (int i=0; i<OutN; i++) { double sumTemp = 0.0; for (int j=0; j<HideN_2; j++) { sumTemp += pBp->v[j][i] * pBp->hOut_2[j]; } pBp->yOut[i] = fuction_sigmod(sumTemp); }/ // 误差传播 / for (int i=0; i< OutN; i++) { double errTemp = pBp->y[i] - pBp->yOut[i]; pBp->y_delta[i] = errTemp * fuction_sigmod(pBp->yOut[i]) * ( 1.0 - fuction_sigmod(pBp->yOut[i])); pBp->err += errTemp * errTemp; } for (int i=0; i<HideN_2; i++) { double errTemp = 0.0; for (int j=0; j<OutN; j++) { errTemp += pBp->y_delta[j] * pBp->v[i][j]; } pBp->h2_delta[i] = errTemp * (1-tanh(pBp->hOut_2[i])*tanh(pBp->hOut_2[i])) ; } for (int i=0; i<HideN_1; i++) { double errTemp = 0.0; for (int j=0; j<HideN_2; j++) { errTemp += pBp->h2_delta[j] * pBp->wh2[i][j]; } pBp->h1_delta[i] = errTemp * (1-tanh(pBp->hOut_1[i])*tanh(pBp->hOut_1[i])) ; } for (int i=0; i<HideN_0; i++) { double errTemp = 0.0; for (int j=0; j<HideN_1; j++) { errTemp += pBp->h1_delta[j] * pBp->wh1[i][j]; } pBp->h0_delta[i] = errTemp; } / // 参数修正 / for (int i=0; i<OutN; i++) { for (int j = 0; j<HideN_2; j++) { pBp->deltav[j][i] = pBp->alpha * pBp->deltav[j][i] + pBp->beta * pBp->y_delta[i] * pBp->hOut_2[j]; pBp->v[j][i] += pBp->deltav[j][i]; } }
for (int i=0; i<HideN_2; i++)
{ for (int j = 0; j<HideN_1; j++) { pBp->deltawh2[j][i] = pBp->alpha * pBp->deltawh2[j][i] + pBp->beta * pBp->h2_delta[i] * pBp->hOut_1[j]; pBp->wh2[j][i] += pBp->deltawh2[j][i]; } } for (int i=0; i<HideN_1; i++) { for (int j = 0; j<HideN_0; j++) { pBp->deltawh1[j][i] = pBp->alpha * pBp->deltawh1[j][i] + pBp->beta * pBp->h1_delta[i] * pBp->hOut_0[j]; pBp->wh1[j][i] += pBp->deltawh1[j][i]; } }// for (int i=0; i<HideN_0; i++)
// { // for (int j = 0; j<InputN; j++)// { // pBp->deltawh0[j][i] = pBp->alpha * pBp->deltawh0[j][i] + pBp->beta * pBp->h0_delta[i] * pBp->xOut[j];// pBp->wh0[j][i] += pBp->deltawh0[j][i];// }// } for (int i=0; i<HideN_0; i++) { pBp->deltaFuzzyC[i] = pBp->alpha * pBp->deltaFuzzyC[i] + pBp->beta * pBp->h0_delta[i] * fuction_lishuC(pBp->xOut[i], pBp->FuzzyC[i], pBp->FuzzyU[i]); pBp->FuzzyC[i] += pBp->deltaFuzzyC[i];pBp->deltaFuzzyU[i] = pBp->alpha * pBp->deltaFuzzyU[i] + pBp->beta * pBp->h0_delta[i] * fuction_lishuU(pBp->xOut[i], pBp->FuzzyC[i], pBp->FuzzyU[i]);
pBp->FuzzyU[i] += pBp->deltaFuzzyU[i]; }
}
pBp->err = pBp->err/2;
if (pBp->err < pBp->errLimit) { CString tmp; tmp.Format("学习成功, 已经收敛! 训练次数: %6d", loop); AfxMessageBox(tmp); break; } loop++; }} void FuzzyBP_JianYan(FuzzyBP_t *pBp, FuzzyBP_DATA_t *pData){ for (int i=0; i<InputN; i++) { pBp->xOut[i] = pData->Input[i]; }
// 隐藏层
// for (int i=0; i<HideN_0; i++)// { // double sumTemp = 0.0;// for (int j=0; j<InputN; j++)// { // sumTemp += pBp->wh0[j][i] * pBp->xOut[j];// }// pBp->hOut_0[i] = tanh(sumTemp);// }for (int i=0; i<HideN_0; i++)
{ pBp->hOut_0[i] = fuction_lishu(pBp->xOut[i], pBp->FuzzyC[i],pBp->FuzzyU[i]); }for (int i=0; i<HideN_1; i++)
{ double sumTemp = 0.0; for (int j=0; j<HideN_0; j++) { sumTemp += pBp->wh1[j][i] * pBp->hOut_0[j]; } pBp->hOut_1[i] = tanh(sumTemp); } for (int i=0; i<HideN_2; i++) { double sumTemp = 0.0; for (int j=0; j<HideN_1; j++) { sumTemp += pBp->wh2[j][i] * pBp->hOut_1[j]; } pBp->hOut_2[i] = tanh(sumTemp); }// 输出层
for (int i=0; i<OutN; i++) { double sumTemp = 0.0; for (int j=0; j<HideN_2; j++) { sumTemp += pBp->v[j][i] * pBp->hOut_2[j]; } pBp->yOut[i] = fuction_sigmod(sumTemp);pData->Teach[i] = pBp->yOut[i];
}
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{ int nRetCode = 0;srand(time(NULL));
FuzzyBP_DATA_t data[15] = { { {1.780, 1.140 },1}, { {1.960, 1.180 },1}, { {1.860, 1.200 },1}, { {1.720, 1.240 },0}, { {2.000, 1.260 },1}, { {2.000, 1.280 },1}, { {1.960, 1.300 },1}, { {1.740, 1.360 },0},{ {1.640, 1.380 },0},
{ {1.820, 1.380 },0}, { {1.900, 1.380 },0}, { {1.700, 1.400 },0}, { {1.820, 1.480 },0}, { {1.820, 1.540 },0}, { {2.080, 1.560 },0}, }; FuzzyBP_t *pBp = new FuzzyBP_t; pBp->alpha = 1.00; pBp->beta = 0.86; pBp->err = 100.0; pBp->errLimit = 0.0001; pBp->maxLoopNum = 30000;// pBp->alpha = 0.90;
// pBp->beta = 0.26;// pBp->errLimit = 0.0001;// pBp->maxLoopNum = 5000;// FuzzyBP_XunLian(pBp, data, 15);printf(" 误差 %6.4f \n", pBp->err);
for (int i=0; i<15; i++) { printf("%3d %8.5f %8.5f %8.5f ", i, data[i].Input[0], data[i].Input[1], data[i].Teach[0]); FuzzyBP_JianYan(pBp,&data[i]);printf(" %8.5f \n", data[i].Teach[0]);
}
system("pause");
return nRetCode;}