- 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:
+52
-74
@@ -11,19 +11,28 @@
|
||||
#ifndef LAYER_HPP
|
||||
#define LAYER_HPP
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
#include <Eigen/Dense>
|
||||
#include "noise.h"
|
||||
#include "Weights.hpp"
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
class Layer
|
||||
{
|
||||
public:
|
||||
Layer(uint32_t numUnits = 0, const double *pStatesInit = nullptr)
|
||||
Layer(uint32_t numUnits = 0, const VectorXd *pStatesInit = nullptr)
|
||||
: m_numUnits(numUnits)
|
||||
, m_pProbs(nullptr)
|
||||
, m_pStates(nullptr)
|
||||
, m_probs(numUnits)
|
||||
, m_states(numUnits)
|
||||
{
|
||||
setNumUnits(numUnits, pStatesInit);
|
||||
setNumUnits(numUnits);
|
||||
Noise_Init(&m_noise, 0x12345677);
|
||||
|
||||
if (pStatesInit && (pStatesInit->size() == numUnits))
|
||||
{
|
||||
m_states = *pStatesInit;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~Layer()
|
||||
@@ -32,95 +41,55 @@ public:
|
||||
Noise_Free(&m_noise);
|
||||
}
|
||||
|
||||
void setNumUnits(uint32_t numUnits, const double *pStatesInit = nullptr)
|
||||
void setNumUnits(uint32_t numUnits)
|
||||
{
|
||||
if (m_numUnits)
|
||||
if (m_numUnits == numUnits)
|
||||
{
|
||||
delete [] m_pProbs;
|
||||
delete [] m_pStates;
|
||||
return;
|
||||
}
|
||||
m_numUnits = numUnits;
|
||||
if (m_numUnits)
|
||||
{
|
||||
m_pProbs = new double[m_numUnits];
|
||||
m_pStates = new double[m_numUnits];
|
||||
m_probs.resize(numUnits);
|
||||
m_states.resize(numUnits);
|
||||
|
||||
probsInit(0);
|
||||
if (pStatesInit)
|
||||
{
|
||||
memcpy(m_pStates, pStatesInit, m_numUnits*sizeof(double));
|
||||
}
|
||||
else
|
||||
{
|
||||
statesInit(0);
|
||||
}
|
||||
}
|
||||
probsInit(0);
|
||||
statesInit(0);
|
||||
}
|
||||
|
||||
Layer& operator= (const Layer &rhs)
|
||||
void probsInit(const double &value)
|
||||
{
|
||||
memcpy(m_pProbs, rhs.m_pProbs, m_numUnits*sizeof(double));
|
||||
memcpy(m_pStates, rhs.m_pStates, m_numUnits*sizeof(double));
|
||||
|
||||
return *this;
|
||||
m_probs.fill(value);
|
||||
}
|
||||
|
||||
Layer& operator+= (const Layer &rhs)
|
||||
void statesInit(const double &value)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i=0; i < m_numUnits; i++)
|
||||
{
|
||||
m_pStates[i] += rhs.m_pStates[i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
m_states.fill(value);
|
||||
}
|
||||
|
||||
void probsInit(double value) const
|
||||
void probsUpdate(Layer &layer, Weights &weights, double lambda = 1.0, double variance = 1.0)
|
||||
{
|
||||
probsUpdateLogistic(layer, weights, lambda, variance);
|
||||
}
|
||||
|
||||
void probsUpdateLogistic(Layer &layer, Weights &weights, double lambda, double variance)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < m_numUnits; i++)
|
||||
{
|
||||
m_pProbs[i] = value;
|
||||
m_probs(i) = logSigmoid(lambda/variance*accum(layer, weights, i));
|
||||
}
|
||||
}
|
||||
|
||||
void statesInit(double value) const
|
||||
void probsUpdateGaussian(Layer &layer, Weights &weights, double lambda, double variance)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < m_numUnits; i++)
|
||||
{
|
||||
m_pStates[i] = value;
|
||||
m_probs(i) = gaussProb(lambda*accum(layer, weights, i), variance);
|
||||
}
|
||||
}
|
||||
|
||||
void probsUpdate(const Layer &layer, const Weights &weights) const
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < m_numUnits; i++)
|
||||
{
|
||||
m_pProbs[i] = logSigmoid(accum(layer, weights, i));
|
||||
}
|
||||
}
|
||||
|
||||
void statesScale(double kscale) const
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < m_numUnits; i++)
|
||||
{
|
||||
m_pStates[i] *= kscale;
|
||||
}
|
||||
}
|
||||
|
||||
void statesAssignfromProbs()
|
||||
{
|
||||
memcpy(m_pStates, m_pProbs, m_numUnits*sizeof(double));
|
||||
}
|
||||
|
||||
void statesUpdateStochastic()
|
||||
{
|
||||
uint32_t i;
|
||||
@@ -129,18 +98,18 @@ public:
|
||||
for (i=0; i < m_numUnits; i++)
|
||||
{
|
||||
sample = Noise_Uniform(&m_noise, 0.5);
|
||||
m_pStates[i] = (double)(sample <= m_pProbs[i]);
|
||||
m_states(i) = (double)(sample <= m_probs(i));
|
||||
}
|
||||
}
|
||||
|
||||
const double *getProbs() const
|
||||
VectorXd& probs()
|
||||
{
|
||||
return m_pProbs;
|
||||
return m_probs;
|
||||
}
|
||||
|
||||
const double *getStates() const
|
||||
VectorXd& states()
|
||||
{
|
||||
return m_pStates;
|
||||
return m_states;
|
||||
}
|
||||
|
||||
uint32_t getNumUnits() const
|
||||
@@ -151,19 +120,28 @@ public:
|
||||
virtual double getEnergy(const Weights &weights) = 0;
|
||||
|
||||
private:
|
||||
uint32_t m_numUnits;
|
||||
noise_gen_t m_noise;
|
||||
|
||||
protected:
|
||||
uint32_t m_numUnits;
|
||||
VectorXd m_probs;
|
||||
VectorXd m_states;
|
||||
|
||||
virtual double accum(Layer &layer, Weights &weights, uint32_t index) = 0;
|
||||
inline double logSigmoid(double x) const
|
||||
{
|
||||
return 1./(1 + exp(-x));
|
||||
}
|
||||
|
||||
protected:
|
||||
double *m_pProbs;
|
||||
double *m_pStates;
|
||||
inline double gaussProb(double x, double var) const
|
||||
{
|
||||
double k = 1.0/sqrt(var*2*3.14159265359);
|
||||
|
||||
virtual double accum(const Layer &layer, const Weights &weights, uint32_t index) const = 0;
|
||||
double mu = 0;
|
||||
double x2 = (x-mu)*(x-mu);
|
||||
|
||||
return k*exp(-x2/(2*var));
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user