From 41bcfac86fa4dc856f3d1894efeee0f55f86f7b0 Mon Sep 17 00:00:00 2001 From: Joseph Redmon Date: Mon, 4 Nov 2013 11:11:01 -0800 Subject: [PATCH] First Commit! --- .gitignore | 13 ++ Makefile | 21 +++ dog.jpg | Bin 0 -> 44245 bytes src/connected_layer.c | 92 ++++++++++ src/connected_layer.h | 21 +++ src/convolutional_layer.c | 86 ++++++++++ src/convolutional_layer.h | 21 +++ src/image.c | 348 ++++++++++++++++++++++++++++++++++++++ src/image.h | 42 +++++ src/maxpool_layer.c | 24 +++ src/maxpool_layer.h | 15 ++ src/network.c | 48 ++++++ src/network.h | 23 +++ src/tests.c | 200 ++++++++++++++++++++++ test.jpg | Bin 0 -> 9756 bytes test_color.png | Bin 0 -> 1097 bytes test_dog.jpg | Bin 0 -> 30762 bytes test_hinton.jpg | Bin 0 -> 16456 bytes 18 files changed, 954 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 dog.jpg create mode 100644 src/connected_layer.c create mode 100644 src/connected_layer.h create mode 100644 src/convolutional_layer.c create mode 100644 src/convolutional_layer.h create mode 100644 src/image.c create mode 100644 src/image.h create mode 100644 src/maxpool_layer.c create mode 100644 src/maxpool_layer.h create mode 100644 src/network.c create mode 100644 src/network.h create mode 100644 src/tests.c create mode 100644 test.jpg create mode 100644 test_color.png create mode 100644 test_dog.jpg create mode 100644 test_hinton.jpg diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..da9802e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.o +*.dSYM +*.csv +images/ +opencv/ +cnn + +# OS Generated # +.DS_Store* +ehthumbs.db +Icon? +Thumbs.db +*.swp diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..4dce124c --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +CC=gcc +CFLAGS=-Wall `pkg-config --cflags opencv` -O3 -flto -ffast-math +#CFLAGS=-Wall `pkg-config --cflags opencv` -O0 -g +LDFLAGS=`pkg-config --libs opencv` -lm +VPATH=./src/ + +OBJ=network.o image.o tests.o convolutional_layer.o connected_layer.o maxpool_layer.o + +all: cnn + +cnn: $(OBJ) + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ + +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +.PHONY: clean + +clean: + rm -rf $(OBJ) cnn + diff --git a/dog.jpg b/dog.jpg new file mode 100644 index 0000000000000000000000000000000000000000..16d05ab17c401c39d9d841d931ddb92cd65796f4 GIT binary patch literal 44245 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 literal 0 HcmV?d00001 diff --git a/src/connected_layer.c b/src/connected_layer.c new file mode 100644 index 00000000..fe904bac --- /dev/null +++ b/src/connected_layer.c @@ -0,0 +1,92 @@ +#include "connected_layer.h" + +#include +#include + +double activation(double x) +{ + return x*(x>0); +} + +double gradient(double x) +{ + return (x>=0); +} + +connected_layer make_connected_layer(int inputs, int outputs) +{ + int i; + connected_layer layer; + layer.inputs = inputs; + layer.outputs = outputs; + + layer.output = calloc(outputs, sizeof(double*)); + + layer.weight_updates = calloc(inputs*outputs, sizeof(double)); + layer.weights = calloc(inputs*outputs, sizeof(double)); + for(i = 0; i < inputs*outputs; ++i) + layer.weights[i] = .5 - (double)rand()/RAND_MAX; + + layer.bias_updates = calloc(outputs, sizeof(double)); + layer.biases = calloc(outputs, sizeof(double)); + for(i = 0; i < outputs; ++i) + layer.biases[i] = (double)rand()/RAND_MAX; + + return layer; +} + +void run_connected_layer(double *input, connected_layer layer) +{ + int i, j; + for(i = 0; i < layer.outputs; ++i){ + layer.output[i] = layer.biases[i]; + for(j = 0; j < layer.inputs; ++j){ + layer.output[i] += input[j]*layer.weights[i*layer.outputs + j]; + } + layer.output[i] = activation(layer.output[i]); + } +} + +void backpropagate_connected_layer(double *input, connected_layer layer) +{ + int i, j; + double *old_input = calloc(layer.inputs, sizeof(double)); + memcpy(old_input, input, layer.inputs*sizeof(double)); + memset(input, 0, layer.inputs*sizeof(double)); + + for(i = 0; i < layer.outputs; ++i){ + for(j = 0; j < layer.inputs; ++j){ + input[j] += layer.output[i]*layer.weights[i*layer.outputs + j]; + } + } + for(j = 0; j < layer.inputs; ++j){ + input[j] = input[j]*gradient(old_input[j]); + } + free(old_input); +} + +void calculate_updates_connected_layer(double *input, connected_layer layer) +{ + int i, j; + for(i = 0; i < layer.outputs; ++i){ + layer.bias_updates[i] += layer.output[i]; + for(j = 0; j < layer.inputs; ++j){ + layer.weight_updates[i*layer.outputs + j] += layer.output[i]*input[j]; + } + } +} + +void update_connected_layer(connected_layer layer, double step) +{ + int i,j; + for(i = 0; i < layer.outputs; ++i){ + layer.biases[i] += step*layer.bias_updates[i]; + for(j = 0; j < layer.inputs; ++j){ + int index = i*layer.outputs+j; + layer.weights[index] = layer.weight_updates[index]; + } + } + memset(layer.bias_updates, 0, layer.outputs*sizeof(double)); + memset(layer.weight_updates, 0, layer.outputs*layer.inputs*sizeof(double)); +} + diff --git a/src/connected_layer.h b/src/connected_layer.h new file mode 100644 index 00000000..e403b0f9 --- /dev/null +++ b/src/connected_layer.h @@ -0,0 +1,21 @@ +#ifndef CONNECTED_LAYER_H +#define CONNECTED_LAYER_H + +typedef struct{ + int inputs; + int outputs; + double *weights; + double *biases; + double *weight_updates; + double *bias_updates; + double *output; +} connected_layer; + +connected_layer make_connected_layer(int inputs, int outputs); +void run_connected_layer(double *input, connected_layer layer); +void backpropagate_connected_layer(double *input, connected_layer layer); +void calculate_updates_connected_layer(double *input, connected_layer layer); +void update_connected_layer(connected_layer layer, double step); + +#endif + diff --git a/src/convolutional_layer.c b/src/convolutional_layer.c new file mode 100644 index 00000000..f83622b2 --- /dev/null +++ b/src/convolutional_layer.c @@ -0,0 +1,86 @@ +#include "convolutional_layer.h" + +double convolution_activation(double x) +{ + return x*(x>0); +} + +double convolution_gradient(double x) +{ + return (x>=0); +} + +convolutional_layer make_convolutional_layer(int h, int w, int c, int n, int size, int stride) +{ + int i; + convolutional_layer layer; + layer.n = n; + layer.stride = stride; + layer.kernels = calloc(n, sizeof(image)); + layer.kernel_updates = calloc(n, sizeof(image)); + for(i = 0; i < n; ++i){ + layer.kernels[i] = make_random_kernel(size, c); + layer.kernel_updates[i] = make_random_kernel(size, c); + } + layer.output = make_image((h-1)/stride+1, (w-1)/stride+1, n); + layer.upsampled = make_image(h,w,n); + return layer; +} + +void run_convolutional_layer(const image input, const convolutional_layer layer) +{ + int i; + for(i = 0; i < layer.n; ++i){ + convolve(input, layer.kernels[i], layer.stride, i, layer.output); + } + for(i = 0; i < input.h*input.w*input.c; ++i){ + input.data[i] = convolution_activation(input.data[i]); + } +} + +void backpropagate_layer(image input, convolutional_layer layer) +{ + int i; + zero_image(input); + for(i = 0; i < layer.n; ++i){ + back_convolve(input, layer.kernels[i], layer.stride, i, layer.output); + } +} + +void backpropagate_layer_convolve(image input, convolutional_layer layer) +{ + int i,j; + for(i = 0; i < layer.n; ++i){ + rotate_image(layer.kernels[i]); + } + + zero_image(input); + upsample_image(layer.output, layer.stride, layer.upsampled); + for(j = 0; j < input.c; ++j){ + for(i = 0; i < layer.n; ++i){ + two_d_convolve(layer.upsampled, i, layer.kernels[i], j, 1, input, j); + } + } + + for(i = 0; i < layer.n; ++i){ + rotate_image(layer.kernels[i]); + } +} + +void error_convolutional_layer(image input, convolutional_layer layer) +{ + int i; + for(i = 0; i < layer.n; ++i){ + kernel_update(input, layer.kernel_updates[i], layer.stride, i, layer.output); + } + image old_input = copy_image(input); + zero_image(input); + for(i = 0; i < layer.n; ++i){ + back_convolve(input, layer.kernels[i], layer.stride, i, layer.output); + } + for(i = 0; i < input.h*input.w*input.c; ++i){ + input.data[i] = input.data[i]*convolution_gradient(input.data[i]); + } + free_image(old_input); +} + diff --git a/src/convolutional_layer.h b/src/convolutional_layer.h new file mode 100644 index 00000000..b42f5e90 --- /dev/null +++ b/src/convolutional_layer.h @@ -0,0 +1,21 @@ +#ifndef CONVOLUTIONAL_LAYER_H +#define CONVOLUTIONAL_LAYER_H + +#include "image.h" + +typedef struct { + int n; + int stride; + image *kernels; + image *kernel_updates; + image upsampled; + image output; +} convolutional_layer; + +convolutional_layer make_convolutional_layer(int w, int h, int c, int n, int size, int stride); +void run_convolutional_layer(const image input, const convolutional_layer layer); +void backpropagate_layer(image input, convolutional_layer layer); +void backpropagate_layer_convolve(image input, convolutional_layer layer); + +#endif + diff --git a/src/image.c b/src/image.c new file mode 100644 index 00000000..13c6b313 --- /dev/null +++ b/src/image.c @@ -0,0 +1,348 @@ +#include "image.h" +#include + +int windows = 0; + +void subtract_image(image a, image b) +{ + int i; + for(i = 0; i < a.h*a.w*a.c; ++i) a.data[i] -= b.data[i]; +} + +void normalize_image(image p) +{ + double *min = calloc(p.c, sizeof(double)); + double *max = calloc(p.c, sizeof(double)); + int i,j; + for(i = 0; i < p.c; ++i) min[i] = max[i] = p.data[i*p.h*p.w]; + + for(j = 0; j < p.c; ++j){ + for(i = 0; i < p.h*p.w; ++i){ + double v = p.data[i+j*p.h*p.w]; + if(v < min[j]) min[j] = v; + if(v > max[j]) max[j] = v; + } + } + for(i = 0; i < p.c; ++i){ + if(max[i] - min[i] < .00001){ + min[i] = 0; + max[i] = 1; + } + } + for(j = 0; j < p.c; ++j){ + for(i = 0; i < p.w*p.h; ++i){ + p.data[i+j*p.h*p.w] = (p.data[i+j*p.h*p.w] - min[j])/(max[j]-min[j]); + } + } +} + +void threshold_image(image p, double t) +{ + int i; + for(i = 0; i < p.w*p.h*p.c; ++i){ + if(p.data[i] < t) p.data[i] = 0; + } +} + +image copy_image(image p) +{ + image copy = p; + copy.data = calloc(p.h*p.w*p.c, sizeof(double)); + memcpy(copy.data, p.data, p.h*p.w*p.c*sizeof(double)); + return copy; +} + +void show_image(image p, char *name) +{ + int i,j,k; + image copy = copy_image(p); + normalize_image(copy); + + char buff[256]; + sprintf(buff, "%s (%d)", name, windows); + + IplImage *disp = cvCreateImage(cvSize(p.w,p.h), IPL_DEPTH_8U, p.c); + int step = disp->widthStep; + cvNamedWindow(buff, CV_WINDOW_AUTOSIZE); + cvMoveWindow(buff, 100*(windows%10) + 200*(windows/10), 100*(windows%10)); + ++windows; + for(i = 0; i < p.h; ++i){ + for(j = 0; j < p.w; ++j){ + for(k= 0; k < p.c; ++k){ + disp->imageData[i*step + j*p.c + k] = (unsigned char)(get_pixel(copy,i,j,k)*255); + } + } + } + if(disp->height < 100 || disp->width < 100){ + IplImage *buffer = disp; + disp = cvCreateImage(cvSize(100,100*p.h/p.w), buffer->depth, buffer->nChannels); + cvResize(buffer, disp, CV_INTER_NN); + cvReleaseImage(&buffer); + } + cvShowImage(buff, disp); + cvReleaseImage(&disp); +} + +void show_image_layers(image p, char *name) +{ + int i; + char buff[256]; + for(i = 0; i < p.c; ++i){ + sprintf(buff, "%s - Layer %d", name, i); + image layer = get_image_layer(p, i); + show_image(layer, buff); + free_image(layer); + } +} + +image make_image(int h, int w, int c) +{ + image out; + out.h = h; + out.w = w; + out.c = c; + out.data = calloc(h*w*c, sizeof(double)); + return out; +} + +void zero_image(image m) +{ + memset(m.data, 0, m.h*m.w*m.c*sizeof(double)); +} + +void zero_channel(image m, int c) +{ + memset(&(m.data[c*m.h*m.w]), 0, m.h*m.w*sizeof(double)); +} + +void rotate_image(image m) +{ + int i,j; + for(j = 0; j < m.c; ++j){ + for(i = 0; i < m.h*m.w/2; ++i){ + double swap = m.data[j*m.h*m.w + i]; + m.data[j*m.h*m.w + i] = m.data[j*m.h*m.w + (m.h*m.w-1 - i)]; + m.data[j*m.h*m.w + (m.h*m.w-1 - i)] = swap; + } + } +} + +image make_random_image(int h, int w, int c) +{ + image out = make_image(h,w,c); + int i; + for(i = 0; i < h*w*c; ++i){ + out.data[i] = (double)rand()/RAND_MAX; + } + return out; +} + +image make_random_kernel(int size, int c) +{ + int pad; + if((pad=(size%2==0))) ++size; + image out = make_random_image(size,size,c); + int i,k; + if(pad){ + for(k = 0; k < out.c; ++k){ + for(i = 0; i < size; ++i) { + set_pixel(out, i, 0, k, 0); + set_pixel(out, 0, i, k, 0); + } + } + } + return out; +} + + +image load_image(char *filename) +{ + IplImage* src = 0; + if( (src = cvLoadImage(filename,-1)) == 0 ) + { + printf("Cannot load file image %s\n", filename); + exit(0); + } + unsigned char *data = (unsigned char *)src->imageData; + int c = src->nChannels; + int h = src->height; + int w = src->width; + int step = src->widthStep; + image out = make_image(h,w,c); + int i, j, k, count=0;; + + for(k= 0; k < c; ++k){ + for(i = 0; i < h; ++i){ + for(j = 0; j < w; ++j){ + out.data[count++] = data[i*step + j*c + k]; + } + } + } + cvReleaseImage(&src); + return out; +} + +image get_image_layer(image m, int l) +{ + image out = make_image(m.h, m.w, 1); + int i; + for(i = 0; i < m.h*m.w; ++i){ + out.data[i] = m.data[i+l*m.h*m.w]; + } + return out; +} + +double get_pixel(image m, int x, int y, int c) +{ + assert(x < m.h && y < m.w && c < m.c); + return m.data[c*m.h*m.w + x*m.w + y]; +} +double get_pixel_extend(image m, int x, int y, int c) +{ + if(x < 0 || x >= m.h || y < 0 || y >= m.w || c < 0 || c >= m.c) return 0; + return get_pixel(m, x, y, c); +} +void set_pixel(image m, int x, int y, int c, double val) +{ + assert(x < m.h && y < m.w && c < m.c); + m.data[c*m.h*m.w + x*m.w + y] = val; +} +void set_pixel_extend(image m, int x, int y, int c, double val) +{ + if(x < 0 || x >= m.h || y < 0 || y >= m.w || c < 0 || c >= m.c) return; + set_pixel(m, x, y, c, val); +} + +void add_pixel(image m, int x, int y, int c, double val) +{ + assert(x < m.h && y < m.w && c < m.c); + m.data[c*m.h*m.w + x*m.w + y] += val; +} + +void add_pixel_extend(image m, int x, int y, int c, double val) +{ + if(x < 0 || x >= m.h || y < 0 || y >= m.w || c < 0 || c >= m.c) return; + add_pixel(m, x, y, c, val); +} + +void two_d_convolve(image m, int mc, image kernel, int kc, int stride, image out, int oc) +{ + int x,y,i,j; + for(x = 0; x < m.h; x += stride){ + for(y = 0; y < m.w; y += stride){ + double sum = 0; + for(i = 0; i < kernel.h; ++i){ + for(j = 0; j < kernel.w; ++j){ + sum += get_pixel(kernel, i, j, kc)*get_pixel_extend(m, x+i-kernel.h/2, y+j-kernel.w/2, mc); + } + } + add_pixel(out, x/stride, y/stride, oc, sum); + } + } +} + +double single_convolve(image m, image kernel, int x, int y) +{ + double sum = 0; + int i, j, k; + for(i = 0; i < kernel.h; ++i){ + for(j = 0; j < kernel.w; ++j){ + for(k = 0; k < kernel.c; ++k){ + sum += get_pixel(kernel, i, j, k)*get_pixel_extend(m, x+i-kernel.h/2, y+j-kernel.w/2, k); + } + } + } + return sum; +} + +void convolve(image m, image kernel, int stride, int channel, image out) +{ + assert(m.c == kernel.c); + int i; + zero_channel(out, channel); + for(i = 0; i < m.c; ++i){ + two_d_convolve(m, i, kernel, i, stride, out, channel); + } + /* + int j; + for(i = 0; i < m.h; i += stride){ + for(j = 0; j < m.w; j += stride){ + double val = single_convolve(m, kernel, i, j); + set_pixel(out, i/stride, j/stride, channel, val); + } + } + */ +} + +void upsample_image(image m, int stride, image out) +{ + int i,j,k; + zero_image(out); + for(k = 0; k < m.c; ++k){ + for(i = 0; i < m.h; ++i){ + for(j = 0; j< m.w; ++j){ + double val = get_pixel(m, i, j, k); + set_pixel(out, i*stride, j*stride, k, val); + } + } + } +} + +void single_update(image m, image update, int x, int y, double error) +{ + int i, j, k; + for(i = 0; i < update.h; ++i){ + for(j = 0; j < update.w; ++j){ + for(k = 0; k < update.c; ++k){ + double val = get_pixel_extend(m, x+i-update.h/2, y+j-update.w/2, k); + add_pixel(update, i, j, k, val*error); + } + } + } +} + +void kernel_update(image m, image update, int stride, int channel, image out) +{ + assert(m.c == update.c); + zero_image(update); + int i, j; + for(i = 0; i < m.h; i += stride){ + for(j = 0; j < m.w; j += stride){ + double error = get_pixel(out, i/stride, j/stride, channel); + single_update(m, update, i, j, error); + } + } + for(i = 0; i < update.h*update.w*update.c; ++i){ + update.data[i] /= (m.h/stride)*(m.w/stride); + } +} + +void single_back_convolve(image m, image kernel, int x, int y, double val) +{ + int i, j, k; + for(i = 0; i < kernel.h; ++i){ + for(j = 0; j < kernel.w; ++j){ + for(k = 0; k < kernel.c; ++k){ + double pval = get_pixel(kernel, i, j, k) * val; + add_pixel_extend(m, x+i-kernel.h/2, y+j-kernel.w/2, k, pval); + } + } + } +} + +void back_convolve(image m, image kernel, int stride, int channel, image out) +{ + assert(m.c == kernel.c); + int i, j; + for(i = 0; i < m.h; i += stride){ + for(j = 0; j < m.w; j += stride){ + double val = get_pixel(out, i/stride, j/stride, channel); + single_back_convolve(m, kernel, i, j, val); + } + } +} + +void free_image(image m) +{ + free(m.data); +} diff --git a/src/image.h b/src/image.h new file mode 100644 index 00000000..85306f05 --- /dev/null +++ b/src/image.h @@ -0,0 +1,42 @@ +#ifndef IMAGE_H +#define IMAGE_H + +#include "opencv2/highgui/highgui_c.h" +#include "opencv2/imgproc/imgproc_c.h" +typedef struct { + int h; + int w; + int c; + double *data; +} image; + +void normalize_image(image p); +void threshold_image(image p, double t); +void zero_image(image m); +void rotate_image(image m); + +void show_image(image p, char *name); +void show_image_layers(image p, char *name); + +image make_image(int h, int w, int c); +image make_random_image(int h, int w, int c); +image make_random_kernel(int size, int c); +image copy_image(image p); +image load_image(char *filename); + +double get_pixel(image m, int x, int y, int c); +double get_pixel_extend(image m, int x, int y, int c); +void set_pixel(image m, int x, int y, int c, double val); + + +image get_image_layer(image m, int l); + +void two_d_convolve(image m, int mc, image kernel, int kc, int stride, image out, int oc); +void upsample_image(image m, int stride, image out); +void convolve(image m, image kernel, int stride, int channel, image out); +void back_convolve(image m, image kernel, int stride, int channel, image out); +void kernel_update(image m, image update, int stride, int channel, image out); + +void free_image(image m); +#endif + diff --git a/src/maxpool_layer.c b/src/maxpool_layer.c new file mode 100644 index 00000000..38ac582a --- /dev/null +++ b/src/maxpool_layer.c @@ -0,0 +1,24 @@ +#include "maxpool_layer.h" + +maxpool_layer make_maxpool_layer(int h, int w, int c, int stride) +{ + maxpool_layer layer; + layer.stride = stride; + layer.output = make_image((h-1)/stride+1, (w-1)/stride+1, c); + return layer; +} + +void run_maxpool_layer(const image input, const maxpool_layer layer) +{ + int i,j,k; + for(i = 0; i < layer.output.h*layer.output.w*layer.output.c; ++i) layer.output.data[i] = -DBL_MAX; + for(i = 0; i < input.h; ++i){ + for(j = 0; j < input.w; ++j){ + for(k = 0; k < input.c; ++k){ + double val = get_pixel(input, i, j, k); + double cur = get_pixel(layer.output, i/layer.stride, j/layer.stride, k); + if(val > cur) set_pixel(layer.output, i/layer.stride, j/layer.stride, k, val); + } + } + } +} diff --git a/src/maxpool_layer.h b/src/maxpool_layer.h new file mode 100644 index 00000000..077bcfa6 --- /dev/null +++ b/src/maxpool_layer.h @@ -0,0 +1,15 @@ +#ifndef MAXPOOL_LAYER_H +#define MAXPOOL_LAYER_H + +#include "image.h" + +typedef struct { + int stride; + image output; +} maxpool_layer; + +maxpool_layer make_maxpool_layer(int h, int w, int c, int stride); +void run_maxpool_layer(const image input, const maxpool_layer layer); + +#endif + diff --git a/src/network.c b/src/network.c new file mode 100644 index 00000000..e55535ce --- /dev/null +++ b/src/network.c @@ -0,0 +1,48 @@ +#include "network.h" +#include "image.h" + +#include "connected_layer.h" +#include "convolutional_layer.h" +#include "maxpool_layer.h" + +void run_network(image input, network net) +{ + int i; + double *input_d = 0; + for(i = 0; i < net.n; ++i){ + if(net.types[i] == CONVOLUTIONAL){ + convolutional_layer layer = *(convolutional_layer *)net.layers[i]; + run_convolutional_layer(input, layer); + input = layer.output; + input_d = layer.output.data; + } + else if(net.types[i] == CONNECTED){ + connected_layer layer = *(connected_layer *)net.layers[i]; + run_connected_layer(input_d, layer); + input_d = layer.output; + } + else if(net.types[i] == MAXPOOL){ + maxpool_layer layer = *(maxpool_layer *)net.layers[i]; + run_maxpool_layer(input, layer); + input = layer.output; + input_d = layer.output.data; + } + } +} + +image get_network_image(network net) +{ + int i; + for(i = net.n-1; i >= 0; --i){ + if(net.types[i] == CONVOLUTIONAL){ + convolutional_layer layer = *(convolutional_layer *)net.layers[i]; + return layer.output; + } + else if(net.types[i] == MAXPOOL){ + maxpool_layer layer = *(maxpool_layer *)net.layers[i]; + return layer.output; + } + } + return make_image(1,1,1); +} + diff --git a/src/network.h b/src/network.h new file mode 100644 index 00000000..826eafab --- /dev/null +++ b/src/network.h @@ -0,0 +1,23 @@ +// Oh boy, why am I about to do this.... +#ifndef NETWORK_H +#define NETWORK_H + +#include "image.h" + +typedef enum { + CONVOLUTIONAL, + CONNECTED, + MAXPOOL +} LAYER_TYPE; + +typedef struct { + int n; + void **layers; + LAYER_TYPE *types; +} network; + +void run_network(image input, network net); +image get_network_image(network net); + +#endif + diff --git a/src/tests.c b/src/tests.c new file mode 100644 index 00000000..7e2539a1 --- /dev/null +++ b/src/tests.c @@ -0,0 +1,200 @@ +#include "connected_layer.h" +#include "convolutional_layer.h" +#include "maxpool_layer.h" +#include "network.h" +#include "image.h" + +#include +#include +#include + +void test_convolve() +{ + image dog = load_image("dog.jpg"); + //show_image_layers(dog, "Dog"); + printf("dog channels %d\n", dog.c); + image kernel = make_random_image(3,3,dog.c); + image edge = make_image(dog.h, dog.w, 1); + int i; + clock_t start = clock(), end; + for(i = 0; i < 1000; ++i){ + convolve(dog, kernel, 1, 0, edge); + } + end = clock(); + printf("Convolutions: %lf seconds\n", (double)(end-start)/CLOCKS_PER_SEC); + show_image_layers(edge, "Test Convolve"); +} + +void test_color() +{ + image dog = load_image("test_color.png"); + show_image_layers(dog, "Test Color"); +} + +void test_convolutional_layer() +{ + srand(0); + image dog = load_image("test_dog.jpg"); + int i; + int n = 5; + int stride = 1; + int size = 8; + convolutional_layer layer = make_convolutional_layer(dog.h, dog.w, dog.c, n, size, stride); + char buff[256]; + for(i = 0; i < n; ++i) { + sprintf(buff, "Kernel %d", i); + show_image(layer.kernels[i], buff); + } + run_convolutional_layer(dog, layer); + + maxpool_layer mlayer = make_maxpool_layer(layer.output.h, layer.output.w, layer.output.c, 3); + run_maxpool_layer(layer.output,mlayer); + + show_image_layers(mlayer.output, "Test Maxpool Layer"); +} + +void test_load() +{ + image dog = load_image("dog.jpg"); + show_image(dog, "Test Load"); + show_image_layers(dog, "Test Load"); +} +void test_upsample() +{ + image dog = load_image("dog.jpg"); + int n = 3; + image up = make_image(n*dog.h, n*dog.w, dog.c); + upsample_image(dog, n, up); + show_image(up, "Test Upsample"); + show_image_layers(up, "Test Upsample"); +} + +void test_rotate() +{ + int i; + image dog = load_image("dog.jpg"); + clock_t start = clock(), end; + for(i = 0; i < 1001; ++i){ + rotate_image(dog); + } + end = clock(); + printf("Rotations: %lf seconds\n", (double)(end-start)/CLOCKS_PER_SEC); + show_image(dog, "Test Rotate"); + + image random = make_random_image(3,3,3); + show_image(random, "Test Rotate Random"); + rotate_image(random); + show_image(random, "Test Rotate Random"); + rotate_image(random); + show_image(random, "Test Rotate Random"); +} + +void test_network() +{ + network net; + net.n = 11; + net.layers = calloc(net.n, sizeof(void *)); + net.types = calloc(net.n, sizeof(LAYER_TYPE)); + net.types[0] = CONVOLUTIONAL; + net.types[1] = MAXPOOL; + net.types[2] = CONVOLUTIONAL; + net.types[3] = MAXPOOL; + net.types[4] = CONVOLUTIONAL; + net.types[5] = CONVOLUTIONAL; + net.types[6] = CONVOLUTIONAL; + net.types[7] = MAXPOOL; + net.types[8] = CONNECTED; + net.types[9] = CONNECTED; + net.types[10] = CONNECTED; + + image dog = load_image("test_hinton.jpg"); + + int n = 48; + int stride = 4; + int size = 11; + convolutional_layer cl = make_convolutional_layer(dog.h, dog.w, dog.c, n, size, stride); + maxpool_layer ml = make_maxpool_layer(cl.output.h, cl.output.w, cl.output.c, 2); + + n = 128; + size = 5; + stride = 1; + convolutional_layer cl2 = make_convolutional_layer(ml.output.h, ml.output.w, ml.output.c, n, size, stride); + maxpool_layer ml2 = make_maxpool_layer(cl2.output.h, cl2.output.w, cl2.output.c, 2); + + n = 192; + size = 3; + convolutional_layer cl3 = make_convolutional_layer(ml2.output.h, ml2.output.w, ml2.output.c, n, size, stride); + convolutional_layer cl4 = make_convolutional_layer(cl3.output.h, cl3.output.w, cl3.output.c, n, size, stride); + n = 128; + convolutional_layer cl5 = make_convolutional_layer(cl4.output.h, cl4.output.w, cl4.output.c, n, size, stride); + maxpool_layer ml3 = make_maxpool_layer(cl5.output.h, cl5.output.w, cl5.output.c, 4); + connected_layer nl = make_connected_layer(ml3.output.h*ml3.output.w*ml3.output.c, 4096); + connected_layer nl2 = make_connected_layer(4096, 4096); + connected_layer nl3 = make_connected_layer(4096, 1000); + + net.layers[0] = &cl; + net.layers[1] = &ml; + net.layers[2] = &cl2; + net.layers[3] = &ml2; + net.layers[4] = &cl3; + net.layers[5] = &cl4; + net.layers[6] = &cl5; + net.layers[7] = &ml3; + net.layers[8] = &nl; + net.layers[9] = &nl2; + net.layers[10] = &nl3; + + int i; + clock_t start = clock(), end; + for(i = 0; i < 10; ++i){ + run_network(dog, net); + rotate_image(dog); + } + end = clock(); + printf("Ran %lf second per iteration\n", (double)(end-start)/CLOCKS_PER_SEC/10); + + show_image_layers(get_network_image(net), "Test Network Layer"); +} +void test_backpropagate() +{ + int n = 3; + int size = 4; + int stride = 10; + image dog = load_image("dog.jpg"); + show_image(dog, "Test Backpropagate Input"); + image dog_copy = copy_image(dog); + convolutional_layer cl = make_convolutional_layer(dog.h, dog.w, dog.c, n, size, stride); + run_convolutional_layer(dog, cl); + show_image(cl.output, "Test Backpropagate Output"); + int i; + clock_t start = clock(), end; + for(i = 0; i < 100; ++i){ + backpropagate_layer(dog_copy, cl); + } + end = clock(); + printf("Backpropagate: %lf seconds\n", (double)(end-start)/CLOCKS_PER_SEC); + start = clock(); + for(i = 0; i < 100; ++i){ + backpropagate_layer_convolve(dog, cl); + } + end = clock(); + printf("Backpropagate Using Convolutions: %lf seconds\n", (double)(end-start)/CLOCKS_PER_SEC); + show_image(dog_copy, "Test Backpropagate 1"); + show_image(dog, "Test Backpropagate 2"); + subtract_image(dog, dog_copy); + show_image(dog, "Test Backpropagate Difference"); +} + +int main() +{ + //test_backpropagate(); + //test_convolve(); + //test_upsample(); + //test_rotate(); + //test_load(); + test_network(); + //test_convolutional_layer(); + //test_color(); + cvWaitKey(0); + return 0; +} diff --git a/test.jpg b/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f7b6cb8de4d405581a2ee6802c04c091b42a4395 GIT binary patch literal 9756 zcmV+%Cga)v*#F=F5K2Z#MgRc;0RTtFhMaiIXgZ+J|!+hNkcqHH$6T(|G)qX2mty3 z`T+qE0RO}Q8~^|U0s{d70000000000000970tEpE2LK5F!~jDO00IF60|EsB1qB5L z1qA>A0RjU61Q7)iAu&M)6CzPzaTGFvk+BCOLZQJGBvN9s79}%7a?vIo(4z z`hO1}olbcdanJZp1y^bsu~1;QJmU=C&`_bcbhu?6rgc&Ls1wVEY@RdQy7WX?~%nr0B3hvJ)kW3RmnAd3?Wbwr|yD46&crT8H^GST#QvitdmTG%K$gUDLe)_ z3U>yKEC$eBz|XY^+r%3i*wE#RX*+oz6a!fmEMmQii&hO{yk>-#A$8IrI&%1Z4t$V#56nPjT44=}itSl|%C(VvYSbKfn&Y6MLBB>f+c1^x%Mad(C$3ek$}KZdB+q7WQeX*9(bi*+%@7zeM-kU_Nhv~ zS-~rwnf9v7lp%?%K*5_~=XVreu`Yc>uS#BMJfp$m+|V&u&Ic79y=xWfcH2$+L_$wF zKs|uwnN2F)PpO^1l^5)G$@gL(k2T{G?H~X@3aAT*EAvbeK{yq;>il?*P#r&iA^!mP zG>rRqDPxWg=~IhmlB9c3Efq|!pKt3!)S^a182%+9wW1#0QZt5Aip2h4nY_l_-AN}k zJB7`|ejlZHs+kB*odsQZa@H9xTkRio`gk}aX2RZgQ2TlbDTgFlxe#;(L>MF)a@X~>^2q(MrB=x7&8OA@V|b^?=<-+4G*MN&$F}UZSl6gUxt=J7%KFJJlH&xjzP-NYJ8^dB-)iYVV&BY6EXeiGS8= zzUbu>BLte9KnRqPk+z3ngEQms{OVWn;nU~-^+Bmy?7ESCjVpN@Ez9t6$LUzO$hmy` z(JfPSqvEeL9p>SbDQ-#Nbf+~NMf2K0F@eu5hT!o*w6&7qqHqa~7X`h|TA~#Jat_R6 z=laxk0_B-MPZX%}xnSGpvi)*2J;1F5%yr zkU*m>agK6LL0x3$_)kOcRI-d+$@MhO>f3cRXYn?q2WyEx)tW;6Knau1Xpksa6VeVx zy$;0}&V2X(0KHEA7)=*B1pfe9Q(M!UBI!DGVO4i2o2fYO+LXHk&(1NPYtS$a$j=pL zr1`#XQLq}FytsKA$!q|5IP56)moCa6i0}?QJ%w0p+Sn&K90A^kpS(hxb|W+IKb2ByN`^Muj3a`KIuL0I zP8**5;8(7*B1TB$0<{}t$myDP&K%5gI2_aI5Qsg*rwFlit5un81ol zs90NRI*gdJfb_`Zd;6Xb8LAy!t?i+f-ZC@1ZRaNgrBcf-ew7rMx!de>in6hYv2X@( zaaL(;v3~FP-><-`op(?Ue#r^+kG+odOIe~K*O*ZI)tq-bbY+isCCdI3lO8jUD$h%t z$&kmV6br@0`}~~$04k6xj!!kYYKxx}>OFzEll@elqKo!!I^+;A5ierm5#)r^g@+aUJA=BVZjWXrbaCz=G!xsK7muUZY$fsVC# zr?7|5mmM1e>r3A20U~%U$!25fdZZ+il5$OYixOny(e`FN+h|TXp^?oR6*57y+4EDG zHbw(*eWw=2R#I4? zv5DQl^mOh|#a5Py+kDa(({4%*t&tC$opdP(B9Vr=@34#YBXwGRX`Q>NEeStZk85JYK1C!U9QcQ!* zK~#v#;EeP%&W?g@S_C9uw=~YLy4Euq90!%L?~10cRHIGpigq}?EuIMeb>{TvBaXBt z9Ow0*H{PkhaG6rVb}mEUOlU!>X{xf)Km}o@6A{0 zw-Kyj5O+vOBq{s6_oWfyh)1-tb-nWb}#ocqv-!OJ()&}6}3 z&S;a6u_^++KN=mK%h}zl-!G z`tyyWoYgd}e6tmlLP*08HfH`VYST@ywu0SQ02#(f?r2(e)xNnI<2+#e(J#|=^}8=S zPJf+d{Y;9|;ElZjpi16Wf@NR^25V9UWSkN?egQSLY1SJf3@~y#4mjv&I=QxjCWq|4 zRQcSJsK)9Ao~wS)$pXBS$0F@0eL!=Z^V9I4?DOPAOs?~vrYM?}f(uz94q5Yp2G#cF6~0=j+kde-@^TOCWq zT7t+B5HQI6X^S}Hdv(Tf+LO~_15vu~&rDWz1aIvNZbwmp zkD6lkH%lkT91c(8R9e);X;!x5_|!9VTJ*{uHOCm~{{VWu@aCZJn@O&=Km4%#hxpHG zy}h@R;sI%M7*;(8Omoy%t#m}wUK^`>*Nwlyv>g2@ZB3$zN0>USj&fZi#($-2SB|na z0VgN#H+l#!8t=y5Fa-gwr|mA#J*X1O&-b01<&9zp_sR6E+zc@kxa(PQijQiXNMw~0 zyAUg3eKPLOAvfPc)DG1jFU?KEk@{79v6Und$m>bT)~97|*H=pt^);|X;nh?7$M3~j z$72i#6b^c3yhbuJir2N}+jfjQr}d%7U|J zt`6_Ui)eqlMn*XYBiQDX(^-b2cZD3DarL8J0Qb=D9D+LiX`N6H?D={Q1!}snGCV4$ z0V4w#>r{6@n~j6{Q*c2Xg;1TH%MPpbt80B;`qTdaFoN<-J}cKgB$w?1OHDcA zPU^&;!{U^^)y?=DZDbAYgY8kbvC6cv;K&9-_5?@Y?5EkKsxFRlBlo;0gqm*i({8 z&%P;R6GliJrg*ANdOzPo@}z${kDas8pS#6wTK-3j?xP0<<|jXitm9xz5I8fM?^E3kMWzd9w}KecVR;g1!aRzS8=4w>M7b*5b087|8)9EVog@pFMR8@YW zfzCqq{HlPAOOKi?gVUM-6|#6X)6LXcQZuk|TlbKRJvj&KRQ@H08hCA_ZE?@mwDTIM zFUD%BVoQ@xczBVn+U@Sde=6VJA{kBytVma$x%yIX8mo2dRGRF0n%mfuRV_M}J$lzf z@f2Wq_CdhQx9VtmvbyQ>EFY z@F+H!mPC&nW~`!R5jt)dBLkdJE{FG5mpL1HR=PG zOCG|u3BPpwekT;Jqa2r7Y_JdxwK2EW0@qr_vl2#%bRxa)Yw_(Bi zz#b^j<<-etmqIc-ccDW9+(^Pv$Q&QkRYs`hIr#5_Gur~IZZ00>hEGl@n=jq4Zk%yV zgS88@anynBRrl9Lkj4nd2P3^!p0zjW^%TyPV)xh4#HvUqoOTt|bmaRzx<78z3W=8MxMbuSaOt{8J?$0^v z#bZT*MwM(;$Qyh8YL08yx4yk-o-j9@$o&)#Z=Z@r8v}o;TgPz|BvS&wxgn&-bL~*^ z#K9KBPDNEn!#^K93e}KeL5?ZZLW{ieDeHOHV=E}bVE#F)I3*avdXFG`Qd40k>T;(T z_NT0-+X>0WMmqe^9_?3q9PZpjYnPL~#lw(rDlo>|ho|HUutX^cE;^mxl@4kBJ3-)# znyiy0vrsiK3+))K`@&i(+S>i5U-*&_yN-gkK@QQo0R9~+3hWyV!1t**!u{dzS`Ud; zQ(K!I)k*r|wfVVv-~2733mqvXmx(9!5$rovt40fS1M#59rZK~RI$A-!^N&#WrElPp zYbjE0Bio+5Fh$XuSM+|`x(f8tvNj{^}kY92d$ z_={k{*%FM_yc^a#Rh%VWFD##$E_}2g43pZMv7Mb%lftPOs9d-+@}xF$e!kV^c8!1l zjEsIYD}W%kW<0Ymr@tq^){?Tbh^w=XgS|Hd5ugP}U^07r&~CtTdjY}E>s4|oQH=9I zVS&v+k7~Z~wv+v*dAa`p;l;`Mu8$B9AVgA&j+A`vUMNg~o1rxah)OnlY0Zmq6P?9{8p7TWGGe+el>qqshqkuA0$-fW0w+UNDwkf`=q~LELyA!j_Y1`;F48 z^*JQ_1mhpUjMlb`9>vOx;8yG6*%5qHCUdnTnVE}r8LC}ZQG1*PiNr;794b9>f0@0O zt$aVE!h$R57|kn!z`r2|dI3!7D#u*Z#xaIoGhVs$_^QZpkqg#`<0tbxQFH(RF4g{3 zQ4~!f;C(8}+AXP^QLDQZn zL{|IzKeiubl2X5Uy8Kq&E!3&t@j{ds`9eiTH+Ed^8TwbQMBinXX5HHx8280;bOhy3 z-soyDG?D617>N=ri?<&6uCW}LQ|75&dy2`HGz5oVerahZX;iA?A6iwmgU&PXX-!5w z_A_HYaMr4==^sklyh(8_--+&RL5J-gdwDUAK<626eD%dyCX*JKrd>O~opU5@=1kp5 z$7AjBMDXuAJ-ac_82mFq(eeGis)qjn8h({4lmo^#Kw#$G&o$3{T!nm1b@E5)N!iB7 z83P|RWf&X2?lJ!W&XpsFkS8RQ-l20D5|mO7PC(5bN0QQEDr81_0q6Qt4UpNyzx5fZE)gcBsrjBNPK&N5Qt= zXV7COIg^^$OKjt|DQkjRa0LleAOxIZrn5$RGMskJa;ekHxtj-%F@}E{&WRVD;wvTh zm>RY_s+XH%f?r5T#iQN zoff_!ZX z#AhIKXbT0=nOMNyzfj8c`c=N237RI3;Yjk(l>~Lb=|Q)Qtc}SD$ldXt)Z(K&Y=|+n zN7AWY02>TCccL_5FhK<4jPZj@Pj2q4S$$njIL%eM6(>JRUC7JLwLr}WB&lQf7Yx2 z0B9Cr^d*>ZW0SwNbE{p<+i_Ml@|$^)gqUSLny0C1*HX%oEy*mM2*yQh9v<<^k1Eev zw@G5i2`Eli>sw~LY|fr8Z8j?cSh*dsPuln|Me!Dm4b7gU(Mh)_V=DlDM{28!!B@67 zO&^*jjZZ8_0Vn6)wat4)yRf}xXwQ;)+@m9&^n(H|!5>aB$o`a*ZVUq+2KtOlz+KwO!fCKoG*0FDG$qYZ9 zXpbCm1~}*mIj&5n%x8QLQ?VbNJK>*CimdWKi2jDUmzC(`k)Fb#<*!rLfgl@!1pO&? zU|VX`09~bBPEBby7TCFzW22wex1SnC8fy0CM_cT%_opr){{VK}Hr(z;KS6^^cyTk~ z+doSWN#q_n()v_EyhW@jW*8}t%DsBuX7P2q%OF)tIT@M2z!|Mi#r`QxQr1f=bNhsG zgNzqG{{TwXEeXceCnwsaEK)^+NF};p)XJnNHx2IH25T1Db@rol*6|@%UT}Elu0FMY zCH&gPfi0!X%?;g%^&mfda0W$F>0Thzw0U<}+`LEFF#y$+-YoGH(;I`T$fq3R(mx?Y z(fn7aY5Ix1dxn^>A<{#YaqK~+@3nh7xf)nPL%d`l7y~^;Rr6l4>^5Il{Dxr2BJSg$LQfsOUJN$Pz^a0PMVuE5RMH*9WsxP}`Kr>%~@h zitt(Jw^HN-<&|Hl;<==1sTe?Vam^COQD@={DM=s+S0sF#e_HCw`xpG9j%a>sNuCDW z<063W454syj+GL-GQo094Uw0gwM9LPHN=gMu1{Z@**tWg-)+e}o8e4f%F)@)7(epa zf03lTGV+}U+BIRc0y+B7bot@3*EPBB zBYEoT4o~Ak@&21*r)m0hc93~wGblaC$A5F4^{86{nLUj)B#D4YIUe-1CRs0{Sg_I; z0W;G*vt1lp+jv&uz)IQj?PZcyA9_b(0sMP?D_OtOueCi+;z;2!-%0D4SA~uu1_Alx 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 literal 0 HcmV?d00001 diff --git a/test_dog.jpg b/test_dog.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aa98311a8cc997d3e130afbd3bb776cff6489092 GIT binary patch literal 30762 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 BTFU?c literal 0 HcmV?d00001