|
@@ -0,0 +1,113 @@
|
|
|
+#include "convolution.hpp"
|
|
|
+
|
|
|
+namespace Layer{
|
|
|
+
|
|
|
+ void
|
|
|
+ Convolution::init(Real m,Real d){
|
|
|
+ default_random_engine generator;
|
|
|
+ normal_distribution<Real> distribution(m,d);
|
|
|
+ for(size_t i=0;i<mf*nf*i*q;++i){
|
|
|
+ K[i]=distribution(generator);
|
|
|
+ }
|
|
|
+ for(size_t i=0;i<mf*nf;++i){
|
|
|
+ b[i]=distribution(generator);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Vector
|
|
|
+ Convolution::feed_forward(Vector x){
|
|
|
+ x_in=x;
|
|
|
+ for(size_t g=0;g<mf;++g){
|
|
|
+ for(size_t k=0;k<mi;++k){
|
|
|
+ for(size_t l=0;l<mj;++l){
|
|
|
+ Real temp=0;
|
|
|
+ for(size_t f=0;f<nf;++f){
|
|
|
+ for(size_t r=0;r<p;++r){
|
|
|
+ for(size_t s=0;s<q;++s){
|
|
|
+ temp+=x[indice3(f,k+r,l+s,ni,nj)]*K[indice4(g,f,r,s,nf,p,q)];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ temp+=b[indice2(g,f,nf)];
|
|
|
+ }
|
|
|
+ x_out[indice3(g,k,l,mi,mj)]=temp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return x_out;
|
|
|
+ }
|
|
|
+
|
|
|
+ void
|
|
|
+ Convolution::init_nabla(){
|
|
|
+ for(size_t i=0;i<mf*nf;++i){
|
|
|
+ nabla_b[i]=0;
|
|
|
+ }
|
|
|
+ for(size_t i=0;i<mf*nf*p*q;++i){
|
|
|
+ nabla_K[i]=0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Vector
|
|
|
+ Convolution::back_propagation(Vector d){
|
|
|
+ for(size_t f=0;f<nf;++f){
|
|
|
+ for(size_t i=0;i<ni;++i){
|
|
|
+ for(size_t j=0;j<nj;++j){
|
|
|
+ Real temp=0;
|
|
|
+ for(size_t g=0;g<mf;++g){
|
|
|
+ size_t r=(i>=mi-1)?i-mi+1:0;
|
|
|
+ for(;r<min(i,p);++r){
|
|
|
+ size_t s=(j>=mj-1)?j-mj+1:0;
|
|
|
+ for(;s<min(j,q);++s){
|
|
|
+ temp+=K[indice4(g,f,r,s,nf,p,q)]*d[indice3(g,i-r,j-s,mi,mj)];
|
|
|
+ }//s
|
|
|
+ }//r
|
|
|
+ }//g
|
|
|
+ delta[indice3(f,i,j,ni,nj)]=temp;
|
|
|
+ }//j
|
|
|
+ }//i
|
|
|
+ }//f
|
|
|
+ //display(delta,nf*ni*nj);
|
|
|
+ //char a;cin>>a;
|
|
|
+ //cout<<" - Update nabla_b"<<endl;
|
|
|
+ //Update nabla_b<<
|
|
|
+ for(size_t g=0;g<mf;++g){
|
|
|
+ for(size_t f=0;f<nf;++f){
|
|
|
+ Real temp=0;
|
|
|
+ for(size_t k=0;k<mi;++k){
|
|
|
+ for(size_t l=0;l<mj;++l){
|
|
|
+ temp+=d[indice3(g,k,l,mi,mj)];
|
|
|
+ }//l
|
|
|
+ }//k
|
|
|
+ nabla_b[indice2(g,f,nf)]+=temp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //Update nabla_w
|
|
|
+ for(size_t g=0;g<mf;++g){
|
|
|
+ for(size_t f=0;f<nf;++f){
|
|
|
+ for(size_t r=0;r<p;++r){
|
|
|
+ for(size_t s=0;s<q;++s){
|
|
|
+ Real temp=0;
|
|
|
+ for(size_t k=0;k<mi;++k){
|
|
|
+ for(size_t l=0;l<mj;++l){
|
|
|
+ temp+=d[indice3(g,k,l,mi,mj)]*x_in[indice3(f,k+r,l+s,ni,nj)];
|
|
|
+ }//l
|
|
|
+ }//k
|
|
|
+ nabla_K[indice4(g,f,r,s,nf,p,q)]+=temp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return delta;
|
|
|
+ }
|
|
|
+
|
|
|
+ void
|
|
|
+ Convolution::update(Real eta){
|
|
|
+ //Update b
|
|
|
+ for(size_t i=0;i<mf*nf;++i){
|
|
|
+ b[i]-=eta*nabla_b[i];
|
|
|
+ }
|
|
|
+ //Update K
|
|
|
+ for(size_t i=0;i<mf*nf*p*q;++i){
|
|
|
+ K[i]-=eta*nabla_K[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|