git-svn-id: http://moon:8086/svn/software/trunk/projects/RBM@40 b431acfa-c32f-4a4a-93f1-934dc6c82436
161 lines
2.9 KiB
C++
161 lines
2.9 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;
|
|
}
|
|
|
|
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 &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 = ((double)mu[i]);
|
|
m_probs[i] = 1-exp(-0.5*x2*x2/var);
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif // LAYER_HPP
|