Files
Rbm-legacy/Source/Layer.hpp
T
2014-10-12 14:30:40 +00:00

150 lines
2.7 KiB
C++

/*
==============================================================================
Layer.hpp
Created: 21 Sep 2014 1:55:15pm
Author: jens
==============================================================================
*/
#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 VectorXd *pStatesInit = nullptr)
: m_numUnits(numUnits)
, m_probs(numUnits)
, m_states(numUnits)
{
setNumUnits(numUnits);
Noise_Init(&m_noise, 0x12345677);
if (pStatesInit && (pStatesInit->size() == numUnits))
{
m_states = *pStatesInit;
}
}
virtual ~Layer()
{
setNumUnits(0);
Noise_Free(&m_noise);
}
void setNumUnits(uint32_t numUnits)
{
if (m_numUnits == numUnits)
{
return;
}
m_numUnits = numUnits;
m_probs.resize(numUnits);
m_states.resize(numUnits);
probsInit(0);
statesInit(0);
}
void probsInit(const double &value)
{
m_probs.fill(value);
}
void statesInit(const double &value)
{
m_states.fill(value);
}
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_probs(i) = logSigmoid(lambda/variance*accum(layer, weights, i));
}
}
void probsUpdateGaussian(Layer &layer, Weights &weights, double lambda, double variance)
{
uint32_t i;
for (i=0; i < m_numUnits; i++)
{
m_probs(i) = gaussProb(lambda*accum(layer, weights, i), variance);
}
}
void statesUpdateStochastic()
{
uint32_t i;
double sample;
for (i=0; i < m_numUnits; i++)
{
sample = Noise_Uniform(&m_noise, 0.5);
m_states(i) = (double)(sample <= m_probs(i));
}
}
VectorXd& probs()
{
return m_probs;
}
VectorXd& states()
{
return m_states;
}
uint32_t getNumUnits() const
{
return m_numUnits;
}
virtual double getEnergy(const Weights &weights) = 0;
private:
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));
}
inline double gaussProb(double x, double var) const
{
double k = 1.0/sqrt(var*2*3.14159265359);
double mu = 0;
double x2 = (x-mu)*(x-mu);
return k*exp(-x2/(2*var));
}
};
#endif // LAYER_HPP