diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile index 18189a1..1fa4de5 100644 --- a/Builds/Linux/Makefile +++ b/Builds/Linux/Makefile @@ -51,6 +51,7 @@ ifeq ($(CONFIG),Release) endif OBJECTS := \ + $(OBJDIR)/DrawComponent_eda766fa.o \ $(OBJDIR)/noise_3051d25b.o \ $(OBJDIR)/MainComponent_a6ffb4a5.o \ $(OBJDIR)/Main_90ebc5c2.o \ @@ -85,6 +86,11 @@ strip: @echo Stripping RBM -@strip --strip-unneeded $(OUTDIR)/$(TARGET) +$(OBJDIR)/DrawComponent_eda766fa.o: ../../Source/DrawComponent.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling DrawComponent.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/noise_3051d25b.o: ../../Source/noise.c -@mkdir -p $(OBJDIR) @echo "Compiling noise.c" diff --git a/RBM.jucer b/RBM.jucer index 0dcf29b..7d05cdc 100644 --- a/RBM.jucer +++ b/RBM.jucer @@ -4,6 +4,9 @@ includeBinaryInAppConfig="1" jucerVersion="3.1.0"> + + @@ -22,19 +25,19 @@ targetName="RBM"/> - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/Source/.cproject b/Source/.cproject index 178f72c..71042e3 100644 --- a/Source/.cproject +++ b/Source/.cproject @@ -1,8 +1,8 @@ - - + + @@ -15,27 +15,26 @@ - - - - - - - - + + + + + + + + - - + + - - + + - + - @@ -43,10 +42,13 @@ - + + + + diff --git a/Source/.project b/Source/.project index 935ab33..e68a8a1 100644 --- a/Source/.project +++ b/Source/.project @@ -7,7 +7,7 @@ org.eclipse.cdt.managedbuilder.core.genmakebuilder - + clean,full,incremental, @@ -28,7 +28,7 @@ JuceLibraryCode 2 - /home/jens/work/RBM/JuceLibraryCode + /home/jens/work/repos/software/trunk/projects/RBM/JuceLibraryCode modules diff --git a/Source/.settings/language.settings.xml b/Source/.settings/language.settings.xml index 4c1d4e5..980e504 100644 --- a/Source/.settings/language.settings.xml +++ b/Source/.settings/language.settings.xml @@ -1,11 +1,10 @@ - + - diff --git a/Source/Main.cpp b/Source/Main.cpp index e40bbe2..8d5b0f9 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -10,7 +10,6 @@ #include "../JuceLibraryCode/JuceHeader.h" #include "MainComponent.h" -#include "Rbm.hpp" //============================================================================== class RBMApplication : public JUCEApplication @@ -19,7 +18,6 @@ public: //============================================================================== RBMApplication() : mainWindow(nullptr) - , m_pRbm(nullptr) { } @@ -31,70 +29,14 @@ public: //============================================================================== void initialise (const String& commandLine) override { - double trainingData[6][16] = - { - {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, - {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}, - {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}, - {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}, - {1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0} - }; - - double hiddenTest[16][4] = - { - {0, 0, 0, 0}, - {0, 0, 0, 1}, - {0, 0, 1, 0}, - {0, 0, 1, 1}, - {0, 1, 0, 0}, - {0, 1, 0, 1}, - {0, 1, 1, 0}, - {0, 1, 1, 1}, - {1, 0, 0, 0}, - {1, 0, 0, 1}, - {1, 0, 1, 0}, - {1, 0, 1, 1}, - {1, 1, 0, 0}, - {1, 1, 0, 1}, - {1, 1, 1, 0}, - {1, 1, 1, 1} - }; - // Add your application's initialisation code here.. - m_pRbm = new Rbm(16, 4); -// mainWindow = new MainWindow; - - m_pRbm->weightsShuffle(0.01); - m_pRbm->setNumTrainingPatterns(6); - - for (uint32_t i=0; i < 6; i++) - { - m_pRbm->setTrainingInput(i, trainingData[i]); - } - - m_pRbm->train(10000, 0.2); - m_pRbm->prob(); - -/* - m_pRbm->weightsPrint(); - // Test the network - for (uint32_t i=0; i < 6; i++) - { - m_pRbm->toHidden(trainingData[i]); - } - for (uint32_t i=0; i < 16; i++) - { - m_pRbm->toVisible(hiddenTest[i]); - } -*/ + mainWindow = new MainWindow; } void shutdown() override { // Add your application's shutdown code here.. mainWindow = nullptr; // (deletes our window) - m_pRbm = nullptr; } //============================================================================== @@ -151,7 +93,6 @@ public: private: ScopedPointer mainWindow; - ScopedPointer m_pRbm; }; diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index c1c4ae0..5900139 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -34,12 +34,14 @@ MainComponent::MainComponent () //[UserPreSize] + addAndMakeVisible (Draw = new DrawComponent (4, 4, 32)); //[/UserPreSize] setSize (600, 400); //[Constructor] You can add your own custom stuff here.. + m_pRbm = new Rbm(16, 4); //[/Constructor] } @@ -52,6 +54,8 @@ MainComponent::~MainComponent() //[Destructor]. You can add your own custom destruction code here.. + Draw = nullptr; + m_pRbm = nullptr; //[/Destructor] } @@ -69,20 +73,77 @@ void MainComponent::paint (Graphics& g) void MainComponent::resized() { - textButton->setBounds (88, 96, 150, 24); + textButton->setBounds (72, 312, 150, 24); //[UserResized] Add your own custom resize handling here.. + Draw->setBounds (16, 16, 336, 232); //[/UserResized] } void MainComponent::buttonClicked (Button* buttonThatWasClicked) { //[UserbuttonClicked_Pre] + double trainingData[6][16] = + { + {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}, + {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}, + {1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0} + }; + + double hiddenTest[16][4] = + { + {0, 0, 0, 0}, + {0, 0, 0, 1}, + {0, 0, 1, 0}, + {0, 0, 1, 1}, + {0, 1, 0, 0}, + {0, 1, 0, 1}, + {0, 1, 1, 0}, + {0, 1, 1, 1}, + {1, 0, 0, 0}, + {1, 0, 0, 1}, + {1, 0, 1, 0}, + {1, 0, 1, 1}, + {1, 1, 0, 0}, + {1, 1, 0, 1}, + {1, 1, 1, 0}, + {1, 1, 1, 1} + }; //[/UserbuttonClicked_Pre] if (buttonThatWasClicked == textButton) { //[UserButtonCode_textButton] -- add your button handler code here.. - //[/UserButtonCode_textButton] + m_pRbm->weightsShuffle(0.01); + m_pRbm->setNumTrainingPatterns(6); + + for (uint32_t i=0; i < 6; i++) + { + m_pRbm->setTrainingInput(i, trainingData[i]); + } + + m_pRbm->train(10000, 0.2); + m_pRbm->prob(); + +// Draw->drawGray(m_pRbm->toVisible(m_pRbm->toHidden(trainingData[rand()%6]))); + Draw->drawGray(m_pRbm->toVisible(hiddenTest[rand()%16])); + +#if 0 + m_pRbm->weightsPrint(); + // Test the network + for (uint32_t i=0; i < 6; i++) + { + m_pRbm->toHidden(trainingData[i]); + } + for (uint32_t i=0; i < 16; i++) + { + m_pRbm->toVisible(hiddenTest[i]); + } +#endif + + //[/UserButtonCode_textButton] } //[UserbuttonClicked_Post] @@ -107,11 +168,14 @@ BEGIN_JUCER_METADATA + fixedSize="1" initialWidth="600" initialHeight="400"> + END_JUCER_METADATA diff --git a/Source/MainComponent.h b/Source/MainComponent.h index 3654f92..67e6961 100644 --- a/Source/MainComponent.h +++ b/Source/MainComponent.h @@ -22,8 +22,10 @@ //[Headers] -- You can add your own extra header files here -- #include "JuceHeader.h" +#include "Rbm.hpp" //[/Headers] +#include "DrawComponent.h" //============================================================================== @@ -54,6 +56,8 @@ public: private: //[UserVariables] -- You can add your own custom variables in this section. + ScopedPointer m_pRbm; + ScopedPointer Draw; //[/UserVariables] //============================================================================== diff --git a/Source/Rbm.hpp b/Source/Rbm.hpp index ea34e73..676fa89 100644 --- a/Source/Rbm.hpp +++ b/Source/Rbm.hpp @@ -96,6 +96,8 @@ class Rbm public: Rbm(uint32_t numVisible, uint32_t numHidden) : m_w(numVisible, numHidden) + , tv(numVisible) + , th(numHidden) , m_numVisible(numVisible) , m_numHidden(numHidden) , m_numTrainingPatterns(0) @@ -313,48 +315,44 @@ public: delete [] h; } - void toHidden(const double *pVisible) + const double* toHidden(const double *pVisible) { double p; uint32_t i; - VisibleLayer v(m_numVisible); - HiddenLayer h(m_numHidden); + tv.setInput(pVisible); + tv.statesAssignfromInput(); - v.setInput(pVisible); - v.statesAssignfromInput(); - - h.probsUpdate(v, m_w); + th.probsUpdate(tv, m_w); printf("pi(t) = (pi^, v>)\n"); for (i=0; i < m_numHidden; i++) { - p = h.getProbs()[i]; + p = th.getProbs()[i]; printf("%3.6f\n", p); } printf("\n"); + return th.getProbs(); } - void toVisible(const double *pHidden) + const double* toVisible(const double *pHidden) { double p; uint32_t i; - VisibleLayer v(m_numVisible); - HiddenLayer h(m_numHidden); + th.setInput(pHidden); + th.statesAssignfromInput(); - h.setInput(pHidden); - h.statesAssignfromInput(); - - v.probsUpdate(h, m_w); + tv.probsUpdate(th, m_w); printf("pi(t) = (pi^, v>)\n"); for (i=0; i < m_numVisible; i++) { - p = v.getProbs()[i]; + p = tv.getProbs()[i]; printf("%3.6f\n", p); } printf("\n"); + return tv.getProbs(); } void weightsPrint() @@ -367,9 +365,15 @@ public: m_w.shuffle(stdDev); } + double **getWeights() + { + return m_w.getWeights(); + } private: Weights m_w; + VisibleLayer tv; + HiddenLayer th; uint32_t m_numVisible; uint32_t m_numHidden; uint32_t m_numTrainingPatterns; @@ -404,7 +408,6 @@ private: delete [] m_pVisibleTraining; m_pVisibleTraining = nullptr; } - m_numTrainingPatterns = 0; } }; diff --git a/Source/noise.c b/Source/noise.c index a7cfd3a..c3be36c 100644 --- a/Source/noise.c +++ b/Source/noise.c @@ -1,79 +1,79 @@ -// -------------------------------------------------------------- -// -------------------------------------------------------------- - -#include -#include -#include -#include - -#include "noise.h" - -// -------------------------------------------------------------- -// internal funcs -// -------------------------------------------------------------- -#define PM_IA 16807 -#define PM_IM 2147483647 -#define PM_AM (1.0/PM_IM) -#define PM_IQ 127773 -#define PM_IR 2836 -#define PM_MASK 123459876 - -// 'Minimal' random number generator of Park and Miller. Returns a uniform random deviate -// between 0.0 and 1.0. Set or reset idum to any integer value (except the unlikely value MASK) -// to initialize the sequence; idum must not be altered between calls for successive deviates in -// a sequence. -double ran0(long *idum) -{ - long k; - double ans; - - *idum ^= PM_MASK; // XORing with MASK allows use of zero and other - k=(*idum)/PM_IQ; // simple bit patterns for idum. - *idum=PM_IA*(*idum-k*PM_IQ)-PM_IR *k; // Compute idum=(IA*idum) % IM without over- - // flows by Schrage’s method. - if (*idum < 0) - *idum += PM_IM; - - ans=PM_AM*(*idum); // Convert idumto a floating result. - *idum ^= PM_MASK; // Unmask before return. - - return ans; -} - -// -------------------------------------------------------------- -// Exported functions -// -------------------------------------------------------------- -void Noise_Init(noise_gen_t *pObj, long seed) -{ - pObj->state = seed; -} - -void Noise_Free(noise_gen_t *pObj) -{ -} - -double Noise_Uniform(noise_gen_t *pObj, double mu) -{ - return ran0(&pObj->state) + mu -0.5; -} - -double Noise_Gaussian(noise_gen_t *pObj, double mu, double sigma) -{ - double U1, U2, V1, V2, S, Y; - - do - { - U1 = Noise_Uniform(pObj, 0.5); // U1=[0,1] - U2 = Noise_Uniform(pObj, 0.5); // U2=[0,1] - V1 = 2 * U1 - 1; // V1=[-1,1] - V2 = 2 * U2 - 1; // V2=[-1,1] - S = V1 * V1 + V2 * V2; - - } while (S >= 1); - - // X = sqrt(-2 * log(S) / S) * V1; - Y = sqrt(-2 * log(S) / S) * V2; - Y = mu + sigma*Y; - - return Y; -} +// -------------------------------------------------------------- +// -------------------------------------------------------------- + +#include +#include +#include +#include + +#include "noise.h" + +// -------------------------------------------------------------- +// internal funcs +// -------------------------------------------------------------- +#define PM_IA 16807 +#define PM_IM 2147483647 +#define PM_AM (1.0/PM_IM) +#define PM_IQ 127773 +#define PM_IR 2836 +#define PM_MASK 123459876 + +// 'Minimal' random number generator of Park and Miller. Returns a uniform random deviate +// between 0.0 and 1.0. Set or reset idum to any integer value (except the unlikely value MASK) +// to initialize the sequence; idum must not be altered between calls for successive deviates in +// a sequence. +double ran0(long *idum) +{ + long k; + double ans; + + *idum ^= PM_MASK; // XORing with MASK allows use of zero and other + k=(*idum)/PM_IQ; // simple bit patterns for idum. + *idum=PM_IA*(*idum-k*PM_IQ)-PM_IR *k; // Compute idum=(IA*idum) % IM without over- + // flows by Schrage’s method. + if (*idum < 0) + *idum += PM_IM; + + ans=PM_AM*(*idum); // Convert idumto a floating result. + *idum ^= PM_MASK; // Unmask before return. + + return ans; +} + +// -------------------------------------------------------------- +// Exported functions +// -------------------------------------------------------------- +void Noise_Init(noise_gen_t *pObj, long seed) +{ + pObj->state = seed; +} + +void Noise_Free(noise_gen_t *pObj) +{ +} + +double Noise_Uniform(noise_gen_t *pObj, double mu) +{ + return ran0(&pObj->state) + mu -0.5; +} + +double Noise_Gaussian(noise_gen_t *pObj, double mu, double sigma) +{ + double U1, U2, V1, V2, S, Y; + + do + { + U1 = Noise_Uniform(pObj, 0.5); // U1=[0,1] + U2 = Noise_Uniform(pObj, 0.5); // U2=[0,1] + V1 = 2 * U1 - 1; // V1=[-1,1] + V2 = 2 * U2 - 1; // V2=[-1,1] + S = V1 * V1 + V2 * V2; + + } while (S >= 1); + + // X = sqrt(-2 * log(S) / S) * V1; + Y = sqrt(-2 * log(S) / S) * V2; + Y = mu + sigma*Y; + + return Y; +}