#include "bp_head.h"
//sigm
double core_function(double x){
return (1.0f/(double)(1.0+exp(-x)));
}
// input data normalize 0-1
void scale_input(double *inputdata,int num){
int i;
for(i=0;i<num;i++)
inputdata[i]=(inputdata[i]-MIN)/(MAX-MIN);
}
void read_trains_data(_Bp_Params *bp,FILE *fp){
double *input_buf;
int i;
input_buf=(double *)malloc(bp->input_num*sizeof(double));
bp->input_params->inbuf=input_buf;
for(i=0;i<bp->input_num;i++)
fscanf(fp,"%f",input_buf[i]);
}
// return double -1.0~1.0
double get_random_weight(void){
return (((double)rand()/(double)RAND_MAX)*2.0-1.0);
}
void init_output_weight(_Bp_Params *bp){
double **output_weight;
int i,j;
output_weight=(double **)malloc(bp->output_num*sizeof(double *));
bp->out_params->weight=output_weight;
for(i=0;i<bp->output_num;i++)
{
*(output_weight+i)=(double *)malloc(bp->hidden_layer_num[bp->hidden_num-1]*sizeof(double));
for(j=0;j<bp->hidden_layer_num[bp->hidden_num-1];j++)
output_weight[i][j]=get_random_weight();
}
}
void init_hidden_weight(_Bp_Params *bp){
_Hidden_Layer_Params *hidden_params;
hidden_params=bp->hidden_params;
int i,j,k;
double **hidden_weight;
for(i=0;i<bp->hidden_num;i++)
{
hidden_weight=(double **)malloc(bp->hidden_layer_num[i]*sizeof(double *));
(hidden_params+i)->weight=hidden_weight;
if(i==0)
{
for(j=0;j<bp->hidden_layer_num[i];j++)
{
*(hidden_weight+j)=(double *)malloc(bp->input_num*sizeof(double));
for(k=0;k<bp->input_num;k++)
hidden_weight[j][k]=get_random_weight();
}
}
else
{
for(j=0;j<bp->hidden_layer_num[i];j++)
{
*(hidden_weight+j)=(double *)malloc(bp->hidden_layer_num[i-1]*sizeof(double));
for(k=0;k<bp->hidden_layer_num[i-1];k++)
hidden_weight[j][k]=get_random_weight();
}
}
}
}
void init_deltas_weight(_Bp_Params *bp){
_Hidden_Layer_Params *hidden_params;
hidden_params=bp->hidden_params;
int i,j,k;
double **deltas_weight;
for(i=0;i<bp->hidden_num;i++)
{
deltas_weight=(double **)malloc(bp->hidden_layer_num[i]*sizeof(double *));
(hidden_params+i)->deltas_weight_prior=deltas_weight;
if(i==0)
{
for(j=0;j<bp->hidden_layer_num[i];j++)
{
*(deltas_weight+j)=(double *)malloc(bp->input_num*sizeof(double));
for(k=0;k<bp->input_num;k++)
deltas_weight[j][k]=0.0f;
}
}
else
{
for(j=0;j<bp->hidden_layer_num[i];j++)
{
*(deltas_weight+j)=(double *)malloc(bp->hidden_layer_num[i-1]*sizeof(double));
for(k=0;k<bp->hidden_layer_num[i-1];k++)
deltas_weight[j][k]=0.0f;
}
}
}
deltas_weight=(double **)malloc(bp->output_num*sizeof(double *));
bp->out_params->deltas_weight_prior=deltas_weight;
for(i=0;i<bp->output_num;i++)
{
*(deltas_weight+i)=(double *)malloc(bp->hidden_layer_num[bp->hidden_num-1]*sizeof(double));
for(j=0;j<bp->hidden_layer_num[bp->hidden_num-1];j++)
deltas_weight[i][j]=0.0f;
}
}
#ifdef Lm
void init_deltas_Grad(_Bp_Params *bp){
_Hidden_Layer_Params *hidden_params;
hidden_params=bp->hidden_params;
double **deltas_Grad;
double **deltas_Grad_2;
int i,j,k;
for(i=0;i<bp->hidden_num;i++)
{
deltas_Grad =(double **)malloc(bp->hidden_layer_num[i]*sizeof(double *));
deltas_Grad_2 =(double **)malloc(bp->hidden_layer_num[i]*sizeof(double *));
(hidden_params+i)->deltas_Grad =deltas_Grad;
(hidden_params+i)->deltas_Grad_2 =deltas_Grad_2;
if(i==0)
{
for(j=0;j<bp->hidden_layer_num[i];j++)
{
*(deltas_Grad+j) =(double *)malloc((bp->input_num+1)*sizeof(double));
*(deltas_Grad_2+j) =(double *)malloc((bp->input_num+1)*sizeof(double));
for(k=0;k<=bp->input_num;k++)
{
deltas_Grad[j][k] =0.0f;
deltas_Grad_2[j][k] =0.0f;
}
}
}
else
{
for(j=0;j<bp->hidden_layer_num[i];j++)
{
*(deltas_Grad+j) =(double *)malloc((bp->hidden_layer_num[i-1]+1)*sizeof(double));
*(deltas_Grad_2+j) =(double *)malloc((bp->hidden_layer_num[i-1]+1)*sizeof(double));
for(k=0;k<=bp->hidden_layer_num[i-1];k++)
{
deltas_Grad[j][k] =0.0f;
deltas_Grad_2[j][k] =0.0f;
}
}
}
}
deltas_Grad =(double **)malloc(bp->output_num*sizeof(double *));
deltas_Grad_2 =(double **)malloc(bp->output_num*sizeof(double *));
bp->out_params->deltas_Grad =deltas_Grad;
bp->out_params->deltas_Grad_2 =deltas_Grad_2;
for(i=0;i<bp->output_num;i++)
{
*(deltas_Grad+i) =(double *)malloc((bp->hidden_layer_num[bp->hidden_num-1]+1)*sizeof(double));
*(deltas_Grad_2+i) =(double *)malloc((bp->hidden_layer_num[bp->hidden_num-1]+1)*sizeof(double));
for(j=0;j<=bp->hidden_layer_num[bp->hidden_num-1];j++)
{
deltas_Grad[i][j] =0.0f;
deltas_Grad_2[i][j] =0.0f;
}
}
}
#endif
void init_weight(_Bp_Params *bp){
srand(time(NULL));
init_hidden_weight(bp);
init_output_weight(bp);
init_deltas_weight(bp);
#ifdef Lm
init_deltas_Grad(bp);
#endif
}
#ifdef Lm
void zero_grad(_Bp_Params *bp){
double **deltas_Grad;
double **deltas_Grad_2;
_Hidden_Layer_Params *hidden_params;
_Output_Layer_Params *output_params;
int i,j,k;
hidden_params=bp->hidden_params;
output_params=bp->out_params;
for(i=0;i<bp->hidden_num;i++)
{
deltas_Grad =(hidden_params+i)->deltas_Grad;
deltas_Grad_2 =(hidden_params+i)->deltas_Grad_2;
if(i==0)
{
for(j=0;j<bp->hidden_layer_num[i];j++)
{
for(k=0;k<=bp->input_num;k++)
{
deltas_Grad[j][k] =0.0f;
deltas_Grad_2[j][k] =0.0f;
}
}
}
else
{
for(j=0;j<bp->hidden_layer_num[i];j++)
{
for(k=0;k<=bp->hidden_layer_num[i-1];k++)
{
deltas_Grad[j][k] =0.0f;
deltas_Grad_2[j][k] =0.0f;
}
}
}
}
deltas_Grad =output_params->deltas_Grad;
deltas_Grad_2 =output_params->deltas_Grad_2;
for(i=0;i<bp->output_num;i++)
{
for(j=0;j<=bp->hidden_layer_num[bp->hidden_num-1];j++)
{
deltas_Grad[i][j] =0.0f;
deltas_Grad_2[i][j] =0.0f;
}
}
}
#endif
void init_train_input(_Bp_Params *bp,FILE *fp){
double *input_data;
int i;
input_data=bp->input_params->inbuf;
for(i=0;i<bp->input_num;i++)
{
fscanf(fp,"%lf",input_data+i);
}
scale_input(input_data,bp->input_num);
}
void init_train_label(_Bp_Params *bp,FILE *fp){
double *label_data;
int train_label;
label_data=bp->out_params->label;
memset(label_data,0x00,bp->output_num*sizeof(double));
fscanf(fp,"%d",&train_label);
label_data[train_label]=1.0;
}
void init_train_data(_Bp_Params *bp,FILE *fp){
init_train_input(bp,fp);
init_train_label(bp,fp);
}
void calcuate_k_layer_output(_Bp_Params *bp){
_Hidden_Layer_Params *hidden_params;
_Input_Layer_Params *input_params;
_Output_Layer_Params *output_params;
double **hidden_