further development
git-svn-id: http://moon:8086/svn/software/trunk/projects/RBM@17 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
+76
-56
@@ -18,8 +18,8 @@
|
||||
*/
|
||||
|
||||
//[Headers] You can add your own extra header files here...
|
||||
#include <cstdio>
|
||||
#include "noise.h"
|
||||
void mylog(const char* format, ...);
|
||||
//[/Headers]
|
||||
|
||||
#include "DrawComponent.h"
|
||||
@@ -29,14 +29,16 @@
|
||||
//[/MiscUserDefs]
|
||||
|
||||
//==============================================================================
|
||||
DrawComponent::DrawComponent (int width, int height, int scale)
|
||||
DrawComponent::DrawComponent (int width, int height)
|
||||
{
|
||||
|
||||
//[UserPreSize]
|
||||
noise_gen_t noise;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_scale = scale;
|
||||
m_scaleX = 1.0;
|
||||
m_scaleY = 1.0;
|
||||
m_pG = nullptr;
|
||||
|
||||
//[/UserPreSize]
|
||||
|
||||
@@ -44,21 +46,11 @@ DrawComponent::DrawComponent (int width, int height, int scale)
|
||||
|
||||
|
||||
//[Constructor] You can add your own custom stuff here..
|
||||
m_pImage = new Image(Image::RGB , scale*width, scale*height, true);
|
||||
m_pG = new Graphics(*m_pImage);
|
||||
setSize (scale*width, scale*height);
|
||||
// m_pG = new Graphics(m_image);
|
||||
m_pData = new double[width*height];
|
||||
|
||||
memset(m_pData, 0, m_width*m_height*sizeof(double));
|
||||
Noise_Init(&noise, 0x3231);
|
||||
|
||||
double *pData = m_pData;
|
||||
for (int i=0; i < width; i++)
|
||||
{
|
||||
for (int j=0; j < height; j++)
|
||||
{
|
||||
*(pData++) = Noise_Gaussian(&noise, 0.5, 0.3);
|
||||
}
|
||||
}
|
||||
m_pG->setImageResamplingQuality(Graphics::lowResamplingQuality);
|
||||
//[/Constructor]
|
||||
}
|
||||
@@ -71,7 +63,6 @@ DrawComponent::~DrawComponent()
|
||||
|
||||
|
||||
//[Destructor]. You can add your own custom destruction code here..
|
||||
m_pImage = nullptr;
|
||||
m_pG = nullptr;
|
||||
m_pData = nullptr;
|
||||
//[/Destructor]
|
||||
@@ -83,7 +74,7 @@ void DrawComponent::paint (Graphics& g)
|
||||
//[UserPrePaint] Add your own custom painting code here..
|
||||
AffineTransform t;
|
||||
|
||||
g.drawImage(*m_pImage, 0, 0, getWidth(), getHeight(), 0, 0, getWidth(), getHeight(), false);
|
||||
g.drawImage(m_image, 0, 0, getWidth(), getHeight(), 0, 0, getWidth(), getHeight(), false);
|
||||
// g.drawImageTransformed(*m_pImage, t.rotated(8), false);
|
||||
return;
|
||||
//[/UserPrePaint]
|
||||
@@ -97,7 +88,13 @@ void DrawComponent::paint (Graphics& g)
|
||||
void DrawComponent::resized()
|
||||
{
|
||||
//[UserResized] Add your own custom resize handling here..
|
||||
printf("%s (%d,%d)\n", __func__, getWidth(), getHeight());
|
||||
// mylog("%s (%d,%d)\n", __func__, getWidth(), getHeight());
|
||||
m_scaleX = (float)getWidth()/m_width;
|
||||
m_scaleY = (float)getHeight()/m_height;
|
||||
m_image = Image(Image::RGB , getWidth(), getHeight(), true);
|
||||
m_pG = nullptr;
|
||||
m_pG = new Graphics(m_image);
|
||||
|
||||
repaint();
|
||||
//[/UserResized]
|
||||
}
|
||||
@@ -105,101 +102,124 @@ void DrawComponent::resized()
|
||||
void DrawComponent::mouseMove (const MouseEvent& e)
|
||||
{
|
||||
//[UserCode_mouseMove] -- Add your code here...
|
||||
printf("%s\n", __func__);
|
||||
// mylogMessage(String("MouseMove"));
|
||||
//[/UserCode_mouseMove]
|
||||
}
|
||||
|
||||
void DrawComponent::mouseEnter (const MouseEvent& e)
|
||||
{
|
||||
//[UserCode_mouseEnter] -- Add your code here...
|
||||
printf("%s\n", __func__);
|
||||
// mylog("%s\n", __func__);
|
||||
//[/UserCode_mouseEnter]
|
||||
}
|
||||
|
||||
void DrawComponent::mouseExit (const MouseEvent& e)
|
||||
{
|
||||
//[UserCode_mouseExit] -- Add your code here...
|
||||
printf("%s\n", __func__);
|
||||
// mylog("%s\n", __func__);
|
||||
//[/UserCode_mouseExit]
|
||||
}
|
||||
|
||||
void DrawComponent::mouseDown (const MouseEvent& e)
|
||||
{
|
||||
//[UserCode_mouseDown] -- Add your code here...
|
||||
printf("%s\n", __func__);
|
||||
m_pG->setColour (Colours::black);
|
||||
m_pG->fillAll();
|
||||
repaint();
|
||||
// mylog("%s x:%d, y:%d\n", __func__, e.x, e.y);
|
||||
if (e.mods.isRightButtonDown())
|
||||
{
|
||||
clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
drawAt(e.x, e.y);
|
||||
}
|
||||
//[/UserCode_mouseDown]
|
||||
}
|
||||
|
||||
void DrawComponent::mouseDrag (const MouseEvent& e)
|
||||
{
|
||||
//[UserCode_mouseDrag] -- Add your code here...
|
||||
int x, y;
|
||||
x = e.x;
|
||||
y = e.y;
|
||||
|
||||
printf("%s x:%d, y:%d\n", __func__, x, y);
|
||||
m_pG->setColour (Colours::white);
|
||||
m_pG->fillRect(x, y, 5, 5);
|
||||
repaint();
|
||||
// mylog("%s x:%d, y:%d\n", __func__, e.x, e.y);
|
||||
if (e.mods.isLeftButtonDown())
|
||||
{
|
||||
drawAt(e.x, e.y);
|
||||
}
|
||||
//[/UserCode_mouseDrag]
|
||||
}
|
||||
|
||||
void DrawComponent::mouseUp (const MouseEvent& e)
|
||||
{
|
||||
//[UserCode_mouseUp] -- Add your code here...
|
||||
printf("%s\n", __func__);
|
||||
// mylog("%s\n", __func__);
|
||||
//[/UserCode_mouseUp]
|
||||
}
|
||||
|
||||
void DrawComponent::mouseDoubleClick (const MouseEvent& e)
|
||||
{
|
||||
//[UserCode_mouseDoubleClick] -- Add your code here...
|
||||
printf("%s\n", __func__);
|
||||
// mylog("%s\n", __func__);
|
||||
//[/UserCode_mouseDoubleClick]
|
||||
}
|
||||
|
||||
void DrawComponent::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel)
|
||||
{
|
||||
//[UserCode_mouseWheelMove] -- Add your code here...
|
||||
printf("%s\n", __func__);
|
||||
// mylog("%s\n", __func__);
|
||||
//[/UserCode_mouseWheelMove]
|
||||
}
|
||||
|
||||
|
||||
|
||||
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
|
||||
void DrawComponent::drawGray (const double *pData)
|
||||
void DrawComponent::drawAt(int x, int y)
|
||||
{
|
||||
int index;
|
||||
double fx = (double)x / m_scaleX;
|
||||
double fy = (double)y / m_scaleY;
|
||||
|
||||
index = (int)(x/m_scaleX) + m_width*(int)(y/m_scaleY);
|
||||
// mylog("Write(%d)\n", index);
|
||||
|
||||
if (index >= 0)
|
||||
if (index < m_width*m_height)
|
||||
m_pData[index] = 1.0;
|
||||
|
||||
x = (int)fx * m_scaleX;
|
||||
y = (int)fy * m_scaleY;
|
||||
m_pG->setColour (Colours::white);
|
||||
m_pG->fillRect((float)x, (float)y, m_scaleX, m_scaleY);
|
||||
repaint();
|
||||
}
|
||||
|
||||
void DrawComponent::clear()
|
||||
{
|
||||
double *pData = m_pData;
|
||||
for (int i=0; i < m_width*m_height; i++)
|
||||
{
|
||||
*(pData++) = 0;
|
||||
}
|
||||
setData(m_pData);
|
||||
}
|
||||
|
||||
const double* DrawComponent::getData ()
|
||||
{
|
||||
return m_pData;
|
||||
}
|
||||
|
||||
void DrawComponent::setData (const double *pData)
|
||||
{
|
||||
double a;
|
||||
double min = +1E12;
|
||||
double max = -1E12;
|
||||
|
||||
for (int i=0; i < m_width*m_height; i++)
|
||||
for (int i=0; i < m_width*m_height; i++)
|
||||
{
|
||||
m_pData[i] = pData[i];
|
||||
min = std::min<double>(min, pData[i]);
|
||||
max = std::max<double>(max, pData[i]);
|
||||
}
|
||||
for (int i=0; i < m_width*m_height; i++)
|
||||
for (int i=0; i < m_height; i++)
|
||||
{
|
||||
m_pData[i] -= min;
|
||||
}
|
||||
for (int i=0; i < m_width*m_height; i++)
|
||||
{
|
||||
m_pData[i] /= (max-min);
|
||||
}
|
||||
|
||||
pData = m_pData;
|
||||
for (int i=0; i < m_width; i++)
|
||||
{
|
||||
for (int j=0; j < m_height; j++)
|
||||
for (int j=0; j < m_width; j++)
|
||||
{
|
||||
a = std::min<double>(std::max<double>(*pData, 0), 1);
|
||||
m_pG->setColour(Colour(Colours::white).greyLevel(a));
|
||||
m_pG->fillRect(m_scale*i, m_scale*j, m_scale, m_scale);
|
||||
m_pG->fillRect(m_scaleX*j, m_scaleY*i, m_scaleX, m_scaleY);
|
||||
pData++;
|
||||
}
|
||||
}
|
||||
@@ -218,7 +238,7 @@ void DrawComponent::drawGray (const double *pData)
|
||||
BEGIN_JUCER_METADATA
|
||||
|
||||
<JUCER_COMPONENT documentType="Component" className="DrawComponent" componentName=""
|
||||
parentClasses="public Component" constructorParams="int width, int height, int scale"
|
||||
parentClasses="public Component" constructorParams="int width, int height"
|
||||
variableInitialisers="" snapPixels="8" snapActive="1" snapShown="1"
|
||||
overlayOpacity="0.330" fixedSize="0" initialWidth="80" initialHeight="80">
|
||||
<METHODS>
|
||||
|
||||
@@ -38,12 +38,15 @@ class DrawComponent : public Component
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
DrawComponent (int width, int height, int scale);
|
||||
DrawComponent (int width, int height);
|
||||
~DrawComponent();
|
||||
|
||||
//==============================================================================
|
||||
//[UserMethods] -- You can add your own custom methods in this section.
|
||||
void drawGray(const double *pData);
|
||||
void drawAt(int x, int y);
|
||||
void setData(const double *pData);
|
||||
const double* getData();
|
||||
void clear();
|
||||
//[/UserMethods]
|
||||
|
||||
void paint (Graphics& g);
|
||||
@@ -63,10 +66,11 @@ private:
|
||||
//[UserVariables] -- You can add your own custom variables in this section.
|
||||
int m_width;
|
||||
int m_height;
|
||||
int m_scale;
|
||||
ScopedPointer<Image>m_pImage;
|
||||
float m_scaleX;
|
||||
float m_scaleY;
|
||||
ScopedPointer<Graphics>m_pG;
|
||||
ScopedPointer<double>m_pData;
|
||||
Image m_image;
|
||||
//[/UserVariables]
|
||||
|
||||
//==============================================================================
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* HiddenLayer.hpp
|
||||
*
|
||||
* Created on: 21.09.2014
|
||||
* Author: jens
|
||||
*/
|
||||
|
||||
#ifndef HIDDENLAYER_HPP_
|
||||
#define HIDDENLAYER_HPP_
|
||||
|
||||
#include "Layer.hpp"
|
||||
#include <cmath>
|
||||
|
||||
class HiddenLayer : public Layer
|
||||
{
|
||||
public:
|
||||
HiddenLayer(uint32_t numUnits = 0, const double *pStatesInit = nullptr)
|
||||
: Layer(numUnits, pStatesInit)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~HiddenLayer()
|
||||
{
|
||||
}
|
||||
|
||||
double getEnergy(const Weights &weights)
|
||||
{
|
||||
uint32_t i;
|
||||
double energy = 0;
|
||||
|
||||
for (i=0; i < getNumUnits(); i++)
|
||||
{
|
||||
energy -= weights.getBiasHidden()[i] * getStates()[i];
|
||||
}
|
||||
return energy;
|
||||
}
|
||||
|
||||
private:
|
||||
double accum(const Layer &layer, const Weights &weights, uint32_t index) const
|
||||
{
|
||||
uint32_t i;
|
||||
double sum = weights.getBiasVisible()[index];
|
||||
const double *pStates = layer.getStates();
|
||||
|
||||
for (i=0; i < layer.getNumUnits(); i++)
|
||||
{
|
||||
sum += pStates[i] * weights.getWeights()[index][i];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* HIDDENLAYER_HPP_ */
|
||||
+10
-164
@@ -10,165 +10,18 @@
|
||||
|
||||
#ifndef LAYER_HPP
|
||||
#define LAYER_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include "noise.h"
|
||||
|
||||
class Weights
|
||||
{
|
||||
public:
|
||||
Weights(uint32_t numVisible, uint32_t numHidden)
|
||||
: m_ppW(nullptr)
|
||||
, m_pBiasVisible(nullptr)
|
||||
, m_pBiasHidden(nullptr)
|
||||
, m_numVisible(numVisible)
|
||||
, m_numHidden(numHidden)
|
||||
{
|
||||
alloc();
|
||||
Noise_Init(&m_noise, 0x32727155);
|
||||
|
||||
shuffle(0);
|
||||
}
|
||||
|
||||
~Weights()
|
||||
{
|
||||
Noise_Free(&m_noise);
|
||||
free();
|
||||
}
|
||||
|
||||
void shuffle(double stdDev)
|
||||
{
|
||||
uint32_t i, j;
|
||||
double kdev = stdDev*sqrt(12.0);
|
||||
|
||||
for (j=0; j < m_numVisible; j++)
|
||||
{
|
||||
m_pBiasVisible[j] = kdev*Noise_Uniform(&m_noise, 0.5);
|
||||
}
|
||||
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
m_pBiasHidden[i] = kdev*Noise_Uniform(&m_noise, 0.5);
|
||||
}
|
||||
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
for (j=0; j < m_numVisible; j++)
|
||||
{
|
||||
m_ppW[i][j] = kdev*Noise_Uniform(&m_noise, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double **getWeights() const
|
||||
{
|
||||
return m_ppW;
|
||||
}
|
||||
|
||||
double *getBiasVisible() const
|
||||
{
|
||||
return m_pBiasVisible;
|
||||
}
|
||||
|
||||
double *getBiasHidden() const
|
||||
{
|
||||
return m_pBiasHidden;
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
uint32_t i, j;
|
||||
double w;
|
||||
|
||||
printf("\n");
|
||||
printf("w(v,h) = (v^, h>)\n");
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
{
|
||||
for (j=0; j < m_numHidden; j++)
|
||||
{
|
||||
w = m_ppW[j][i];
|
||||
printf("%3.6f ", w);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("bv = \n");
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
{
|
||||
w = m_pBiasVisible[i];
|
||||
printf("%3.6f\n", w);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("bh = \n");
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
w = m_pBiasHidden[i];
|
||||
printf("%3.6f\n", w);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
private:
|
||||
double **m_ppW;
|
||||
double *m_pBiasVisible;
|
||||
double *m_pBiasHidden;
|
||||
uint32_t m_numVisible;
|
||||
uint32_t m_numHidden;
|
||||
noise_gen_t m_noise;
|
||||
|
||||
void alloc()
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (m_ppW)
|
||||
{
|
||||
free();
|
||||
alloc();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ppW = new double*[m_numHidden];
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
m_ppW[i] = new double[m_numVisible];
|
||||
}
|
||||
m_pBiasVisible = new double[m_numVisible];
|
||||
m_pBiasHidden = new double[m_numHidden];
|
||||
}
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
|
||||
if (m_ppW)
|
||||
{
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
delete [] m_ppW[i];
|
||||
}
|
||||
delete [] m_ppW;
|
||||
m_ppW = nullptr;
|
||||
}
|
||||
|
||||
delete [] m_pBiasVisible;
|
||||
m_pBiasVisible = nullptr;
|
||||
|
||||
delete [] m_pBiasHidden;
|
||||
m_pBiasHidden = nullptr;
|
||||
}
|
||||
};
|
||||
#include "Weights.hpp"
|
||||
|
||||
class Layer
|
||||
{
|
||||
public:
|
||||
Layer(uint32_t numUnits = 0)
|
||||
Layer(uint32_t numUnits = 0, const double *pStatesInit = nullptr)
|
||||
: m_numUnits(numUnits)
|
||||
, m_pInput(nullptr)
|
||||
, m_pProbs(nullptr)
|
||||
, m_pStates(nullptr)
|
||||
, m_pStatesInit(pStatesInit)
|
||||
{
|
||||
setNumUnits(numUnits);
|
||||
Noise_Init(&m_noise, 0x12345677);
|
||||
@@ -204,6 +57,10 @@ public:
|
||||
{
|
||||
m_pStates[i] = 0.0;
|
||||
}
|
||||
if (m_pStatesInit)
|
||||
{
|
||||
memcpy(m_pStates, m_pStatesInit, m_numUnits*sizeof(double));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,11 +68,8 @@ public:
|
||||
{
|
||||
memcpy(m_pProbs, rhs.m_pProbs, m_numUnits*sizeof(double));
|
||||
memcpy(m_pStates, rhs.m_pStates, m_numUnits*sizeof(double));
|
||||
}
|
||||
|
||||
void setInput(const double *pInput)
|
||||
{
|
||||
m_pInput = pInput;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void probsUpdate(const Layer &layer, const Weights &weights) const
|
||||
@@ -228,14 +82,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void statesAssignfromInput()
|
||||
{
|
||||
if (!m_pInput)
|
||||
return;
|
||||
|
||||
memcpy(m_pStates, m_pInput, m_numUnits*sizeof(double));
|
||||
}
|
||||
|
||||
void statesAssignfromProbs()
|
||||
{
|
||||
memcpy(m_pStates, m_pProbs, m_numUnits*sizeof(double));
|
||||
@@ -272,7 +118,6 @@ public:
|
||||
|
||||
private:
|
||||
uint32_t m_numUnits;
|
||||
const double *m_pInput;
|
||||
noise_gen_t m_noise;
|
||||
|
||||
inline double logSigmoid(double x) const
|
||||
@@ -283,6 +128,7 @@ private:
|
||||
protected:
|
||||
double *m_pProbs;
|
||||
double *m_pStates;
|
||||
const double *m_pStatesInit;
|
||||
|
||||
virtual double accum(const Layer &layer, const Weights &weights, uint32_t index) const = 0;
|
||||
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
LayerArray.hpp
|
||||
Created: 21 Sep 2014 1:55:15pm
|
||||
Author: jens
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef LAYERARRAY_HPP
|
||||
#define LAYERARRAY_HPP
|
||||
#include <cstdint>
|
||||
#include "VisibleLayer.hpp"
|
||||
|
||||
class VisibleLayerArray;
|
||||
|
||||
class VisibleLayerArrayListener
|
||||
{
|
||||
public:
|
||||
VisibleLayerArrayListener() {}
|
||||
virtual~VisibleLayerArrayListener() {}
|
||||
|
||||
virtual void onChanged(const VisibleLayerArray &obj) = 0;
|
||||
};
|
||||
|
||||
class VisibleLayerArray
|
||||
{
|
||||
class Entry : public VisibleLayer
|
||||
{
|
||||
public:
|
||||
Entry(uint32_t numUnits, const double *pInit)
|
||||
: VisibleLayer(numUnits, pInit)
|
||||
, pPrev(nullptr)
|
||||
, pNext(nullptr)
|
||||
{
|
||||
}
|
||||
~Entry()
|
||||
{
|
||||
}
|
||||
Entry *pPrev;
|
||||
Entry *pNext;
|
||||
private:
|
||||
};
|
||||
|
||||
public:
|
||||
VisibleLayerArray(VisibleLayerArrayListener *pListener = nullptr)
|
||||
: m_size(0)
|
||||
, m_pRoot(nullptr)
|
||||
, m_ppIndex(nullptr)
|
||||
, m_pListener(pListener)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~VisibleLayerArray()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void add(const double *pData, uint32_t size)
|
||||
{
|
||||
Entry *pL = m_pRoot;
|
||||
|
||||
if (!m_pRoot)
|
||||
{
|
||||
m_pRoot = new Entry(size, pData);
|
||||
}
|
||||
else
|
||||
{
|
||||
pL = m_pRoot;
|
||||
while(pL->pNext)
|
||||
{
|
||||
pL = pL->pNext;
|
||||
}
|
||||
pL->pNext = new Entry(size, pData);
|
||||
pL->pNext->pPrev = pL;
|
||||
}
|
||||
rebuildIndex();
|
||||
if (m_pListener)
|
||||
m_pListener->onChanged(*this);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
// rebuildIndex();
|
||||
if (m_ppIndex)
|
||||
{
|
||||
for (int i=0; i < m_size; i++)
|
||||
{
|
||||
if (m_ppIndex[i])
|
||||
delete m_ppIndex[i];
|
||||
|
||||
m_ppIndex[i] = nullptr;
|
||||
}
|
||||
}
|
||||
m_ppIndex = nullptr;
|
||||
m_pRoot = nullptr;
|
||||
m_size = 0;
|
||||
allocIndex(0);
|
||||
if (m_pListener)
|
||||
m_pListener->onChanged(*this);
|
||||
}
|
||||
|
||||
VisibleLayer& getAt(uint32_t index)
|
||||
{
|
||||
return *m_ppIndex[index];
|
||||
}
|
||||
|
||||
void removeAt(uint32_t index)
|
||||
{
|
||||
if (m_ppIndex[index]->pPrev)
|
||||
{
|
||||
m_ppIndex[index]->pPrev->pNext = m_ppIndex[index]->pNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pRoot = m_ppIndex[index]->pNext;
|
||||
m_ppIndex[index]->pNext->pPrev = nullptr;
|
||||
}
|
||||
delete m_ppIndex[index];
|
||||
m_ppIndex[index] = nullptr;
|
||||
rebuildIndex();
|
||||
if (m_pListener)
|
||||
m_pListener->onChanged(*this);
|
||||
}
|
||||
|
||||
uint32_t getSize() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void save(const char *pFilename)
|
||||
{
|
||||
FILE *pFile;
|
||||
|
||||
pFile = fopen(pFilename,"w");
|
||||
|
||||
if (!pFile)
|
||||
return;
|
||||
|
||||
|
||||
fprintf(pFile, "%d\n", m_size);
|
||||
|
||||
uint32_t i, j;
|
||||
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
uint32_t numUnits = ((VisibleLayer*)m_ppIndex[i])->getNumUnits();
|
||||
fprintf(pFile, "%d\n", numUnits);
|
||||
|
||||
for (j=0; j < numUnits; j++)
|
||||
{
|
||||
fprintf(pFile, "%3.6f\n", ((VisibleLayer*)m_ppIndex[i])->getStates()[j]);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
void load(const char *pFilename)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
FILE *pFile;
|
||||
|
||||
pFile = fopen(pFilename,"r");
|
||||
|
||||
if (!pFile)
|
||||
return;
|
||||
|
||||
fscanf(pFile, "%d\n", &size);
|
||||
|
||||
uint32_t i, j;
|
||||
float v;
|
||||
double *pData;
|
||||
for (i=0; i < size; i++)
|
||||
{
|
||||
uint32_t numUnits;
|
||||
fscanf(pFile, "%d\n", &numUnits);
|
||||
pData = new double[numUnits];
|
||||
|
||||
for (j=0; j < numUnits; j++)
|
||||
{
|
||||
fscanf(pFile, "%f", &v);
|
||||
pData[j] = v;
|
||||
}
|
||||
add(pData, numUnits);
|
||||
delete [] pData;
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_size;
|
||||
Entry *m_pRoot;
|
||||
Entry **m_ppIndex;
|
||||
VisibleLayerArrayListener *m_pListener;
|
||||
void allocIndex(size_t size)
|
||||
{
|
||||
if (m_ppIndex)
|
||||
{
|
||||
delete [] m_ppIndex;
|
||||
m_ppIndex = nullptr;
|
||||
allocIndex(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
m_ppIndex = new Entry*[size];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rebuildIndex()
|
||||
{
|
||||
Entry *pL;
|
||||
uint32_t size;
|
||||
|
||||
size = 0;
|
||||
pL = m_pRoot;
|
||||
while(pL)
|
||||
{
|
||||
size++;
|
||||
pL = pL->pNext;
|
||||
}
|
||||
allocIndex(size);
|
||||
|
||||
size = 0;
|
||||
pL = m_pRoot;
|
||||
while(pL)
|
||||
{
|
||||
m_ppIndex[size++] = pL;
|
||||
pL = pL->pNext;
|
||||
}
|
||||
m_size = size;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#endif // LAYERARRAY_HPP
|
||||
+489
-72
@@ -18,30 +18,174 @@
|
||||
*/
|
||||
|
||||
//[Headers] You can add your own extra header files here...
|
||||
#include <Windows.h>
|
||||
//[/Headers]
|
||||
|
||||
#include "MainComponent.h"
|
||||
|
||||
|
||||
//[MiscUserDefs] You can add your own user definitions and misc code here...
|
||||
void mylog(const char* format, ...)
|
||||
{
|
||||
char log_buf[257];
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
vsprintf(log_buf, format, argptr);
|
||||
va_end(argptr);
|
||||
OutputDebugStringA (log_buf);
|
||||
}
|
||||
//[/MiscUserDefs]
|
||||
|
||||
//==============================================================================
|
||||
MainComponent::MainComponent ()
|
||||
: m_layers(this),
|
||||
m_pRbm(nullptr),
|
||||
Draw(nullptr),
|
||||
Draw2(nullptr),
|
||||
DrawWeights(nullptr)
|
||||
{
|
||||
addAndMakeVisible (textButton = new TextButton ("new button"));
|
||||
textButton->addListener (this);
|
||||
addAndMakeVisible (trainButton = new TextButton ("Train button"));
|
||||
trainButton->setButtonText (TRANS("Train"));
|
||||
trainButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (addButton = new TextButton ("Add button"));
|
||||
addButton->setButtonText (TRANS("Add"));
|
||||
addButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (patterSlider = new Slider ("Pattern slider"));
|
||||
patterSlider->setRange (0, 10, 1);
|
||||
patterSlider->setSliderStyle (Slider::LinearHorizontal);
|
||||
patterSlider->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20);
|
||||
patterSlider->addListener (this);
|
||||
|
||||
addAndMakeVisible (reconstructButton = new TextButton ("Reconstruct button"));
|
||||
reconstructButton->setButtonText (TRANS("Reconstruct"));
|
||||
reconstructButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (ShakeButton = new TextButton ("Shake button"));
|
||||
ShakeButton->setButtonText (TRANS("Shake"));
|
||||
ShakeButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (WeightsSlider = new Slider ("Weights slider"));
|
||||
WeightsSlider->setRange (0, 10, 1);
|
||||
WeightsSlider->setSliderStyle (Slider::LinearHorizontal);
|
||||
WeightsSlider->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20);
|
||||
WeightsSlider->addListener (this);
|
||||
|
||||
addAndMakeVisible (numEpochslabel = new Label ("Num Epochs label",
|
||||
TRANS("99999")));
|
||||
numEpochslabel->setFont (Font (15.00f, Font::plain));
|
||||
numEpochslabel->setJustificationType (Justification::centred);
|
||||
numEpochslabel->setEditable (true, true, false);
|
||||
numEpochslabel->setColour (TextEditor::textColourId, Colours::black);
|
||||
numEpochslabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
|
||||
numEpochslabel->addListener (this);
|
||||
|
||||
addAndMakeVisible (learningRateLabel = new Label ("Learning Rate label",
|
||||
TRANS("0.001")));
|
||||
learningRateLabel->setFont (Font (15.00f, Font::plain));
|
||||
learningRateLabel->setJustificationType (Justification::centred);
|
||||
learningRateLabel->setEditable (true, true, false);
|
||||
learningRateLabel->setColour (TextEditor::textColourId, Colours::black);
|
||||
learningRateLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
|
||||
learningRateLabel->addListener (this);
|
||||
|
||||
addAndMakeVisible (testButton = new TextButton ("Test button"));
|
||||
testButton->setButtonText (TRANS("Test"));
|
||||
testButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (numVisibleLabel = new Label ("Num Visible label",
|
||||
TRANS("99999")));
|
||||
numVisibleLabel->setFont (Font (15.00f, Font::plain));
|
||||
numVisibleLabel->setJustificationType (Justification::centred);
|
||||
numVisibleLabel->setEditable (true, true, false);
|
||||
numVisibleLabel->setColour (TextEditor::textColourId, Colours::black);
|
||||
numVisibleLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
|
||||
numVisibleLabel->addListener (this);
|
||||
|
||||
addAndMakeVisible (numHiddenLabel = new Label ("Num Hidden label",
|
||||
TRANS("99999")));
|
||||
numHiddenLabel->setFont (Font (15.00f, Font::plain));
|
||||
numHiddenLabel->setJustificationType (Justification::centred);
|
||||
numHiddenLabel->setEditable (true, true, false);
|
||||
numHiddenLabel->setColour (TextEditor::textColourId, Colours::black);
|
||||
numHiddenLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
|
||||
numHiddenLabel->addListener (this);
|
||||
|
||||
addAndMakeVisible (createButton = new TextButton ("Create button"));
|
||||
createButton->setButtonText (TRANS("Create"));
|
||||
createButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (projectNameLabel = new Label ("Project Name label",
|
||||
TRANS("ProjectName")));
|
||||
projectNameLabel->setFont (Font (15.00f, Font::plain));
|
||||
projectNameLabel->setJustificationType (Justification::centred);
|
||||
projectNameLabel->setEditable (true, true, false);
|
||||
projectNameLabel->setColour (TextEditor::textColourId, Colours::black);
|
||||
projectNameLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
|
||||
projectNameLabel->addListener (this);
|
||||
|
||||
addAndMakeVisible (loadButton = new TextButton ("Load button"));
|
||||
loadButton->setButtonText (TRANS("Load"));
|
||||
loadButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (saveButton = new TextButton ("Save button"));
|
||||
saveButton->setButtonText (TRANS("Save"));
|
||||
saveButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (numVisibleYLabel = new Label ("Num Visible Y label",
|
||||
TRANS("99999")));
|
||||
numVisibleYLabel->setFont (Font (15.00f, Font::plain));
|
||||
numVisibleYLabel->setJustificationType (Justification::centred);
|
||||
numVisibleYLabel->setEditable (true, true, false);
|
||||
numVisibleYLabel->setColour (TextEditor::textColourId, Colours::black);
|
||||
numVisibleYLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
|
||||
numVisibleYLabel->addListener (this);
|
||||
|
||||
addAndMakeVisible (loadTrainingButton = new TextButton ("Load Training button"));
|
||||
loadTrainingButton->setButtonText (TRANS("Load T"));
|
||||
loadTrainingButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (saveTrainingButton = new TextButton ("Save Training button"));
|
||||
saveTrainingButton->setButtonText (TRANS("Save T"));
|
||||
saveTrainingButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (clearTrainingButton = new TextButton ("Clear Training button"));
|
||||
clearTrainingButton->setButtonText (TRANS("Clear T"));
|
||||
clearTrainingButton->addListener (this);
|
||||
|
||||
addAndMakeVisible (removeTrainingButton = new TextButton ("Remove Training button"));
|
||||
removeTrainingButton->setButtonText (TRANS("Remove T"));
|
||||
removeTrainingButton->addListener (this);
|
||||
|
||||
|
||||
//[UserPreSize]
|
||||
addAndMakeVisible (Draw = new DrawComponent (4, 4, 32));
|
||||
m_vNumX = 16;
|
||||
m_vNumY = 16;
|
||||
m_hNum = 64;
|
||||
m_vNumX_next = 16;
|
||||
m_vNumY_next = 16;
|
||||
m_hNum_next = 64;
|
||||
|
||||
// m_pWeights = new Weights(m_vNumX*m_vNumY, m_hNum);
|
||||
// m_pWeights = new Weights("C:\\Dokumente und Einstellungen\\Jens\\Desktop\\weights.dat");
|
||||
m_weights.load("C:\\Dokumente und Einstellungen\\Jens\\Desktop\\weights.dat");
|
||||
m_layers.load("C:\\Dokumente und Einstellungen\\Jens\\Desktop\\training_states.dat");
|
||||
create();
|
||||
|
||||
//[/UserPreSize]
|
||||
|
||||
setSize (600, 400);
|
||||
|
||||
|
||||
//[Constructor] You can add your own custom stuff here..
|
||||
m_pRbm = new Rbm(16, 4);
|
||||
|
||||
projectNameLabel->setText(String("TestPrj"), dontSendNotification );
|
||||
numVisibleLabel->setText(String(m_vNumX), dontSendNotification );
|
||||
numVisibleYLabel->setText(String(m_vNumY), dontSendNotification );
|
||||
numHiddenLabel->setText(String(m_hNum), dontSendNotification );
|
||||
numEpochslabel->setText(String(1000), dontSendNotification );
|
||||
learningRateLabel->setText(String(0.2), dontSendNotification );
|
||||
//[/Constructor]
|
||||
}
|
||||
|
||||
@@ -50,12 +194,34 @@ MainComponent::~MainComponent()
|
||||
//[Destructor_pre]. You can add your own custom destruction code here..
|
||||
//[/Destructor_pre]
|
||||
|
||||
textButton = nullptr;
|
||||
trainButton = nullptr;
|
||||
addButton = nullptr;
|
||||
patterSlider = nullptr;
|
||||
reconstructButton = nullptr;
|
||||
ShakeButton = nullptr;
|
||||
WeightsSlider = nullptr;
|
||||
numEpochslabel = nullptr;
|
||||
learningRateLabel = nullptr;
|
||||
testButton = nullptr;
|
||||
numVisibleLabel = nullptr;
|
||||
numHiddenLabel = nullptr;
|
||||
createButton = nullptr;
|
||||
projectNameLabel = nullptr;
|
||||
loadButton = nullptr;
|
||||
saveButton = nullptr;
|
||||
numVisibleYLabel = nullptr;
|
||||
loadTrainingButton = nullptr;
|
||||
saveTrainingButton = nullptr;
|
||||
clearTrainingButton = nullptr;
|
||||
removeTrainingButton = nullptr;
|
||||
|
||||
|
||||
//[Destructor]. You can add your own custom destruction code here..
|
||||
Draw = nullptr;
|
||||
Draw2 = nullptr;
|
||||
DrawWeights = nullptr;
|
||||
m_pRbm = nullptr;
|
||||
|
||||
//[/Destructor]
|
||||
}
|
||||
|
||||
@@ -73,86 +239,268 @@ void MainComponent::paint (Graphics& g)
|
||||
|
||||
void MainComponent::resized()
|
||||
{
|
||||
textButton->setBounds (72, 312, 150, 24);
|
||||
trainButton->setBounds (120, 280, 72, 24);
|
||||
addButton->setBounds (24, 176, 72, 24);
|
||||
patterSlider->setBounds (224, 280, 184, 24);
|
||||
reconstructButton->setBounds (24, 280, 72, 24);
|
||||
ShakeButton->setBounds (120, 320, 72, 24);
|
||||
WeightsSlider->setBounds (224, 320, 184, 24);
|
||||
numEpochslabel->setBounds (24, 248, 72, 24);
|
||||
learningRateLabel->setBounds (120, 248, 72, 24);
|
||||
testButton->setBounds (120, 176, 72, 24);
|
||||
numVisibleLabel->setBounds (440, 256, 72, 24);
|
||||
numHiddenLabel->setBounds (488, 288, 72, 24);
|
||||
createButton->setBounds (488, 320, 72, 24);
|
||||
projectNameLabel->setBounds (472, 224, 96, 24);
|
||||
loadButton->setBounds (440, 192, 72, 24);
|
||||
saveButton->setBounds (520, 192, 72, 24);
|
||||
numVisibleYLabel->setBounds (512, 256, 72, 24);
|
||||
loadTrainingButton->setBounds (440, 48, 72, 24);
|
||||
saveTrainingButton->setBounds (520, 48, 72, 24);
|
||||
clearTrainingButton->setBounds (520, 88, 72, 24);
|
||||
removeTrainingButton->setBounds (440, 88, 72, 24);
|
||||
//[UserResized] Add your own custom resize handling here..
|
||||
Draw->setBounds (16, 16, 336, 232);
|
||||
Draw->setBounds (16, 16, 100, 100);
|
||||
Draw2->setBounds (110+16, 16, 100, 100);
|
||||
DrawWeights->setBounds (220+16, 16, 100, 100);
|
||||
//[/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)
|
||||
if (buttonThatWasClicked == trainButton)
|
||||
{
|
||||
//[UserButtonCode_textButton] -- add your button handler code here..
|
||||
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]
|
||||
//[UserButtonCode_trainButton] -- add your button handler code here..
|
||||
m_pRbm->train(m_layers, numEpochslabel->getText().getIntValue(), learningRateLabel->getText().getFloatValue());
|
||||
//[/UserButtonCode_trainButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == addButton)
|
||||
{
|
||||
//[UserButtonCode_addButton] -- add your button handler code here..
|
||||
Draw2->setData(Draw->getData());
|
||||
for (int i=0; i < m_vNumX*m_vNumY; i++)
|
||||
{
|
||||
mylog("%3.6f\n", Draw->getData()[i]);
|
||||
}
|
||||
m_layers.add(Draw->getData(), m_vNumX*m_vNumY);
|
||||
patterSlider->setRange (0, m_layers.getSize()-1, 1);
|
||||
//[/UserButtonCode_addButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == reconstructButton)
|
||||
{
|
||||
//[UserButtonCode_reconstructButton] -- add your button handler code here..
|
||||
Draw2->setData(m_pRbm->toVisible(m_pRbm->toHidden(Draw->getData())));
|
||||
//[/UserButtonCode_reconstructButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == ShakeButton)
|
||||
{
|
||||
//[UserButtonCode_ShakeButton] -- add your button handler code here..
|
||||
m_weights.shuffle(0.01);
|
||||
//[/UserButtonCode_ShakeButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == testButton)
|
||||
{
|
||||
//[UserButtonCode_testButton] -- add your button handler code here..
|
||||
Draw->setData(Draw2->getData());
|
||||
//[/UserButtonCode_testButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == createButton)
|
||||
{
|
||||
//[UserButtonCode_createButton] -- add your button handler code here..
|
||||
m_vNumX = m_vNumX_next;
|
||||
m_vNumY = m_vNumY_next;
|
||||
m_hNum = m_hNum_next;
|
||||
numVisibleLabel->setText(String(m_vNumX), dontSendNotification );
|
||||
numVisibleYLabel->setText(String(m_vNumY), dontSendNotification );
|
||||
numHiddenLabel->setText(String(m_hNum), dontSendNotification );
|
||||
m_weights.setUnits(m_vNumX*m_vNumY, m_hNum);
|
||||
create();
|
||||
//[/UserButtonCode_createButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == loadButton)
|
||||
{
|
||||
//[UserButtonCode_loadButton] -- add your button handler code here..
|
||||
load();
|
||||
//[/UserButtonCode_loadButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == saveButton)
|
||||
{
|
||||
//[UserButtonCode_saveButton] -- add your button handler code here..
|
||||
save();
|
||||
//[/UserButtonCode_saveButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == loadTrainingButton)
|
||||
{
|
||||
//[UserButtonCode_loadTrainingButton] -- add your button handler code here..
|
||||
m_layers.clear();
|
||||
m_layers.load((String(getBaseDir() + String(".trainingStates.dat"))).toUTF8());
|
||||
//[/UserButtonCode_loadTrainingButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == saveTrainingButton)
|
||||
{
|
||||
//[UserButtonCode_saveTrainingButton] -- add your button handler code here..
|
||||
m_layers.save((String(getBaseDir() + String(".trainingStates.dat"))).toUTF8());
|
||||
//[/UserButtonCode_saveTrainingButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == clearTrainingButton)
|
||||
{
|
||||
//[UserButtonCode_clearTrainingButton] -- add your button handler code here..
|
||||
m_layers.clear();
|
||||
//[/UserButtonCode_clearTrainingButton]
|
||||
}
|
||||
else if (buttonThatWasClicked == removeTrainingButton)
|
||||
{
|
||||
//[UserButtonCode_removeTrainingButton] -- add your button handler code here..
|
||||
m_layers.removeAt((int)patterSlider->getValue());
|
||||
//[/UserButtonCode_removeTrainingButton]
|
||||
}
|
||||
|
||||
//[UserbuttonClicked_Post]
|
||||
//[/UserbuttonClicked_Post]
|
||||
}
|
||||
|
||||
void MainComponent::sliderValueChanged (Slider* sliderThatWasMoved)
|
||||
{
|
||||
//[UsersliderValueChanged_Pre]
|
||||
//[/UsersliderValueChanged_Pre]
|
||||
|
||||
if (sliderThatWasMoved == patterSlider)
|
||||
{
|
||||
//[UserSliderCode_patterSlider] -- add your slider handling code here..
|
||||
if (m_layers.getSize() > 0)
|
||||
{
|
||||
VisibleLayer &p = m_layers.getAt((int)sliderThatWasMoved->getValue());
|
||||
Draw2->setData(p.getStates());
|
||||
}
|
||||
//[/UserSliderCode_patterSlider]
|
||||
}
|
||||
else if (sliderThatWasMoved == WeightsSlider)
|
||||
{
|
||||
//[UserSliderCode_WeightsSlider] -- add your slider handling code here..
|
||||
double *pW = m_weights.getWeights()[(int)sliderThatWasMoved->getValue()];
|
||||
ScopedPointer<double> pTemp = new double [m_vNumX*m_vNumY];
|
||||
double min = +1E12;
|
||||
double max = -1E12;
|
||||
|
||||
for (int i=0; i < m_vNumX*m_vNumY; i++)
|
||||
{
|
||||
pTemp[i] = pW[i];
|
||||
min = std::min<double>(min, pW[i]);
|
||||
max = std::max<double>(max, pW[i]);
|
||||
}
|
||||
for (int i=0; i < m_vNumX*m_vNumY; i++)
|
||||
{
|
||||
pTemp[i] -= min;
|
||||
}
|
||||
for (int i=0; i < m_vNumX*m_vNumY; i++)
|
||||
{
|
||||
pTemp[i] /= (max-min);
|
||||
}
|
||||
|
||||
DrawWeights->setData(pTemp);
|
||||
//[/UserSliderCode_WeightsSlider]
|
||||
}
|
||||
|
||||
//[UsersliderValueChanged_Post]
|
||||
//[/UsersliderValueChanged_Post]
|
||||
}
|
||||
|
||||
void MainComponent::labelTextChanged (Label* labelThatHasChanged)
|
||||
{
|
||||
//[UserlabelTextChanged_Pre]
|
||||
//[/UserlabelTextChanged_Pre]
|
||||
|
||||
if (labelThatHasChanged == numEpochslabel)
|
||||
{
|
||||
//[UserLabelCode_numEpochslabel] -- add your label text handling code here..
|
||||
//[/UserLabelCode_numEpochslabel]
|
||||
}
|
||||
else if (labelThatHasChanged == learningRateLabel)
|
||||
{
|
||||
//[UserLabelCode_learningRateLabel] -- add your label text handling code here..
|
||||
//[/UserLabelCode_learningRateLabel]
|
||||
}
|
||||
else if (labelThatHasChanged == numVisibleLabel)
|
||||
{
|
||||
//[UserLabelCode_numVisibleLabel] -- add your label text handling code here..
|
||||
m_vNumX_next = labelThatHasChanged->getText().getIntValue();
|
||||
//[/UserLabelCode_numVisibleLabel]
|
||||
}
|
||||
else if (labelThatHasChanged == numHiddenLabel)
|
||||
{
|
||||
//[UserLabelCode_numHiddenLabel] -- add your label text handling code here..
|
||||
m_hNum_next = labelThatHasChanged->getText().getIntValue();
|
||||
//[/UserLabelCode_numHiddenLabel]
|
||||
}
|
||||
else if (labelThatHasChanged == projectNameLabel)
|
||||
{
|
||||
//[UserLabelCode_projectNameLabel] -- add your label text handling code here..
|
||||
//[/UserLabelCode_projectNameLabel]
|
||||
}
|
||||
else if (labelThatHasChanged == numVisibleYLabel)
|
||||
{
|
||||
//[UserLabelCode_numVisibleYLabel] -- add your label text handling code here..
|
||||
m_vNumY_next = labelThatHasChanged->getText().getIntValue();
|
||||
//[/UserLabelCode_numVisibleYLabel]
|
||||
}
|
||||
|
||||
//[UserlabelTextChanged_Post]
|
||||
//[/UserlabelTextChanged_Post]
|
||||
}
|
||||
|
||||
|
||||
|
||||
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
|
||||
void MainComponent::load ()
|
||||
{
|
||||
m_weights.load((String(getBaseDir() + String(".weights.dat"))).toUTF8());
|
||||
m_layers.clear();
|
||||
m_layers.load((String(getBaseDir() + String(".trainingStates.dat"))).toUTF8());
|
||||
|
||||
m_vNumX = m_vNumY = (int)sqrt((float)m_weights.getNumVisible());
|
||||
m_hNum = m_weights.getNumHidden();
|
||||
create();
|
||||
}
|
||||
|
||||
void MainComponent::save ()
|
||||
{
|
||||
m_weights.save((String(getBaseDir() + String(".weights.dat"))).toUTF8());
|
||||
}
|
||||
|
||||
void MainComponent::create()
|
||||
{
|
||||
Draw = nullptr;
|
||||
Draw2 = nullptr;
|
||||
DrawWeights = nullptr;
|
||||
m_pRbm = nullptr;
|
||||
addAndMakeVisible (Draw = new DrawComponent (m_vNumX, m_vNumX));
|
||||
addAndMakeVisible (Draw2 = new DrawComponent (m_vNumX, m_vNumX));
|
||||
addAndMakeVisible (DrawWeights = new DrawComponent (m_vNumX, m_vNumX));
|
||||
m_pRbm = new Rbm(m_weights);
|
||||
WeightsSlider->setRange(0, m_hNum-1, 1);
|
||||
resized();
|
||||
}
|
||||
|
||||
void MainComponent::destroy()
|
||||
{
|
||||
}
|
||||
|
||||
const juce::String& MainComponent::getBaseDir()
|
||||
{
|
||||
static String baseDir(String("C:\\Dokumente und Einstellungen\\Jens\\Desktop\\") + projectNameLabel->getText());
|
||||
|
||||
return baseDir;
|
||||
|
||||
}
|
||||
|
||||
void MainComponent::onChanged(const VisibleLayerArray &obj)
|
||||
{
|
||||
patterSlider->setRange(0, std::max(0,(int)m_layers.getSize()-1), 1);
|
||||
}
|
||||
|
||||
//[/MiscUserCode]
|
||||
|
||||
|
||||
@@ -166,16 +514,85 @@ void MainComponent::buttonClicked (Button* buttonThatWasClicked)
|
||||
BEGIN_JUCER_METADATA
|
||||
|
||||
<JUCER_COMPONENT documentType="Component" className="MainComponent" componentName=""
|
||||
parentClasses="public Component" constructorParams="" variableInitialisers=""
|
||||
parentClasses="public Component, public VisibleLayerArrayListener"
|
||||
constructorParams="" variableInitialisers="m_layers(this), m_pRbm(nullptr) Draw(nullptr), Draw2(nullptr), DrawWeights(nullptr)"
|
||||
snapPixels="8" snapActive="1" snapShown="1" overlayOpacity="0.330"
|
||||
fixedSize="1" initialWidth="600" initialHeight="400">
|
||||
<BACKGROUND backgroundColour="ffffffff"/>
|
||||
<TEXTBUTTON name="new button" id="7909d74b5522987c" memberName="textButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="72 312 150 24" buttonText="new button"
|
||||
<TEXTBUTTON name="Train button" id="7909d74b5522987c" memberName="trainButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="120 280 72 24" buttonText="Train"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<TEXTBUTTON name="Add button" id="4609f7b526ec1aef" memberName="addButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="24 176 72 24" buttonText="Add"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<SLIDER name="Pattern slider" id="c3e0a2c816db81d1" memberName="patterSlider"
|
||||
virtualName="" explicitFocusOrder="0" pos="224 280 184 24" min="0"
|
||||
max="10" int="1" style="LinearHorizontal" textBoxPos="TextBoxLeft"
|
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
|
||||
<TEXTBUTTON name="Reconstruct button" id="c1901d121a5819d6" memberName="reconstructButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="24 280 72 24" buttonText="Reconstruct"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<TEXTBUTTON name="Shake button" id="7fa4964a9a9ed199" memberName="ShakeButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="120 320 72 24" buttonText="Shake"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<SLIDER name="Weights slider" id="699075a1fc01458a" memberName="WeightsSlider"
|
||||
virtualName="" explicitFocusOrder="0" pos="224 320 184 24" min="0"
|
||||
max="10" int="1" style="LinearHorizontal" textBoxPos="TextBoxLeft"
|
||||
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
|
||||
<LABEL name="Num Epochs label" id="b23ae372ee931474" memberName="numEpochslabel"
|
||||
virtualName="" explicitFocusOrder="0" pos="24 248 72 24" edTextCol="ff000000"
|
||||
edBkgCol="0" labelText="99999" editableSingleClick="1" editableDoubleClick="1"
|
||||
focusDiscardsChanges="0" fontname="Default font" fontsize="15"
|
||||
bold="0" italic="0" justification="36"/>
|
||||
<LABEL name="Learning Rate label" id="49611a27914e910d" memberName="learningRateLabel"
|
||||
virtualName="" explicitFocusOrder="0" pos="120 248 72 24" edTextCol="ff000000"
|
||||
edBkgCol="0" labelText="0.001" editableSingleClick="1" editableDoubleClick="1"
|
||||
focusDiscardsChanges="0" fontname="Default font" fontsize="15"
|
||||
bold="0" italic="0" justification="36"/>
|
||||
<TEXTBUTTON name="Test button" id="a1e6fed732ae7ee1" memberName="testButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="120 176 72 24" buttonText="Test"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<LABEL name="Num Visible label" id="60acd702770b77dd" memberName="numVisibleLabel"
|
||||
virtualName="" explicitFocusOrder="0" pos="440 256 72 24" edTextCol="ff000000"
|
||||
edBkgCol="0" labelText="99999" editableSingleClick="1" editableDoubleClick="1"
|
||||
focusDiscardsChanges="0" fontname="Default font" fontsize="15"
|
||||
bold="0" italic="0" justification="36"/>
|
||||
<LABEL name="Num Hidden label" id="8a56c0419bd3ce86" memberName="numHiddenLabel"
|
||||
virtualName="" explicitFocusOrder="0" pos="488 288 72 24" edTextCol="ff000000"
|
||||
edBkgCol="0" labelText="99999" editableSingleClick="1" editableDoubleClick="1"
|
||||
focusDiscardsChanges="0" fontname="Default font" fontsize="15"
|
||||
bold="0" italic="0" justification="36"/>
|
||||
<TEXTBUTTON name="Create button" id="6c71593a581844eb" memberName="createButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="488 320 72 24" buttonText="Create"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<LABEL name="Project Name label" id="b4e855167abdac6b" memberName="projectNameLabel"
|
||||
virtualName="" explicitFocusOrder="0" pos="472 224 96 24" edTextCol="ff000000"
|
||||
edBkgCol="0" labelText="ProjectName" editableSingleClick="1"
|
||||
editableDoubleClick="1" focusDiscardsChanges="0" fontname="Default font"
|
||||
fontsize="15" bold="0" italic="0" justification="36"/>
|
||||
<TEXTBUTTON name="Load button" id="4e606c77b12e7d11" memberName="loadButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="440 192 72 24" buttonText="Load"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<TEXTBUTTON name="Save button" id="c435e774a51e39bf" memberName="saveButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="520 192 72 24" buttonText="Save"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<LABEL name="Num Visible Y label" id="101a4f77ca2445ba" memberName="numVisibleYLabel"
|
||||
virtualName="" explicitFocusOrder="0" pos="512 256 72 24" edTextCol="ff000000"
|
||||
edBkgCol="0" labelText="99999" editableSingleClick="1" editableDoubleClick="1"
|
||||
focusDiscardsChanges="0" fontname="Default font" fontsize="15"
|
||||
bold="0" italic="0" justification="36"/>
|
||||
<TEXTBUTTON name="Load Training button" id="c603a32c128de05d" memberName="loadTrainingButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="440 48 72 24" buttonText="Load T"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<TEXTBUTTON name="Save Training button" id="8e665b97490357c4" memberName="saveTrainingButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="520 48 72 24" buttonText="Save T"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<TEXTBUTTON name="Clear Training button" id="b4c148828519c013" memberName="clearTrainingButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="520 88 72 24" buttonText="Clear T"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<TEXTBUTTON name="Remove Training button" id="f0e1d068c39986f3" memberName="removeTrainingButton"
|
||||
virtualName="" explicitFocusOrder="0" pos="440 88 72 24" buttonText="Remove T"
|
||||
connectedEdges="0" needsCallback="1" radioGroupId="0"/>
|
||||
<JUCERCOMP name="" id="5843cf32f5b9956c" memberName="Draw" virtualName=""
|
||||
explicitFocusOrder="0" pos="16 16 336 232" sourceFile="DrawComponent.cpp"
|
||||
constructorParams="200, 200, 2"/>
|
||||
</JUCER_COMPONENT>
|
||||
|
||||
END_JUCER_METADATA
|
||||
|
||||
+46
-4
@@ -22,10 +22,11 @@
|
||||
|
||||
//[Headers] -- You can add your own extra header files here --
|
||||
#include "JuceHeader.h"
|
||||
#include "DrawComponent.h"
|
||||
#include "LayerArray.hpp"
|
||||
#include "Rbm.hpp"
|
||||
//[/Headers]
|
||||
|
||||
#include "DrawComponent.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
@@ -37,7 +38,10 @@
|
||||
//[/Comments]
|
||||
*/
|
||||
class MainComponent : public Component,
|
||||
public ButtonListener
|
||||
public VisibleLayerArrayListener,
|
||||
public ButtonListener,
|
||||
public SliderListener,
|
||||
public LabelListener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -51,17 +55,55 @@ public:
|
||||
void paint (Graphics& g);
|
||||
void resized();
|
||||
void buttonClicked (Button* buttonThatWasClicked);
|
||||
void sliderValueChanged (Slider* sliderThatWasMoved);
|
||||
void labelTextChanged (Label* labelThatHasChanged);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
//[UserVariables] -- You can add your own custom variables in this section.
|
||||
ScopedPointer<Rbm> m_pRbm;
|
||||
Weights m_weights;
|
||||
ScopedPointer<Rbm> m_pRbm;
|
||||
ScopedPointer<DrawComponent> Draw;
|
||||
ScopedPointer<DrawComponent> Draw2;
|
||||
ScopedPointer<DrawComponent> DrawWeights;
|
||||
Array<VisibleLayer>m_trainingData;
|
||||
uint32_t m_vNumX;
|
||||
uint32_t m_vNumY;
|
||||
uint32_t m_hNum;
|
||||
uint32_t m_vNumX_next;
|
||||
uint32_t m_vNumY_next;
|
||||
uint32_t m_hNum_next;
|
||||
VisibleLayerArray m_layers;
|
||||
void load();
|
||||
void save();
|
||||
void create();
|
||||
void destroy();
|
||||
const juce::String& getBaseDir();
|
||||
void onChanged(const VisibleLayerArray &obj);
|
||||
//[/UserVariables]
|
||||
|
||||
//==============================================================================
|
||||
ScopedPointer<TextButton> textButton;
|
||||
ScopedPointer<TextButton> trainButton;
|
||||
ScopedPointer<TextButton> addButton;
|
||||
ScopedPointer<Slider> patterSlider;
|
||||
ScopedPointer<TextButton> reconstructButton;
|
||||
ScopedPointer<TextButton> ShakeButton;
|
||||
ScopedPointer<Slider> WeightsSlider;
|
||||
ScopedPointer<Label> numEpochslabel;
|
||||
ScopedPointer<Label> learningRateLabel;
|
||||
ScopedPointer<TextButton> testButton;
|
||||
ScopedPointer<Label> numVisibleLabel;
|
||||
ScopedPointer<Label> numHiddenLabel;
|
||||
ScopedPointer<TextButton> createButton;
|
||||
ScopedPointer<Label> projectNameLabel;
|
||||
ScopedPointer<TextButton> loadButton;
|
||||
ScopedPointer<TextButton> saveButton;
|
||||
ScopedPointer<Label> numVisibleYLabel;
|
||||
ScopedPointer<TextButton> loadTrainingButton;
|
||||
ScopedPointer<TextButton> saveTrainingButton;
|
||||
ScopedPointer<TextButton> clearTrainingButton;
|
||||
ScopedPointer<TextButton> removeTrainingButton;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
||||
+67
-209
@@ -8,161 +8,63 @@
|
||||
#ifndef RBM_HPP_
|
||||
#define RBM_HPP_
|
||||
|
||||
#include "Layer.hpp"
|
||||
#include "VisibleLayer.hpp"
|
||||
#include "HiddenLayer.hpp"
|
||||
#include "Weights.hpp"
|
||||
#include <cmath>
|
||||
|
||||
class VisibleLayer : public Layer
|
||||
{
|
||||
public:
|
||||
VisibleLayer(uint32_t numUnits = 0)
|
||||
: Layer(numUnits)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~VisibleLayer()
|
||||
{
|
||||
}
|
||||
|
||||
double getEnergy(const Weights &weights)
|
||||
{
|
||||
uint32_t i;
|
||||
double energy = 0;
|
||||
|
||||
for (i=0; i < getNumUnits(); i++)
|
||||
{
|
||||
energy -= weights.getBiasVisible()[i] * getStates()[i];
|
||||
}
|
||||
return energy;
|
||||
}
|
||||
|
||||
private:
|
||||
double accum(const Layer &layer, const Weights &weights, uint32_t index) const
|
||||
{
|
||||
uint32_t i;
|
||||
double sum = weights.getBiasVisible()[index];
|
||||
const double *pStates = layer.getStates();
|
||||
|
||||
for (i=0; i < layer.getNumUnits(); i++)
|
||||
{
|
||||
sum += pStates[i] * weights.getWeights()[i][index];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
|
||||
class HiddenLayer : public Layer
|
||||
{
|
||||
public:
|
||||
HiddenLayer(uint32_t numUnits = 0)
|
||||
: Layer(numUnits)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~HiddenLayer()
|
||||
{
|
||||
}
|
||||
|
||||
double getEnergy(const Weights &weights)
|
||||
{
|
||||
uint32_t i;
|
||||
double energy = 0;
|
||||
|
||||
for (i=0; i < getNumUnits(); i++)
|
||||
{
|
||||
energy -= weights.getBiasHidden()[i] * getStates()[i];
|
||||
}
|
||||
return energy;
|
||||
}
|
||||
|
||||
private:
|
||||
double accum(const Layer &layer, const Weights &weights, uint32_t index) const
|
||||
{
|
||||
uint32_t i;
|
||||
double sum = weights.getBiasVisible()[index];
|
||||
const double *pStates = layer.getStates();
|
||||
|
||||
for (i=0; i < layer.getNumUnits(); i++)
|
||||
{
|
||||
sum += pStates[i] * weights.getWeights()[index][i];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
void mylog(const char* format, ...);
|
||||
#define printf mylog
|
||||
|
||||
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)
|
||||
, m_pVisibleTraining(nullptr)
|
||||
Rbm(Weights &weights)
|
||||
: m_w(weights)
|
||||
, m_tv(weights.getNumVisible())
|
||||
, m_th(weights.getNumHidden())
|
||||
{
|
||||
Noise_Init(&m_noise, 0x32727155);
|
||||
}
|
||||
|
||||
~Rbm()
|
||||
{
|
||||
freeTrainingPatterns();
|
||||
Noise_Free(&m_noise);
|
||||
}
|
||||
|
||||
void setTrainingInput(uint32_t index, const double *pValues)
|
||||
{
|
||||
if (!m_pVisibleTraining)
|
||||
return;
|
||||
|
||||
if (index >= m_numTrainingPatterns)
|
||||
return;
|
||||
|
||||
m_pVisibleTraining[index].setInput(pValues);
|
||||
m_pVisibleTraining[index].statesAssignfromInput();
|
||||
}
|
||||
|
||||
void setNumTrainingPatterns(uint32_t numTrainingPatterns)
|
||||
{
|
||||
m_numTrainingPatterns = numTrainingPatterns;
|
||||
allocTrainingPatterns();
|
||||
}
|
||||
|
||||
void weightsUpdate(VisibleLayer &v, VisibleLayer &vr, HiddenLayer &h, HiddenLayer &hr, double mu)
|
||||
{
|
||||
uint32_t i, j;
|
||||
double dw;
|
||||
|
||||
// Update weights
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
{
|
||||
dw = 0;
|
||||
for (j=0; j < m_numVisible; j++)
|
||||
for (j=0; j < m_w.getNumVisible(); j++)
|
||||
{
|
||||
dw = v.getStates()[j] * h.getStates()[i];
|
||||
m_w.getWeights()[i][j] += mu*dw;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
{
|
||||
dw = 0;
|
||||
for (j=0; j < m_numVisible; j++)
|
||||
for (j=0; j < m_w.getNumVisible(); j++)
|
||||
{
|
||||
dw = vr.getStates()[j] * hr.getStates()[i];
|
||||
m_w.getWeights()[i][j] -= mu*dw;
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
for (i=0; i < m_w.getNumVisible(); i++)
|
||||
{
|
||||
dw = v.getStates()[i] - vr.getStates()[i];
|
||||
m_w.getBiasVisible()[i] += mu*dw;
|
||||
}
|
||||
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
{
|
||||
dw = h.getStates()[i] - hr.getStates()[i];
|
||||
m_w.getBiasHidden()[i] += mu*dw;
|
||||
@@ -170,37 +72,36 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
void train(uint32_t numEpochs, double mu)
|
||||
void train(VisibleLayerArray &vts, uint32_t numEpochs, double mu)
|
||||
{
|
||||
uint32_t epoch;
|
||||
uint32_t trainingPatternIndex;
|
||||
VisibleLayer *pV;
|
||||
VisibleLayer vr(m_numVisible);
|
||||
HiddenLayer h(m_numHidden);
|
||||
HiddenLayer hr(m_numHidden);
|
||||
VisibleLayer vr(m_w.getNumVisible());
|
||||
HiddenLayer h(m_w.getNumHidden());
|
||||
HiddenLayer hr(m_w.getNumHidden());
|
||||
const uint32_t monitorInterval = 100; // epochs
|
||||
uint32_t monitorCount = monitorInterval; // epochs
|
||||
|
||||
for (epoch=0; epoch < numEpochs; epoch++)
|
||||
{
|
||||
trainingPatternIndex = (uint32_t)((m_numTrainingPatterns)*Noise_Uniform(&m_noise, 0.5));
|
||||
trainingPatternIndex = (uint32_t)((vts.getSize())*Noise_Uniform(&m_noise, 0.5));
|
||||
|
||||
if (trainingPatternIndex == m_numTrainingPatterns)
|
||||
if (trainingPatternIndex == vts.getSize())
|
||||
continue;
|
||||
|
||||
// Assign training data
|
||||
pV = &m_pVisibleTraining[trainingPatternIndex];
|
||||
VisibleLayer &vt = vts.getAt(trainingPatternIndex);
|
||||
|
||||
// Create hidden layer base on training data
|
||||
h.probsUpdate(*pV, m_w);
|
||||
h.probsUpdate(vt, m_w);
|
||||
// h.statesAssignfromProbs();
|
||||
h.statesUpdateStochastic();
|
||||
|
||||
// Create visible reconstruction (a fantasy...)
|
||||
vr = *pV;
|
||||
vr = vt;
|
||||
vr.probsUpdate(h, m_w);
|
||||
vr.statesAssignfromProbs();
|
||||
// vr.statesUpdateStochastic();
|
||||
// vr.statesAssignfromProbs();
|
||||
vr.statesUpdateStochastic();
|
||||
|
||||
// Create hidden reconstruction
|
||||
hr.probsUpdate(vr, m_w);
|
||||
@@ -208,7 +109,7 @@ public:
|
||||
hr.statesUpdateStochastic();
|
||||
|
||||
// Update weights
|
||||
weightsUpdate(*pV, vr, h, hr, mu);
|
||||
weightsUpdate(vt, vr, h, hr, mu);
|
||||
|
||||
if (!monitorCount)
|
||||
{
|
||||
@@ -237,27 +138,27 @@ public:
|
||||
return energy;
|
||||
}
|
||||
|
||||
void prob()
|
||||
void prob(VisibleLayerArray &vts)
|
||||
{
|
||||
uint32_t i, j;
|
||||
double z;
|
||||
double p;
|
||||
|
||||
HiddenLayer *h = new HiddenLayer[m_numTrainingPatterns];
|
||||
HiddenLayer *h = new HiddenLayer[vts.getSize()];
|
||||
|
||||
// Create hidden layer activations based on training data
|
||||
for (j=0; j < m_numTrainingPatterns; j++)
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
h[j].setNumUnits(m_numHidden);
|
||||
h[j].probsUpdate(m_pVisibleTraining[j], m_w);
|
||||
h[j].setNumUnits(m_w.getNumHidden());
|
||||
h[j].probsUpdate(vts.getAt(j), m_w);
|
||||
// h[j].statesAssignfromProbs();
|
||||
h[j].statesUpdateStochastic();
|
||||
}
|
||||
|
||||
printf("pi(t) = (pi^, v>)\n");
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
{
|
||||
for (j=0; j < m_numTrainingPatterns; j++)
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
p = h[j].getProbs()[i];
|
||||
printf("%3.6f ", p);
|
||||
@@ -267,9 +168,9 @@ public:
|
||||
printf("\n");
|
||||
|
||||
printf("si(t) = (si^, v>)\n");
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
{
|
||||
for (j=0; j < m_numTrainingPatterns; j++)
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
p = h[j].getStates()[i];
|
||||
printf("%3.6f ", p);
|
||||
@@ -279,16 +180,16 @@ public:
|
||||
printf("\n");
|
||||
|
||||
printf("p(v) = (t^, v>)\n");
|
||||
for (i=0; i < m_numTrainingPatterns; i++)
|
||||
for (i=0; i < vts.getSize(); i++)
|
||||
{
|
||||
z = 0;
|
||||
for (j=0; j < m_numTrainingPatterns; j++)
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
z += exp(-getEnergy(m_pVisibleTraining[j], h[i]));
|
||||
z += exp(-getEnergy(vts.getAt(j), h[i]));
|
||||
}
|
||||
for (j=0; j < m_numTrainingPatterns; j++)
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
p = exp(-getEnergy(m_pVisibleTraining[j], h[i]))/z;
|
||||
p = exp(-getEnergy(vts.getAt(j), h[i]))/z;
|
||||
printf("%3.6f ", p);
|
||||
}
|
||||
printf("\n");
|
||||
@@ -296,17 +197,17 @@ public:
|
||||
printf("\n");
|
||||
|
||||
// Reconstruct
|
||||
for (i=0; i < m_numTrainingPatterns; i++)
|
||||
for (i=0; i < vts.getSize(); i++)
|
||||
{
|
||||
m_pVisibleTraining[i].probsUpdate(h[i], m_w);
|
||||
vts.getAt(i).probsUpdate(h[i], m_w);
|
||||
}
|
||||
|
||||
printf("A fantasy... (v^, t>)\n");
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
for (i=0; i < m_w.getNumVisible(); i++)
|
||||
{
|
||||
for (j=0; j < m_numTrainingPatterns; j++)
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
p = m_pVisibleTraining[j].getProbs()[i];
|
||||
p = vts.getAt(j).getProbs()[i];
|
||||
printf("%3.6f ", p);
|
||||
}
|
||||
printf("\n");
|
||||
@@ -320,19 +221,22 @@ public:
|
||||
double p;
|
||||
uint32_t i;
|
||||
|
||||
tv.setInput(pVisible);
|
||||
tv.statesAssignfromInput();
|
||||
VisibleLayer tv(m_w.getNumVisible(), pVisible);
|
||||
|
||||
th.probsUpdate(tv, m_w);
|
||||
m_th.probsUpdate(tv, m_w);
|
||||
m_th.statesAssignfromProbs();
|
||||
// m_th.statesUpdateStochastic();
|
||||
|
||||
#if 0
|
||||
printf("pi(t) = (pi^, v>)\n");
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
{
|
||||
p = th.getProbs()[i];
|
||||
p = m_th.getProbs()[i];
|
||||
printf("%3.6f\n", p);
|
||||
}
|
||||
printf("\n");
|
||||
return th.getProbs();
|
||||
#endif
|
||||
return m_th.getStates();
|
||||
}
|
||||
|
||||
const double* toVisible(const double *pHidden)
|
||||
@@ -340,76 +244,30 @@ public:
|
||||
double p;
|
||||
uint32_t i;
|
||||
|
||||
th.setInput(pHidden);
|
||||
th.statesAssignfromInput();
|
||||
HiddenLayer th(m_w.getNumHidden(), pHidden);
|
||||
|
||||
tv.probsUpdate(th, m_w);
|
||||
m_tv.probsUpdate(th, m_w);
|
||||
m_tv.statesAssignfromProbs();
|
||||
// m_tv.statesUpdateStochastic();
|
||||
|
||||
#if 0
|
||||
printf("pi(t) = (pi^, v>)\n");
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
for (i=0; i < m_w.getNumVisible(); i++)
|
||||
{
|
||||
p = tv.getProbs()[i];
|
||||
p = m_tv.getProbs()[i];
|
||||
printf("%3.6f\n", p);
|
||||
}
|
||||
printf("\n");
|
||||
return tv.getProbs();
|
||||
#endif
|
||||
return m_tv.getStates();
|
||||
}
|
||||
|
||||
void weightsPrint()
|
||||
{
|
||||
m_w.print();
|
||||
}
|
||||
|
||||
void weightsShuffle(double stdDev)
|
||||
{
|
||||
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;
|
||||
VisibleLayer *m_pVisibleTraining;
|
||||
Weights &m_w;
|
||||
VisibleLayer m_tv;
|
||||
HiddenLayer m_th;
|
||||
noise_gen_t m_noise;
|
||||
|
||||
void allocTrainingPatterns()
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (m_pVisibleTraining)
|
||||
{
|
||||
freeTrainingPatterns();
|
||||
allocTrainingPatterns();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pVisibleTraining = new VisibleLayer[m_numTrainingPatterns];
|
||||
for (i=0; i < m_numTrainingPatterns; i++)
|
||||
{
|
||||
m_pVisibleTraining[i].setNumUnits(m_numVisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void freeTrainingPatterns()
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (m_pVisibleTraining)
|
||||
{
|
||||
delete [] m_pVisibleTraining;
|
||||
m_pVisibleTraining = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* VisibleLayer.hpp
|
||||
*
|
||||
* Created on: 21.09.2014
|
||||
* Author: jens
|
||||
*/
|
||||
|
||||
#ifndef VISIBLELAYER_HPP_
|
||||
#define VISIBLELAYER_HPP_
|
||||
|
||||
#include "Layer.hpp"
|
||||
#include <cmath>
|
||||
|
||||
class VisibleLayer : public Layer
|
||||
{
|
||||
public:
|
||||
VisibleLayer(uint32_t numUnits = 0, const double *pStatesInit = nullptr)
|
||||
: Layer(numUnits, pStatesInit)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~VisibleLayer()
|
||||
{
|
||||
}
|
||||
|
||||
double getEnergy(const Weights &weights)
|
||||
{
|
||||
uint32_t i;
|
||||
double energy = 0;
|
||||
|
||||
for (i=0; i < getNumUnits(); i++)
|
||||
{
|
||||
energy -= weights.getBiasVisible()[i] * getStates()[i];
|
||||
}
|
||||
return energy;
|
||||
}
|
||||
|
||||
private:
|
||||
double accum(const Layer &layer, const Weights &weights, uint32_t index) const
|
||||
{
|
||||
uint32_t i;
|
||||
double sum = weights.getBiasVisible()[index];
|
||||
const double *pStates = layer.getStates();
|
||||
|
||||
for (i=0; i < layer.getNumUnits(); i++)
|
||||
{
|
||||
sum += pStates[i] * weights.getWeights()[i][index];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* VISIBLELAYER_HPP_ */
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
Weights.hpp
|
||||
Created: 21 Sep 2014 1:55:15pm
|
||||
Author: jens
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef WEIGHTS_HPP
|
||||
#define WEIGHTS_HPP
|
||||
#include <cstdint>
|
||||
#include "noise.h"
|
||||
|
||||
class Weights
|
||||
{
|
||||
public:
|
||||
Weights(const char *pFilename)
|
||||
: m_ppW(nullptr)
|
||||
, m_pBiasVisible(nullptr)
|
||||
, m_pBiasHidden(nullptr)
|
||||
, m_numVisible(0)
|
||||
, m_numHidden(0)
|
||||
{
|
||||
load(pFilename);
|
||||
}
|
||||
|
||||
Weights(uint32_t numVisible, uint32_t numHidden)
|
||||
: m_ppW(nullptr)
|
||||
, m_pBiasVisible(nullptr)
|
||||
, m_pBiasHidden(nullptr)
|
||||
, m_numVisible(numVisible)
|
||||
, m_numHidden(numHidden)
|
||||
{
|
||||
alloc();
|
||||
Noise_Init(&m_noise, 0x32727155);
|
||||
|
||||
shuffle(0);
|
||||
}
|
||||
|
||||
Weights()
|
||||
: m_ppW(nullptr)
|
||||
, m_pBiasVisible(nullptr)
|
||||
, m_pBiasHidden(nullptr)
|
||||
, m_numVisible(0)
|
||||
, m_numHidden(0)
|
||||
{
|
||||
Noise_Init(&m_noise, 0x32727155);
|
||||
}
|
||||
|
||||
~Weights()
|
||||
{
|
||||
Noise_Free(&m_noise);
|
||||
free();
|
||||
}
|
||||
|
||||
void setUnits(uint32_t numVisible, uint32_t numHidden)
|
||||
{
|
||||
m_numVisible = numVisible;
|
||||
m_numHidden = numHidden;
|
||||
alloc();
|
||||
shuffle(0);
|
||||
}
|
||||
|
||||
void shuffle(double stdDev)
|
||||
{
|
||||
uint32_t i, j;
|
||||
double kdev = stdDev*sqrt(12.0);
|
||||
|
||||
for (j=0; j < m_numVisible; j++)
|
||||
{
|
||||
m_pBiasVisible[j] = kdev*Noise_Uniform(&m_noise, 0.5);
|
||||
}
|
||||
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
m_pBiasHidden[i] = kdev*Noise_Uniform(&m_noise, 0.5);
|
||||
}
|
||||
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
for (j=0; j < m_numVisible; j++)
|
||||
{
|
||||
m_ppW[i][j] = kdev*Noise_Uniform(&m_noise, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double **getWeights() const
|
||||
{
|
||||
return m_ppW;
|
||||
}
|
||||
|
||||
double *getBiasVisible() const
|
||||
{
|
||||
return m_pBiasVisible;
|
||||
}
|
||||
|
||||
double *getBiasHidden() const
|
||||
{
|
||||
return m_pBiasHidden;
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
uint32_t i, j;
|
||||
double w;
|
||||
|
||||
printf("\n");
|
||||
printf("w(v,h) = (v^, h>)\n");
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
{
|
||||
for (j=0; j < m_numHidden; j++)
|
||||
{
|
||||
w = m_ppW[j][i];
|
||||
printf("%3.6f ", w);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("bv = \n");
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
{
|
||||
w = m_pBiasVisible[i];
|
||||
printf("%3.6f\n", w);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("bh = \n");
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
w = m_pBiasHidden[i];
|
||||
printf("%3.6f\n", w);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
uint32_t getNumVisible()
|
||||
{
|
||||
return m_numVisible;
|
||||
}
|
||||
|
||||
uint32_t getNumHidden()
|
||||
{
|
||||
return m_numHidden;
|
||||
}
|
||||
|
||||
void save(const char *pFilename)
|
||||
{
|
||||
FILE *pFile;
|
||||
|
||||
pFile = fopen(pFilename,"w");
|
||||
|
||||
if (!pFile)
|
||||
return;
|
||||
|
||||
|
||||
fprintf(pFile, "%d %d\n", m_numVisible, m_numHidden);
|
||||
|
||||
uint32_t i, j;
|
||||
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
{
|
||||
fprintf(pFile, "%3.6f\n", m_pBiasVisible[i]);
|
||||
}
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
fprintf(pFile, "%3.6f\n", m_pBiasHidden[i]);
|
||||
}
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
{
|
||||
for (j=0; j < m_numHidden; j++)
|
||||
{
|
||||
fprintf(pFile, "%3.6f ", m_ppW[j][i]);
|
||||
}
|
||||
fprintf(pFile, "\n");
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
void load(const char *pFilename)
|
||||
{
|
||||
FILE *pFile;
|
||||
|
||||
pFile = fopen(pFilename,"r");
|
||||
|
||||
if (!pFile)
|
||||
return;
|
||||
|
||||
m_numVisible = m_numHidden = 0;
|
||||
fscanf(pFile, "%d %d\n", &m_numVisible, &m_numHidden);
|
||||
|
||||
alloc();
|
||||
|
||||
uint32_t i, j;
|
||||
float v;
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
{
|
||||
fscanf(pFile, "%f", &v);
|
||||
m_pBiasVisible[i] = v;
|
||||
}
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
fscanf(pFile, "%f", &v);
|
||||
m_pBiasHidden[i] = v;
|
||||
}
|
||||
for (i=0; i < m_numVisible; i++)
|
||||
{
|
||||
for (j=0; j < m_numHidden; j++)
|
||||
{
|
||||
|
||||
fscanf(pFile, "%f", &v);
|
||||
m_ppW[j][i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
private:
|
||||
double **m_ppW;
|
||||
double *m_pBiasVisible;
|
||||
double *m_pBiasHidden;
|
||||
uint32_t m_numVisible;
|
||||
uint32_t m_numHidden;
|
||||
noise_gen_t m_noise;
|
||||
|
||||
void alloc()
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (m_ppW)
|
||||
{
|
||||
free();
|
||||
alloc();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ppW = new double*[m_numHidden];
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
m_ppW[i] = new double[m_numVisible];
|
||||
}
|
||||
m_pBiasVisible = new double[m_numVisible];
|
||||
m_pBiasHidden = new double[m_numHidden];
|
||||
}
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
|
||||
if (m_ppW)
|
||||
{
|
||||
for (i=0; i < m_numHidden; i++)
|
||||
{
|
||||
delete [] m_ppW[i];
|
||||
}
|
||||
delete [] m_ppW;
|
||||
m_ppW = nullptr;
|
||||
}
|
||||
|
||||
delete [] m_pBiasVisible;
|
||||
m_pBiasVisible = nullptr;
|
||||
|
||||
delete [] m_pBiasHidden;
|
||||
m_pBiasHidden = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // WEIGHTS_HPP
|
||||
@@ -11,6 +11,7 @@
|
||||
#ifndef _NOISE_H_
|
||||
#define _NOISE_H_
|
||||
|
||||
#define __func__ ""
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user