得验证一下BP算法是不是正确的
NG的方法值得一搞, http://deeplearning.stanford.edu/wiki/index.php/Gradient_checking_and_advanced_optimization
简单来说就是为了求 df/dx,一方面可以真的去计算,一方面可以用 df/dx = (f(x+e) - f(x))/e when e -> 0的方式来估算。
直接上代码吧。
1 // 利用NG的办法进行BP算法正确性的检查 2 void checkBp(Layer layerList[], int nLayer, Vector input, Vector y, CostFun& costFun, double alpha, Vector prevA) 3 { 4 Vector forward(Layer layerList[], int nLayer, Vector input); 5 6 // BP算法计算的结果 7 Vector db = delta; 8 Matrix dw(w.row, w.col); 9 for(int i = 0;i < w.row;i++) { 10 for(int j = 0;j < w.col;j++) { 11 dw[i][j] = prevA[j] * delta[i]; 12 } 13 } 14 15 // NG办法计算的结果 16 // 1. 考虑对b增加一个e 17 double EPS = 0.0001; 18 for(int i = 0;i < b.size;i++) { 19 double tmp = b[i]; 20 // +eps 21 b[i] = tmp + EPS; 22 Vector output1 = forward(layerList, nLayer, input); 23 double err1 = costFun(output1, y); 24 // -eps 25 b[i] = tmp - EPS; 26 Vector output2 = forward(layerList, nLayer, input); 27 double err2 = costFun(output2, y); 28 29 // 恢复原值 30 b[i] = tmp; 31 32 // NG方法的估算值 33 double v = (err1 - err2) / (2 * EPS); 34 if(v > 0) { 35 double x = fabs( (v-db[i]) / v); 36 if(x > 0.0001) { 37 cerr << "BP算法结果误差太大了" << endl; 38 } 39 } 40 } 41 42 // 2. 考虑对w增加一个e 43 for(int i = 0;i < w.row;i++) { 44 for(int j = 0;j < w.col;j++) { 45 double tmp = w[i][j]; 46 // +eps 47 w[i][j] = tmp + EPS; 48 Vector output1 = forward(layerList, nLayer, input); 49 double err1 = costFun(output1, y); 50 // -eps 51 w[i][j] = tmp - EPS; 52 Vector output2 = forward(layerList, nLayer, input); 53 double err2 = costFun(output2, y); 54 55 // 恢复原值 56 w[i][j] = tmp; 57 58 // NG方法的估算值 59 double v = (err1 - err2) / (2 * EPS); 60 if(v > 0) { 61 double x = fabs( (v-dw[i][j]) / v); 62 if(x > 0.0001) { 63 cerr << "BP算法结果误差太大了" << endl; 64 } 65 } 66 } 67 } 68 }
通过检查,一切ok。另外还可以通过故意改错我们的BP实现来触发这个检查的失败。
看来BP算法的实现也没那么难嘛。
浙公网安备 33010602011771号