- 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:
2014-10-12 14:30:40 +00:00
parent 7b1a713adc
commit 19c69ac02a
13 changed files with 246 additions and 359 deletions
+67 -92
View File
@@ -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: