Compare commits

..

3 Commits

3 changed files with 36 additions and 36 deletions

View File

@ -39,8 +39,8 @@ mnistVisualization.o: mnistVisualization.c
matrixTests: matrix.o matrixTests.c matrixTests: matrix.o matrixTests.c
$(CC) $(CFLAGS) -I$(unityfolder) -o runMatrixTests matrixTests.c matrix.o $(BINARIES)/libunity.a $(CC) $(CFLAGS) -I$(unityfolder) -o runMatrixTests matrixTests.c matrix.o $(BINARIES)/libunity.a
neuralNetworkTests: neuralNetwork.o neuralNetworkTests.c neuralNetworkTests: neuralNetwork.o matrix.o neuralNetworkTests.c
$(CC) $(CFLAGS) -I$(unityfolder) -o runNeuralNetworkTests neuralNetworkTests.c neuralNetwork.o $(BINARIES)/libunity.a $(CC) $(CFLAGS) -I$(unityfolder) -o runNeuralNetworkTests neuralNetworkTests.c neuralNetwork.o matrix.o $(BINARIES)/libunity.a
imageInputTests: imageInput.o imageInputTests.c imageInputTests: imageInput.o imageInputTests.c
$(CC) $(CFLAGS) -I$(unityfolder) -o runImageInputTests imageInputTests.c imageInput.o $(BINARIES)/libunity.a $(CC) $(CFLAGS) -I$(unityfolder) -o runImageInputTests imageInputTests.c imageInput.o $(BINARIES)/libunity.a

View File

@ -20,7 +20,7 @@ static void softmax(Matrix *matrix)
for(int rowIdx = 0; rowIdx < matrix->rows; rowIdx++) for(int rowIdx = 0; rowIdx < matrix->rows; rowIdx++)
{ {
MatrixType expValue = exp(getMatrixAt(*matrix, rowIdx, colIdx)); MatrixType expValue = exp(getMatrixAt(*matrix, rowIdx, colIdx));
setMatrixAt(expValue, *matrix, rowIdx, colIdx); setMatrixAt(expValue, matrix, rowIdx, colIdx);
colSums[colIdx] += expValue; colSums[colIdx] += expValue;
} }
} }
@ -30,7 +30,7 @@ static void softmax(Matrix *matrix)
for(int rowIdx = 0; rowIdx < matrix->rows; rowIdx++) for(int rowIdx = 0; rowIdx < matrix->rows; rowIdx++)
{ {
MatrixType normalizedValue = getMatrixAt(*matrix, rowIdx, colIdx) / colSums[colIdx]; MatrixType normalizedValue = getMatrixAt(*matrix, rowIdx, colIdx) / colSums[colIdx];
setMatrixAt(normalizedValue, *matrix, rowIdx, colIdx); setMatrixAt(normalizedValue, matrix, rowIdx, colIdx);
} }
} }
free(colSums); free(colSums);
@ -182,7 +182,7 @@ static Matrix imageBatchToMatrixOfImageVectors(const GrayScaleImage images[], un
{ {
for(int j = 0; j < images[i].width * images[i].height; j++) for(int j = 0; j < images[i].width * images[i].height; j++)
{ {
setMatrixAt((MatrixType)images[i].buffer[j], matrix, j, i); setMatrixAt((MatrixType)images[i].buffer[j], &matrix, j, i);
} }
} }
} }

View File

@ -23,49 +23,49 @@
// 2) Stellen Sie sicher, dass alle Unittests erfolgreich durchlaufen. // 2) Stellen Sie sicher, dass alle Unittests erfolgreich durchlaufen.
// make neuralNetworkTests && ./runNeuralNetworkTests // make neuralNetworkTests && ./runNeuralNetworkTests
static void prepareNeuralNetworkFile(const char *path, const NeuralNetwork nn) static void prepareNeuralNetworkFile(const char *path, const NeuralNetwork nn)
{ {
// First Draft
// 1. Datei im binären Schreibmodus öffnen
FILE *file = fopen(path, "wb"); FILE *file = fopen(path, "wb");
if (file == NULL) { if (file == NULL) {
perror("Fehler beim Öffnen der Datei");
return; return;
} }
// 2. Den Identifikations-Tag schreiben // 1. Header schreiben
const char *fileTag = "__info2_neural_network_file_format__"; const char *fileHeader = "__info2_neural_network_file_format__";
fwrite(fileTag, sizeof(char), strlen(fileTag), file); fwrite(fileHeader, sizeof(char), strlen(fileHeader), file);
// 3. Die Anzahl der Schichten schreiben // Prüfen ob Layer existieren
fwrite(&nn.numberOfLayers, sizeof(int), 1, file); if (nn.numberOfLayers > 0)
{
// 2. Die Input-Dimension der ALLERERSTEN Schicht schreiben
// (Das sind die Spalten der Gewichtsmatrix der ersten Schicht)
int inputDim = nn.layers[0].weights.cols;
fwrite(&inputDim, sizeof(int), 1, file);
// 4. Schleife über alle Schichten, um deren Daten zu schreiben // 3. Durch alle Schichten iterieren
for (int i = 0; i < nn.numberOfLayers; i++) { for(int i = 0; i < nn.numberOfLayers; i++)
Layer currentLayer = nn.layers[i]; {
// Die Output-Dimension dieser Schicht schreiben (Zeilen der Gewichtsmatrix)
int outputDim = nn.layers[i].weights.rows;
fwrite(&outputDim, sizeof(int), 1, file);
// 4a. Daten der Gewichts-Matrix (weights) schreiben // 4. Gewichte (Weights) schreiben (nur den Buffer, keine Dimensionen mehr!)
Matrix weights = currentLayer.weights; // loadModel weiß durch inputDim und outputDim schon, wie groß die Matrix ist.
int weightElements = weights.rows * weights.cols; int weightsCount = nn.layers[i].weights.rows * nn.layers[i].weights.cols;
fwrite(nn.layers[i].weights.buffer, sizeof(MatrixType), weightsCount, file);
// Schreibe Dimensionen (Zeilen, Spalten) // 5. Biases schreiben (nur den Buffer)
fwrite(&weights.rows, sizeof(int), 1, file); int biasCount = nn.layers[i].biases.rows * nn.layers[i].biases.cols;
fwrite(&weights.cols, sizeof(int), 1, file); fwrite(nn.layers[i].biases.buffer, sizeof(MatrixType), biasCount, file);
// Schreibe den Daten-Buffer (die eigentlichen Zahlen)
fwrite(weights.buffer, sizeof(MatrixType), weightElements, file);
// 4b. Daten der Bias-Matrix (biases) schreiben
Matrix biases = currentLayer.biases;
int biasElements = biases.rows * biases.cols;
// Schreibe Dimensionen (Zeilen, Spalten)
fwrite(&biases.rows, sizeof(int), 1, file);
fwrite(&biases.cols, sizeof(int), 1, file);
// Schreibe den Daten-Buffer
fwrite(biases.buffer, sizeof(MatrixType), biasElements, file);
} }
// 5. Datei schließen }
// 6. Eine 0 schreiben, um das Ende der Dimensionen zu signalisieren
// (loadModel bricht die while-Schleife ab, wenn readDimension 0 liefert)
int stopMark = 0;
fwrite(&stopMark, sizeof(int), 1, file);
fclose(file); fclose(file);
} }