From b7e44e96703a982b32610cb0c8f459b8cf8fd4f0 Mon Sep 17 00:00:00 2001 From: Tubui <21020129@vnu.edu.vn> Date: Sun, 16 Nov 2025 19:08:19 +0100 Subject: [PATCH] Second commit --- imageInput.c | 113 +++++++++++++++++++------------------------ neuralNetwork.c | 2 + neuralNetworkTests.c | 41 ++++++++-------- test_nn_file.info2 | Bin 88 -> 0 bytes 4 files changed, 73 insertions(+), 83 deletions(-) delete mode 100644 test_nn_file.info2 diff --git a/imageInput.c b/imageInput.c index 9a3f2f9..c21456f 100644 --- a/imageInput.c +++ b/imageInput.c @@ -3,85 +3,58 @@ #include #include "imageInput.h" +#define BUFFER_SIZE 100 #define FILE_HEADER_STRING "__info2_image_file_format__" -// -------------------------- -// Hilfsfunktion: Prüft den Header der Datei -// -------------------------- +// ----------------------------------------------------- +// Hilfsfunktion: Überprüft den Header der Datei +// ----------------------------------------------------- static int checkFileHeader(FILE *file) { - char buffer[100] = {0}; + char buffer[BUFFER_SIZE] = {0}; size_t headerLen = strlen(FILE_HEADER_STRING); - // Lese Header aus Datei if (fread(buffer, sizeof(char), headerLen, file) != headerLen) return 0; - // Prüfe, ob Header korrekt ist - return strcmp(buffer, FILE_HEADER_STRING) == 0; + return (strncmp(buffer, FILE_HEADER_STRING, headerLen) == 0); } -// -------------------------- -// Hilfsfunktion: Liest ein einzelnes Bild -// -------------------------- -static int readImage(FILE *file, GrayScaleImage *image, unsigned int width, unsigned int height) -{ - image->width = width; // Breite setzen - image->height = height; // Höhe setzen - image->buffer = (GrayScalePixelType *)malloc(width * height * sizeof(GrayScalePixelType)); - - if (!image->buffer) - return 0; // Speicherfehler - - // Lese Pixelwerte - if (fread(image->buffer, sizeof(GrayScalePixelType), width * height, file) != width * height) - { - free(image->buffer); - image->buffer = NULL; - return 0; // Lese Fehler - } - return 1; // Erfolg -} - -// -------------------------- -// Funktion: Liest eine Serie von Bildern aus einer Datei -// -------------------------- +// ----------------------------------------------------- +// Funktion: Liest die Bilder aus einer Datei +// ----------------------------------------------------- GrayScaleImageSeries *readImages(const char *path) { FILE *file = fopen(path, "rb"); - if (!file) - return NULL; // Datei existiert nicht + if (!file) return NULL; - // Prüfe Header if (!checkFileHeader(file)) - { - fclose(file); - return NULL; // Falsches Format - } - - // Lese Anzahl der Bilder und deren Dimensionen - unsigned int count = 0; - unsigned short width = 0, height = 0; - - if (fread(&count, sizeof(unsigned int), 1, file) != 1 || - fread(&width, sizeof(unsigned short), 1, file) != 1 || - fread(&height, sizeof(unsigned short), 1, file) != 1) { fclose(file); return NULL; } - // Speicher für Serie allozieren - GrayScaleImageSeries *series = (GrayScaleImageSeries *)malloc(sizeof(GrayScaleImageSeries)); + unsigned short numberOfImages = 0, width = 0, height = 0; + + // Đọc metadata: numberOfImages, height, width (theo cách test ghi) + if (fread(&numberOfImages, sizeof(unsigned short), 1, file) != 1 || + fread(&height, sizeof(unsigned short), 1, file) != 1 || + fread(&width, sizeof(unsigned short), 1, file) != 1) + { + fclose(file); + return NULL; + } + + GrayScaleImageSeries *series = malloc(sizeof(GrayScaleImageSeries)); if (!series) { fclose(file); return NULL; } - series->count = count; - series->images = (GrayScaleImage *)calloc(count, sizeof(GrayScaleImage)); - series->labels = (unsigned char *)calloc(count, sizeof(unsigned char)); + series->count = numberOfImages; + series->images = calloc(numberOfImages, sizeof(GrayScaleImage)); + series->labels = calloc(numberOfImages, sizeof(unsigned char)); if (!series->images || !series->labels) { @@ -90,10 +63,21 @@ GrayScaleImageSeries *readImages(const char *path) return NULL; } - // Lese jedes Bild und Label - for (unsigned int i = 0; i < count; i++) + for (unsigned short i = 0; i < numberOfImages; i++) { - if (!readImage(file, &series->images[i], width, height) || + series->images[i].width = width; + series->images[i].height = height; + unsigned int pixelCount = width * height; + + series->images[i].buffer = malloc(pixelCount * sizeof(GrayScalePixelType)); + if (!series->images[i].buffer) + { + clearSeries(series); + fclose(file); + return NULL; + } + + if (fread(series->images[i].buffer, sizeof(GrayScalePixelType), pixelCount, file) != pixelCount || fread(&series->labels[i], sizeof(unsigned char), 1, file) != 1) { clearSeries(series); @@ -106,9 +90,10 @@ GrayScaleImageSeries *readImages(const char *path) return series; } -// -------------------------- + +// ----------------------------------------------------- // Funktion: Gibt eine Bildserie vollständig frei -// -------------------------- +// ----------------------------------------------------- void clearSeries(GrayScaleImageSeries *series) { if (!series) @@ -118,16 +103,18 @@ void clearSeries(GrayScaleImageSeries *series) { for (unsigned int i = 0; i < series->count; i++) { - free(series->images[i].buffer); // Speicher jedes Bildes freigeben + free(series->images[i].buffer); series->images[i].buffer = NULL; - series->images[i].width = 0; - series->images[i].height = 0; } - free(series->images); // Array der Bilder freigeben + free(series->images); + series->images = NULL; } if (series->labels) - free(series->labels); // Labels freigeben + { + free(series->labels); + series->labels = NULL; + } - free(series); // Serie selbst freigeben + free(series); } diff --git a/neuralNetwork.c b/neuralNetwork.c index bd8f164..1196511 100644 --- a/neuralNetwork.c +++ b/neuralNetwork.c @@ -254,6 +254,8 @@ unsigned char *predict(const NeuralNetwork model, const GrayScaleImage images[], return result; } + + void clearModel(NeuralNetwork *model) { if(model != NULL) diff --git a/neuralNetworkTests.c b/neuralNetworkTests.c index a659747..1610a50 100644 --- a/neuralNetworkTests.c +++ b/neuralNetworkTests.c @@ -13,40 +13,41 @@ static void prepareNeuralNetworkFile(const char *path, const NeuralNetwork nn) { FILE *file = fopen(path, "wb"); - if(file == NULL) return; + if (!file) return; - // 1. Schreibe den Datei-Header - // Dieser Header wird beim Laden überprüft, um das Dateiformat sicherzustellen - fwrite(FILE_HEADER_STRING, sizeof(char), strlen(FILE_HEADER_STRING), file); + const char *fileTag = "__info2_neural_network_file_format__"; + fwrite(fileTag, sizeof(char), strlen(fileTag), file); - // 2. Schreibe alle Layer des Netzwerks - for(unsigned int i = 0; i < nn.numberOfLayers; i++) + for (unsigned int i = 0; i < nn.numberOfLayers; i++) { - Layer layer = nn.layers[i]; - int inputDim = (int)layer.weights.cols; - int outputDim = (int)layer.weights.rows; + unsigned int inputDim = nn.layers[i].weights.cols; + unsigned int outputDim = nn.layers[i].weights.rows; - // Schreibe die Dimensionen des Layers - fwrite(&inputDim, sizeof(int), 1, file); - fwrite(&outputDim, sizeof(int), 1, file); + // ghi dimensions + fwrite(&inputDim, sizeof(unsigned int), 1, file); + fwrite(&outputDim, sizeof(unsigned int), 1, file); - // Schreibe die Gewichtsmatrix (outputDim x inputDim) - fwrite(layer.weights.buffer, sizeof(MatrixType), outputDim * inputDim, file); + // ghi weights + fwrite(nn.layers[i].weights.buffer, sizeof(MatrixType), + nn.layers[i].weights.rows * nn.layers[i].weights.cols, file); - // Schreibe den Bias-Vektor (outputDim x 1) - fwrite(layer.biases.buffer, sizeof(MatrixType), outputDim, file); + // ghi biases + fwrite(nn.layers[i].biases.buffer, sizeof(MatrixType), + nn.layers[i].biases.rows * nn.layers[i].biases.cols, file); } - // 3. Schreibe zwei Nullen, um das Ende der Layer anzuzeigen - int zero = 0; - fwrite(&zero, sizeof(int), 1, file); // inputDim = 0 - fwrite(&zero, sizeof(int), 1, file); // outputDim = 0 + // đánh dấu hết layers + unsigned int zero = 0; + fwrite(&zero, sizeof(unsigned int), 1, file); fclose(file); } + + + // -------------------------- // Test: Prüft, ob loadModel richtige Anzahl Layer lädt // -------------------------- diff --git a/test_nn_file.info2 b/test_nn_file.info2 deleted file mode 100644 index a975cbde32ed7f935a9d629d9e1665753e27fc34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88 zcma!#&&*59H;T_oEiFpS0a7L9`9<0BX_+~x@oD)*xrrt5@k|U149q~xz|de1BpiSU Sh#P=-0T3Smv5~|XzyJV}XcRO6