Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a9d8275a8
|
||
|
|
bbb0ea1cf5
|
||
|
|
12825cc1d3
|
||
|
|
633ee723f4
|
||
|
|
7ea80137b0 | ||
|
|
6ba9ba3195 | ||
|
|
9c3d9f0a40 | ||
|
|
f4427d2892 | ||
|
|
84b65525a6 | ||
|
|
92ad1e1c31
|
||
|
|
6137e45bdb
|
||
|
|
0d7f380d87
|
||
|
|
645d471860
|
||
|
|
721f5cc2d1 | ||
|
|
79ad1285b5
|
No files matched your search
+3
-59
@@ -1,61 +1,5 @@
|
||||
# ---> 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
|
||||
runMatrixTests
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "imageInput.h"
|
||||
|
||||
#define BUFFER_SIZE 100
|
||||
#define FILE_HEADER_STRING "__info2_image_file_format__"
|
||||
|
||||
//Datei öffnen, Header, Anzahl, Höhe und Breite lesen, geöffnete Datei zurückgeben
|
||||
static FILE* openAndReadShort (const char *path, unsigned short *count, unsigned short *width, unsigned short *height) {
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (!file) {
|
||||
return NULL;
|
||||
}
|
||||
size_t headerLength = strlen(FILE_HEADER_STRING);
|
||||
char *header = malloc (headerLength + 1);
|
||||
if(!header) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fread(header, sizeof(char), headerLength, file) != headerLength) {
|
||||
free (header);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
header[headerLength] = '\0';
|
||||
|
||||
if (strcmp (header, FILE_HEADER_STRING) != 0) {
|
||||
free(header);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free (header);
|
||||
|
||||
fread(count, sizeof(unsigned short), 1, file);
|
||||
fread(width, sizeof(unsigned short), 1, file);
|
||||
fread(height, sizeof(unsigned short), 1, file);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
//Speicher anlegen und Pixel eines Bildes einlesen
|
||||
static GrayScaleImage* readPixles (FILE *file, unsigned short *width, unsigned short *height) {
|
||||
GrayScaleImage *image = malloc (sizeof(GrayScaleImage));
|
||||
image->width = *width;
|
||||
image->height = *height;
|
||||
image->buffer = malloc ((*width) * (*height) * sizeof(GrayScalePixelType));
|
||||
if (!image->buffer) {
|
||||
free(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < (*width) * (*height); i++) {
|
||||
unsigned char pixel;
|
||||
if (fread(&pixel, sizeof(unsigned char), 1, file) != 1) {
|
||||
free(image->buffer);
|
||||
free(image);
|
||||
return NULL;
|
||||
}
|
||||
image->buffer[i] = pixel;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
//Ausführen von openAndReadShort, Anlegen des Speichers für Bilderserie, readPixles wird für jedes Bild ausgeführt
|
||||
//Nach jedem Bild wird das zugehörige Label gelesen, bei sämtlichen Fehlern wird NULL zurückgegeben und Speicher durch clearSeries bereinigt
|
||||
GrayScaleImageSeries *readImages(const char *path)
|
||||
{
|
||||
unsigned short count = 0, width = 0, height = 0;
|
||||
|
||||
FILE *file = openAndReadShort(path, &count, &width, &height);
|
||||
if (file == 0) {
|
||||
return NULL;
|
||||
}
|
||||
GrayScaleImageSeries *series = malloc(sizeof(GrayScaleImageSeries));
|
||||
if (!series) {
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
series->count = count;
|
||||
|
||||
series->images = malloc(count * sizeof(GrayScaleImage));
|
||||
series->labels = malloc(count* sizeof(unsigned char));
|
||||
|
||||
for (unsigned int i = 0; i < series->count; i++) {
|
||||
GrayScaleImage *image = readPixles(file, &width, &height);
|
||||
series->images[i] = *image;
|
||||
free(image);
|
||||
|
||||
if (fread(&series->labels[i], sizeof(unsigned char), 1, file) != 1) {
|
||||
clearSeries(series);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
return series;
|
||||
}
|
||||
|
||||
//Bereinigt den Speicher
|
||||
void clearSeries(GrayScaleImageSeries *series)
|
||||
{
|
||||
for (unsigned int i = 0; i < series->count; i++) {
|
||||
free(series->images[i].buffer);
|
||||
}
|
||||
|
||||
free(series->images);
|
||||
free(series->labels);
|
||||
free(series);
|
||||
}
|
||||
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"
|
||||
#include <stdio.h>
|
||||
|
||||
Matrix createMatrix(unsigned int rows, unsigned int cols)
|
||||
{
|
||||
Matrix mat = {.rows = rows, .cols = cols};
|
||||
// If one dimension is 0, return both dimensions as 0 and don't init the array/buffer.
|
||||
if (rows == 0 || cols == 0)
|
||||
{
|
||||
mat.rows = 0;
|
||||
mat.cols = 0;
|
||||
return mat;
|
||||
}
|
||||
|
||||
// allocate contiguous and 0 initialized memory
|
||||
mat.buffer = calloc(rows * cols, sizeof(MatrixType));
|
||||
|
||||
// check if calloc failed
|
||||
if (mat.buffer == NULL)
|
||||
{
|
||||
clearMatrix(&mat);
|
||||
perror("could not allocate memory");
|
||||
}
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
// reduce the dimensions to (0, 0) and free the memory
|
||||
void clearMatrix(Matrix *matrix)
|
||||
{
|
||||
free(matrix->buffer);
|
||||
matrix->buffer = NULL;
|
||||
matrix->cols = 0;
|
||||
matrix->rows = 0;
|
||||
}
|
||||
|
||||
void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx)
|
||||
{
|
||||
// do nothing if idx is not in array or matrix buffer is NULL
|
||||
if (!(rowIdx < matrix.rows) || !(colIdx < matrix.cols) || matrix.buffer == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
matrix.buffer[rowIdx * matrix.cols + colIdx] = value;
|
||||
}
|
||||
|
||||
MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx)
|
||||
{
|
||||
// return UNDEFINED_MATRIX_VALUE if idx is not in array or matrix buffer is NULL
|
||||
if (!(rowIdx < matrix.rows) || !(colIdx < matrix.cols) || matrix.buffer == NULL)
|
||||
{
|
||||
return UNDEFINED_MATRIX_VALUE;
|
||||
}
|
||||
|
||||
return matrix.buffer[rowIdx * matrix.cols + colIdx];
|
||||
};
|
||||
|
||||
Matrix add(const Matrix matrix1, const Matrix matrix2)
|
||||
{
|
||||
Matrix resMat = (matrix1.cols > matrix2.cols) ? createMatrix(matrix1.rows, matrix1.cols) : createMatrix(matrix2.rows, matrix2.cols);
|
||||
|
||||
if (resMat.buffer == NULL)
|
||||
{
|
||||
return createMatrix(0, 0);
|
||||
}
|
||||
|
||||
// matrices not compatible
|
||||
if (matrix1.rows != matrix2.rows)
|
||||
{
|
||||
clearMatrix(&resMat);
|
||||
return resMat;
|
||||
}
|
||||
|
||||
// check if broadcasting is possible
|
||||
if (matrix1.cols != matrix2.cols)
|
||||
{
|
||||
// matrix1 is a vector
|
||||
if (matrix1.cols == 1)
|
||||
{
|
||||
// broadcast vector
|
||||
for (size_t m = 0; m < matrix2.rows; m++)
|
||||
{
|
||||
for (size_t n = 0; n < matrix2.cols; n++)
|
||||
{
|
||||
setMatrixAt(getMatrixAt(matrix2, m, n) + getMatrixAt(matrix1, m, 0), resMat, m, n);
|
||||
}
|
||||
}
|
||||
return resMat;
|
||||
}
|
||||
// matrix2 is a vector
|
||||
else if (matrix2.cols == 1)
|
||||
{
|
||||
// broadcast vector
|
||||
for (size_t m = 0; m < matrix1.rows; m++)
|
||||
{
|
||||
for (size_t n = 0; n < matrix1.cols; n++)
|
||||
{
|
||||
setMatrixAt(getMatrixAt(matrix1, m, n) + getMatrixAt(matrix2, m, 0), resMat, m, n);
|
||||
}
|
||||
}
|
||||
return resMat;
|
||||
}
|
||||
// addition not possible
|
||||
else
|
||||
{
|
||||
clearMatrix(&resMat);
|
||||
return resMat;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t m = 0; m < matrix1.rows; m++)
|
||||
{
|
||||
for (size_t n = 0; n < matrix1.cols; n++)
|
||||
{
|
||||
// this is unnecessarily complicated because at this point we already know that the matrices are compatible
|
||||
setMatrixAt(getMatrixAt(matrix1, m, n) + getMatrixAt(matrix2, m, n), resMat, m, n);
|
||||
}
|
||||
}
|
||||
|
||||
return resMat;
|
||||
}
|
||||
|
||||
Matrix multiply(const Matrix matrix1, const Matrix matrix2)
|
||||
{
|
||||
if (matrix1.cols != matrix2.rows || matrix1.buffer == NULL || matrix2.buffer == NULL)
|
||||
{
|
||||
return createMatrix(0, 0);
|
||||
}
|
||||
|
||||
int rows = matrix1.rows, cols = matrix2.cols;
|
||||
Matrix resMat = createMatrix(rows, cols);
|
||||
|
||||
if (resMat.buffer == NULL)
|
||||
{
|
||||
return createMatrix(0, 0);
|
||||
}
|
||||
|
||||
for (size_t rowIdx = 0; rowIdx < rows; rowIdx++)
|
||||
{
|
||||
for (size_t colIdx = 0; colIdx < cols; colIdx++)
|
||||
{
|
||||
int curCellVal = 0;
|
||||
for (size_t k = 0; k < matrix1.cols; k++)
|
||||
{
|
||||
curCellVal += getMatrixAt(matrix1, rowIdx, k) * getMatrixAt(matrix2, k, colIdx);
|
||||
}
|
||||
setMatrixAt(curCellVal, resMat, rowIdx, colIdx);
|
||||
}
|
||||
}
|
||||
return resMat;
|
||||
}
|
||||
@@ -5,8 +5,13 @@
|
||||
|
||||
typedef float MatrixType;
|
||||
|
||||
// TODO Matrixtyp definieren
|
||||
|
||||
// Matrixtyp
|
||||
typedef struct Matrix
|
||||
{
|
||||
MatrixType *buffer;
|
||||
size_t rows;
|
||||
size_t cols;
|
||||
} Matrix;
|
||||
|
||||
Matrix createMatrix(unsigned int rows, unsigned int cols);
|
||||
void clearMatrix(Matrix *matrix);
|
||||
@@ -15,5 +20,4 @@ MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int co
|
||||
Matrix add(const Matrix matrix1, const Matrix matrix2);
|
||||
Matrix multiply(const Matrix matrix1, const Matrix matrix2);
|
||||
|
||||
|
||||
#endif
|
||||
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.
@@ -5,10 +5,46 @@
|
||||
#include "unity.h"
|
||||
#include "neuralNetwork.h"
|
||||
|
||||
static void writeLayer(FILE *file, const Matrix weights, const Matrix biases, unsigned int inputDim)
|
||||
{
|
||||
unsigned int outputDim = (unsigned int)weights.rows;
|
||||
fwrite(&outputDim, sizeof(unsigned int), 1, file);
|
||||
if (weights.buffer != NULL)
|
||||
fwrite(weights.buffer, sizeof(MatrixType), outputDim * inputDim, file);
|
||||
|
||||
if (biases.buffer != NULL)
|
||||
fwrite(biases.buffer, sizeof(MatrixType), outputDim, file);
|
||||
}
|
||||
|
||||
|
||||
static void prepareNeuralNetworkFile(const char *path, const NeuralNetwork nn)
|
||||
{
|
||||
// TODO
|
||||
FILE *file = fopen(path, "wb");
|
||||
if (!file) return;
|
||||
|
||||
const char tag[] = "__info2_neural_network_file_format__";
|
||||
fwrite(tag, sizeof(char), strlen(tag), file);
|
||||
|
||||
if (nn.numberOfLayers == 0)
|
||||
{
|
||||
unsigned int zero = 0;
|
||||
fwrite(&zero, sizeof(unsigned int), 1, file);
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int inputDim = (unsigned int)nn.layers[0].weights.cols;
|
||||
fwrite(&inputDim, sizeof(unsigned int), 1, file);
|
||||
|
||||
for (int i = 0; i < nn.numberOfLayers; i++)
|
||||
{
|
||||
writeLayer(file, nn.layers[i].weights, nn.layers[i].biases, inputDim);
|
||||
inputDim = (unsigned int)nn.layers[i].weights.rows;
|
||||
}
|
||||
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.
@@ -0,0 +1 @@
|
||||
some_tag
|
||||
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