neuralnetwork.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package neuralnetworkbase
  2. import (
  3. teach "../teach"
  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. trainingCycles int
  15. }
  16. func NewNeuralNetwork(Sizes []int, nu float64, trainingCycles int) (nn *NeuralNetwork) {
  17. nn = &NeuralNetwork{}
  18. nn.Sizes = Sizes
  19. nn.Count = len(Sizes)
  20. nn.Weights = make([]*mat.Dense, nn.Count)
  21. nn.Biases = make([]*mat.Dense, nn.Count)
  22. nn.A = make([]*mat.Dense, nn.Count)
  23. nn.Z = make([]*mat.Dense, nn.Count)
  24. nn.alpha = nu / float64(nn.Sizes[0])
  25. nn.trainingCycles = trainingCycles
  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) Teach(teacher teach.Teacher) {
  47. for i := 0; i < nn.trainingCycles; i++ {
  48. for teacher.Next() {
  49. nn.backward(teacher.GetData(), teacher.GetExpect())
  50. }
  51. }
  52. }
  53. func (nn *NeuralNetwork) SaveState(filename string) {
  54. }
  55. func (nn *NeuralNetwork) LoadState(filename string) {
  56. }
  57. func (nn *NeuralNetwork) forward(aIn mat.Matrix) {
  58. nn.A[0] = mat.DenseCopyOf(aIn)
  59. for i := 1; i < nn.Count; i++ {
  60. nn.A[i] = mat.NewDense(nn.Sizes[i], 1, nil)
  61. aSrc := nn.A[i-1]
  62. aDst := nn.A[i]
  63. // r, c := nn.Weights[i].Dims()
  64. // fmt.Printf("r: %v,c: %v\n", r, c)
  65. // r, c = aSrc.Dims()
  66. // fmt.Printf("src r: %v,c: %v\n\n\n", r, c)
  67. aDst.Mul(nn.Weights[i], aSrc)
  68. aDst.Add(aDst, nn.Biases[i])
  69. nn.Z[i] = mat.DenseCopyOf(aDst)
  70. aDst.Apply(applySigmoid, aDst)
  71. }
  72. }
  73. func (nn *NeuralNetwork) backward(aIn, aOut mat.Matrix) {
  74. nn.forward(aIn)
  75. lastLayerNum := nn.Count - 1
  76. //Initial error
  77. err := &mat.Dense{}
  78. err.Sub(nn.result(), aOut)
  79. sigmoidsPrime := &mat.Dense{}
  80. sigmoidsPrime.Apply(applySigmoidPrime, nn.Z[lastLayerNum])
  81. delta := &mat.Dense{}
  82. delta.MulElem(err, sigmoidsPrime)
  83. biases := mat.DenseCopyOf(delta)
  84. weights := &mat.Dense{}
  85. weights.Mul(delta, nn.A[lastLayerNum-1].T())
  86. newBiases := []*mat.Dense{makeBackGradien(biases, nn.Biases[lastLayerNum], nn.alpha)}
  87. newWeights := []*mat.Dense{makeBackGradien(weights, nn.Weights[lastLayerNum], nn.alpha)}
  88. err = delta
  89. for i := nn.Count - 2; i > 0; i-- {
  90. sigmoidsPrime := &mat.Dense{}
  91. sigmoidsPrime.Apply(applySigmoidPrime, nn.Z[i])
  92. delta := &mat.Dense{}
  93. wdelta := &mat.Dense{}
  94. wdelta.Mul(nn.Weights[i+1].T(), err)
  95. delta.MulElem(wdelta, sigmoidsPrime)
  96. err = delta
  97. biases := mat.DenseCopyOf(delta)
  98. weights := &mat.Dense{}
  99. weights.Mul(delta, nn.A[i-1].T())
  100. // Scale down
  101. newBiases = append([]*mat.Dense{makeBackGradien(biases, nn.Biases[i], nn.alpha)}, newBiases...)
  102. newWeights = append([]*mat.Dense{makeBackGradien(weights, nn.Weights[i], nn.alpha)}, newWeights...)
  103. }
  104. newBiases = append([]*mat.Dense{&mat.Dense{}}, newBiases...)
  105. newWeights = append([]*mat.Dense{&mat.Dense{}}, newWeights...)
  106. nn.Biases = newBiases
  107. nn.Weights = newWeights
  108. }
  109. func (nn *NeuralNetwork) result() *mat.Dense {
  110. return nn.A[nn.Count-1]
  111. }