| | |
| | | #include "connected_layer.h" |
| | | #include "convolutional_layer.h" |
| | | #include "maxpool_layer.h" |
| | | #include "cost_layer.h" |
| | | #include "normalization_layer.h" |
| | | #include "freeweight_layer.h" |
| | | #include "softmax_layer.h" |
| | | #include "dropout_layer.h" |
| | | |
| | |
| | | } |
| | | |
| | | #ifdef GPU |
| | | void forward_network(network net, float *input, int train) |
| | | void forward_network_gpu(network net, cl_mem input, cl_mem truth, int train) |
| | | { |
| | | cl_setup(); |
| | | size_t size = get_network_input_size(net); |
| | | if(!net.input_cl){ |
| | | net.input_cl = clCreateBuffer(cl.context, |
| | | CL_MEM_READ_WRITE, size*sizeof(float), 0, &cl.error); |
| | | check_error(cl); |
| | | } |
| | | cl_write_array(net.input_cl, input, size); |
| | | cl_mem input_cl = net.input_cl; |
| | | int i; |
| | | for(i = 0; i < net.n; ++i){ |
| | | if(net.types[i] == CONVOLUTIONAL){ |
| | | convolutional_layer layer = *(convolutional_layer *)net.layers[i]; |
| | | forward_convolutional_layer_gpu(layer, input_cl); |
| | | input_cl = layer.output_cl; |
| | | input = layer.output; |
| | | forward_convolutional_layer_gpu(layer, input); |
| | | input = layer.output_cl; |
| | | } |
| | | else if(net.types[i] == COST){ |
| | | cost_layer layer = *(cost_layer *)net.layers[i]; |
| | | forward_cost_layer_gpu(layer, input, truth); |
| | | } |
| | | /* |
| | | else if(net.types[i] == CONNECTED){ |
| | | connected_layer layer = *(connected_layer *)net.layers[i]; |
| | | forward_connected_layer(layer, input, train); |
| | |
| | | forward_normalization_layer(layer, input); |
| | | input = layer.output; |
| | | } |
| | | */ |
| | | } |
| | | } |
| | | |
| | | #else |
| | | void backward_network_gpu(network net, cl_mem input) |
| | | { |
| | | int i; |
| | | cl_mem prev_input; |
| | | cl_mem prev_delta; |
| | | for(i = net.n-1; i >= 0; --i){ |
| | | if(i == 0){ |
| | | prev_input = input; |
| | | prev_delta = 0; |
| | | }else{ |
| | | prev_input = get_network_output_cl_layer(net, i-1); |
| | | prev_delta = get_network_delta_cl_layer(net, i-1); |
| | | } |
| | | if(net.types[i] == CONVOLUTIONAL){ |
| | | convolutional_layer layer = *(convolutional_layer *)net.layers[i]; |
| | | backward_convolutional_layer_gpu(layer, prev_delta); |
| | | } |
| | | else if(net.types[i] == COST){ |
| | | cost_layer layer = *(cost_layer *)net.layers[i]; |
| | | backward_cost_layer_gpu(layer, prev_input, prev_delta); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void forward_network(network net, float *input, int train) |
| | | void update_network_gpu(network net) |
| | | { |
| | | int i; |
| | | for(i = 0; i < net.n; ++i){ |
| | | if(net.types[i] == CONVOLUTIONAL){ |
| | | convolutional_layer layer = *(convolutional_layer *)net.layers[i]; |
| | | update_convolutional_layer_gpu(layer); |
| | | } |
| | | else if(net.types[i] == MAXPOOL){ |
| | | //maxpool_layer layer = *(maxpool_layer *)net.layers[i]; |
| | | } |
| | | else if(net.types[i] == SOFTMAX){ |
| | | //maxpool_layer layer = *(maxpool_layer *)net.layers[i]; |
| | | } |
| | | else if(net.types[i] == NORMALIZATION){ |
| | | //maxpool_layer layer = *(maxpool_layer *)net.layers[i]; |
| | | } |
| | | else if(net.types[i] == CONNECTED){ |
| | | connected_layer layer = *(connected_layer *)net.layers[i]; |
| | | update_connected_layer(layer); |
| | | } |
| | | } |
| | | } |
| | | |
| | | cl_mem get_network_output_cl_layer(network net, int i) |
| | | { |
| | | if(net.types[i] == CONVOLUTIONAL){ |
| | | convolutional_layer layer = *(convolutional_layer *)net.layers[i]; |
| | | return layer.output_cl; |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | cl_mem get_network_delta_cl_layer(network net, int i) |
| | | { |
| | | if(net.types[i] == CONVOLUTIONAL){ |
| | | convolutional_layer layer = *(convolutional_layer *)net.layers[i]; |
| | | return layer.delta_cl; |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | #endif |
| | | |
| | | void forward_network(network net, float *input, float *truth, int train) |
| | | { |
| | | int i; |
| | | for(i = 0; i < net.n; ++i){ |
| | |
| | | forward_crop_layer(layer, input); |
| | | input = layer.output; |
| | | } |
| | | else if(net.types[i] == COST){ |
| | | cost_layer layer = *(cost_layer *)net.layers[i]; |
| | | forward_cost_layer(layer, input, truth); |
| | | } |
| | | else if(net.types[i] == SOFTMAX){ |
| | | softmax_layer layer = *(softmax_layer *)net.layers[i]; |
| | | forward_softmax_layer(layer, input); |
| | |
| | | dropout_layer layer = *(dropout_layer *)net.layers[i]; |
| | | forward_dropout_layer(layer, input); |
| | | } |
| | | else if(net.types[i] == FREEWEIGHT){ |
| | | if(!train) continue; |
| | | freeweight_layer layer = *(freeweight_layer *)net.layers[i]; |
| | | forward_freeweight_layer(layer, input); |
| | | } |
| | | } |
| | | } |
| | | #endif |
| | | |
| | | void update_network(network net) |
| | | { |
| | |
| | | } |
| | | float *get_network_output(network net) |
| | | { |
| | | return get_network_output_layer(net, net.n-1); |
| | | int i; |
| | | for(i = net.n-1; i > 0; --i) if(net.types[i] != COST) break; |
| | | return get_network_output_layer(net, i); |
| | | } |
| | | |
| | | float *get_network_delta_layer(network net, int i) |
| | |
| | | return 0; |
| | | } |
| | | |
| | | float get_network_cost(network net) |
| | | { |
| | | if(net.types[net.n-1] == COST){ |
| | | return ((cost_layer *)net.layers[net.n-1])->output[0]; |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | float *get_network_delta(network net) |
| | | { |
| | | return get_network_delta_layer(net, net.n-1); |
| | |
| | | return max_index(out, k); |
| | | } |
| | | |
| | | float backward_network(network net, float *input, float *truth) |
| | | void backward_network(network net, float *input) |
| | | { |
| | | float error = calculate_error_network(net, truth); |
| | | int i; |
| | | float *prev_input; |
| | | float *prev_delta; |
| | |
| | | connected_layer layer = *(connected_layer *)net.layers[i]; |
| | | backward_connected_layer(layer, prev_input, prev_delta); |
| | | } |
| | | else if(net.types[i] == COST){ |
| | | cost_layer layer = *(cost_layer *)net.layers[i]; |
| | | backward_cost_layer(layer, prev_input, prev_delta); |
| | | } |
| | | } |
| | | return error; |
| | | } |
| | | |
| | | float train_network_datum(network net, float *x, float *y) |
| | | { |
| | | forward_network(net, x, 1); |
| | | forward_network(net, x, y, 1); |
| | | //int class = get_predicted_class_network(net); |
| | | float error = backward_network(net, x, y); |
| | | backward_network(net, x); |
| | | float error = get_network_cost(net); |
| | | update_network(net); |
| | | //return (y[class]?1:0); |
| | | return error; |
| | |
| | | float *X = calloc(batch*d.X.cols, sizeof(float)); |
| | | float *y = calloc(batch*d.y.cols, sizeof(float)); |
| | | |
| | | int i,j; |
| | | int i; |
| | | float sum = 0; |
| | | int index = 0; |
| | | for(i = 0; i < n; ++i){ |
| | | for(j = 0; j < batch; ++j){ |
| | | index = rand()%d.X.rows; |
| | | memcpy(X+j*d.X.cols, d.X.vals[index], d.X.cols*sizeof(float)); |
| | | memcpy(y+j*d.y.cols, d.y.vals[index], d.y.cols*sizeof(float)); |
| | | } |
| | | |
| | | get_batch(d, batch, X, y); |
| | | float err = train_network_datum(net, X, y); |
| | | sum += err; |
| | | //train_network_datum(net, X, y); |
| | | /* |
| | | float *y = d.y.vals[index]; |
| | | int class = get_predicted_class_network(net); |
| | | correct += (y[class]?1:0); |
| | | */ |
| | | |
| | | /* |
| | | for(j = 0; j < d.y.cols*batch; ++j){ |
| | | printf("%6.3f ", y[j]); |
| | | } |
| | | printf("\n"); |
| | | for(j = 0; j < d.y.cols*batch; ++j){ |
| | | printf("%6.3f ", get_network_output(net)[j]); |
| | | } |
| | | printf("\n"); |
| | | printf("\n"); |
| | | */ |
| | | |
| | | |
| | | //printf("%d %f %f\n", i,net.output[0], d.y.vals[index][0]); |
| | | //if((i+1)%10 == 0){ |
| | | // printf("%d: %f\n", (i+1), (float)correct/(i+1)); |
| | | //} |
| | | } |
| | | //printf("Accuracy: %f\n",(float) correct/n); |
| | | //show_image(float_to_image(32,32,3,X), "Orig"); |
| | | free(X); |
| | | free(y); |
| | | return (float)sum/(n*batch); |
| | |
| | | int index = rand()%d.X.rows; |
| | | float *x = d.X.vals[index]; |
| | | float *y = d.y.vals[index]; |
| | | forward_network(net, x, 1); |
| | | sum += backward_network(net, x, y); |
| | | forward_network(net, x, y, 1); |
| | | backward_network(net, x); |
| | | sum += get_network_cost(net); |
| | | } |
| | | update_network(net); |
| | | } |
| | |
| | | else if(net.types[i] == CONNECTED){ |
| | | connected_layer layer = *(connected_layer *)net.layers[i]; |
| | | return layer.outputs; |
| | | } else if(net.types[i] == DROPOUT){ |
| | | } |
| | | else if(net.types[i] == DROPOUT){ |
| | | dropout_layer layer = *(dropout_layer *) net.layers[i]; |
| | | return layer.inputs; |
| | | } |
| | |
| | | |
| | | int get_network_output_size(network net) |
| | | { |
| | | int i = net.n-1; |
| | | int i; |
| | | for(i = net.n-1; i > 0; --i) if(net.types[i] != COST) break; |
| | | return get_network_output_size_layer(net, i); |
| | | } |
| | | |
| | |
| | | |
| | | float *network_predict(network net, float *input) |
| | | { |
| | | forward_network(net, input, 0); |
| | | forward_network(net, input, 0, 0); |
| | | float *out = get_network_output(net); |
| | | return out; |
| | | } |