- use Matrix, linear algebra library Eigen 3.2.2
git-svn-id: http://moon:8086/svn/software/trunk/projects/RBM@23 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
+67
-92
@@ -12,6 +12,9 @@
|
||||
#include "HiddenLayer.hpp"
|
||||
#include "Weights.hpp"
|
||||
#include <cmath>
|
||||
#include <Eigen/Dense>
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
void mylog(const char* format, ...);
|
||||
#define printf mylog
|
||||
@@ -47,35 +50,20 @@ public:
|
||||
|
||||
void weightsUpdate(VisibleLayer &v, HiddenLayer &h, double mu)
|
||||
{
|
||||
uint32_t i, j;
|
||||
double dw;
|
||||
|
||||
double **ppW = m_w.getWeights();
|
||||
const double *pH = h.getStates();
|
||||
const double *pV = v.getStates();
|
||||
MatrixXd &w = (MatrixXd&)m_w.weights();
|
||||
|
||||
// Update weights
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
{
|
||||
for (j=0; j < m_w.getNumVisible(); j++)
|
||||
{
|
||||
dw = pV[j] * pH[i];
|
||||
ppW[i][j] += mu*dw;
|
||||
}
|
||||
}
|
||||
double *pBias = m_w.getBiasVisible();
|
||||
for (i=0; i < m_w.getNumVisible(); i++)
|
||||
{
|
||||
dw = pV[i];
|
||||
pBias[i] += mu*dw;
|
||||
}
|
||||
w += mu*(v.states() * h.states().transpose());
|
||||
}
|
||||
|
||||
pBias = m_w.getBiasHidden();
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
{
|
||||
dw = pH[i];
|
||||
pBias[i] += mu*dw;
|
||||
}
|
||||
void visibleBiasUpdate(VisibleLayer &v, double mu)
|
||||
{
|
||||
m_w.visibleBias().array() += mu*v.states().array();
|
||||
}
|
||||
|
||||
void hiddenBiasUpdate(HiddenLayer &h, double mu)
|
||||
{
|
||||
m_w.hiddenBias().array() += mu*h.states().array();
|
||||
}
|
||||
|
||||
void train(LayerArray<VisibleLayer> &vt, uint32_t numEpochs, double mu, uint32_t numGibbs = 1, bool useExpectations = false, bool doRaoBlackwell = false, bool useProbsForHiddenReconstruction = false, bool doRobbinsMonro = false)
|
||||
@@ -93,6 +81,10 @@ public:
|
||||
double dProgress = 1.0/numEpochs;
|
||||
m_progress = 0;
|
||||
|
||||
const double lambda = 1.0;
|
||||
const double variance = 1.0;
|
||||
const double penalty = 0.0;
|
||||
|
||||
if (useExpectations)
|
||||
{
|
||||
mu /= vt.getSize();
|
||||
@@ -103,7 +95,7 @@ public:
|
||||
for (i=0; i < vt.getSize(); i++)
|
||||
{
|
||||
// Create hidden layer base on training data
|
||||
ht[i].probsUpdate(vt[i], w);
|
||||
ht[i].probsUpdate(vt[i], w, lambda, variance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +104,7 @@ public:
|
||||
for (i=0; i < vt.getSize(); i++)
|
||||
{
|
||||
t = (uint32_t)(0.5 + (vt.getSize()-1)*Noise_Uniform(&m_noise, 0.5));
|
||||
h.probsUpdate(vt[t], w);
|
||||
h.probsUpdate(vt[t], w, lambda, variance);
|
||||
|
||||
// Create hidden layer base on training data
|
||||
if (doRobbinsMonro)
|
||||
@@ -127,23 +119,25 @@ public:
|
||||
// Update weights (positive phase)
|
||||
if (doRaoBlackwell)
|
||||
{
|
||||
pH->statesAssignfromProbs();
|
||||
pH->states() = pH->probs();
|
||||
}
|
||||
else
|
||||
{
|
||||
pH->statesUpdateStochastic();
|
||||
}
|
||||
weightsUpdate(vt[t], h, +mu);
|
||||
visibleBiasUpdate(vt[t], +mu);
|
||||
hiddenBiasUpdate(h, +mu);
|
||||
|
||||
for (gibbs=0; gibbs < numGibbs; gibbs++)
|
||||
{
|
||||
pH->statesUpdateStochastic();
|
||||
|
||||
// Create visible reconstruction (a fantasy...)
|
||||
v.probsUpdate(*pH, w);
|
||||
v.probsUpdate(*pH, w, lambda, variance);
|
||||
if (useProbsForHiddenReconstruction)
|
||||
{
|
||||
v.statesAssignfromProbs();
|
||||
v.states() = v.probs();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -151,18 +145,20 @@ public:
|
||||
}
|
||||
|
||||
// Create hidden reconstruction
|
||||
pH->probsUpdate(v, w);
|
||||
pH->probsUpdate(v, w, lambda, variance);
|
||||
}
|
||||
// Update weights (negative phase)
|
||||
if (doRaoBlackwell)
|
||||
{
|
||||
pH->statesAssignfromProbs();
|
||||
pH->states() = pH->probs();
|
||||
}
|
||||
else
|
||||
{
|
||||
pH->statesUpdateStochastic();
|
||||
}
|
||||
weightsUpdate(v, *pH, -mu);
|
||||
visibleBiasUpdate(v, -mu);
|
||||
hiddenBiasUpdate(*pH, -mu);
|
||||
|
||||
if (!useExpectations)
|
||||
{
|
||||
@@ -170,11 +166,28 @@ public:
|
||||
}
|
||||
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
HiddenLayer th(m_w.getNumHidden());
|
||||
for (i=0; i < vt.getSize(); i++)
|
||||
{
|
||||
ht[i].probsUpdate(vt[t], w, lambda, variance);
|
||||
ht[i].statesUpdateStochastic();
|
||||
th += ht[i];
|
||||
}
|
||||
th *= 1.0/vt.getSize();
|
||||
th += -0.02;
|
||||
hiddenBiasUpdate(th, -mu);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (useExpectations)
|
||||
{
|
||||
w = m_w;
|
||||
}
|
||||
|
||||
getEnergy(v, *pH);
|
||||
|
||||
m_progress += dProgress;
|
||||
if (m_pListener)
|
||||
{
|
||||
@@ -199,9 +212,12 @@ public:
|
||||
{
|
||||
for (j=0; j < v.getNumUnits(); j++)
|
||||
{
|
||||
energy -= v.getStates()[j] * h.getStates()[i] * m_w.getWeights()[i][j];
|
||||
// energy -= v.getStates()[j] * h.getStates()[i] * m_w.getWeights()[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// ToDo: make this correct
|
||||
// energy -= (v.states().transpose() * h.states()); // * m_w.weights();
|
||||
return energy;
|
||||
}
|
||||
|
||||
@@ -223,28 +239,18 @@ public:
|
||||
}
|
||||
|
||||
printf("pi(t) = (pi^, v>)\n");
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
p = h[j].getProbs()[i];
|
||||
printf("%3.6f ", p);
|
||||
}
|
||||
printf("\n");
|
||||
cout << h[j].probs() << endl;
|
||||
}
|
||||
printf("\n");
|
||||
cout << endl;
|
||||
|
||||
printf("si(t) = (si^, v>)\n");
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
p = h[j].getStates()[i];
|
||||
printf("%3.6f ", p);
|
||||
}
|
||||
printf("\n");
|
||||
cout << h[j].states() << endl;
|
||||
}
|
||||
printf("\n");
|
||||
cout << endl;
|
||||
|
||||
printf("p(v) = (t^, v>)\n");
|
||||
for (i=0; i < vts.getSize(); i++)
|
||||
@@ -257,11 +263,11 @@ public:
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
p = exp(-getEnergy(vts.getAt(j), h[i]))/z;
|
||||
printf("%3.6f ", p);
|
||||
cout << p << endl;
|
||||
}
|
||||
printf("\n");
|
||||
cout << endl;
|
||||
}
|
||||
printf("\n");
|
||||
cout << endl;
|
||||
|
||||
// Reconstruct
|
||||
for (i=0; i < vts.getSize(); i++)
|
||||
@@ -270,61 +276,30 @@ public:
|
||||
}
|
||||
|
||||
printf("A fantasy... (v^, t>)\n");
|
||||
for (i=0; i < m_w.getNumVisible(); i++)
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
for (j=0; j < vts.getSize(); j++)
|
||||
{
|
||||
p = vts.getAt(j).getProbs()[i];
|
||||
printf("%3.6f ", p);
|
||||
}
|
||||
printf("\n");
|
||||
cout << vts.getAt(j).probs() << endl;
|
||||
}
|
||||
|
||||
delete [] h;
|
||||
}
|
||||
|
||||
const double* toHidden(const double *pVisible)
|
||||
const VectorXd& toHidden(const VectorXd& visible)
|
||||
{
|
||||
double p;
|
||||
uint32_t i;
|
||||
|
||||
VisibleLayer tv(m_w.getNumVisible(), pVisible);
|
||||
VisibleLayer tv(m_w.getNumVisible(), (const VectorXd*)&visible);
|
||||
|
||||
m_th.probsUpdate(tv, m_w);
|
||||
m_th.statesAssignfromProbs();
|
||||
|
||||
#if 0
|
||||
printf("pi(t) = (pi^, v>)\n");
|
||||
for (i=0; i < m_w.getNumHidden(); i++)
|
||||
{
|
||||
p = m_th.getProbs()[i];
|
||||
printf("%3.6f\n", p);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
return m_th.getStates();
|
||||
return m_th.probs();
|
||||
}
|
||||
|
||||
const double* toVisible(const double *pHidden)
|
||||
const VectorXd& toVisible(const VectorXd& hidden)
|
||||
{
|
||||
double p;
|
||||
uint32_t i;
|
||||
|
||||
HiddenLayer th(m_w.getNumHidden(), pHidden);
|
||||
HiddenLayer th(m_w.getNumHidden(), (const VectorXd*)&hidden);
|
||||
|
||||
m_tv.probsUpdate(th, m_w);
|
||||
m_tv.statesAssignfromProbs();
|
||||
|
||||
#if 0
|
||||
printf("pi(t) = (pi^, v>)\n");
|
||||
for (i=0; i < m_w.getNumVisible(); i++)
|
||||
{
|
||||
p = m_tv.getProbs()[i];
|
||||
printf("%3.6f\n", p);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
return m_tv.getStates();
|
||||
return m_tv.probs();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user