示例#1
0
func GradientDescent(
	initialGuess []float64,
	learningRate, precision float64,
	maxIterations int,
	gradient func([]float64) ([]float64, error),
) ([]float64, error) {
	if len(initialGuess) == 0 {
		return nil, errors.New("initialGuess cannot be empty")
	}

	oldResult := make([]float64, len(initialGuess))
	newResult := make([]float64, len(initialGuess))
	copy(oldResult, initialGuess)

	for i := 0; i < maxIterations; i++ {
		gradientAtOldResult, err := gradient(oldResult)
		if err != nil {
			return nil, err
		}

		newResult = vectorutilities.Add(oldResult, vectorutilities.Scale(-learningRate, gradientAtOldResult))

		if (knnutilities.Euclidean(newResult, oldResult, precision)) < precision*precision {
			return newResult, nil
		} else {
			oldResult = newResult
		}
	}

	return newResult, nil
}
func (gdpe *gradientDescentParameterEstimator) Estimate(initialParameters []float64) ([]float64, error) {
	if gdpe.trainingSet == nil {
		return nil, gdeErrors.NewUntrainedEstimatorError()
	}

	if len(initialParameters) == 0 {
		return nil, gdeErrors.NewEmptyInitialParametersError()
	}

	gradient := func(guess []float64) ([]float64, error) {
		sumLossGradient := make([]float64, len(initialParameters))

		for i := 0; i < gdpe.trainingSet.NumRows(); i++ {
			row, _ := gdpe.trainingSet.Row(i)
			features, _ := row.Features().(slice.FloatSlice)
			target, _ := row.Target().(slice.FloatSlice)
			x := features.Values()
			y := target.Values()[0]

			lossGradient, err := gdpe.plgf(guess, x, y)
			if err != nil {
				return nil, err
			}
			sumLossGradient = vectorutilities.Add(sumLossGradient, lossGradient)
		}

		return sumLossGradient, nil
	}

	return gradientdescent.GradientDescent(initialParameters, gdpe.learningRate, gdpe.precision, gdpe.maxIterations, gradient)
}
package vectorutilities_test

import (
	"github.com/amitkgupta/goodlearn/vectorutilities"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Vector Utilities", func() {
	Describe("Add", func() {
		It("Adds", func() {
			x := []float64{1.01, 2, 3, 4}
			y := []float64{3.14, -1, 0, 0}

			Ω(vectorutilities.Add(x, y)).Should(Equal([]float64{4.15, 1, 3, 4}))
		})
	})

	Describe("Scale", func() {
		It("Scales", func() {
			x := []float64{1, 2, 3, 4}
			a := -2.33

			Ω(vectorutilities.Scale(a, x)).Should(Equal([]float64{-2.33, -4.66, -6.99, -9.32}))
		})
	})
})