Files
Rbm-legacy/Source/Layer.hpp
T
2014-10-20 06:47:51 +00:00

164 lines
3.0 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)
{
Noise_Init(&m_noise, 0x12345677);
setNumUnits(numUnits);
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 probsUpdateLogistic(Layer &layer, Weights &weights, double lambda, double sigma)
{
uint32_t i;
double var = sigma*sigma;
for (i=0; i < m_numUnits; i++)
{
m_probs(i) = lambda/var*accum(layer, weights, i);
}
logSigmoid(m_probs);
}
void probsUpdateGaussian(Layer &layer, Weights &weights, double lambda, double sigma)
{
uint32_t i;
for (i=0; i < m_numUnits; i++)
{
m_probs(i) = lambda*accum(layer, weights, i);
}
gaussProb(m_probs, sigma);
}
void statesUpdateStochastic()
{
uint32_t i;
double sample;
for (i=0; i < m_numUnits; i++)
{
sample = Noise_Uniform(&m_noise);
m_states(i) = (double)(sample <= m_probs(i));
}
}
void sampleGaussian(Layer &layer, Weights &weights, double lambda, double sigma)
{
uint32_t i;
for (i=0; i < m_numUnits; i++)
{
m_states(i) = sigma*Noise_Gaussian(&m_noise) + lambda*accum(layer, weights, 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;
void logSigmoid(const VectorXd &x)
{
uint32_t i;
for (i=0; i < m_numUnits; i++)
{
m_probs[i] = 1./(1 + exp(-(double)x[i]));
}
}
void gaussProb(const VectorXd &x, double sigma)
{
uint32_t i;
double var = sigma*sigma;
double k = 1.0/sqrt(2*3.14159265359*var);
double mu = 0;
for (i=0; i < m_numUnits; i++)
{
double x2 = ((double)x[i]-mu);
m_probs[i] = 1-exp(-x2*x2/(2*var));
}
}
};
#endif // LAYER_HPP