?? bp.txt
字號:
#include "stdafx.h"
#include <string>
#include <cmath>
#include<ctime>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
const int N = 8; //樣本數量
const int d = 4; //樣本特征維數
const int nH = 3; //隱含層元素個數,包括闕值
const int c = 1; //每個樣本的目標值都是1維的
const double error_limit = 0.01; //迭代結束的誤差
const double rate = 0.05; //學習率
const double momentum = 0.9; //沖量大小
//
class weight{
public:
double samples[N][d]; //N個樣本的d維特征空間
double weight_HI[nH][d]; //輸入層到隱含層權值
double weight_OH[c][nH]; //隱含層到輸出層權值
double old_weight_HI[nH][d]; //前一時刻輸入層和隱含層權重的變化率
double old_weight_OH[c][nH]; //前一時刻輸出層和隱含層權重的變化率
double dweight_HI[nH][d]; //輸入層和隱含層權重的變化率
double dweight_OH[c][nH]; //隱含層和輸出層權重的變化率
double old_dweight_HI[nH][d]; //輸入層和隱含層上一次權重的變化率
double old_dweight_OH[c][nH]; //隱含層和輸出層上一次權重的變化率
double sensitity_k[c]; //隱含層敏感度
double sensitity_j[nH]; //輸出層敏感度
double x[d]; //隨機選擇的樣本
double y[nH]; //類的定義中,只能聲明不能實例化,也就是不能有分配內存空間的變量
double z[c]; //在新的權值(weight_HI和weight_OH)下輸出層的輸出值
double net_j[nH]; //隱含層凈值
double net_k[c]; //輸出層層凈值
double t[N][c]; //N個樣本的標準輸出值
double t_now[c]; //當前樣本的標準輸出值
double error; //準則函數誤差變化率
//構造函數
weight(double s[N][d],double st[N][c]) {
for(int k = 0;k < c;k++) {
sensitity_k[k] = 0;
}
for(int j = 0;j < nH;j++) {
sensitity_j[j] = 0;
}
for(int n = 0;n < N;n++)
for(int i = 0;i < d;i++) {
samples[n] = s[n];
}
for(int n = 0;n < N;n++)
for(int k = 0;k < c;k++) {
t[n][k] = st[n][k];
}
}
//輸入層到隱含層權值初始化
void ini_weight_HI(double wHI[nH][d]) {
for(int j = 0;j < nH;j++)
for(int i = 0;i < d;i++) {
weight_HI[j] = wHI[j];
old_weight_HI[j] = wHI[j];
}
}
//隱含層到輸出層權值初始化
void ini_weight_OH(double wOH[c][nH]) {
for(int k = 0;k < c;k++)
for(int j = 0;j < nH;j++) {
weight_OH[k][j] = wOH[k][j];
old_weight_OH[k][j] = wOH[k][j];
}
}
//輸入層到隱含層權值初始化
void ini_dweight_HI() {
for(int j = 0;j < nH;j++)
for(int i = 0;i < d;i++) {
dweight_HI[j] = 0;
}
}
//隱含層到輸出層權值初始化
void ini_dweight_OH() {
for(int k = 0;k < c;k++)
for(int j = 0;j < nH;j++) {
dweight_OH[k][j] = 0;
}
}
//輸入層到隱含層權值初始化
void ini_old_dweight_HI() {
for(int j = 0;j < nH;j++)
for(int i = 0;i < d;i++) {
old_dweight_HI[j] = 0;
}
}
//隱含層到輸出層權值初始化
void ini_old_dweight_OH() {
for(int k = 0;k < c;k++)
for(int j = 0;j < nH;j++) {
old_dweight_OH[k][j] = 0;
}
}
//獲取當前樣本標準輸出值
void obtain_t_now(double t[c]) { //獲取當前樣本標準輸出值
for(int k = 0;k < c;k++) {
t_now[k] = t[k];
}
}
//獲取當前隨機選擇的樣本
void obtain_x(double tem_x[d]) { //獲取當前隨機選擇的樣本
for(int i = 0;i < d;i++) {
x = tem_x;
}
}
//計算y[j]以及net_j[j]
void obtain_y() {
y[0] = 1;
//
for(int j = 1;j < nH;j++) {
//凈值初始為零
net_j[j] = 0;
//計算凈值
for(int i = 0;i < d;i++) {
net_j[j] += weight_HI[j] * x;
}
//計算凈值輸出
y[j] = 1 / ( 1 + exp(-net_j[j]) );
}
}
//計算z[k]
void obtain_z() {
for(int k = 0;k < c;k++) {
//
net_k[k] = 0;
//
for(int j = 0;j < nH;j++) {
net_k[k] += weight_OH[k][j] * y[j];
}
z[k] = 1 / ( 1 + exp(-net_k[k]) );
}
}
//計算校正后輸入層到隱含層的權值
void obtain_new_weight_HI(double rate) {
for(int j = 0;j < nH;j++) {
//
sensitity_j[j] = 0;
//
for(int k = 0;k < c;k++) {
sensitity_j[j] += y[j] * (1- y[j]) * weight_OH[k][j] * sensitity_k[k];
}
//
for(int i = 0;i < d;i++){
//
dweight_HI[j] = rate * sensitity_j[j] * x;
//
weight_HI[j] = weight_HI[j] + (momentum * dweight_HI[j] + (1 - momentum) * old_dweight_HI[j]);
//
old_dweight_HI[j] = dweight_HI[j];
}
}
}
//計算校正后隱含層到輸出層的權值
void obtain_new_weight_OH(double rate) {
for(int k = 0;k < c;k++) {
//
sensitity_k[k] = (t_now[k] - z[k]) * z[k] * (1 - z[k]);
//
for(int j = 0;j < nH;j++){
//
dweight_OH[k][j] = rate * sensitity_k[k] * y[j];
//
weight_OH[k][j] = weight_OH[k][j] + (momentum * dweight_OH[k][j] + (1 - momentum) * old_dweight_OH[k][j]);
//
old_dweight_OH[k][j] = dweight_OH[k][j];
}
}
}
//判斷迭代是否結束
int if_over() {
error = 0;
for(int n = 0;n < N;n++) {
obtain_x(samples[n]);
obtain_t_now(t[n]);
obtain_y();
obtain_z();
for(int k = 0;k < c;k++) {
error += fabs( 0.5 * pow( z[k] - t_now[k],2 ) );
}
}
if( (error) < error_limit ) return 1;
else return 0;
}
}; //分號;最容易誤事 !
//
int main(){
//
double samples[N][d] = { {1,0,0,1},{1,0,0,0},{1,0,1,0},{1,0,1,1},{1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1} }; //最基本的數組初始化也忘了 !
double t[N][c] = {0.1,0.9,0.1,0.9,0.1,0.9,0.9,0.1};
double test[8][4] = { {1,0,0,0},{1,1,1,1},{1,0.0,0.0,0.2},{1,0.0,0.0,0.8},{1,0.0,0.2,0.0},{1,0.0,0.8,0.0},{1,0.0,0.2,0.2},{1,0.0,0.8,0.8} };
//
weight w_obj(samples,t);
w_obj.ini_dweight_HI();
w_obj.ini_dweight_OH();
w_obj.ini_old_dweight_HI();
w_obj.ini_old_dweight_OH();
//
srand((unsigned)time(0));
//隨機初始化權值weight_OH
double random_weight_OH[c][nH];
for(int k = 0;k < c;k++)
for(int j = 0;j < nH;j++) {
random_weight_OH[k][j] = (double)( rand() % 100 ) / 100 - 0.5;
}
w_obj.ini_weight_OH(random_weight_OH);
//隨機初始化權值weight_HI
double random_weight_HI[nH][d];
for(int j = 0;j < nH;j++)
for(int i = 0;i < d;i++) {
random_weight_HI[j] = (double)( rand() % 100 ) / 100 - 0.5;
}
//
w_obj.ini_weight_HI(random_weight_HI);
w_obj.obtain_x(samples[n]);
w_obj.obtain_t_now(t[n]);
w_obj.obtain_y();
w_obj.obtain_z();
}
//
cout<<"Begin"<<endl;
int count = 0;
int num;
int if_over = 0;
while( !if_over ) {
num = rand() % N;
w_obj.obtain_x(samples[num]);
w_obj.obtain_t_now(t[num]);
w_obj.obtain_y();
w_obj.obtain_z();
w_obj.obtain_new_weight_OH(rate);
w_obj.obtain_new_weight_HI(rate);
if_over = w_obj.if_over();
count++; //保存迭代次數
}
getchar();
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -