// New creates new GBRBM instance. func New(numVisibleUnits, numHiddenUnits int) *GBRBM { rbm := new(GBRBM) rand.Seed(time.Now().UnixNano()) rbm.NumVisibleUnits = numVisibleUnits rbm.NumHiddenUnits = numHiddenUnits rbm.W = nnet.MakeMatrix(numHiddenUnits, numVisibleUnits) rbm.B = make([]float64, numVisibleUnits) rbm.C = make([]float64, numHiddenUnits) rbm.GradW = nnet.MakeMatrix(numHiddenUnits, numVisibleUnits) rbm.GradB = make([]float64, numVisibleUnits) rbm.GradC = make([]float64, numHiddenUnits) rbm.InitParam() return rbm }
// NewNeuralNetwork returns a new network instance with the number of // input units, number of hidden units and number output units // of the network. func NewNeuralNetwork(numInputUnits, numHiddenUnits, numOutputUnits int) *NeuralNetwork { net := new(NeuralNetwork) rand.Seed(time.Now().UnixNano()) // Layers net.InputLayer = make([]float64, numInputUnits+1) // plus bias net.HiddenLayer = make([]float64, numHiddenUnits) net.OutputLayer = make([]float64, numOutputUnits) // Weights net.OutputWeight = nnet.MakeMatrix(numHiddenUnits, numOutputUnits) net.HiddenWeight = nnet.MakeMatrix(numInputUnits+1, numHiddenUnits) net.InitParam() return net }
func NewHiddenLayer(numInputUnits, numHiddenUnits int) *HiddenLayer { h := new(HiddenLayer) h.W = nnet.MakeMatrix(numInputUnits, numHiddenUnits) h.NumInputUnits = numInputUnits h.NumHiddenUnits = numHiddenUnits h.B = make([]float64, numHiddenUnits) h.Init() return h }
// Gradient returns gradients of GBRBM parameters for a given (mini-batch) dataset. func (rbm *GBRBM) Gradient(data [][]float64, miniBatchIndex int) ([][]float64, []float64, []float64) { gradW := nnet.MakeMatrix(rbm.NumHiddenUnits, rbm.NumVisibleUnits) gradB := make([]float64, rbm.NumVisibleUnits) gradC := make([]float64, rbm.NumHiddenUnits) for i, v := range data { // Set start state of Gibbs-sampling var gibbsStart []float64 persistentIndex := i + miniBatchIndex*rbm.Option.MiniBatchSize if rbm.Option.UsePersistent { gibbsStart = rbm.PersistentVisibleUnits[persistentIndex] } else { gibbsStart = v } // Perform reconstruction using Gibbs-sampling reconstructedVisible := rbm.Reconstruct(gibbsStart, rbm.Option.OrderOfGibbsSampling, rbm.Option.UseMean) // keep recostructed visible if rbm.Option.UsePersistent { rbm.PersistentVisibleUnits[persistentIndex] = reconstructedVisible } // pre-computation that is used in gradient computation p_h_given_v1 := rbm.P_H_Given_V_Batch(v) p_h_given_v2 := rbm.P_H_Given_V_Batch(reconstructedVisible) // Gompute gradient of W for i := 0; i < rbm.NumHiddenUnits; i++ { for j := 0; j < rbm.NumVisibleUnits; j++ { gradW[i][j] += p_h_given_v1[i]*v[j] - p_h_given_v2[i]*reconstructedVisible[j] } } // Gompute gradient of B for j := 0; j < rbm.NumVisibleUnits; j++ { gradB[j] += v[j] - reconstructedVisible[j] } // Gompute gradient of C for i := 0; i < rbm.NumHiddenUnits; i++ { gradC[i] += p_h_given_v1[i] - p_h_given_v2[i] } } return rbm.normalizeGradBySizeOfBatch(gradW, gradB, gradC, len(data)) }
func (h *HiddenLayer) Gradient(input, deltas [][]float64) ([][]float64, []float64) { gradW := nnet.MakeMatrix(len(h.W), len(h.W[0])) gradB := make([]float64, len(h.B)) // Gradient for n := range input { for i := 0; i < h.NumHiddenUnits; i++ { for j := 0; j < h.NumInputUnits; j++ { gradW[j][i] -= deltas[n][i] * input[n][j] } gradB[i] -= deltas[n][i] } } return gradW, gradB }
// Train performs Contrastive divergense learning algorithm to train GBRBM. // The alrogithm is based on (mini-batch) Stochastic Gradient Ascent. func (rbm *GBRBM) Train(data [][]float64, option TrainingOption) error { rbm.Option = option opt := nnet.BaseTrainingOption{ Epoches: rbm.Option.Epoches, MiniBatchSize: rbm.Option.MiniBatchSize, Monitoring: rbm.Option.Monitoring, } // Peistent Contrastive learning if rbm.Option.UsePersistent { rbm.PersistentVisibleUnits = nnet.MakeMatrix(len(data), len(data[0])) copy(rbm.PersistentVisibleUnits, data) } s := nnet.NewTrainer(opt) return s.UnSupervisedMiniBatchTrain(rbm, data) }