From eee503a405b3268178bd117d9a42679775c64d7c Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 15 Oct 2018 06:54:38 +0200 Subject: [PATCH] unexport network features (neurons, weights, biases) --- network.go | 62 ++++++++++++++++++++++++++++--------------------- network_test.go | 30 ++++++++++++------------ storage.go | 24 +++++++++---------- 3 files changed, 62 insertions(+), 54 deletions(-) diff --git a/network.go b/network.go index 2c6bbd6..6712ffa 100644 --- a/network.go +++ b/network.go @@ -11,9 +11,9 @@ type Network struct { fed bool // whether the network has the state fed by a forward pass - Neurons []*mat.Dense // neuron value vector for each layer (size=L) - Biases []*mat.Dense // neuron bias vector for each layer (size=L-1) - Weights []*mat.Dense // weights between each 2-layers (size=L-1) + neurons []*mat.Dense // neuron value vector for each layer (size=L) + biases []*mat.Dense // neuron bias vector for each layer (size=L-1) + weights []*mat.Dense // weights between each 2-layers (size=L-1) } const MaxLayerCount = 255 @@ -34,9 +34,9 @@ func Empty(_layers ...uint) (*Network, error) { net := &Network{ layers: _layers, fed: false, - Neurons: make([]*mat.Dense, 0), - Biases: make([]*mat.Dense, 0), - Weights: make([]*mat.Dense, 0), + neurons: make([]*mat.Dense, 0), + biases: make([]*mat.Dense, 0), + weights: make([]*mat.Dense, 0), } for i, layer := range _layers { @@ -47,7 +47,7 @@ func Empty(_layers ...uint) (*Network, error) { } // create neurons - net.Neurons = append(net.Neurons, mat.NewDense(int(layer), 1, nil)) + net.neurons = append(net.neurons, mat.NewDense(int(layer), 1, nil)) // do not create weights nor biases for first layer // (no previous layer to bound to) @@ -62,7 +62,7 @@ func Empty(_layers ...uint) (*Network, error) { biases = append(biases, rand.Float64()) } biasesVec := mat.NewDense(int(layer), 1, biases) - net.Biases = append(net.Biases, biasesVec) + net.biases = append(net.biases, biasesVec) rows, cols := int(layer), int(_layers[i-1]) weights := make([]float64, 0, rows*cols+1) @@ -71,7 +71,7 @@ func Empty(_layers ...uint) (*Network, error) { weights = append(weights, rand.Float64()) } weightsMat := mat.NewDense(rows, cols, weights) - net.Weights = append(net.Weights, weightsMat) + net.weights = append(net.weights, weightsMat) } @@ -83,8 +83,8 @@ func Empty(_layers ...uint) (*Network, error) { func (net *Network) reset() { net.fed = false - for i, _ := range net.Neurons { - net.Neurons[i] = mat.NewDense(int(net.layers[i]), 1, nil) + for i, _ := range net.neurons { + net.neurons[i] = mat.NewDense(int(net.layers[i]), 1, nil) } } @@ -93,26 +93,26 @@ func (net *Network) reset() { func (net *Network) forward(_input ...float64) error { // check input size - if len(_input) < net.Neurons[0].ColView(0).Len() { + if len(_input) < net.neurons[0].ColView(0).Len() { return ErrMissingInput } // reset neuron values net.reset() // forward input to first layer - for n, l := 0, net.Neurons[0].ColView(0).Len(); n < l; n++ { - net.Neurons[0].Set(n, 0, _input[n]) + for n, l := 0, net.neurons[0].ColView(0).Len(); n < l; n++ { + net.neurons[0].Set(n, 0, _input[n]) } // process each layer from the previous one for l, ll := 1, len(net.layers); l < ll; l++ { // Z = w^l . a^(l-1) + b^l - z := net.Neurons[l] + z := net.neurons[l] - a := net.Neurons[l-1] // neurons of previous layer - w := net.Weights[l-1] // shifted by 1 because no weights between layers -1 and 0 - b := net.Biases[l-1] // same shift as weights + a := net.neurons[l-1] // neurons of previous layer + w := net.weights[l-1] // shifted by 1 because no weights between layers -1 and 0 + b := net.biases[l-1] // same shift as weights z.Mul(w, a) z.Add(z, b) @@ -140,7 +140,11 @@ func (net *Network) Cost(_expect ...float64) (float64, error) { // from the given _expect data func (net *Network) costVec(_expect ...float64) (*mat.Dense, error) { - out := net.Neurons[len(net.Neurons)-1] + if !net.fed { + return nil, ErrNoState + } + + out := net.neurons[len(net.neurons)-1] // check output size if len(_expect) < out.ColView(0).Len() { @@ -163,7 +167,11 @@ func (net *Network) costVec(_expect ...float64) (*mat.Dense, error) { // output (as a vector) from the given _expect data func (net *Network) errorVec(_expect ...float64) (*mat.Dense, error) { - outLayer := net.Neurons[len(net.Neurons)-1] + if !net.fed { + return nil, ErrNoState + } + + outLayer := net.neurons[len(net.neurons)-1] // check output size if len(_expect) < outLayer.ColView(0).Len() { @@ -186,7 +194,7 @@ func (net *Network) errorVec(_expect ...float64) (*mat.Dense, error) { // and the expected data : _expect func (net *Network) backward(_expect ...float64) error { - out := net.Neurons[len(net.Neurons)-1] + out := net.neurons[len(net.neurons)-1] // 1. fail on no state (no forward pass applied first) if !net.fed { @@ -208,10 +216,10 @@ func (net *Network) backward(_expect ...float64) error { // FOR EACH LAYER (from last to 1) for l := len(net.layers) - 1; l > 0; l-- { - neurons := net.Neurons[l] - previous := net.Neurons[l-1] - weights := net.Weights[l-1] // from l-1 to l - biases := net.Biases[l-1] // at l + neurons := net.neurons[l] + previous := net.neurons[l-1] + weights := net.weights[l-1] // from l-1 to l + biases := net.biases[l-1] // at l // calc GRADIENTS = sigmoid'( neuron[l-1] ) gradients := new(mat.Dense) @@ -258,7 +266,7 @@ func (net *Network) Guess(_input ...float64) ([]float64, error) { // to guess the _expect instead func (net *Network) Train(_input []float64, _expect []float64) error { - out := net.Neurons[len(net.Neurons)-1] + out := net.neurons[len(net.neurons)-1] // check output size if len(_expect) != out.ColView(0).Len() { @@ -283,7 +291,7 @@ func (net Network) Output() ([]float64, error) { return nil, ErrNoState } - out := net.Neurons[len(net.Neurons)-1] + out := net.neurons[len(net.neurons)-1] output := make([]float64, 0, net.layers[len(net.layers)-1]) for n, l := 0, out.ColView(0).Len(); n < l; n++ { output = append(output, out.At(n, 0)) diff --git a/network_test.go b/network_test.go index 956d5ff..e170daf 100644 --- a/network_test.go +++ b/network_test.go @@ -67,31 +67,31 @@ func TestEmptyNetworkSizes(t *testing.T) { } // 1. Check neuron layer count - if len(net.Neurons) != len(test) { - t.Errorf("Expected %d layers of neurons, got %d", len(test), len(net.Neurons)) + if len(net.neurons) != len(test) { + t.Errorf("Expected %d layers of neurons, got %d", len(test), len(net.neurons)) continue } // 2. Check bias layer count (layers-1) - if len(net.Biases) != len(test)-1 { - t.Errorf("Expected %d layers of biases, got %d", len(test)-1, len(net.Biases)) + if len(net.biases) != len(test)-1 { + t.Errorf("Expected %d layers of biases, got %d", len(test)-1, len(net.biases)) continue } // 3. Check weights layer count (layers-1) - if len(net.Weights) != len(test)-1 { - t.Errorf("Expected %d layers of weights, got %d", len(test)-1, len(net.Weights)) + if len(net.weights) != len(test)-1 { + t.Errorf("Expected %d layers of weights, got %d", len(test)-1, len(net.weights)) continue } // 4. Check each neuron layer count - for n, neuron := range net.Neurons { + for n, neuron := range net.neurons { if uint(neuron.ColView(0).Len()) != test[n] { t.Errorf("Expected %d neurons on layer %d, got %d", test[n], n, neuron.ColView(0).Len()) } } // 5. Check each bias layer count - for b, bias := range net.Biases { + for b, bias := range net.biases { if uint(bias.ColView(0).Len()) != test[b+1] { t.Errorf("Expected %d biases on layer %d, got %d", test[b+1], b, bias.ColView(0).Len()) @@ -100,7 +100,7 @@ func TestEmptyNetworkSizes(t *testing.T) { } // 6. Check each weight layer count - for w, weight := range net.Weights { + for w, weight := range net.weights { rows, cols := weight.Dims() @@ -151,19 +151,19 @@ func TestForwardPass(t *testing.T) { for l, ll := 1, len(net.layers); l < ll; l++ { // each neuron = ( each previous neuron times its weight ) + neuron bias - for n, nl := 0, net.Neurons[l].ColView(0).Len(); n < nl; n++ { - sum := net.Biases[l-1].At(n, 0) + for n, nl := 0, net.neurons[l].ColView(0).Len(); n < nl; n++ { + sum := net.biases[l-1].At(n, 0) // sum each previous neuron*its weight - for i, il := 0, net.Neurons[l-1].ColView(0).Len(); i < il; i++ { - sum += net.Neurons[l-1].At(i, 0) * net.Weights[l-1].At(n, i) + for i, il := 0, net.neurons[l-1].ColView(0).Len(); i < il; i++ { + sum += net.neurons[l-1].At(i, 0) * net.weights[l-1].At(n, i) } sum = sigmoid(0, 0, sum) // check sum - if !floats.EqualWithinAbs(net.Neurons[l].At(n, 0), sum, 1e9) { - t.Fatalf("Expected neuron %d.%d to be %f, got %f", l, n, sum, net.Neurons[l].At(n, 0)) + if !floats.EqualWithinAbs(net.neurons[l].At(n, 0), sum, 1e9) { + t.Fatalf("Expected neuron %d.%d to be %f, got %f", l, n, sum, net.neurons[l].At(n, 0)) } } diff --git a/storage.go b/storage.go index 9bac442..e63d2eb 100644 --- a/storage.go +++ b/storage.go @@ -24,7 +24,7 @@ func (net *Network) MarshalJSON() ([]byte, error) { // 2. Biases raw.Biases = make([][]float64, 0) - for _, bias := range net.Biases { + for _, bias := range net.biases { vector := bias.ColView(0) biasJSON := make([]float64, 0) @@ -38,7 +38,7 @@ func (net *Network) MarshalJSON() ([]byte, error) { // 3. Weights raw.Weights = make([][]float64, 0) - for _, weight := range net.Weights { + for _, weight := range net.weights { rows, cols := weight.Dims() weightJSON := make([]float64, 0) @@ -70,28 +70,28 @@ func (net *Network) UnmarshalJSON(in []byte) error { net.layers = raw.Layers // extract biases - net.Biases = make([]*mat.Dense, 0) + net.biases = make([]*mat.Dense, 0) for l, layer := range net.layers { if l == 0 { continue } - net.Biases = append(net.Biases, mat.NewDense(int(layer), 1, raw.Biases[l-1])) + net.biases = append(net.biases, mat.NewDense(int(layer), 1, raw.Biases[l-1])) } // extract weights - net.Weights = make([]*mat.Dense, 0) + net.weights = make([]*mat.Dense, 0) for l, layer := range net.layers { if l == 0 { continue } - net.Weights = append(net.Weights, mat.NewDense(int(layer), int(net.layers[l-1]), raw.Weights[l-1])) + net.weights = append(net.weights, mat.NewDense(int(layer), int(net.layers[l-1]), raw.Weights[l-1])) } // mockup neurons - net.Neurons = make([]*mat.Dense, 0) + net.neurons = make([]*mat.Dense, 0) for _, layer := range net.layers { - net.Neurons = append(net.Neurons, mat.NewDense(int(layer), 1, nil)) + net.neurons = append(net.neurons, mat.NewDense(int(layer), 1, nil)) } - fmt.Printf("neurons: %v\n", net.Neurons) + fmt.Printf("neurons: %v\n", net.neurons) // extract into the current network receiver (net) return nil @@ -130,9 +130,9 @@ func (net *Network) ReadFrom(r io.Reader) (int64, error) { // copy values net.layers = readNet.layers net.fed = readNet.fed - net.Neurons = readNet.Neurons - net.Biases = readNet.Biases - net.Weights = readNet.Weights + net.neurons = readNet.neurons + net.biases = readNet.biases + net.weights = readNet.weights return int64(len(raw)), nil }