Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06109225f8 | ||
|
|
7837be1c3e | ||
|
|
44f0bfc16d | ||
|
|
ff21ecab21 | ||
|
|
7f5291deca | ||
|
|
dadcdc873d | ||
|
|
9e7fcca725 | ||
|
|
da8dc2a9ef | ||
|
|
07f217f1f4 | ||
|
|
d4375c31e8 | ||
|
|
67c5110e5c | ||
|
|
e40a5cbd7b | ||
|
|
42e92f278f | ||
|
|
14388a5637 | ||
|
|
ebff958c4e | ||
|
|
5b5e1182bd | ||
|
|
c560fd5241 | ||
|
|
e206895359 | ||
|
|
ddf70dbefd |
No files matched your search
+3
-60
@@ -1,61 +1,4 @@
|
||||
# ---> C
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
mnist
|
||||
runTests
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
Startcode/mnist
|
||||
Startcode/runTests
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# IDE folders
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
*.exe
|
||||
Vendored
+33
@@ -0,0 +1,33 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/mnist.exe",
|
||||
"args": ["mnist_test.info2","mnist_model.info2"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${fileDirname}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "C:\\msys64\\ucrt64\\bin\\gdb.exe",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "imageInput.h"
|
||||
|
||||
#define BUFFER_SIZE 100
|
||||
#define FILE_HEADER_STRING "__info2_image_file_format__"
|
||||
|
||||
// TODO Implementieren Sie geeignete Hilfsfunktionen für das Lesen der Bildserie aus einer Datei
|
||||
|
||||
// TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen
|
||||
GrayScaleImageSeries *readImages(const char *path)
|
||||
{
|
||||
GrayScaleImageSeries *series = NULL;
|
||||
|
||||
return series;
|
||||
}
|
||||
|
||||
// TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt
|
||||
void clearSeries(GrayScaleImageSeries *series)
|
||||
{
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "matrix.h"
|
||||
|
||||
// TODO Matrix-Funktionen implementieren
|
||||
|
||||
Matrix createMatrix(unsigned int rows, unsigned int cols)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void clearMatrix(Matrix *matrix)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Matrix add(const Matrix matrix1, const Matrix matrix2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Matrix multiply(const Matrix matrix1, const Matrix matrix2)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "imageInput.h"
|
||||
|
||||
#define BUFFER_SIZE 100
|
||||
#define FILE_HEADER_STRING "__info2_image_file_format__"
|
||||
|
||||
// TODO Implementieren Sie geeignete Hilfsfunktionen für das Lesen der Bildserie aus einer Datei
|
||||
|
||||
// TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen
|
||||
GrayScaleImageSeries *readImages(const char *path)
|
||||
{
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (file == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Überprüfe den Header
|
||||
char fileTag[strlen(FILE_HEADER_STRING)];
|
||||
fread(fileTag, sizeof(fileTag[0]), strlen(FILE_HEADER_STRING), file);
|
||||
|
||||
if (strcmp(fileTag, FILE_HEADER_STRING) != 0)
|
||||
{
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Lese die Metadaten: Anzahl der Bilder, Breite und Höhe
|
||||
unsigned short numberOfImages, width, height;
|
||||
fread(&numberOfImages, sizeof(numberOfImages), 1, file);
|
||||
fread(&width, sizeof(width), 1, file);
|
||||
fread(&height, sizeof(height), 1, file);
|
||||
|
||||
GrayScaleImageSeries *series = (GrayScaleImageSeries *)malloc(sizeof(GrayScaleImageSeries));
|
||||
if (series == NULL)
|
||||
{
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
series->count = numberOfImages;
|
||||
series->images = (GrayScaleImage *)malloc(numberOfImages * sizeof(GrayScaleImage));
|
||||
series->labels = (unsigned char *)malloc(numberOfImages * sizeof(unsigned char));
|
||||
|
||||
if (series->images == NULL || series->labels == NULL)
|
||||
{
|
||||
free(series);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numberOfImages; i++)
|
||||
{
|
||||
series->images[i].width = width;
|
||||
series->images[i].height = height;
|
||||
series->images[i].buffer = (GrayScalePixelType *)malloc(width * height * sizeof(GrayScalePixelType));
|
||||
|
||||
if (series->images[i].buffer == NULL)
|
||||
{
|
||||
// Fehlerbehandlung: Speicher freigeben, wenn malloc fehlschlägt
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
free(series->images[j].buffer);
|
||||
}
|
||||
free(series->images);
|
||||
free(series->labels);
|
||||
free(series);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Lese die Pixel-Daten und das Label
|
||||
fread(series->images[i].buffer, sizeof(GrayScalePixelType), width * height, file);
|
||||
fread(&series->labels[i], sizeof(unsigned char), 1, file);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return series;
|
||||
}
|
||||
|
||||
// TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt
|
||||
void clearSeries(GrayScaleImageSeries *series)
|
||||
{
|
||||
if (series == NULL)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < series->count; i++)
|
||||
{
|
||||
free(series->images[i].buffer); // Speicher für das Bild freigeben
|
||||
}
|
||||
|
||||
free(series->images); // Speicher für die Bild-Array freigeben
|
||||
free(series->labels); // Speicher für die Labels freigeben
|
||||
free(series); // Speicher freigeben
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,154 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "matrix.h"
|
||||
|
||||
// TODO Matrix-Funktionen implementieren
|
||||
|
||||
Matrix createMatrix(unsigned int rows, unsigned int cols)
|
||||
{
|
||||
Matrix m = {NULL, 0, 0};
|
||||
|
||||
if (rows > 0 && cols > 0)
|
||||
{
|
||||
m.buffer = malloc(rows * cols * sizeof(MatrixType));
|
||||
m.rows = rows;
|
||||
m.cols = cols;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void clearMatrix(Matrix *matrix)
|
||||
{
|
||||
|
||||
if (matrix == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Speicher freigeben, falls vorhanden
|
||||
free(matrix->buffer);
|
||||
matrix->buffer = NULL;
|
||||
|
||||
// Metadaten zurücksetzen
|
||||
matrix->rows = 0;
|
||||
matrix->cols = 0;
|
||||
}
|
||||
|
||||
void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx)
|
||||
{
|
||||
matrix.buffer[rowIdx * matrix.cols + colIdx] = value; // setzte Matrix auf den Wert value am Punkt (row col)
|
||||
}
|
||||
|
||||
MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx)
|
||||
{
|
||||
MatrixType value = 0;
|
||||
|
||||
if (rowIdx < matrix.rows && colIdx < matrix.cols)
|
||||
{
|
||||
value = matrix.buffer[rowIdx * matrix.cols + colIdx]; // hole Wert value am Punkt (row col)
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
Matrix add(const Matrix matrix1, const Matrix matrix2)
|
||||
{
|
||||
Matrix result = {0};
|
||||
|
||||
int broadcast_case =
|
||||
(matrix1.cols == 1 && matrix1.rows == matrix2.rows) ||
|
||||
(matrix2.cols == 1 && matrix1.rows == matrix2.rows);
|
||||
|
||||
if (!broadcast_case && (matrix1.rows != matrix2.rows || matrix1.cols != matrix2.cols))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
if (matrix1.cols == 1 && matrix1.rows == matrix2.rows) // Broadcasting
|
||||
{
|
||||
result = createMatrix(matrix2.rows, matrix2.cols);
|
||||
|
||||
for (unsigned int i = 0; i < matrix1.rows; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < result.cols; j++)
|
||||
{
|
||||
result.buffer[i * result.cols + j] = matrix1.buffer[i] + matrix2.buffer[i * matrix2.cols + j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
else if (matrix2.cols == 1 && matrix1.rows == matrix2.rows)
|
||||
{
|
||||
result = createMatrix(matrix1.rows, matrix1.cols);
|
||||
|
||||
for (unsigned int i = 0; i < matrix2.rows; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < result.cols; j++)
|
||||
{
|
||||
result.buffer[i * result.cols + j] = matrix1.buffer[i * matrix1.cols + j] + matrix2.buffer[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
result = createMatrix(matrix1.rows, matrix1.cols);
|
||||
// Elementweise Addition
|
||||
for (unsigned int i = 0; i < result.rows; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < result.cols; j++)
|
||||
{
|
||||
result.buffer[i * result.cols + j] = matrix1.buffer[i * matrix1.cols + j] + matrix2.buffer[i * matrix2.cols + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix multiply(const Matrix matrix1, const Matrix matrix2)
|
||||
{
|
||||
Matrix result = {0};
|
||||
|
||||
if (matrix1.cols != matrix2.rows)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result.rows = matrix1.rows;
|
||||
result.cols = matrix2.cols;
|
||||
result.buffer = malloc(result.rows * result.cols * sizeof(MatrixType));
|
||||
|
||||
// wenn buffer nicht allokiert werden kann dann zurücksetzen und abbrechen
|
||||
if (result.buffer == NULL)
|
||||
{
|
||||
result.rows = result.cols = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Matritzenmultiplikation
|
||||
|
||||
for (int r = 0; r < result.rows; r++) // Zeile in Ergebnis
|
||||
{
|
||||
for (int m = 0; m < result.cols; m++) // Spalte in Ergebnis
|
||||
{
|
||||
MatrixType sum = 0;
|
||||
|
||||
for (int n = 0; n < matrix1.cols; n++)
|
||||
{
|
||||
sum += matrix1.buffer[r * matrix1.cols + n] *
|
||||
matrix2.buffer[n * matrix2.cols + m];
|
||||
}
|
||||
|
||||
result.buffer[r * result.cols + m] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,19 +1,26 @@
|
||||
#ifndef MATRIX_H
|
||||
#define MATRIX_H
|
||||
|
||||
#define UNDEFINED_MATRIX_VALUE 0
|
||||
|
||||
typedef float MatrixType;
|
||||
|
||||
// TODO Matrixtyp definieren
|
||||
|
||||
|
||||
Matrix createMatrix(unsigned int rows, unsigned int cols);
|
||||
void clearMatrix(Matrix *matrix);
|
||||
void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx);
|
||||
MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx);
|
||||
Matrix add(const Matrix matrix1, const Matrix matrix2);
|
||||
Matrix multiply(const Matrix matrix1, const Matrix matrix2);
|
||||
|
||||
|
||||
#endif
|
||||
#ifndef MATRIX_H
|
||||
#define MATRIX_H
|
||||
|
||||
#define UNDEFINED_MATRIX_VALUE 0
|
||||
|
||||
typedef float MatrixType;
|
||||
|
||||
// TODO Matrixtyp definieren
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MatrixType *buffer; // Zeiger auf die Matrixdaten
|
||||
unsigned int rows; // Anzahl der Zeilen
|
||||
unsigned int cols; // Anzahl der Spalten
|
||||
} Matrix;
|
||||
|
||||
|
||||
Matrix createMatrix(unsigned int rows, unsigned int cols);
|
||||
void clearMatrix(Matrix *matrix);
|
||||
void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx);
|
||||
MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx);
|
||||
Matrix add(const Matrix matrix1, const Matrix matrix2);
|
||||
Matrix multiply(const Matrix matrix1, const Matrix matrix2);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -164,7 +164,7 @@ void test_setMatrixAtFailsOnIndicesOutOfRange(void)
|
||||
Matrix matrixToTest = {.rows=2, .cols=3, .buffer=buffer};
|
||||
|
||||
setMatrixAt(-1, matrixToTest, 2, 3);
|
||||
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, matrixToTest.buffer, sizeof(buffer)/sizeof(MatrixType));
|
||||
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, matrixToTest.buffer, matrixToTest.cols * matrixToTest.rows);
|
||||
}
|
||||
|
||||
void setUp(void) {
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -8,7 +8,62 @@
|
||||
|
||||
static void prepareNeuralNetworkFile(const char *path, const NeuralNetwork nn)
|
||||
{
|
||||
// TODO
|
||||
FILE *file = fopen(path, "wb");
|
||||
if (!file) {
|
||||
perror("Fehler beim Erstellen der Testdatei");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// File header
|
||||
const char *fileTag = "__info2_neural_network_file_format__";
|
||||
fwrite(fileTag, strlen(fileTag), 1, file);
|
||||
|
||||
|
||||
if (nn.numberOfLayers == 0)
|
||||
{
|
||||
unsigned int zero = 0;
|
||||
fwrite(&zero, sizeof(unsigned int), 1, file);
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
|
||||
// first layer dimension
|
||||
unsigned int in = nn.layers[0].weights.cols;
|
||||
unsigned int out = nn.layers[0].weights.rows;
|
||||
|
||||
fwrite(&in, sizeof(unsigned int), 1, file);
|
||||
fwrite(&out, sizeof(unsigned int), 1, file);
|
||||
|
||||
// do all layers
|
||||
for (unsigned int i = 0; i < nn.numberOfLayers; i++)
|
||||
{
|
||||
const Layer *L = &nn.layers[i];
|
||||
|
||||
// Write weights matrix
|
||||
fwrite(L->weights.buffer,
|
||||
sizeof(MatrixType),
|
||||
L->weights.rows * L->weights.cols,
|
||||
file);
|
||||
|
||||
// Write biases matrix
|
||||
fwrite(L->biases.buffer,
|
||||
sizeof(MatrixType),
|
||||
L->biases.rows * L->biases.cols,
|
||||
file);
|
||||
|
||||
// After layer i, write dimension of next layer
|
||||
if (i + 1 < nn.numberOfLayers)
|
||||
{
|
||||
unsigned int nextOut = nn.layers[i+1].weights.rows;
|
||||
fwrite(&nextOut, sizeof(unsigned int), 1, file);
|
||||
}
|
||||
}
|
||||
|
||||
// --- 5. Write terminating zero ---
|
||||
unsigned int zero = 0;
|
||||
fwrite(&zero, sizeof(unsigned int), 1, file);
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
void test_loadModelReturnsCorrectNumberOfLayers(void)
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user