-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcnn.c
148 lines (130 loc) · 4.93 KB
/
cnn.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include"cnn.h"
#include"conv_layer.h"
#include"relu_layer.h"
#include"pool_layer.h"
#include"BN_layer.h"
#include"dense_layer.h"
#include"softmax.h"
#include<stdlib.h>
#include<math.h>
struct CNN *cnn_init(struct data_box *input_data){
struct CNN *cnn = (struct CNN *)malloc(sizeof(struct CNN));
int *shape=input_data->shape;
int ndims=input_data->ndims;
cnn->state=TRAIN;
cnn->adam_para.beta1=0.9;
cnn->adam_para.beta2=0.99;
cnn->adam_para.eps=1e-8;
cnn->adam_para.lr=1e-3;
cnn->adam_para.t=0;
struct data_box *common_p;
struct data_box *dcommon_p;
common_p=(struct data_box *)malloc(sizeof(struct data_box));
//common_p->data=(double *)malloc(shape[0]*neuron_num*sizeof(double));
common_p->shape=shape;
common_p->ndims=ndims;
int size=1;
for(int i=0;i<ndims;i++) size*=shape[i];
dcommon_p=(struct data_box *)malloc(sizeof(struct data_box));
dcommon_p->data=(double *)malloc(size*sizeof(double));
dcommon_p->shape=shape;
dcommon_p->ndims=ndims;
//定义网络的结构
// conv_layer_init(&cnn->layer_box[0],common_p,dcommon_p);
// BN_layer_init(&cnn->layer_box[1],common_p,dcommon_p);
// relu_layer_init(&cnn->layer_box[2],common_p,dcommon_p);
// conv_layer_init(&cnn->layer_box[3],common_p,dcommon_p);
// BN_layer_init(&cnn->layer_box[4],common_p,dcommon_p);
// relu_layer_init(&cnn->layer_box[5],common_p,dcommon_p);
// pool_layer_init(&cnn->layer_box[6],common_p,dcommon_p);
// conv_layer_init(&cnn->layer_box[7],common_p,dcommon_p);
// BN_layer_init(&cnn->layer_box[8],common_p,dcommon_p);
// relu_layer_init(&cnn->layer_box[9],common_p,dcommon_p);
// pool_layer_init(&cnn->layer_box[10],common_p,dcommon_p);
// dense_layer_init(&cnn->layer_box[0],&common_p,&dcommon_p,2048);
// relu_layer_init(&cnn->layer_box[1],&common_p,&dcommon_p);
conv_layer_init(&cnn->layer_box[0],&common_p,&dcommon_p,32,5,5,1,1);
BN_layer_init(&cnn->layer_box[1],&common_p,&dcommon_p);
relu_layer_init(&cnn->layer_box[2],&common_p,&dcommon_p);
pool_layer_init(&cnn->layer_box[3],&common_p,&dcommon_p,2,2);
conv_layer_init(&cnn->layer_box[4],&common_p,&dcommon_p,64,5,5,1,1);
BN_layer_init(&cnn->layer_box[5],&common_p,&dcommon_p);
relu_layer_init(&cnn->layer_box[6],&common_p,&dcommon_p);
pool_layer_init(&cnn->layer_box[7],&common_p,&dcommon_p,2,2);
dense_layer_init(&cnn->layer_box[8],&common_p,&dcommon_p,1024);
BN_layer_init(&cnn->layer_box[9],&common_p,&dcommon_p);
relu_layer_init(&cnn->layer_box[10],&common_p,&dcommon_p);
dense_layer_init(&cnn->layer_box[11],&common_p,&dcommon_p,10);
cnn->softmax_obj=softmax_init(common_p,dcommon_p);
cnn->weight_size=0;
for(int i=0;i<sizeof(cnn->layer_box)/sizeof(struct layer *);i++){
cnn->weight_size+=cnn->layer_box[i]->weight_size;
}
return cnn;
}
//神经网络运行流程控制
double *go(struct CNN *cnn,int state){
double *result_box;//返回loss和acc
cnn->state=state;
//前向传播
for(int i=0;i<sizeof(cnn->layer_box)/sizeof(struct layer *);i++){
struct layer *layer=cnn->layer_box[i];
layer->forward_pass(layer,TRAIN);
}
result_box=cnn->softmax_obj->forward_pass(cnn->softmax_obj,state);
if(state==TRAIN){
//反向传播
for(int i=sizeof(cnn->layer_box)/sizeof(struct layer *)-1;i>=0;i--){
struct layer *layer=cnn->layer_box[i];
layer->backward_pass(layer);
}
cnn->adam_para.t++;
//更新梯度
for(int i=0;i<sizeof(cnn->layer_box)/sizeof(struct layer *);i++){
struct layer *layer=cnn->layer_box[i];
layer->update(cnn,layer);
}
}else{//state==test
}
return result_box;//记得释放内存
}
//adam优化器
void adam(struct CNN *cnn,double *x,double *dx,double *m,double *v,int size){
double b1,b2,lr,eps,t,coef;
b1=cnn->adam_para.beta1;
b2=cnn->adam_para.beta2;
eps=cnn->adam_para.eps;
lr=cnn->adam_para.lr;
t=cnn->adam_para.t;
coef=-lr*sqrt(1-pow(b2,t))/(1-pow(b1,t));
for(int i=0;i<size;i++){
m[i]=b1*m[i]+(1-b1)*dx[i];
v[i]=b2*v[i]+(1-b2)*dx[i]*dx[i];
x[i]+=coef*m[i]/(sqrt(v[i])+eps);
}
}
//喂数据
void feed(struct CNN *cnn,struct feed_data *data){
struct layer *layer=cnn->layer_box[0];
layer->x->data=data->data;
layer->x->shape[0]=data->sample_num;
cnn->softmax_obj->label=data->label;
}
void load_weight(struct CNN *cnn,double *buf){
int current_size=0;
struct layer *layer;
for(int i=0;i<sizeof(cnn->layer_box)/sizeof(struct layer *);i++){
layer=cnn->layer_box[i];
layer->load_weight(layer,buf+current_size);
current_size+=layer->weight_size;
}
}
void pack_dweight(struct CNN *cnn,double *buf){
int current_size=0;
struct layer *layer;
for(int i=0;i<sizeof(cnn->layer_box)/sizeof(struct layer *);i++){
layer=cnn->layer_box[i];
layer->pack_dweight(layer,buf+current_size);
current_size+=layer->weight_size;
}
}