Documentation ¶
Index ¶
- Constants
- type BinaryCost
- type ConnID
- type Connection
- type Coster
- type CrossEntropyCost
- type GateType
- type Hopfield
- type Layer
- func (l *Layer) Activate(inputs []float64) ([]float64, error)
- func (l *Layer) Gate(conn *LayerConnection, gateType GateType) error
- func (l *Layer) Project(toLayer *Layer, ltype LayerType) *LayerConnection
- func (l *Layer) Propagate(rate float64, target []float64) error
- func (l *Layer) SetBias(bias float64)
- type LayerConnection
- type LayerType
- type LookupTable
- func (t *LookupTable) GetConnection(id ConnID) *Connection
- func (t *LookupTable) GetNeuron(id NeuronID) *Neuron
- func (t *LookupTable) SetConnection(conn *Connection) ConnID
- func (t *LookupTable) SetConnectionWithID(id ConnID, conn *Connection)
- func (t *LookupTable) SetNeuron(neuron *Neuron) NeuronID
- type MeanSquaredErrorCost
- type Network
- func (n *Network) Activate(input []float64) ([]float64, error)
- func (n *Network) Gate(conn *LayerConnection, gateType GateType)
- func (n *Network) ProjectLayer(layer *Layer, ltype LayerType)
- func (n *Network) ProjectNetwork(network *Network, ltype LayerType)
- func (n *Network) Propagate(rate float64, target []float64) error
- type Networker
- type Neuron
- type NeuronID
- type SquashIdentity
- type SquashLogistic
- type SquashRelu
- type SquashTanh
- type Squasher
- type TrainSet
- type Trainer
Constants ¶
const ( GateTypeInput = iota GateTypeOutput GateTypeOneToOne )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BinaryCost ¶
type BinaryCost struct{}
BinaryCost implement the binary (Zero-One Loss) function
func (*BinaryCost) Cost ¶
func (c *BinaryCost) Cost(target, output []float64) float64
Cost of the given output
type Connection ¶
type Connection struct { ID ConnID From *Neuron To *Neuron Gater *Neuron Weight float64 Gain float64 }
Connection represents a connection between two neurons.
func NewConnection ¶
func NewConnection(from, to *Neuron, weight *float64) *Connection
type Coster ¶
type Coster interface { // Cost of the given output. The length of target and output will always be the same. Cost(target, output []float64) (cost float64) }
Coster defines a cost function for use with the Trainer.
type CrossEntropyCost ¶
type CrossEntropyCost struct{}
CrossEntropyCost implement the cross entropy function (Eq. 9)
func (*CrossEntropyCost) Cost ¶
func (c *CrossEntropyCost) Cost(target, output []float64) (cost float64)
Cost of the given output
type Hopfield ¶
type Hopfield struct {
Network
}
func NewHopfieldNetwork ¶
func NewHopfieldNetwork(table *LookupTable, size int) *Hopfield
NewHopfieldNetwork creates a new Hopfield network. 'size' dictates the number of input neurons and the number of output neurons. Generally this value should match the number of boolean options in your network e.g. 1 neuron per pixel if recalling images.
type Layer ¶
type Layer struct { List []*Neuron ConnectedTo []LayerConnection LookupTable *LookupTable }
Layer represents a group of neurons which activate together.
func NewLayer ¶
func NewLayer(table *LookupTable, size int) Layer
func (*Layer) Gate ¶
func (l *Layer) Gate(conn *LayerConnection, gateType GateType) error
Gate a connection between two layers.
func (*Layer) Project ¶
func (l *Layer) Project(toLayer *Layer, ltype LayerType) *LayerConnection
Project a connection from this layer to another one.
type LayerConnection ¶
type LayerConnection struct { From *Layer To *Layer Type LayerType Connections map[ConnID]*Connection List []*Connection }
LayerConnection represents a connection between two layers.
func NewLayerConnection ¶
func NewLayerConnection(from, to *Layer, ltype LayerType) LayerConnection
type LookupTable ¶
type LookupTable struct { Neurons []*Neuron Connections []*Connection }
LookupTable stores mappings of:
- Neuron IDs to Neurons
- Connection IDs to Connections
It can be thought of as a global hash map, but is implemented slightly differently for performance reasons.
Rationale: Neurons need references to other neurons/connections (e.g. neighbours). The simplest way to do this is to store a map[ID]*Thing in the Neuron struct itself. This ends up being slow because this is called a lot and each time incurs hashing overheads. It would be better if this was done as a slice, especially since network topologies don't tend to change at runtime so there are no resizing overheads. This means the IDs would be indexes. LookupTable is a massive global slice which provides Neurons/Layers/Connections access to each other via their ID. It's not a true global variable as it is dependency injected at the point of use, allowing the ability of running multiple disconnected networks without sharing the same ID space. Sharing the same LookupTable for all neurons in a network also lowers memory usage from O(n) to O(1), as each neuron is not having to store its own mini lookup table.
func (*LookupTable) GetConnection ¶
func (t *LookupTable) GetConnection(id ConnID) *Connection
GetConnection from the lookup table. Returns nil if the ID does not exist in the table.
func (*LookupTable) GetNeuron ¶
func (t *LookupTable) GetNeuron(id NeuronID) *Neuron
GetNeuron from the lookup table. Returns nil if the ID does not exist in the table.
func (*LookupTable) SetConnection ¶
func (t *LookupTable) SetConnection(conn *Connection) ConnID
SetConnection in the lookup table. Returns the ID for this connection.
func (*LookupTable) SetConnectionWithID ¶
func (t *LookupTable) SetConnectionWithID(id ConnID, conn *Connection)
SetConnectionWithID in the lookup table. If the ID is already associated with a Connection then it is replaced.
func (*LookupTable) SetNeuron ¶
func (t *LookupTable) SetNeuron(neuron *Neuron) NeuronID
SetNeuron in the lookup table. Returns the ID for this neuron.
type MeanSquaredErrorCost ¶
type MeanSquaredErrorCost struct{}
MeanSquaredErrorCost implements the MSE cost function.
func (*MeanSquaredErrorCost) Cost ¶
func (c *MeanSquaredErrorCost) Cost(target, output []float64) (cost float64)
Cost of the given output.
type Network ¶
Network represents an arbitrary artificial neural network.
func NewLSTM ¶
func NewLSTM(table *LookupTable, inputSize int, memoryBlocks []int, outputSize int) *Network
NewLSTM creates a new Long-Short Term Memory network. 'inputSize' is the number of neurons in the input layer. 'outputSize' is the number of neurons in the output layer. The length of 'memoryBlocks' determines how many memory blocks the network will have, whilst the elements determine the number of memory cells in that block.
func NewPerceptronNetwork ¶
func NewPerceptronNetwork(table *LookupTable, sizesOfLayers []int) (*Network, error)
NewPerceptronNetwork creates a new Perceptron with the number of layers equal to the length of the provided slice. The elements in the slice determine the size of each layer. The first element is the input layer. The last element is the output layer. The inbetween elements are hidden layers. The length of the slice must be at least 3 to accomodate an input, hidden and output layer. For example:
// create a network with: // - 2 neurons on the input layer // - 3 neurons on the first hidden layer // - 4 neurons on the second hidden layer // - 1 neuron on the output layer perceptron := automata.NewPerceptron([]int{2,3,4,1})
func (*Network) Activate ¶
Activate the network with the given neuron, feeding forward to produce an output.
func (*Network) Gate ¶
func (n *Network) Gate(conn *LayerConnection, gateType GateType)
func (*Network) ProjectLayer ¶
func (*Network) ProjectNetwork ¶
func (*Network) Propagate ¶
Propagate the error through the entire network.
This is subject to the Vanishing Gradient problem. As errors propagate, they will be multiplied by the weights which are typically a fraction between 0-1. This will rapidly diminish the error value as the error continues to propagate, and can be exacerbated depending on the squashing function used, making earlier layers difficult to train.
type Networker ¶
type Networker interface { Activate(input []float64) ([]float64, error) Propagate(rate float64, target []float64) error }
Networker represents an abstraction of a Network, which is used primarily with the Trainer to accommodate different Network structs such as Hopfield.
type Neuron ¶
type Neuron struct { ID NeuronID Old float64 State float64 Derivative float64 Activation float64 Self *Connection Squash Squasher Bias float64 Neighbours []NeuronID Inputs []ConnID Projected []ConnID Gated []ConnID ErrorResponsibility float64 ErrorProjected float64 ErrorGated float64 TraceEligibility []float64 // Efficient form of map[ConnID]float64 TraceExtended map[NeuronID]map[ConnID]float64 TraceInfluences map[NeuronID][]ConnID LookupTable *LookupTable }
Neuron represents a base unit of work in a neural network.
func NewNeuron ¶
func NewNeuron(table *LookupTable) *Neuron
func (*Neuron) Activate ¶
Activate this neuron with an optional input.
The logic in this function is based on "A generalized LSTM-like training algorithm for second-order recurrent neural networks" See: http://www.overcomplete.net/papers/nn2012.pdf
func (*Neuron) ConnectionForNeuron ¶
func (n *Neuron) ConnectionForNeuron(target *Neuron) *Connection
ConnectionForNeuron returns the connection between the two neurons or nil if there is no connection.
func (*Neuron) Gate ¶
func (n *Neuron) Gate(conn *Connection)
func (*Neuron) Project ¶
func (n *Neuron) Project(targetNeuron *Neuron, weight *float64) *Connection
func (*Neuron) Propagate ¶
Propagate an error through this neuron. 'rate' is the learning rate for this neuron, target is set if this neuron forms part of an output layer, otherwise is nil.
The logic in this function is based on "A generalized LSTM-like training algorithm for second-order recurrent neural networks" See: http://www.overcomplete.net/papers/nn2012.pdf
type SquashRelu ¶
type SquashRelu struct{}
SquashRelu implements the ReLU activation function, which is not subject to the Vanishing Gradient problem . https://en.wikipedia.org/wiki/Rectifier_(neural_networks)
type Squasher ¶
type Squasher interface { // Squash an input x into a suitable output. If 'derivate' is true, the derivative should // be returned. Squash(x float64, derivate bool) float64 }
Squasher implements a squashing function which can be used as an activation function. Squashing functions modify inputs allowing neurons to model non-linear relationships. This typically involves clamping/bounding the output at one or both ends.
These functions can be very sensitive to the weights which are applied to them which can make training difficult because you need to discover the precise weightings which will squash the input in the way you want. Some functions can exacerbate the Vanishing Gradient problem.
Common squash functions are already implemented.