MNIST w c++

0

Dzień dobry, cześć i czołem
Mam na studia zrobić projekt zaliczeniowy z c++
Uznałem że jak spadać to z wysokiego konia, więc próbowałem zrobić klasyfikator do bazy MNIST
Kod jest obrzydliwy, nie działa a ja powoli tracę nadzieję, mimo wszystko, choć spodziewam się że potężnych pocisków, to uznałem że pokażę go tutaj, może znajdzie się ktoś kto zechce pomóc. Teraz staram się ogarnąć error żeby móc wstecznie propagować po neuronach. Dodam tylko że to mój pierwszy projekt s c++, jeżeli popatrzycie na to i powiecie że g00wno, a macie pomysł na jakąś gierkę (pierwszy semestr infy, nie było klas) to też rzućcie, coś trzeba zrobić.



#include <iostream>
#include <string>
#include <fstream>
#include <math.h>

using namespace std;


//global data
double*** weights;
double dataset[60001][783] = {};
double output_layer_1[128], output_layer_2[10];
double output_layers[2] = { *output_layer_1,*output_layer_2 };

void init_weights(int num_layers, int layer_sizes[]) {
	weights = new double** [num_layers];
	for (int i = 0; i < num_layers; i++) {
		weights[i] = new double* [layer_sizes[i]];
		for (int j = 0; j < layer_sizes[i]; j++) {
			weights[i][j] = new double[layer_sizes[i + 1]];
			for (int k = 0; k < layer_sizes[i + 1]; k++) {
				weights[i][j][k] = rand() % 201;
				weights[i][j][k] /= 100;
				//Weights can have values between 0 & 2
			}
		}
	}
}

//pobiera dane z csv
void get_data(string directory, int layer_sizes, int num_rows)
{
	fstream file;
	string row, s;
	int iter_count = 0;
	file.open(directory, ios::in);
	for (int i = 1; i < num_rows; i++) {
		getline(file, row);
		for (int j = 0; j < row.length(); j++)
		{	
			if (row[j] != ' ') {
				if (row[j] == ',')
				{
					dataset[i][iter_count] = stod(s);
					iter_count++;
					s = "";
					//Assign value to dataset, and than empty s variable to prepare it for another one
				}
				else {
					s += row[j];
				}
			}
		}
	}
}


void feedforward(double *dataset, double **weights, int previous_size,int target_size, double *target_list) 
{
	for (int i = 0; i < target_size; i++) 
	{
		double value = 0;
		for (int j = 0; j < previous_size; j++) 
		{
			double datapoint = dataset[j];
			value += datapoint * weights[i][j];
		}
		target_list[i] = activation(value);
	}


}



double activation(double x)
{
	return exp(x)/(1 + exp(x));
}
/*
mnozenie

int len = sizeof(x) / sizeof(x[0]);
	int len_2 = sizeof(y) / sizeof(y[0]);
	len_2 /= len;
	double* output;
	output = new double [len]
	for (int i = 0; i < len; i++) {
		for (int j = 0; j  < len_2; j++) {
			output[i] += x[i] * y[i][j];
	}*/


void back_propagation() {}


int main()
{
	//SETTINGS
	int num_layers = 3, epochs = 10;
	int layer_sizes[3] = { 728,128,10 };



	string 
		root = "C:\\Users\\Surface\\Documents\\",	//Absolute path to projects files
		data_directory = root + "mnist_train.csv", 
		test_directory = root + "mnist_test.csv", 
		weights_directory = root + "weights.csv";



	//string data_directory ="mnist_train.csv", test_directory = "mnist_test.csv", weights_directory = "weights.csv";
	//1.Input layer, ...... , n. Output layer

	//PREPARATION
	init_weights(num_layers, layer_sizes);
	get_data(data_directory, layer_sizes[0]+1, 60001);

	//TRAINING
	for (int i = 0; i < epochs; i++) {
		for (int j = 0; j < num_layers; j++) {
			feedforward(dataset[j], weights[j], layer_sizes[j], layer_sizes[j+1], &output_layers[j]);

		}

		

		back_propagation();
	}

	//TESTING

}
/*
TODO:
in feedforward we should be able to specify activation function


*/


1

Spróbuj to zrobić na kontenerach z STL. ALbo zamiast tak atakować sieć neuronową, nie wystarczy zwykła regresja? Będzie łatwiej.

1
  1. sprawdzaj czy cos ci sie wczytalo po getline - https://stackoverflow.com/a/2251612
  2. nie zakladaj konkretnej dlugosci pliku - obsluz tyle wierszy ile Ci sie uda wczytac
  3. nie zakladaj konkretnego katalogu (nawet w domu) - uzyj aktualnego albo podawaj jako parametr
  4. uzyj cmath zamiast math.h (tak sie robi w c++), http://www.cplusplus.com/reference/cmath/

1 użytkowników online, w tym zalogowanych: 0, gości: 1