func (self *FFNet) Train(trainSet []util.TrainExample) { prev_delta_w := make([]util.Matrix_t, len(self.w)) for l := range prev_delta_w { prev_delta_w[l] = util.NewMatrix(len(self.w[l]), len(self.w[l][0])) } prev_delta_b := make(util.Matrix_t, len(self.b)) for l := range prev_delta_b { prev_delta_b[l] = make(util.Row_t, len(self.b[l])) } for iteration := 0; iteration < self.conf.Iterations; iteration++ { fmt.Println("Iteration #", iteration+1) dw, db := self.createDeltaWeights() for k := range trainSet { input := trainSet[k].Input output := trainSet[k].Output activations := self.forward(input) deltas := self.backward(activations, output) self.computeDeltaWeights(activations, deltas, dw, db) } self.applyDeltaWeights(len(trainSet), dw, db, prev_delta_w, prev_delta_b) } // pretty.Println(self.w) // pretty.Println(self.b) }
func (self *FFNet) createDeltaWeights() ([]util.Matrix_t, util.Matrix_t) { dw := make([]util.Matrix_t, len(self.w)) for l := range dw { dw[l] = util.NewMatrix(len(self.w[l]), len(self.w[l][0])) } db := make(util.Matrix_t, len(self.b)) for l := range db { db[l] = make(util.Row_t, len(self.b[l])) } return dw, db }
func BuildFFNet(conf *FFNetConf) *FFNet { if conf == nil { panic("Need config to build FFNet") } if conf.Layers == nil || len(conf.Layers) < 2 { panic("Number of layers should be >= 2") } if conf.Activation == nil { conf.Activation = Sigma } if conf.Iterations == 0 { conf.Iterations = 100 } nn := &FFNet{conf: conf} nn.randomSource = rand.New(rand.NewSource(time.Now().UnixNano())) nn.w = make([]util.Matrix_t, len(conf.Layers)-1) for l := range nn.w { nn.w[l] = util.NewMatrix(conf.Layers[l], conf.Layers[l+1]) for i := range nn.w[l] { for j := range nn.w[l][i] { nn.w[l][i][j] = nn.randomSource.Float64()*(2*RAND_EPSILON) - RAND_EPSILON } } } nn.b = make(util.Matrix_t, len(conf.Layers)-1) for l := range nn.b { nn.b[l] = make(util.Row_t, conf.Layers[l+1]) if conf.Bias { for j := range nn.b[l] { nn.b[l][j] = nn.randomSource.Float64()*(2*RAND_EPSILON) - RAND_EPSILON } } } return nn }