neuralnetwork.go 3.1 KB

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