A lightweight, pure Go implementation of a feedforward neural network with backpropagation training. Perfect for learning neural network fundamentals or building small machine learning models directly in Go.
- Modular Architecture: Clean separation between neurons, layers, and networks
- Backpropagation Training: Implements standard backpropagation algorithm for model training
- Sigmoid Activation: Uses sigmoid activation function for non-linearity
- Flexible Network Configuration: Create networks with arbitrary layer sizes
- Learning Rate Support: Adjustable learning rates for training control
- Delta-based Learning: Support for both direct corrections and delta propagation
- Binary Serialize/Deserialize: Persist network weights and biases to an io.Writer/io.Reader
go get github.com/boolka/goaipkg/
├── neuron/ # Individual neuron implementation
├── layer/ # Layer of neurons
└── network/ # Multi-layer neural network and serialization helpers
A single neuron with weights, bias, sigmoid activation, and training methods.
type Neuron struct {
Weights []float64 // Connection weights
Bias float64 // Bias term
}A collection of neurons that operate on the same inputs.
type NeuronLayer struct {
Neurons []neuron.Neuron
}A complete feedforward neural network composed of multiple layers.
type Network struct {
Layers []layer.NeuronLayer
}Train a simple 3-layer network to learn a XOR-like pattern:
package main
import (
"fmt"
"github.com/boolka/goai/pkg/network"
)
func main() {
// Create a network with 3 input neurons, 3 hidden neurons, 3 output neurons
net := network.NewNetwork([]int{3, 3, 3})
// Randomize weights and biases
net.Randomize(1.0)
// Define training data
inputs := []float64{10.0, 0.5, -20.0}
expectedOutputs := []float64{1.0, 0.0, 1.0}
learningRate := 0.01
// Get prediction before training
prediction := net.Activate(inputs)
fmt.Printf("Before training: %v\n", prediction)
// Train the network
for i := 0; i < 10000; i++ {
output := net.Correct(inputs, expectedOutputs, learningRate)
// Print progress
if i%1000 == 0 {
fmt.Printf("Iteration %d: %v\n", i, output)
}
}
// Get prediction after training
finalPrediction := net.Activate(inputs)
fmt.Printf("After training: %v\n", finalPrediction)
fmt.Printf("Expected: %v\n", expectedOutputs)
}Train a network until it reaches desired accuracy:
package main
import (
"fmt"
"math"
"github.com/boolka/goai/pkg/network"
)
func main() {
// Create network
net := network.NewNetwork([]int{2, 4, 1})
net.Randomize(0.5)
// Training parameters
inputs := []float64{0.5, 0.3}
expected := []float64{0.8}
learningRate := 0.01
tolerance := 1e-3
// Training loop with early stopping
converged := false
iterations := 0
maxIterations := 100000
for iterations = 0; iterations < maxIterations; iterations++ {
output := net.Correct(inputs, expected, learningRate)
// Check if converged
converged = true
for i, out := range output {
if math.Abs(out-expected[i]) > tolerance {
converged = false
break
}
}
if converged {
break
}
if iterations%10000 == 0 {
fmt.Printf("Iteration %d | Output: %.6f | Error: %.6f\n",
iterations, output[0], math.Abs(output[0]-expected[0]))
}
}
if converged {
fmt.Printf("Training completed in %d iterations\n", iterations)
fmt.Printf("Final output: %.6f\n", net.Activate(inputs)[0])
} else {
fmt.Printf("Training did not converge after %d iterations\n", maxIterations)
}
}Train on multiple samples in sequence:
package main
import (
"fmt"
"github.com/boolka/goai/pkg/network"
)
func main() {
// Create network
net := network.NewNetwork([]int{2, 128, 128, 128, 2})
net.Randomize(1.0)
trainingData := []struct {
inputs []float64
expected []float64
}{
{[]float64{0, 1}, []float64{1, 0}},
{[]float64{1, 0}, []float64{0, 1}},
{[]float64{1, 1}, []float64{0, 0}},
{[]float64{0, 0}, []float64{1, 1}},
}
learningRate := 0.04
// Train for multiple epochs
for epoch := 0; epoch < 5000; epoch++ {
totalError := 0.0
for _, sample := range trainingData {
output := net.Correct(sample.inputs, sample.expected, learningRate)
// Calculate error
for i, out := range output {
diff := out - sample.expected[i]
totalError += diff * diff
}
}
if epoch%500 == 0 {
fmt.Printf("Epoch %d | Average Error: %.6f\n", epoch, totalError/float64(len(trainingData)))
}
}
// Test predictions
fmt.Println("\nFinal Predictions:")
for _, sample := range trainingData {
prediction := net.Activate(sample.inputs)
fmt.Printf("Input: %v | Output: %v | Expected: %v\n",
sample.inputs, prediction, sample.expected)
}
}NewNetwork(layerSizes []int) *Network- Create a new network with specified layer sizesRandomize(rng float64)- Randomize all weights and biasesActivate(inputs []float64) []float64- Forward pass through networkCorrect(inputs []float64, expected []float64, learningRate float64) []float64- Train on a single sample
NewLayer(neuronCount int, inputCount int) *NeuronLayer- Create a layerRandomize(rng float64)- Randomize layer weights and biasesActivate(inputs []float64) []float64- Forward pass through layerCorrect(inputs []float64, outputs []float64, expected []float64, learningRate float64) []float64- Train layer and return previous-layer deltasCorrectByDelta(inputs []float64, outputs []float64, inDeltas []float64, learningRate float64) []float64- Train with delta backprop and return previous-layer deltas
NewNeuron(weights []float64, bias float64) *Neuron- Create a neuronRandomize(rng float64)- Randomize weights and biasActivate(inputs []float64) float64- Sigmoid activationCorrect(inputs []float64, output float64, expected float64, learningRate float64) float64- Train with output error and return deltaCorrectByDelta(inputs []float64, output float64, delta float64, learningRate float64)- Train with propagated delta
Serialize(f io.Writer) error- Serialize all weights and biases to binary formDeserialize(f io.Reader) error- Deserialize all weights and biases from binary form
- Each neuron computes a weighted sum of inputs plus bias
- The sum is passed through a sigmoid activation function
- The output is passed to the next layer
- Compute error at output layer
- Calculate delta for each output neuron
- Backpropagate deltas through hidden layers
- Update weights and biases using deltas and learning rate
MIT License - see LICENSE file for details.