unexport network features (neurons, weights, biases)
This commit is contained in:
parent
a180e09cf0
commit
eee503a405
62
network.go
62
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))
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
24
storage.go
24
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue