/* ============================================================================== Layer.hpp Created: 21 Sep 2014 1:55:15pm Author: jens ============================================================================== */ #ifndef LAYER_HPP #define LAYER_HPP #include #include #include #include "noise.h" #include "Weights.hpp" using namespace Eigen; class Layer { public: Layer(uint32_t numUnits = 0, const RowVectorXd *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); } } RowVectorXd& probs() { return m_probs; } RowVectorXd& states() { return m_states; } uint32_t getNumUnits() const { return m_numUnits; } private: noise_gen_t m_noise; protected: uint32_t m_numUnits; RowVectorXd m_probs; RowVectorXd m_states; virtual double accum(Layer &layer, Weights &weights, uint32_t index) = 0; void logSigmoid(const RowVectorXd &x) { uint32_t i; for (i=0; i < m_numUnits; i++) { m_probs[i] = 1./(1 + exp(-(double)x[i])); } } void gaussProb(const RowVectorXd &mu, double sigma) { uint32_t i; double var = sigma*sigma; double k = 1.0/sqrt(2*3.14159265359*var); for (i=0; i < m_numUnits; i++) { double x2 = (1-(double)mu[i]); m_probs[i] = exp(-0.5*x2*x2/var); } } }; #endif // LAYER_HPP