This commit is contained in:
HorlogeSkynet 2016-10-20 18:54:59 +02:00
parent 371f2d33d9
commit a9ffa62585
6 changed files with 135 additions and 97 deletions

@ -7,20 +7,19 @@
#include "../Modules/Graphics/graphics.h"
using namespace std;
#define ALPHA 0.001
#define NBPOINTS 250
#define NBITERATIONS 1000
#define INTERNALWIDTH 5
double leadingCoeficient[] = {1, 2};
void getRandomCoordinates(double[], double[]);
void getGradient(double[], double[], double[], double[]);
void getGradient(const double[], const double[], const double[], double[]);
@ -61,7 +60,7 @@ int main(int argc, char **argv)
deltaGrad[1] = grad[1] - gradOld[1];
alpha = (-alpha * (gradOld[0] * deltaGrad[0] + gradOld[1] * deltaGrad[1]))
/ ((deltaGrad[0] * deltaGrad[0]) + (deltaGrad[1] * deltaGrad[1]));
/ ((deltaGrad[0] * deltaGrad[0]) + (deltaGrad[1] * deltaGrad[1]));
}
else
@ -74,13 +73,12 @@ int main(int argc, char **argv)
}
cout << "Theta: [" << theta[0] << "; " << theta[1] << "]" << endl;
cout << "Done in " << i << " iterations." << endl;
cout << "| Done in " << i << " iterations. |" << endl;
/* This function will display the input coordinates, and the computed regression */
glutDisplay(&argc, argv, "Affine Regression (C++)", x, y, (const int)NBPOINTS, theta, sizeof(leadingCoeficient) / sizeof(*leadingCoeficient));
/* This function will display the input coordinates,
and the computed regression, and will be waiting while the window stay open */
sfmlDisplay("Affine Regression (C++)", x, y, (const int)NBPOINTS, theta, NBELEMENTS(leadingCoeficient));
/* Now, waiting for user closing the window */
glutMainLoop();
return 0;
}
@ -97,10 +95,11 @@ void getRandomCoordinates(double x[], double y[])
}
void getGradient(double x[], double y[], double theta[], double gradient[])
void getGradient(const double x[], const double y[], const double theta[], double gradient[])
{
gradient[0]=0;
gradient[1]=0;
gradient[0] = 0;
gradient[1] = 0;
for(int i(0); i < NBPOINTS; i++)
{
gradient[0] += (theta[1] * x[i] + theta[0]) - y[i];

@ -5,19 +5,19 @@
#include <cmath>
#include <ctime>
#include "../Modules/Graphics/graphics.h"
using namespace std;
#define ALPHA 0.001
#define NBPOINTS 25
#define NBPOINTS 500
#define NBITERATIONS 1000
#define INTERNALWIDTH 5
#define LEADINGCOEFICIENT 2
void getRandomCoordinates(double[], double[]);
double getGradient(double[], double[], double);
double getGradient(const double[], const double[], const double[]);
@ -28,35 +28,42 @@ int main(int argc, char const *argv[])
srand(time(0));
double x[NBPOINTS] = {0};
double y[NBPOINTS] = {0};
double x[NBPOINTS] = {0.0};
double y[NBPOINTS] = {0.0};
/* Coordinates generation */
getRandomCoordinates(x, y);
double theta(0);
double theta[1] = {0.0};
double alpha(ALPHA);
double gradOld(getGradient(x, y, theta));
double grad;
double i;
/* Training ! */
for(i=0; i < NBITERATIONS; i++)
int i;
for(i = 0; i < NBITERATIONS; i++)
{
theta -= alpha * gradOld;
theta[0] -= alpha * gradOld;
grad = getGradient(x, y, theta);
if (grad!=gradOld)
if(grad != gradOld)
{
alpha = -alpha * gradOld / (grad - gradOld);
}
else
{
break;
}
gradOld = grad;
}
cout << "Theta: " << theta << endl;
cout << "Done in " << i << " iterations." << endl;
cout << "Theta: " << theta[0] << endl;
cout << "| Done in " << i << " iterations. |" << endl;
sfmlDisplay("Linear Regression (C++)", x, y, (const int)NBPOINTS, theta, NBELEMENTS(theta));
return 0;
}
@ -73,13 +80,13 @@ void getRandomCoordinates(double x[], double y[])
}
double getGradient(double x[], double y[], double theta)
double getGradient(const double x[], const double y[], const double theta[])
{
double value = 0;
double value = 0.0;
for(short int i(0); i < NBPOINTS; i++)
{
value += ((theta * x[i]) - y[i]) * x[i];
value += ((theta[0] * x[i]) - y[i]) * x[i];
}
return value / NBPOINTS;

@ -1,21 +1,24 @@
# Makefile for: MINDLE
CXX=g++
GFLAGS=-lGLU -lGL -lglut
GFLAGS=-lsfml-graphics -lsfml-window -lsfml-system
LIN=LinearRegression
MAT=Modules/Matrix
GRAPH=Modules/Graphics
ifdef DEBUG
CXXFLAGS = -g -ansi -std=c++11 -Wall -Wextra -Wpedantic -Wshadow -Wno-missing-field-initializers -Wstrict-overflow
CXXFLAGS=-g -ansi -std=c++11 -Wall -Wextra -Wpedantic -Wshadow -Wno-missing-field-initializers -Wstrict-overflow
LDFLAGS=-g -ansi -std=c++11 -Wall -Wextra -Wpedantic -Wshadow -Wno-missing-field-initializers -Wstrict-overflow
else
CXXFLAGS = -O3 -ansi -std=c++11 -Wall -Wextra -Wpedantic -Wshadow -Wno-missing-field-initializers -Wstrict-overflow
CXXFLAGS=-O3 -ansi -std=c++11 -Wall -Wextra -Wpedantic -Wshadow -Wno-missing-field-initializers -Wstrict-overflow
LDFLAGS=-O3 -ansi -std=c++11 -Wall -Wextra -Wpedantic -Wshadow -Wno-missing-field-initializers -Wstrict-overflow
endif
all: linearRegression.bin affineRegression.bin linearRegressionVectors.bin
# Linear Regression
linearRegression.bin: LinearRegression/linearRegression.cpp
$(CXX) -o $@ $^ $(LDFLAGS)
@ -28,21 +31,27 @@ affineRegression.bin: $(LIN)/affineRegression.o $(GRAPH)/graphics.o
linearRegressionVectors.bin: $(LIN)/linearRegressionVectors.o $(MAT)/Matrix.o
$(CXX) -o $@ $^ $(LDFLAGS)
# Object files
affineRegression.o: $(LIN)/affineRegression.cpp $(GRAPH)/Graphics.o
$(CXX) -o $@ -c $^ $(CXXFLAGS)
$(CXX) -c -o $@ $^ $(CXXFLAGS)
linearRegressionVectors.o: $(LIN)/linearRegressionVectors.cpp
$(CXX) -c -o $@ $^ $(CXXFLAGS)
# Matrix module
$(MAT)/Matrix.o: $(MAT)/Matrix.cpp $(MAT)/Matrix.h
$(CXX) -c -o $@ $< $(CXXFLAGS)
$(CXX) -c -o $@ $< $(CXXFLAGS)
# Graphics module
$(GRAPH)/Graphics.o: $(GRAPH)/Graphics.cpp $(GRAPH)/Graphics.h
$(CXX) -c -o $@ $< $(CXXFLAGS)
$(CXX) -c -o $@ $< $(CXXFLAGS)
#.SILENT:
.SILENT:
.PHONY: clean
clean:
find . -name '*.bin' -delete
find . -name '*.o' -delete
find . -name '*.o' -delete

@ -1,70 +1,95 @@
#include "graphics.h"
void glutDisplay(int *argc, char *argv[], const char *const windowName, double x[], double y[],
const int nbPoints, double theta[], const size_t nbDimensions)
using namespace sf;
void sfmlDisplay(const char* const string, const double x[], const double y[], const int nbPoints, const double theta[], const int nbDimensions)
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(SIZE_X, SIZE_Y);
glutInitWindowPosition(POSITION_X, POSITION_Y);
glutCreateWindow(windowName);
/* Let's create a new window ! */
RenderWindow window(VideoMode(SIZE_X, SIZE_Y), string);
int window_width = glutGet(GLUT_WINDOW_WIDTH);
int window_height = glutGet(GLUT_WINDOW_HEIGHT);
/* One shape for each points of the coordinates, and for each point of our computed regression */
CircleShape *shape = new CircleShape[2 * nbPoints];
/* Let's display some stuff over here */
glClearColor(255, 255, 255, 255);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, window_width, 0, window_height);
glLineWidth(2.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* Input coordinates */
glBegin(GL_LINES);
double ratio_x = window_width / (double)nbPoints;
double ratio_y = window_height / abs(getMax(y, nbPoints) - getMin(y, nbPoints));
glVertex2f(0.0, 0.0);
glColor3f(0.0, 0.0, 0.0);
for(int i(0); i < nbPoints; i++)
if(shape == nullptr)
{
glVertex2f(x[i] * ratio_x, y[i] * ratio_y);
std::cout << "Error during allocation of the shapes array for display result." << std::endl;
exit(EXIT_FAILURE);
}
glEnd();
const int window_width = window.getSize().x;
const int window_height = window.getSize().y;
/* What the regression has found out */
glBegin(GL_LINES);
const double ratio_x = window_width / (double)nbPoints;
const double ratio_y = window_height / std::abs(getMax(y, nbPoints) - getMin(y, nbPoints));
double temp_y = 0.0;
glVertex2f(0.0, 0.0);
glColor3f(0.75, 0.5, 0.5);
for(int i(0); i < nbPoints; i++)
/* Dots for generated coordinates */
int i;
for(i = 0; i < nbPoints; i++)
{
for(int j(0); j < (int)nbDimensions; j++)
/* The dot will be red, and with a radius of 10 ! */
shape[i].setRadius(2);
shape[i].setFillColor(Color(255, 0, 0));
shape[i].setPosition(x[i] * ratio_x, window_height - y[i] * ratio_y);
}
/* Dots for our computed regression */
for(double temp_y = 0.0; i < 2 * nbPoints; i++, temp_y = 0.0)
{
/* The dot will be blue, and with a radius of 20 ! */
shape[i].setRadius(2);
shape[i].setFillColor(Color(0, 0, 255));
/* Condition if we're doing a simple linear regression (y = a * x), or not */
if(nbDimensions > 1)
{
temp_y += pow(x[i], (double)j) * theta[j];
for(int j(0); j < (int)nbDimensions; j++)
{
temp_y += pow(x[i - nbPoints - 1], (double)j) * theta[j];
}
}
glVertex2f(x[i] * ratio_x, temp_y * ratio_y);
temp_y = 0.0;
else
{
temp_y = x[i - nbPoints - 1] * theta[0];
}
shape[i].setPosition(x[i - nbPoints - 1] * ratio_x, window_height - temp_y * ratio_y);
}
glEnd();
/* Set a low frame rate limit in order to deal with CPU-usage while in the loop below */
window.setFramerateLimit(25);
glFlush();
glutSwapBuffers();
/* Infinite loop waiting for closing action */
while(window.isOpen())
{
Event event;
while(window.pollEvent(event))
{
if(event.type == Event::Closed)
{
window.close();
}
}
window.clear(Color(255, 255, 255, 255));
for(i = 0; i < 2 * nbPoints; i++)
{
window.draw(shape[i]);
}
window.display();
}
delete[] shape;
}
double getMin(double tab[], const int n)
double getMin(const double tab[], const int n)
{
double minimum = tab[0];
@ -80,7 +105,7 @@ double getMin(double tab[], const int n)
}
double getMax(double tab[], const int n)
double getMax(const double tab[], const int n)
{
double maximum = tab[0];

@ -1,19 +1,17 @@
#pragma once
#include <iostream>
#include <cmath>
#include <cstring>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <SFML/Graphics.hpp>
#define POSITION_X 764
#define POSITION_Y 256
#define NBELEMENTS(x) (int)(sizeof(x) / sizeof(*x))
#define SIZE_X 1024
#define SIZE_Y 1024
void glutDisplay(int*, char**, const char *const, double[], double[], const int, double[], const size_t);
void sfmlDisplay(const char* const, const double[], const double[], const int, const double[], const int);
double getMin(double[], const int);
double getMax(double[], const int);
double getMin(const double[], const int);
double getMax(const double[], const int);

@ -1,10 +1,10 @@
# MINDLE Is Not a Deep Learning Experimentation
# MINDLE Is Not a Deep Learning Experimentation
Requirements (for C++ codes):
- g++ 6.2.0 (<-- Because, of course, we won't upload any binaries here)
- freeglut3-dev (<-- Glut library is being used at the moment)
- g++ >= 4.9 (<-- Because, of course, we won't upload any binaries here)
- libsfml-dev (for SFML library)
Old requirements (for Python codes):
@ -18,7 +18,7 @@ Old requirements (for Python codes):
Notes to read:
1. Some words about the frameworks we used with Python in the past: Theano & TensorFlow gave us a too high-level abstraction for our needs. We couldn't manage to get something to work, and this is not about getting computations on the GPU; that was just impossible, and we nearly destroy our computers many times... Now, we start from scratch with C++. At least, we would understand the errors throwed.
1. Some words about the frameworks we used with Python in the past: Theano & TensorFlow gave us a too high-level abstraction for our needs. We couldn't manage to get something to work, and this is not about getting computations on the GPU; that was just impossible, and we nearly destroy our computers many times... Now, we start from scratch with C++. At least, we would understand the errors thrown.
2. Based on [this "tutorial"](https://github.com/Newmu/Theano-Tutorials), you'll be able to perform digits classification by getting the return of [loadMNIST.py](https://github.com/HorlogeSkynet/MachineLearning/tree/master/dev_null/MNIST/loadMNIST.py). If you run it, the code will download and read the training examples automatically.