diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/MLP_MVS/MLP_MVS.sln b/MLP_MVS/MLP_MVS.sln
new file mode 100644
index 0000000..59a6e7f
--- /dev/null
+++ b/MLP_MVS/MLP_MVS.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.23107.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MLP_MVS", "MLP_MVS.vcxproj", "{6BFA9D94-B136-4985-83A1-EE76FFF6F374}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6BFA9D94-B136-4985-83A1-EE76FFF6F374}.Debug|x64.ActiveCfg = Debug|x64
+ {6BFA9D94-B136-4985-83A1-EE76FFF6F374}.Debug|x64.Build.0 = Debug|x64
+ {6BFA9D94-B136-4985-83A1-EE76FFF6F374}.Debug|x86.ActiveCfg = Debug|Win32
+ {6BFA9D94-B136-4985-83A1-EE76FFF6F374}.Debug|x86.Build.0 = Debug|Win32
+ {6BFA9D94-B136-4985-83A1-EE76FFF6F374}.Release|x64.ActiveCfg = Release|x64
+ {6BFA9D94-B136-4985-83A1-EE76FFF6F374}.Release|x64.Build.0 = Release|x64
+ {6BFA9D94-B136-4985-83A1-EE76FFF6F374}.Release|x86.ActiveCfg = Release|Win32
+ {6BFA9D94-B136-4985-83A1-EE76FFF6F374}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/MLP_MVS/MLP_MVS.vcxproj b/MLP_MVS/MLP_MVS.vcxproj
new file mode 100644
index 0000000..4b79bac
--- /dev/null
+++ b/MLP_MVS/MLP_MVS.vcxproj
@@ -0,0 +1,156 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {6BFA9D94-B136-4985-83A1-EE76FFF6F374}
+ Win32Proj
+ MLP_MVS
+ 8.1
+
+
+
+ Application
+ true
+ v140
+ Unicode
+
+
+ Application
+ false
+ v140
+ true
+ Unicode
+
+
+ Application
+ true
+ v140
+ Unicode
+
+
+ Application
+ false
+ v140
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ Console
+ true
+
+
+
+
+
+
+ Level3
+ Disabled
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ Console
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MLP_MVS/MLP_MVS.vcxproj.filters b/MLP_MVS/MLP_MVS.vcxproj.filters
new file mode 100644
index 0000000..5e3ac27
--- /dev/null
+++ b/MLP_MVS/MLP_MVS.vcxproj.filters
@@ -0,0 +1,36 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 331adb9..26c581b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,6 @@
# MLP
+
Simple multilayer perceptron c++ implementation.
+
+
+David Nogueira, 2016.01.16
diff --git a/src/Main.cpp b/src/Main.cpp
new file mode 100644
index 0000000..05b9074
--- /dev/null
+++ b/src/Main.cpp
@@ -0,0 +1,130 @@
+//============================================================================
+// Name : Main.cpp
+// Author : David Nogueira
+//============================================================================
+
+#include "MLP.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+void LearnAND() {
+ std::cout << "Train AND function with mlp." << std::endl;
+
+ std::vector training_set =
+ {
+ {{ 1, 0, 0 },{1,0}},
+ {{ 1, 0, 1 },{1,0}},
+ {{ 1, 1, 0 },{1,0}},
+ {{ 1, 1, 1 },{0,1}}
+ };
+
+ MLP my_mlp(0.1, 100, 0.5);
+ my_mlp.Train(training_set, 1, 1);
+
+ assert(my_mlp.GetOutput({ 1, 0, 0 }) == 0);
+ assert(my_mlp.GetOutput({ 1, 0, 1 }) == 0);
+ assert(my_mlp.GetOutput({ 1, 1, 0 }) == 0);
+ assert(my_mlp.GetOutput({ 1, 1, 1 }) == 1);
+ std::cout << "Trained with success." << std::endl;
+ std::cout << std::endl;
+}
+
+void LearnNAND() {
+ std::cout << "Train NAND function with mlp." << std::endl;
+
+ std::vector training_set =
+ {
+ {{ 1, 0, 0 },{0,1}},
+ {{ 1, 0, 1 },{0,1}},
+ {{ 1, 1, 0 },{0,1}},
+ {{ 1, 1, 1 },{1,0}}
+ };
+
+ MLP my_mlp(0.1, 100, 0.5);
+ my_mlp.Train(training_set, 1, 1);
+
+ assert(my_mlp.GetOutput({ 1, 0, 0 }) == 1);
+ assert(my_mlp.GetOutput({ 1, 0, 1 }) == 1);
+ assert(my_mlp.GetOutput({ 1, 1, 0 }) == 1);
+ assert(my_mlp.GetOutput({ 1, 1, 1 }) == 0);
+ std::cout << "Trained with success." << std::endl;
+ std::cout << std::endl;
+}
+
+void LearnOR() {
+ std::cout << "Train OR function with mlp." << std::endl;
+
+ std::vector training_set =
+ {
+ {{ 1, 0, 0 },{1,0}},
+ {{ 1, 0, 1 },{0,1}},
+ {{ 1, 1, 0 },{0,1}},
+ {{ 1, 1, 1 },{0,1}}
+ };
+
+ MLP my_mlp(0.1, 100, 0.5);
+ my_mlp.Train(training_set, 1, 1);
+
+ assert(my_mlp.GetOutput({ 1, 0, 0 }) == 0);
+ assert(my_mlp.GetOutput({ 1, 0, 1 }) == 1);
+ assert(my_mlp.GetOutput({ 1, 1, 0 }) == 1);
+ assert(my_mlp.GetOutput({ 1, 1, 1 }) == 1);
+ std::cout << "Trained with success." << std::endl;
+ std::cout << std::endl;
+}
+
+void LearnNOR() {
+ std::cout << "Train NOR function with mlp." << std::endl;
+
+ std::vector training_set =
+ {
+ {{ 1, 0, 0 },{0,1}},
+ {{ 1, 0, 1 },{1,0}},
+ {{ 1, 1, 0 },{1,0}},
+ {{ 1, 1, 1 },{1,0}}
+ };
+
+ MLP my_mlp(0.1, 100, 0.5);
+ my_mlp.Train(training_set, 1, 1);
+
+ assert(my_mlp.GetOutput({ 1, 0, 0 }) == 1);
+ assert(my_mlp.GetOutput({ 1, 0, 1 }) == 0);
+ assert(my_mlp.GetOutput({ 1, 1, 0 }) == 0);
+ assert(my_mlp.GetOutput({ 1, 1, 1 }) == 0);
+ std::cout << "Trained with success." << std::endl;
+ std::cout << std::endl;
+}
+
+void LearnNOT() {
+ std::cout << "Train NOT function with mlp." << std::endl;
+
+ std::vector training_set =
+ {
+ {{ 1, 0},{0,1}},
+ {{ 1, 1},{1,1}}
+ };
+
+ MLP my_mlp(0.1, 100, 0.5);
+ my_mlp.Train(training_set, 1, 1);
+
+ assert(my_mlp.GetOutput({ 1, 0 }) == 1);
+ assert(my_mlp.GetOutput({ 1, 1 }) == 0);
+ std::cout << "Trained with success." << std::endl;
+ std::cout << std::endl;
+}
+
+int main() {
+ LearnAND();
+ LearnNAND();
+ LearnOR();
+ LearnNOR();
+ LearnNOT();
+
+ return 0;
+}
\ No newline at end of file
diff --git a/src/Sample.h b/src/Sample.h
new file mode 100644
index 0000000..f4ca12e
--- /dev/null
+++ b/src/Sample.h
@@ -0,0 +1,45 @@
+#ifndef TRAININGSAMPLE_H
+#define TRAININGSAMPLE_H
+
+#include
+#include
+
+class Sample {
+public:
+ Sample(const std::vector & input_vector) {
+
+ m_input_vector = input_vector;
+ }
+ std::vector & input_vector() {
+ return m_input_vector;
+ }
+ uint32_t GetInputVectorSize() const {
+ return m_input_vector.size();
+ }
+ void AddBiasValue(double bias_value) {
+ m_input_vector.insert(m_input_vector.begin(), bias_value);
+ }
+protected:
+ std::vector m_input_vector;
+};
+
+
+class TrainingSample : public Sample {
+public:
+ TrainingSample(const std::vector & input_vector,
+ const std::vector & output_vector) :
+ Sample(input_vector) {
+ m_output_vector = output_vector;
+ }
+ std::vector & output_vector() {
+ return m_output_vector;
+ }
+ uint32_t GetOutputVectorSize() const {
+ return m_output_vector.size();
+ }
+protected:
+ std::vector m_output_vector;
+};
+
+
+#endif // TRAININGSAMPLE_H
\ No newline at end of file
diff --git a/src/Utils.h b/src/Utils.h
new file mode 100644
index 0000000..c663c41
--- /dev/null
+++ b/src/Utils.h
@@ -0,0 +1,62 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+#include
+#include
+#include
+#include
+#ifdef _WIN32
+#include
+#else
+#include
+#endif
+
+namespace utils {
+
+struct gen_rand {
+ double factor;
+public:
+ gen_rand(double r = 1.0) : factor(r / RAND_MAX) {}
+ double operator()() {
+ return rand() * factor;
+ }
+};
+
+inline double sigmoid(double x) {
+ //Typical sigmoid function created from input x
+ //param x: input value
+ //return: sigmoided value
+ return 1 / (1 + exp(-x));
+}
+
+// Derivative of sigmoid function
+inline double deriv_sigmoid(double x) {
+ return sigmoid(x)*(1 - sigmoid(x));
+};
+
+class Chronometer {
+public:
+ Chronometer() {
+ time_span = std::chrono::steady_clock::duration::zero();
+ };
+ virtual ~Chronometer() {};
+
+ void GetTime() {
+ clock_begin = std::chrono::steady_clock::now();
+ }
+ void StopTime() {
+ std::chrono::steady_clock::time_point clock_end = std::chrono::steady_clock::now();
+ time_span += clock_end - clock_begin;
+ }
+ //Return elapsed time in seconds
+ double GetElapsedTime() {
+ return double(time_span.count()) *
+ std::chrono::steady_clock::period::num / std::chrono::steady_clock::period::den;
+ }
+protected:
+ std::chrono::steady_clock::time_point clock_begin;
+ std::chrono::steady_clock::duration time_span;
+};
+
+}
+#endif // UTILS_H
\ No newline at end of file