neuralnetwork.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package neuralnetworkbase
  2. import (
  3. mat "gonum.org/v1/gonum/mat"
  4. )
  5. type NeuralNetwork struct {
  6. Count int
  7. Sizes []int
  8. Biases []*mat.Dense
  9. Weights []*mat.Dense
  10. A []*mat.Dense
  11. Z []*mat.Dense
  12. alpha float64
  13. }
  14. func (nn *NeuralNetwork) Result() *mat.Dense {
  15. return nn.A[nn.Count-1]
  16. }
  17. func NewNeuralNetwork(Sizes []int) (nn *NeuralNetwork) {
  18. nn = &NeuralNetwork{}
  19. nn.Sizes = Sizes
  20. nn.Count = len(Sizes)
  21. nn.Weights = make([]*mat.Dense, nn.Count)
  22. nn.Biases = make([]*mat.Dense, nn.Count)
  23. nn.A = make([]*mat.Dense, nn.Count)
  24. nn.Z = make([]*mat.Dense, nn.Count)
  25. nn.alpha = 0.2 / float64(nn.Sizes[0])
  26. for i := 1; i < nn.Count; i++ {
  27. nn.Weights[i] = generateRandomDense(nn.Sizes[i], nn.Sizes[i-1])
  28. nn.Biases[i] = generateRandomDense(nn.Sizes[i], 1)
  29. }
  30. return
  31. }
  32. func (nn *NeuralNetwork) Predict(aIn mat.Matrix) (maxIndex int, max float64) {
  33. nn.Forward(aIn)
  34. result := nn.Result()
  35. r, _ := result.Dims()
  36. max = 0.0
  37. maxIndex = 0
  38. for i := 0; i < r; i++ {
  39. if result.At(i, 0) > max {
  40. max = result.At(i, 0)
  41. maxIndex = i
  42. }
  43. }
  44. return
  45. }
  46. func (nn *NeuralNetwork) Forward(aIn mat.Matrix) {
  47. nn.A[0] = mat.DenseCopyOf(aIn)
  48. for i := 1; i < nn.Count; i++ {
  49. nn.A[i] = mat.NewDense(nn.Sizes[i], 1, nil)
  50. aSrc := nn.A[i-1]
  51. aDst := nn.A[i]
  52. aDst.Mul(nn.Weights[i], aSrc)
  53. aDst.Add(aDst, nn.Biases[i])
  54. nn.Z[i] = mat.DenseCopyOf(aDst)
  55. aDst.Apply(applySigmoid, aDst)
  56. }
  57. }
  58. func (nn *NeuralNetwork) Backward(aIn, aOut mat.Matrix) {
  59. nn.Forward(aOut)
  60. //Initial error
  61. err := &mat.Dense{}
  62. err.Sub(aOut, nn.Result())
  63. for i := nn.Count - 1; i > 0; i-- {
  64. sigmoidsPrime := &mat.Dense{}
  65. sigmoidsPrime.Apply(applySigmoidPrime, nn.Z[i])
  66. delta := &mat.Dense{}
  67. delta.MulElem(err, sigmoidsPrime)
  68. err = delta
  69. biases := mat.DenseCopyOf(delta)
  70. weights := &mat.Dense{}
  71. weights.Mul(nn.A[i-1], delta)
  72. // Scale down
  73. nn.Weights[i] = makeBackGradien(weights, nn.Weights[i], nn.alpha)
  74. nn.Biases[i] = makeBackGradien(biases, nn.Biases[i], nn.alpha)
  75. }
  76. }
  77. func makeBackGradien(in mat.Matrix, actual mat.Matrix, alpha float64) *mat.Dense {
  78. scaled := &mat.Dense{}
  79. result := &mat.Dense{}
  80. scaled.Scale(alpha, in)
  81. result.Sub(actual, scaled)
  82. return result
  83. }