dataset
Train Layer (1 hidden Layer)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <time.h>
#define the_number_of_input_nodes 784
#define input_training_images 60000
#define output_testing_images 10000
#define zero_input_training_images 5923
#define one_input_training_images 6742
#define two_input_training_images 5958
#define three_input_training_images 6131
#define four_input_training_images 5842
#define batch_size 64
#define hidden_layer 3
#define first_hidden_nodes 100
#define second_hidden_nodes 100
#define third_hidden_nodes 100
#define output_nodes 10
#define Activation_Function sigmoid
#define uc unsigned char
#define epoches 400
#define learning_rate 0.0002
double sigmoid(double x);
double sigmoidMiboon(double x);
typedef struct Node {
int numOfWeights;
double* weights;
double weightSum;
double output;
double bias;
double delta;
double loss;
}Node;
typedef struct NN {
int numOfNodes;
Node* node;
}NN;
typedef struct Image {
uc* file;
}Image;
Image* loadImageData(int number, int idx);
Image* loadTestData(int number, int idx);
void makeNode(Node* node, int sizeOfInputNodes) {
node->numOfWeights = sizeOfInputNodes;
node->weights = (double*)malloc(sizeOfInputNodes * sizeof(double));
srand(time(NULL));
for (int i = 0; i < sizeOfInputNodes; ++i) {
*(node->weights + i) = ((double)rand() / RAND_MAX) * 2.0 - 1.0;
//printf("%lf\n", *(node->weights + i));
}
node->weightSum = 0.0;
node->output = 0.0;
node->bias = 0.01;
node->loss = 0.0;
node->delta = 0.0;
return;
}
NN* makeNeuralNetwork(int sizeOfInputNodes, int sizeOfOutputNodes) {
NN* nn = (NN*)malloc(sizeof(NN));
nn->numOfNodes = sizeOfOutputNodes;
nn->node = (Node*)malloc(nn->numOfNodes * sizeof(Node));
for (int i = 0; i < nn->numOfNodes; ++i) {
makeNode(nn->node + i, sizeOfInputNodes);
}
return nn;
}
void freeNN(NN* nn) {
if (nn == NULL) return;
for (int i = 0; i < nn->numOfNodes; ++i) {
free((nn->node + i)->weights);
}
free(nn->node);
free(nn);
}
void forpass(NN* inputNN, NN* outputNN) {
//printf("%d ", outputNN->numOfNodes); 100
//printf("%d ", inputNN->numOfNodes); 784
//printf("%lf", *((outputNN->node + 99)->weights+100));
//printf("%d", outputNN->node->numOfWeights);
for (int i = 0; i < outputNN->numOfNodes; ++i) {
(outputNN->node + i)->weightSum = 0.0;
//printf("%lf ", (outputNN->node + i)->weightSum);
//printf("%lf ", *((outputNN->node + i)->weights + 3));
//printf("%lf ", (inputNN->node + 783)->output);
//printf("%lf ", (inputNN->node + i)->output);
// printf("%d ", (outputNN->node + i)->numOfWeights); ->100��
for (int j = 0; j < inputNN->numOfNodes; ++j) {
//printf("%lf ", *((outputNN->node + i)->weights + j));
(outputNN->node + i)->weightSum += *((outputNN->node + i)->weights + j) * (inputNN->node + j)->output;
}
(outputNN->node + i)->weightSum += outputNN->node->bias;
}
for (int i = 0; i < outputNN->numOfNodes; ++i) {
(outputNN->node + i)->output = Activation_Function((outputNN->node + i)->weightSum);
//if (outputNN->numOfNodes == 100) printf("%d %lf\n", i, (outputNN->node + i)->output);
//if(outputNN->numOfNodes==10) printf("%d %lf\n", i, (outputNN->node + i)->output);
}
}
void backpropagationDirectly(NN* outputNN, NN* inputNN, int answer) {
for (int i = 0; i < outputNN->numOfNodes; ++i) {
double val = 0.0;
if (answer == i) val = 1.0;
(outputNN->node + i)->loss = val - (outputNN->node + i)->output;
(outputNN->node + i)->delta = (outputNN->node + i)->loss * sigmoidMiboon((outputNN->node + i)->output);
for (int j = 0; j < (outputNN->node + i)->numOfWeights; ++j) {
*((outputNN->node + i)->weights + j) += learning_rate * (outputNN->node + i)->delta * (inputNN->node + j)->output;
//printf("%d %lf\n", i, learning_rate * (outputNN->node + i)->delta * (inputNN->node + j)->output);
}
}
}
/*
void backpropagation(NN* outputNN, NN* inputNN,NN* restNN, int answer) {
//printf("%d %d %d\n", outputNN->numOfNodes, inputNN->numOfNodes, restNN->numOfNodes);
for (int i = 0; i < outputNN->numOfNodes; ++i) {
(outputNN->node + i)->delta = 0.0;
for (int j = 0; j < restNN->numOfNodes; ++j) {
(outputNN->node + i)->delta += (restNN->node + j)->delta * *((restNN->node + j)->weights + i);
}
(outputNN->node + i)->delta *= sigmoidMiboon((outputNN->node + i)->output);
for (int j = 0; j < (outputNN->node + i)->numOfWeights; ++j) {
*((outputNN->node + i)->weights + j) -= learning_rate * (outputNN->node + i)->delta * (inputNN->node + j)->output;
}
}
}*/
void backpropagation(NN* outputNN, NN* inputNN, NN* restNN, int answer) {
for (int i = 0; i < outputNN->numOfNodes; ++i) {
double actual = (answer == i) ? 1.0 : 0.0;
double output = (outputNN->node + i)->output;
double delta = (actual - output) * sigmoidMiboon(output);
for (int j = 0; j < restNN->numOfNodes; ++j) {
(restNN->node + j)->delta += delta * *((outputNN->node + i)->weights + j);
}
for (int j = 0; j < (outputNN->node + i)->numOfWeights; ++j) {
*((outputNN->node + i)->weights + j) += learning_rate * delta * (inputNN->node + j)->output;
}
}
}
void makeInputNode(uc* file, NN* nn) {
for (int i = 0; i < the_number_of_input_nodes; ++i) {
(nn->node + i)->output = (double)*(file + i) / 255.0;
//printf("%lf\n", (nn->node + i)->output);
// if (i % 28 == 0) printf("\n");
// if ((nn->node + i)->output > 0) printf("1");
// else printf("0");
}
}
void init(Image* data, int answer, NN* inputLayer, NN* firstLayer, NN* outputLayer) {
for (int countOfBatch = 0; countOfBatch < batch_size; ++countOfBatch) {
makeInputNode((data + countOfBatch)->file, inputLayer);
forpass(inputLayer, firstLayer);
//forpass(firstLayer, thirdLayer);
forpass(firstLayer, outputLayer);
//forpass(inputLayer, thirdLayer);
//forpass(thirdLayer, outputLayer);
backpropagationDirectly(outputLayer, firstLayer, answer);
//backpropagation(thirdLayer, inputLayer, outputLayer, answer);
// backpropagation(thirdLayer, firstLayer, outputLayer, answer);
//backpropagation(secondLayer, firstLayer, thirdLayer, answer);
backpropagation(firstLayer, inputLayer, outputLayer, answer);
//backpropagation(firstLayer, secondLayer, thirdLayer, answer);
//backpropagation(inputLayer, firstLayer, secondLayer, answer);
}
}
void freeImage(Image* data) {
if (data == NULL) return;
free(data);
}
int testing(Image* data, int answer, NN* inputLayer, NN* firstLayer, NN* outputLayer) {
makeInputNode(data->file, inputLayer);
forpass(inputLayer, firstLayer);
// forpass(firstLayer, thirdLayer);
//forpass(secondLayer, thirdLayer);
//forpass(inputLayer, thirdLayer);
forpass(firstLayer, outputLayer);
double maxVal = outputLayer->node->output;
int maxIdx = 0;
for (int i = 1; i < 10; ++i) {
if (maxVal < (outputLayer->node + i)->output) {
maxVal = (outputLayer->node + i)->output;
maxIdx = i;
}
}
//printf("%d %lf %d\n",answer, maxVal, maxIdx);
if (maxIdx == answer) return 1;
return 0;
}
void writeTestNote(int* correctAns, NN* inputLayer, NN* firstLayer, NN* outputLayer) {
FILE* fp;
fp = fopen("..\\mnist_raw\\hiddenLayerOne\\hiddenLayer1.txt", "wt");
for (int i = 0; i < firstLayer->numOfNodes; ++i) {
fprintf(fp, "node %d :", i);
for (int j = 0; j < inputLayer->numOfNodes; ++j) {
double tmp = *((firstLayer->node + i)->weights + j);
fprintf(fp, "%lf ", tmp);
}
fprintf(fp, "\n");
}
fclose(fp);
/* fp = fopen(".\\hiddenLayer2.txt", "wt");
for (int i = 0; i < secondLayer->numOfNodes; ++i) {
fprintf(fp, "node %d :", i);
for (int j = 0; j < firstLayer->numOfNodes; ++j) {
double tmp = *((secondLayer->node + i)->weights+j);
fprintf(fp, "%lf ", tmp);
}
fprintf(fp, "\n");
}
fclose(fp);*/
/*fp = fopen(".\\hiddenLayer2.txt", "wt");
for (int i = 0; i < thirdLayer->numOfNodes; ++i) {
fprintf(fp, "node %d :", i);
for (int j = 0; j < firstLayer->numOfNodes; ++j) {
double tmp = *((thirdLayer->node +i)->weights+j);
fprintf(fp, "%lf ", tmp);
}
fprintf(fp, "\n");
}*
fclose(fp);*/
fp = fopen("..\\mnist_raw\\hiddenLayerOne\\outputLayer.txt", "wt");
for (int i = 0; i < outputLayer->numOfNodes; ++i) {
fprintf(fp, "node %d :", i);
for (int j = 0; j < firstLayer->numOfNodes; ++j) {
double tmp = *((outputLayer->node + i)->weights + j);
fprintf(fp, "%lf ", tmp);
}
fprintf(fp, "\n");
}
fclose(fp);
fp = fopen("..\\mnist_raw\\hiddenLayerThree\\ans.txt", "wt");
int totalAns = 0;
for (int i = 0; i < 10; ++i) {
fprintf(fp, "correct of %d : ", i);
int tmp = *(correctAns + i);
fprintf(fp, "%d\n", tmp);
totalAns += tmp;
}
double total = (double)totalAns / (double)output_testing_images;
fprintf(fp, "total : %lf", total);
fclose(fp);
printf("real done!\n");
printf("the accuracy is %lf", total);
}
int main() {
// 1 epoches
NN* inputLayer = makeNeuralNetwork(1, the_number_of_input_nodes);
NN* firstLayer = makeNeuralNetwork(the_number_of_input_nodes, first_hidden_nodes);
//NN* secondLayer = makeNeuralNetwork(first_hidden_nodes, second_hidden_nodes);
//NN* thirdLayer = makeNeuralNetwork(second_hidden_nodes, third_hidden_nodes);
//NN* thirdLayer = makeNeuralNetwork(the_number_of_input_nodes, third_hidden_nodes);
NN* outputLayer = makeNeuralNetwork(third_hidden_nodes, output_nodes);
for (int countEpoches = 0; countEpoches < epoches; ++countEpoches) {
printf("%d epoche(s) start!\n", countEpoches + 1);
for (int i = 0; i < 10; ++i) {
printf("%d batch start: ", i);
for (int j = 0; j < 7000; j += batch_size) {
printf("\b\b\b\b%4d", j / batch_size);
Image* data = loadImageData(i, j);
if (data == NULL) break;
init(data, i, inputLayer, firstLayer, outputLayer);
freeImage(data);
}
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
printf("\n");
}
printf("%d epoche(s) end! \n", countEpoches + 1);
}
int* correctAns = (int*)malloc(sizeof(int) * 10);
printf("test start!\n");
for (int i = 0; i < 10; ++i) {
printf("%d test: ", i);
int tmp = 0;
for (int j = 0; j < 1500; ++j) {
printf("\b\b\b\b%4d", j);
Image* data = loadTestData(i, j);
if (data == NULL) break;
tmp += testing(data, i, inputLayer, firstLayer, outputLayer);
freeImage(data);
}
*(correctAns + i) = tmp;
printf("\n%d test end!\n", i);
}
writeTestNote(correctAns, inputLayer, firstLayer, outputLayer);
freeNN(inputLayer);
freeNN(firstLayer);
//freeNN(secondLayer);
//freeNN(thirdLayer);
freeNN(outputLayer);
}
char* makeFileName(int number, int idx) {
int fileNameLength = 100;
char* filename = (char*)malloc(fileNameLength * sizeof(char));
if (filename == NULL) {
printf("Memory allocation failed.\n");
return NULL;
}
snprintf(filename, fileNameLength, "..\\mnist_raw\\training\\%d\\%d-%d.raw", number, number, idx);
// printf("%s\n", filename);
return filename;
}
Image* loadTestData(int number, int idx) {
Image* data = (Image*)malloc(sizeof(Image));
data->file = (uc*)malloc(sizeof(uc) * the_number_of_input_nodes);
int fileNameLength = 100;
char* filename = (char*)malloc(fileNameLength * sizeof(char));
if (filename == NULL) {
printf("Memory allocation failed.\n");
freeImage(data);
return NULL;
}
snprintf(filename, fileNameLength, "..\\mnist_raw\\testing\\%d\\%d-%d.raw", number, number, idx);
FILE* inputFile = fopen(filename, "rb");
if (inputFile == NULL) {
freeImage(data);
free(filename);
return NULL;
}
fread(data->file, sizeof(uc), the_number_of_input_nodes, inputFile);
free(filename);
fclose(inputFile);
return data;
}
Image* loadImageData(int number, int idx) {
Image* data = (Image*)malloc(sizeof(Image) * batch_size);
for (int i = idx; i < idx + batch_size; ++i) {
(data + i - idx)->file = (uc*)malloc(sizeof(uc) * the_number_of_input_nodes);
char* filename = makeFileName(number, i);
FILE* inputFile = fopen(filename, "rb");
if (inputFile == NULL) {
freeImage(data);
free(filename);
return NULL;
}
fread((data + i - idx)->file, sizeof(uc), the_number_of_input_nodes, inputFile);
free(filename);
fclose(inputFile);
}
return data;
}
double sigmoid(double x) {
return 1 / (1 + exp(-x));
}
double sigmoidMiboon(double x) {
double sig = sigmoid(x);
return sig * (1 - sig);
}
Test Layer (1 hidden Layer)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <time.h>
#include <string.h>
#define the_number_of_input_nodes 784
#define input_training_images 60000
#define output_testing_images 10000
#define zero_input_training_images 5923
#define one_input_training_images 6742
#define two_input_training_images 5958
#define three_input_training_images 6131
#define four_input_training_images 5842
#define batch_size 64
#define hidden_layer 3
#define first_hidden_nodes 100
#define second_hidden_nodes 100
#define third_hidden_nodes 100
#define output_nodes 10
#define Activation_Function sigmoid
#define uc unsigned char
#define epoches 400
#define learning_rate 0.0002
#define line_max 7500
#define Activation_Function sigmoid
double sigmoid(double x);
typedef struct Node {
int numOfWeights;
double* weights;
double weightSum;
double output;
double bias;
double delta;
double loss;
}Node;
typedef struct NN {
int numOfNodes;
Node* node;
}NN;
typedef struct Image {
uc* file;
}Image;
Image* loadImageData(int number, int idx);
Image* loadTestData(int number, int idx);
void makeNode(Node* node, int sizeOfInputNodes) {
node->numOfWeights = sizeOfInputNodes;
node->weights = (double*)malloc(sizeOfInputNodes * sizeof(double));
srand(time(NULL));
for (int i = 0; i < sizeOfInputNodes; ++i) {
*(node->weights + i) = ((double)rand() / RAND_MAX) * 2.0 - 1.0;
//printf("%lf\n", *(node->weights + i));
}
node->weightSum = 0.0;
node->output = 0.0;
node->bias = 0.01;
node->loss = 0.0;
node->delta = 0.0;
return;
}
NN* makeNeuralNetwork(int sizeOfInputNodes, int sizeOfOutputNodes) {
NN* nn = (NN*)malloc(sizeof(NN));
nn->numOfNodes = sizeOfOutputNodes;
nn->node = (Node*)malloc(nn->numOfNodes * sizeof(Node));
for (int i = 0; i < nn->numOfNodes; ++i) {
makeNode(nn->node + i, sizeOfInputNodes);
}
return nn;
}
void makeInputNode(uc* file, NN* nn) {
for (int i = 0; i < the_number_of_input_nodes; ++i) {
(nn->node + i)->output = (double)*(file + i) / 255.0;
//printf("%lf\n", (nn->node + i)->output);
// if (i % 28 == 0) printf("\n");
// if ((nn->node + i)->output > 0) printf("1");
// else printf("0");
}
}
void freeImage(Image* data) {
if (data == NULL) return;
free(data);
}
Image* loadTestData(int number, int idx) {
Image* data = (Image*)malloc(sizeof(Image));
data->file = (uc*)malloc(sizeof(uc) * the_number_of_input_nodes);
int fileNameLength = 100;
char* filename = (char*)malloc(fileNameLength * sizeof(char));
if (filename == NULL) {
printf("Memory allocation failed.\n");
freeImage(data);
return NULL;
}
snprintf(filename, fileNameLength, "..\\mnist_raw\\testing\\%d\\%d-%d.raw", number, number, idx);
FILE* inputFile = fopen(filename, "rb");
if (inputFile == NULL) {
freeImage(data);
free(filename);
return NULL;
}
fread(data->file, sizeof(uc), the_number_of_input_nodes, inputFile);
free(filename);
fclose(inputFile);
return data;
}
void forpass(NN* inputNN, NN* outputNN) {
//printf("%d ", outputNN->numOfNodes); 100
//printf("%d ", inputNN->numOfNodes); 784
//printf("%lf", *((outputNN->node + 99)->weights+100));
//printf("%d", outputNN->node->numOfWeights);
for (int i = 0; i < outputNN->numOfNodes; ++i) {
(outputNN->node + i)->weightSum = 0.0;
//printf("%lf ", (outputNN->node + i)->weightSum);
//printf("%lf ", *((outputNN->node + i)->weights + 3));
//printf("%lf ", (inputNN->node + 783)->output);
//printf("%lf ", (inputNN->node + i)->output);
// printf("%d ", (outputNN->node + i)->numOfWeights); ->100��
for (int j = 0; j < inputNN->numOfNodes; ++j) {
//printf("%lf ", *((outputNN->node + i)->weights + j));
(outputNN->node + i)->weightSum += *((outputNN->node + i)->weights + j) * (inputNN->node + j)->output;
}
(outputNN->node + i)->weightSum += outputNN->node->bias;
}
for (int i = 0; i < outputNN->numOfNodes; ++i) {
(outputNN->node + i)->output = Activation_Function((outputNN->node + i)->weightSum);
//if (outputNN->numOfNodes == 100) printf("%d %lf\n", i, (outputNN->node + i)->output);
//if(outputNN->numOfNodes==10) printf("%d %lf\n", i, (outputNN->node + i)->output);
}
}
int testing(Image* data, int answer, NN* inputLayer, NN* firstLayer, NN* outputLayer) {
makeInputNode(data->file, inputLayer);
forpass(inputLayer, firstLayer);
// forpass(firstLayer, thirdLayer);
//forpass(secondLayer, thirdLayer);
//forpass(inputLayer, thirdLayer);
forpass(firstLayer, outputLayer);
double maxVal = outputLayer->node->output;
int maxIdx = 0;
for (int i = 1; i < 10; ++i) {
if (maxVal < (outputLayer->node + i)->output) {
maxVal = (outputLayer->node + i)->output;
maxIdx = i;
}
}
//printf("%d %lf %d\n",answer, maxVal, maxIdx);
if (maxIdx == answer) return 1;
return 0;
}
void writeTestNote(NN* inputLayer, NN* firstLayer, NN* outputLayer) {
FILE* fp;
fp = fopen("..\\mnist_raw\\hiddenLayerOne\\hiddenLayer1.txt", "r");
char line[line_max];
for (int i = 0; i < first_hidden_nodes; ++i) {
fgets(line, sizeof(line), fp);
char* token = strtok(line, " ");
int ptr = 1;
//printf("%s\n", token);
token = strtok(NULL, " ");
token = strtok(NULL, " ");
char* tmp = strchr(token, ':');
if (tmp != NULL) {
*tmp = ' '; // ':'를 공백으로 대체
}
*((firstLayer->node + i)->weights + 0) = atof(tmp);
token = strtok(NULL, " ");
while (token != NULL) {
// 소수점 확인 후 출력
double num = atof(token);
*((firstLayer->node + i)->weights + ptr) = num;
++ptr;
token = strtok(NULL, " ");
}
}
fclose(fp);
fp = fopen("..\\mnist_raw\\hiddenLayerOne\\outputLayer.txt", "r");
for (int i = 0; i < output_nodes; ++i) {
fgets(line, sizeof(line), fp);
char* token = strtok(line, " ");
int ptr = 1;
token = strtok(NULL, " ");
token = strtok(NULL, " ");
char* tmp = strchr(token, ':');
if (tmp != NULL) {
*tmp = ' ';
}
*((outputLayer->node + i)->weights + 0) = atof(tmp);
token = strtok(NULL, " ");
while (token != NULL) {
double num = atof(token);
*((outputLayer->node + i)->weights + ptr) = num;
++ptr;
token = strtok(NULL, " ");
}
}
fclose(fp);
}
int main() {
NN* inputLayer = makeNeuralNetwork(1, the_number_of_input_nodes);
NN* firstLayer = makeNeuralNetwork(the_number_of_input_nodes, first_hidden_nodes);
//NN* secondLayer = makeNeuralNetwork(first_hidden_nodes, second_hidden_nodes);
//NN* thirdLayer = makeNeuralNetwork(second_hidden_nodes, third_hidden_nodes);
//NN* thirdLayer = makeNeuralNetwork(the_number_of_input_nodes, third_hidden_nodes);
NN* outputLayer = makeNeuralNetwork(first_hidden_nodes, output_nodes);
int* correctAns = (int*)malloc(sizeof(int) * 10);
writeTestNote(inputLayer, firstLayer, outputLayer);
printf("test start!\n");
for (int i = 0; i < 10; ++i) {
printf("%d test: ", i);
int tmp = 0;
for (int j = 0; j < 1500; ++j) {
printf("\b\b\b\b%4d", j);
Image* data = loadTestData(i, j);
if (data == NULL) break;
tmp += testing(data, i, inputLayer, firstLayer, outputLayer);
freeImage(data);
}
*(correctAns + i) = tmp;
printf("\n%d test end!\n", i);
}
int totalAns = 0;
for (int i = 0; i < 10; ++i) {
totalAns += *(correctAns + i);
}
printf("the accuray is %lf!", (double)totalAns / (double)100);
}
double sigmoid(double x) {
return 1 / (1 + exp(-x));
}
결과
돌리는데 1시간 넘게 걸림
'기타' 카테고리의 다른 글
동서양의 윤리 기말 과제 - 더불어 살아가는 사회를 만들기 위해서 윤리적 태도가 필요한 이유 (1) | 2024.09.09 |
---|---|
아두이노 오렌지보드 블루투스 통신(ble통신) 앱인벤터로 앱 만들기 (0) | 2024.06.24 |