neuralnetwork.go 3.8 KB

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