coding utf8 references a practical guide to training restricted boltzmann machines https www cs toronto eduhintonabspsguidetr pdf bernoulli restricted boltzmann machine rbm parameters nhidden int default 128 the number of hidden units learningrate float default 0 1 batchsize int default 10 maxepochs int default 100 bias for visible and hidden units use cd1 training procedure basically an exact inference for positiveassociations followed by a non burnin block gibbs sampling for the negativeassociations for i in rangeself maxepochs error 0 for batch in batchiteratorself x batchsizeself batchsize positivehidden sigmoidnp dotbatch self w self biash hiddenstates self samplepositivehidden sample hidden state h1 positiveassociations np dotbatch t positivehidden negativevisible sigmoidnp dothiddenstates self w t self biasv negativevisible self samplenegativevisible use the sampled hidden state h1 to sample v1 negativehidden sigmoidnp dotnegativevisible self w self biash negativeassociations np dotnegativevisible t negativehidden lr self lr floatbatch shape0 self w lr positiveassociations negativeassociations floatself batchsize self biash lr negativehidden sumaxis0 negativeassociations sumaxis0 self biasv lr np asarraybatch sumaxis0 squeeze negativevisible sumaxis0 error np sumbatch negativevisible 2 self errors appenderror logging infoiteration s error s i error logging debugweights s self w logging debughidden bias s self biash logging debugvisible bias s self biasv def sampleself x return x np random randomsamplesizex shape def predictself xnone return sigmoidnp dotx self w self biash coding utf 8 references a practical guide to training restricted boltzmann machines https www cs toronto edu hinton absps guidetr pdf bernoulli restricted boltzmann machine rbm parameters n_hidden int default 128 the number of hidden units learning_rate float default 0 1 batch_size int default 10 max_epochs int default 100 bias for visible and hidden units use cd 1 training procedure basically an exact inference for positive_associations followed by a non burn in block gibbs sampling for the negative_associations sample hidden state h1 use the sampled hidden state h1 to sample v1
import logging

import numpy as np
from scipy.special import expit

from mla.base import BaseEstimator
from mla.utils import batch_iterator

np.random.seed(9999)
sigmoid = expit




class RBM(BaseEstimator):
    y_required = False

    def __init__(self, n_hidden=128, learning_rate=0.1, batch_size=10, max_epochs=100):
        
        self.max_epochs = max_epochs
        self.batch_size = batch_size
        self.lr = learning_rate
        self.n_hidden = n_hidden

    def fit(self, X, y=None):
        self.n_visible = X.shape[1]
        self._init_weights()
        self._setup_input(X, y)
        self._train()

    def _init_weights(self):

        self.W = np.random.randn(self.n_visible, self.n_hidden) * 0.1

        
        self.bias_v = np.zeros(self.n_visible, dtype=np.float32)
        self.bias_h = np.zeros(self.n_hidden, dtype=np.float32)

        self.errors = []

    def _train(self):
        

        for i in range(self.max_epochs):
            error = 0
            for batch in batch_iterator(self.X, batch_size=self.batch_size):
                positive_hidden = sigmoid(np.dot(batch, self.W) + self.bias_h)
                hidden_states = self._sample(positive_hidden)  
                positive_associations = np.dot(batch.T, positive_hidden)

                negative_visible = sigmoid(np.dot(hidden_states, self.W.T) + self.bias_v)
                negative_visible = self._sample(negative_visible)  
                negative_hidden = sigmoid(np.dot(negative_visible, self.W) + self.bias_h)
                negative_associations = np.dot(negative_visible.T, negative_hidden)

                lr = self.lr / float(batch.shape[0])
                self.W += lr * ((positive_associations - negative_associations) / float(self.batch_size))
                self.bias_h += lr * (negative_hidden.sum(axis=0) - negative_associations.sum(axis=0))
                self.bias_v += lr * (np.asarray(batch.sum(axis=0)).squeeze() - negative_visible.sum(axis=0))

                error += np.sum((batch - negative_visible) ** 2)

            self.errors.append(error)
            logging.info("Iteration %s, error %s" % (i, error))
        logging.debug("Weights: %s" % self.W)
        logging.debug("Hidden bias: %s" % self.bias_h)
        logging.debug("Visible bias: %s" % self.bias_v)

    def _sample(self, X):
        return X > np.random.random_sample(size=X.shape)

    def _predict(self, X=None):
        return sigmoid(np.dot(X, self.W) + self.bias_h)