diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | src/json.c | 21 | ||||
-rw-r--r-- | src/json.h | 16 | ||||
-rw-r--r-- | src/main.c | 27 | ||||
-rw-r--r-- | src/nn.c | 49 | ||||
-rw-r--r-- | src/nn.h | 8 |
6 files changed, 63 insertions, 62 deletions
@@ -1,11 +1,11 @@ -CC = gcc +CC = clang CFLAGS = -std=c11 -Wall -g BIN = ml OBJDIR = objs SRC = $(wildcard src/*.c) HEADERS = $(wildcard src/*.h) OBJS = $(SRC:src/%.c=${OBJDIR}/%.o) -DLIBS = -ljson-c -lm +DLIBS = -lm $(shell pkg-config --libs-only-l blas json-c) .PHONY: clean all run all: build diff --git a/src/json.c b/src/json.c deleted file mode 100644 index 8bf3ed7..0000000 --- a/src/json.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "json.h" - -static void fill_item(HouseItem *item, char *key_buffer, char *value_buffer); -static void fill_buffer(FILE *fp, char *key_buffer, char *value_buffer); - -void json_read(const char *filepath, HouseItem *out) -{ - FILE *fp; - fp = fopen(filepath, "r"); - if (fp == NULL) { - perror("json_read() Error"); - exit(1); - } - - char c, key_buffer[1024], value_buffer[1024]; - size_t out_size = 0; - while ((c = fgetc(fp)) != EOF) { - switch (c) { - } - } -} diff --git a/src/json.h b/src/json.h deleted file mode 100644 index 23cab9a..0000000 --- a/src/json.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __JSON -#define __JSON -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <string.h> - -typedef struct { - float price; - float area; - float latitude; - float longitude; -} HouseItem; - -void json_read(const char *filepath, HouseItem *out); -#endif @@ -4,6 +4,7 @@ #include <json-c/json.h> #include "nn.h" + const size_t MAX_FILE_SIZE = 1<<29; // 0.5 GiB typedef struct Array { @@ -11,9 +12,10 @@ typedef struct Array { size_t shape[2]; } Array; +#define ARRAY_SIZE(x, type) sizeof(x) / sizeof(type) Layer neural[] = { - [0] = {.neurons = 3, .activation = relu}, - [1] = {.neurons = 1, .activation = sigmoid}, + {.neurons = 3, .activation = relu}, + {.neurons = 1, .activation = sigmoid}, }; static Array json_read(const char *filepath); @@ -75,10 +77,25 @@ json_read_error: } int main(void) { - Array json_data = json_read("data/housing_rent.json"); - nn_layer_init_weights(neural, 2, 3); - printf("%lf\n", neural[0].weights[0]); + Array json_data = json_read("data/test.json"); + nn_layer_init_weights(neural, ARRAY_SIZE(neural, Layer), 4); + + printf("neurons: %zu\n", neural[0].neurons); + printf("input_notes: %zu\n", neural[0].input_nodes); + + double *out = nn_layer_forward(neural[0], json_data.data, json_data.shape); + printf("rows: %zu\n", json_data.shape[0]); + printf("cols: %zu\n", neural[0].neurons); + + for (size_t i = 0; i < neural[0].input_nodes; i++) { + for (size_t j = 0; j < neural[0].neurons; j++) { + size_t index = i * neural[0].neurons + j; + printf("%4.2lf\t", out[index]); + } + printf("\n"); + } nn_layer_free_weights(neural, 2); + free(out); free(json_data.data); return 0; } @@ -2,27 +2,51 @@ static void fill_random_weights(double *weights, double *bias, size_t rows, size_t cols); -void nn_layer_init_weights(Layer layer[], size_t nmemb, size_t n_inputs) +double * nn_layer_forward(Layer layer, double *input, size_t input_shape[2]) +{ + double *out = calloc(input_shape[0] * layer.neurons, sizeof(double)); + if (out == NULL) { + perror("nn_layer_forward() Error"); + exit(1); + } + + for (size_t i = 0; i < input_shape[0]; i++) { + for (size_t j = 0; j < layer.neurons; j++) { + size_t index = layer.neurons * i + j; + out[index] = layer.bias[j]; + } + } + + cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, + input_shape[0], layer.neurons, layer.input_nodes, + 1.0, input, input_shape[1], //alpha A + layer.weights, layer.neurons, // B + 1.0, out, layer.neurons); + return out; +} + +void nn_layer_init_weights(Layer layers[], size_t nmemb, size_t n_inputs) { int i; size_t prev_size = n_inputs; for (i = 0; i < nmemb; i++) { - layer[i].weights = calloc(prev_size * layer[i].neurons, sizeof(Layer)); - layer[i].bias = calloc(prev_size, sizeof(Layer)); + layers[i].weights = calloc(prev_size * layers[i].neurons, sizeof(Layer)); + layers[i].bias = calloc(layers[i].neurons, sizeof(Layer)); - if (layer[i].weights == NULL || layer[i].bias == NULL) { - goto nn_layer_calloc_weights_error; + if (layers[i].weights == NULL || layers[i].bias == NULL) { + goto nn_layers_calloc_weights_error; } - fill_random_weights(layer[i].weights, layer[i].bias, prev_size, layer[i].neurons); - prev_size = layer[i].neurons; + fill_random_weights(layers[i].weights, layers[i].bias, prev_size, layers[i].neurons); + layers[i].input_nodes = prev_size; + prev_size = layers[i].neurons; } return; -nn_layer_calloc_weights_error: - perror("nn_layer_calloc_weights() Error"); +nn_layers_calloc_weights_error: + perror("nn_layers_calloc_weights() Error"); exit(1); } @@ -30,15 +54,10 @@ void nn_layer_free_weights(Layer *layer, size_t nmemb) { for (int i = 0; i < nmemb; i++) { free(layer[i].weights); + free(layer[i].bias); } } -double * nn_layer_forward(Layer layer, double *input, size_t input_shape[2]) -{ - double *out = NULL; - return out; -} - double sigmoid(double x) { return 1 / (1 + exp(-x)); @@ -4,20 +4,22 @@ #include <stdlib.h> #include <stdio.h> #include <stdint.h> +#include <string.h> #include <math.h> #include <unistd.h> +#include <openblas/cblas.h> typedef struct Layer { double *weights, *bias; double (*activation)(double x); - size_t neurons, input_size; + size_t neurons, input_nodes; } Layer; void nn_layer_init_weights(Layer *layer, size_t nmemb, size_t input_size); void nn_layer_free_weights(Layer *layer, size_t nmemb); -double * nn_layer_forward(Layer layer, double *input, size_t input_shape[2]); -double * nn_layer_backward(Layer layer, double *output, size_t out_shape[2]); +double * nn_layer_forward(Layer layer, double *input, size_t input_shape[2]); //TODO +double * nn_layer_backward(Layer layer, double *output, size_t out_shape[2]); //TODO double sigmoid(double x); double relu(double x); |