LSTM神经系统互联网的详尽推导及C++完成

摘要: LSTM隐层神经系统元构造:LSTM隐层神经系统元详尽构造://让程序自身学好是不是必须进位,进而学好加减法#include iostream #include math.h #include stdlib.h #include time.h #include vector #include asser...

LSTM隐层神经系统元构造:
这里写图片描述

LSTM隐层神经系统元详尽构造:
这里写图片描述

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

//让程序自身学好是不是必须进位,进而学好加减法
#include iostream 
#include math.h 
#include stdlib.h 
#include time.h 
#include vector 
#include assert.h 
using namespace std;
#define innode 2 //键入节点数,将键入两个加数
#define hidenode 26 //掩藏节点数,储存 带上位 
#define outnode 1 //輸出节点数,将輸出一个预测分析数据
#define alpha 0.1 //学习培训速度
#define binary_dim 8 //二进制数的较大长短
#define randval(high) ( (double)rand() / RAND_MAX * high )
#define uniform_plus_minus_one ( (double)( 2.0 * rand() ) / ((double)RAND_MAX + 1.0) - 1.0 ) //匀称任意遍布

int largest_number = ( pow(2, binary_dim) ); //跟二进制较大长短相匹配的能够表明的较大十进制数 //激话涵数 double sigmoid(double x) return 1.0 / (1.0 + exp(-x)); //激话涵数的导数,y为激话涵数值 double dsigmoid(double y) return y * (1.0 - y); //tanh的导数,y为tanh值 double dtanh(double y) return 1.0 - y * y; //将一个10进制整数金额变换为2进制数 void int2binary(int n, int *arr) int i = 0; while(n) arr[i++] = n % 2; n /= 2; while(i binary_dim) arr[i++] = 0; class RNN public: RNN(); virtual ~RNN(); void train(); public: double W_I[innode][hidenode]; //联接键入与暗含层模块中键入门的权值引流矩阵 double U_I[hidenode][hidenode]; //联接上一隐层輸出与本暗含层模块中键入门的权值引流矩阵 double W_F[innode][hidenode]; //联接键入与暗含层模块中忘却门的权值引流矩阵 double U_F[hidenode][hidenode]; //联接上一暗含层与本暗含层模块中忘却门的权值引流矩阵 double W_O[innode][hidenode]; //联接键入与暗含层模块中忘却门的权值引流矩阵 double U_O[hidenode][hidenode]; //联接上一暗含层与如今時刻的暗含层的权值引流矩阵 double W_G[innode][hidenode]; //用以造成新记忆力的权值引流矩阵 double U_G[hidenode][hidenode]; //用以造成新记忆力的权值引流矩阵 double W_out[hidenode][outnode]; //联接隐层与輸出层的权值引流矩阵 double *x; //layer 0 輸出值,由键入空间向量立即设置 //double *layer_1; //layer 1 輸出值 double *y; //layer 2 輸出值 void winit(double w[], int n) //权值原始化 for(int i=0; i i++) w[i] = uniform_plus_minus_one; //匀称任意遍布 RNN::RNN() x = new double[innode]; y = new double[outnode]; winit((double*)W_I, innode * hidenode); winit((double*)U_I, hidenode * hidenode); winit((double*)W_F, innode * hidenode); winit((double*)U_F, hidenode * hidenode); winit((double*)W_O, innode * hidenode); winit((double*)U_O, hidenode * hidenode); winit((double*)W_G, innode * hidenode); winit((double*)U_G, hidenode * hidenode); winit((double*)W_out, hidenode * outnode); RNN::~RNN() delete x; delete y; void RNN::train() int epoch, i, j, k, m, p; vector double* I_vector; //键入门 vector double* F_vector; //忘却门 vector double* O_vector; //輸出门 vector double* G_vector; //新记忆力 vector double* S_vector; //情况值 vector double* h_vector; //輸出值 vector double y_delta; //储存偏差有关輸出层的偏导 for(epoch=0; epoch 11000; epoch++) //训炼频次 double e = 0.0; //偏差 int predict[binary_dim]; //储存每一次转化成的预测分析值 memset(predict, 0, sizeof(predict)); int a_int = (int)randval(largest_number/2.0); //任意转化成一个加数 a int a[binary_dim]; int2binary(a_int, a); //变为二进制数 int b_int = (int)randval(largest_number/2.0); //任意转化成另外一个加数 b int b[binary_dim]; int2binary(b_int, b); //变为二进制数 int c_int = a_int + b_int; //真正的和 c int c[binary_dim]; int2binary(c_int, c); //变为二进制数 //在0時刻是沒有以前的暗含层的,因此原始化一个全为0的 double *S = new double[hidenode]; //情况值 double *h = new double[hidenode]; //輸出值 for(i=0; i hidenode; i++) S[i] = 0; h[i] = 0; S_vector.push_back(S); h_vector.push_back(h); //顺向散播 for(p=0; p binary_dim; p++) //循环系统解析xml二进制数字能量数组,从最少位刚开始 x[0] = a[p]; x[1] = b[p]; double t = (double)c[p]; //具体值 double *in_gate = new double[hidenode]; //键入门 double *out_gate = new double[hidenode]; //輸出门 double *forget_gate = new double[hidenode]; //忘却门 double *g_gate = new double[hidenode]; //新记忆力 double *state = new double[hidenode]; //情况值 double *h = new double[hidenode]; //隐层輸出值 for(j=0; j hidenode; j++) //键入层直播到隐层 double inGate = 0.0; double outGate = 0.0; double forgetGate = 0.0; double gGate = 0.0; double s = 0.0; for(m=0; m innode; m++) inGate += x[m] * W_I[m][j]; outGate += x[m] * W_O[m][j]; forgetGate += x[m] * W_F[m][j]; gGate += x[m] * W_G[m][j]; double *h_pre = h_vector.back(); double *state_pre = S_vector.back(); for(m=0; m hidenode; m++) inGate += h_pre[m] * U_I[m][j]; outGate += h_pre[m] * U_O[m][j]; forgetGate += h_pre[m] * U_F[m][j]; gGate += h_pre[m] * U_G[m][j]; in_gate[j] = sigmoid(inGate); out_gate[j] = sigmoid(outGate); forget_gate[j] = sigmoid(forgetGate); g_gate[j] = sigmoid(gGate); double s_pre = (j == 0 ? 0 : state[j-1]); state[j] = forget_gate[j] * s_pre + g_gate[j] * in_gate[j]; h[j] = in_gate[j] * tanh(state[j]);
//暗含层误差,根据当今以后一个時间点的暗含层偏差和当今輸出层的偏差测算 double h_delta[hidenode]; double *O_delta = new double[hidenode]; double *I_delta = new double[hidenode]; double *F_delta = new double[hidenode]; double *G_delta = new double[hidenode]; double *state_delta = new double[hidenode]; //当今時间以后的一个掩藏层偏差 double *O_future_delta = new double[hidenode]; double *I_future_delta = new double[hidenode]; double *F_future_delta = new double[hidenode]; double *G_future_delta = new double[hidenode]; double *state_future_delta = new double[hidenode]; double *forget_gate_future = new double[hidenode]; for(j=0; j hidenode; j++) O_future_delta[j] = 0; I_future_delta[j] = 0; F_future_delta[j] = 0; G_future_delta[j] = 0; state_future_delta[j] = 0; forget_gate_future[j] = 0; for(p=binary_dim-1; p p--) x[0] = a[p]; x[1] = b[p]; //当今掩藏层 double *in_gate = I_vector[p]; //键入门 double *out_gate = O_vector[p]; //輸出门 double *forget_gate = F_vector[p]; //忘却门 double *g_gate = G_vector[p]; //新记忆力 double *state = S_vector[p+1]; //情况值 double *h = h_vector[p+1]; //隐层輸出值 //前一个掩藏层 double *h_pre = h_vector[p]; double *state_pre = S_vector[p]; for(k=0; k outnode; k++) //针对互联网中每一个輸出模块,升级权值 //升级暗含层和輸出层中间的联接权 for(j=0; j hidenode; j++) W_out[j][k] += alpha * y_delta[p] * h[j]; //针对互联网中每一个掩藏模块,测算偏差项,并升级权值 for(j=0; j hidenode; j++) h_delta[j] = 0.0; for(k=0; k outnode; k++) h_delta[j] += y_delta[p] * W_out[j][k]; for(k=0; k hidenode; k++) h_delta[j] += I_future_delta[k] * U_I[j][k]; h_delta[j] += F_future_delta[k] * U_F[j][k]; h_delta[j] += O_future_delta[k] * U_O[j][k]; h_delta[j] += G_future_delta[k] * U_G[j][k]; O_delta[j] = 0.0; I_delta[j] = 0.0; F_delta[j] = 0.0; G_delta[j] = 0.0; state_delta[j] = 0.0; //暗含层的校准偏差 O_delta[j] = h_delta[j] * tanh(state[j]) * dsigmoid(out_gate[j]); state_delta[j] = h_delta[j] * out_gate[j] * dtanh(state[j]) + state_future_delta[j] * forget_gate_future[j]; F_delta[j] = state_delta[j] * state_pre[j] * dsigmoid(forget_gate[j]); I_delta[j] = state_delta[j] * g_gate[j] * dsigmoid(in_gate[j]); G_delta[j] = state_delta[j] * in_gate[j] * dsigmoid(g_gate[j]); //升级前一个暗含层和如今暗含层中间的权值 for(k=0; k hidenode; k++) U_I[k][j] += alpha * I_delta[j] * h_pre[k]; U_F[k][j] += alpha * F_delta[j] * h_pre[k]; U_O[k][j] += alpha * O_delta[j] * h_pre[k]; U_G[k][j] += alpha * G_delta[j] * h_pre[k]; //升级键入层和暗含层中间的联接权 for(k=0; k innode; k++) W_I[k][j] += alpha * I_delta[j] * x[k]; W_F[k][j] += alpha * F_delta[j] * x[k]; W_O[k][j] += alpha * O_delta[j] * x[k]; W_G[k][j] += alpha * G_delta[j] * x[k]; if(p == binary_dim-1) delete O_future_delta; delete F_future_delta; delete I_future_delta; delete G_future_delta; delete state_future_delta; delete forget_gate_future; O_future_delta = O_delta; F_future_delta = F_delta; I_future_delta = I_delta; G_future_delta = G_delta; state_future_delta = state_delta; forget_gate_future = forget_gate; delete O_future_delta; delete F_future_delta; delete I_future_delta; delete G_future_delta; delete state_future_delta; if(epoch % 1000 == 0) cout error: e endl; cout pred: for(k=binary_dim-1; k k--) cout predict[k]; cout endl; cout true: for(k=binary_dim-1; k k--) cout c[k]; cout endl; int out = 0; for(k=binary_dim-1; k k--) out += predict[k] * pow(2, k); cout a_int + b_int = out endl endl; for(i=0; i I_vector.size(); i++) delete I_vector[i]; for(i=0; i F_vector.size(); i++) delete F_vector[i]; for(i=0; i O_vector.size(); i++) delete O_vector[i]; for(i=0; i G_vector.size(); i++) delete G_vector[i]; for(i=0; i S_vector.size(); i++) delete S_vector[i]; for(i=0; i h_vector.size(); i++) delete h_vector[i]; I_vector.clear(); F_vector.clear(); O_vector.clear(); G_vector.clear(); S_vector.clear(); h_vector.clear(); y_delta.clear();
}

这里写图片描述

参照:
article/deeplearning/45380
lib/



联系我们

全国服务热线:4000-399-000 公司邮箱:343111187@qq.com

  工作日 9:00-18:00

关注我们

官网公众号

官网公众号

Copyright?2020 广州凡科互联网科技股份有限公司 版权所有 粤ICP备10235580号 客服热线 18720358503