Neural networks
Neural networks: Hopfield's memory, its diluted version, the echo state network, and Elman's recurrent network.
BinaryWeightElement(label, on=0.0)
Bases: Element
Weight of a binary perceptron, where the state 1 stands for +1 and the state 0 for -1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the weight or the group. |
required |
on
|
Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]
|
Whether the weight is |
0.0
|
Examples:
>>> from skcomplex.models.computer_science.neural_networks import BinaryWeightElement
>>> BinaryWeightElement('weight', on=1.0).on
1.0
Source code in src/skcomplex/models/computer_science/neural_networks/_binary_weight.py
30 31 32 | |
DilutedNeuronElement(label, visual=None, *, spin=1.0, pattern=1.0, beta=0.06)
Bases: Element
Binary neuron of an asymmetric diluted Hopfield network, updated in parallel with the others at every step.
The logit choice of diluted_hopfield draws the value s = ±1 of the neuron with probability
1 / (1 + exp(-2 s β h)), where h = Σ_j J_ij s_j is its local field, so its mean is tanh(β h).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the neuron or the group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
spin
|
Annotated[float, StateSpec(domain=ZZ)]
|
The initial value, -1 or 1. |
1.0
|
pattern
|
Annotated[float, ParameterSpec()]
|
The value of the first stored pattern at the neuron, whose overlap with the network is recorded. |
1.0
|
beta
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The inverse temperature |
0.06
|
Examples:
>>> from skcomplex.models.computer_science.neural_networks import DilutedNeuronElement
>>> DilutedNeuronElement('neuron').beta
0.06
Source code in src/skcomplex/models/computer_science/neural_networks/_diluted.py
71 72 73 74 75 76 77 78 79 80 81 82 83 | |
HiddenUnitElement(label, visual=None, *, s=0.5, u=0.0, b=0.0)
Bases: Element
Hidden unit of a simple recurrent network, whose activity is a sigmoid of its recurrent input and its drive.
The drive u holds the weighted input of the previous step, and the bias b is adaptive, so training changes it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the element or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
s
|
Annotated[float, StateSpec()]
|
The activity in |
0.5
|
u
|
Annotated[float, StateSpec()]
|
The weighted input of the previous step. |
0.0
|
b
|
Annotated[float, ParameterSpec(adaptive=True)]
|
The bias, an adaptive parameter. |
0.0
|
Examples:
>>> from skcomplex.models.computer_science.neural_networks import HiddenUnitElement
>>> HiddenUnitElement('unit').s
0.5
Source code in src/skcomplex/models/computer_science/neural_networks/_hidden_unit.py
39 40 41 42 43 44 45 46 47 48 49 50 51 | |
HopfieldUpdateInteraction(label, *, target)
Bases: MapInteraction
Asynchronous update of a Hopfield network, where every neuron in turn takes the sign of its weighted input.
The neurons update one after the other in a new random order every step, each reading the states the neurons before
it set, so the energy -sum w_ij s_i s_j / 2 never increases. A neuron whose input is zero keeps its state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of neurons. |
required |
Examples:
>>> from skcomplex.models.computer_science.neural_networks import HopfieldUpdateInteraction
>>> HopfieldUpdateInteraction('update', target='neurons').check().schedule
'random-sequential'
Source code in src/skcomplex/models/computer_science/neural_networks/_hopfield_update.py
35 36 37 38 39 40 41 42 43 | |
InputCouplingInteraction(label, *, target, source, D=0.0)
Bases: CouplingInteraction
Weighted input of a simple recurrent network, which sets the drive u = D x of every hidden unit each step.
The weights D are an adaptive matrix with one row per hidden unit and one column per input unit, so training
changes them. The coupling runs in the phase drive of the step, which the system declares before the phases
hidden of the recurrence and readout of the readout, so the hidden units read the drive of the same step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction, unique among the parts of its system. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of hidden units. |
required |
source
|
Annotated[str, RoleSpec()]
|
The path of the group of input units. |
required |
D
|
Annotated[object, ParameterSpec(shape=(target, source), adaptive=True)]
|
The input weights, a matrix of shape |
0.0
|
Examples:
>>> from skcomplex.models.computer_science.neural_networks import InputCouplingInteraction
>>> InputCouplingInteraction('input', target='hidden', source='inputs').write
'u'
Source code in src/skcomplex/models/computer_science/neural_networks/_input_coupling.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
InputUnitElement(label, visual=None, *, x=0.0)
Bases: Element
Input unit of a simple recurrent network, whose value a dataset or a schedule sets at every step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the element or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
x
|
Annotated[float, ParameterSpec()]
|
The input. |
0.0
|
Examples:
>>> from skcomplex.models.computer_science.neural_networks import InputUnitElement
>>> InputUnitElement('bit').x
0.0
Source code in src/skcomplex/models/computer_science/neural_networks/_input_unit.py
31 32 33 34 35 36 37 38 39 | |
NeuronElement(label, visual=VisualSpec('agents', {'color_by': 'spin', 'color_range': (-1.0, 1.0)}), *, spin=1.0, weights=0.0)
Bases: Element
Binary neuron of a Hopfield network, which the update aligns with the sign of its weighted input.
The neuron sits on its node of a complete graph and holds the weights of its incoming links, one per node.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'spin', 'color_range': (-1.0, 1.0)})
|
spin
|
Annotated[float, StateSpec(domain=ZZ)]
|
The initial state, -1 or 1. |
1.0
|
weights
|
Annotated[object, StateSpec()]
|
The weights of the links from every node, an array with one value per node. |
0.0
|
Examples:
>>> from skcomplex.models.computer_science.neural_networks import NeuronElement
>>> group = GroupElement('neurons', element=NeuronElement, size=4, values={'spin': 1.0})
>>> group.label, group.element.__name__, group.size
('neurons', 'NeuronElement', 4)
Source code in src/skcomplex/models/computer_science/neural_networks/_hopfield.py
55 56 57 58 59 60 61 62 63 64 65 | |
OutputUnitElement(label, visual=None, *, y=0.5, c=0.0, target=0.0)
Bases: Element
Output unit of a simple recurrent network, whose activity predicts a target.
The bias c is adaptive, so training changes it, and the target is a parameter a dataset or a schedule sets.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the element or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
y
|
Annotated[float, StateSpec()]
|
The prediction in |
0.5
|
c
|
Annotated[float, ParameterSpec(adaptive=True)]
|
The bias, an adaptive parameter. |
0.0
|
target
|
Annotated[float, ParameterSpec()]
|
The value the prediction is compared with. |
0.0
|
Examples:
>>> from skcomplex.models.computer_science.neural_networks import OutputUnitElement
>>> OutputUnitElement('prediction').target
0.0
Source code in src/skcomplex/models/computer_science/neural_networks/_output_unit.py
39 40 41 42 43 44 45 46 47 48 49 50 51 | |
ReadoutCouplingInteraction(label, *, target, source, W=0.0)
Bases: CouplingInteraction
Readout of a simple recurrent network, y_i <- sigmoid(sum_j W_ij s_j + c_i) with the logistic sigmoid.
Every output unit reads the activities of the hidden units through the adaptive matrix W, adds its bias c, and
takes the sigmoid of the sum as its next prediction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction, unique among the parts of its system. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of output units. |
required |
source
|
Annotated[str, RoleSpec()]
|
The path of the group of hidden units. |
required |
W
|
Annotated[object, ParameterSpec(shape=(target, source), adaptive=True)]
|
The readout weights, a matrix of shape |
0.0
|
Examples:
>>> from skcomplex.models.computer_science.neural_networks import ReadoutCouplingInteraction
>>> ReadoutCouplingInteraction('readout', target='outputs', source='hidden').write
'y'
Source code in src/skcomplex/models/computer_science/neural_networks/_readout_coupling.py
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | |
RecurrenceCouplingInteraction(label, *, target, A=0.0)
Bases: CouplingInteraction
Recurrence of a simple recurrent network, s_i <- sigmoid(sum_j A_ij s_j + u_i + b_i) with the logistic sigmoid.
Every hidden unit reads the activities of every hidden unit, itself included, through the adaptive matrix A, adds
its drive u and its bias b, and takes the sigmoid of the sum as its next activity (Gros 2015 Eq. 10.18).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction, unique among the parts of its system. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of hidden units. |
required |
A
|
Annotated[object, ParameterSpec(shape=(target, target), adaptive=True)]
|
The recurrent weights, a square matrix with one row and one column per hidden unit, or a number for every entry. |
0.0
|
Examples:
>>> from skcomplex.models.computer_science.neural_networks import RecurrenceCouplingInteraction
>>> RecurrenceCouplingInteraction('recurrence', target='hidden').include_self
True
Source code in src/skcomplex/models/computer_science/neural_networks/_recurrence_coupling.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | |
ReservoirUnitElement(label, visual=None, *, r=0.0, w_in=1.0, leak=0.3, amplitude=1.0, frequency=0.2)
Bases: Element
Leaky tanh unit of an echo state network, with its activity and the weight, leak, and sine of its input.
The map of echo_state_network sets r(t + 1) = (1 - a) r + a tanh(sum_j W_ij r_j + w u(t)) with the input
u(t) = A sin(f t).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the unit or the group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
r
|
Annotated[float, StateSpec()]
|
The initial activity. |
0.0
|
w_in
|
Annotated[float, ParameterSpec()]
|
The weight |
1.0
|
leak
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The leak rate |
0.3
|
amplitude
|
Annotated[float, ParameterSpec()]
|
The amplitude |
1.0
|
frequency
|
Annotated[float, ParameterSpec()]
|
The angular frequency |
0.2
|
Examples:
>>> from skcomplex.models.computer_science.neural_networks import ReservoirUnitElement
>>> ReservoirUnitElement('unit').leak
0.3
Source code in src/skcomplex/models/computer_science/neural_networks/_echo_state.py
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | |
diluted_hopfield(n_neurons=4000, *, connectivity=50.0, load=0.2, temperature_scale=3.0, overlap=0.3, random_state=0)
Return the asymmetric diluted Hopfield network, which recalls a stored pattern below its memory capacity.
The network stores p = load K random patterns in the couplings J_ij = C_ij Σ_μ ξ_i ξ_j, where every C_ij is
1 with probability K / N independently of C_ji, so the couplings are sparse and asymmetric. All neurons update
together at the inverse temperature β = temperature_scale / K. Started with an overlap m with the first pattern,
the overlap follows m(t + 1) = f(m(t)) for large K, which keeps a nonzero fixed point below the critical load
2 / π.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_neurons
|
int
|
The number of neurons |
4000
|
connectivity
|
float
|
The mean number |
50.0
|
load
|
float
|
The ratio |
0.2
|
temperature_scale
|
float
|
The product |
3.0
|
overlap
|
float
|
The initial overlap with the first pattern. |
0.3
|
random_state
|
int | Generator | None
|
The seed or generator of the patterns, the dilution, and the initial values. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The model, with the values |
Examples:
>>> from skcomplex.models.computer_science.neural_networks import diluted_hopfield
>>> diluted_hopfield(200, connectivity=10).elements[0].check().prepare().size_
200
Source code in src/skcomplex/models/computer_science/neural_networks/_diluted.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | |
echo_state_network(n_units=200, *, spectral_radius=0.9, leak=0.3, connectivity=0.1, input_scaling=1.0, amplitude=1.0, frequency=0.2, random_state=0)
Return an echo state network, a reservoir of leaky tanh units with random recurrent weights driven by a sine.
The recurrent weights are sparse and Gaussian, scaled to a spectral radius below 1, so the reservoir has the echo
state property: its activities forget their initial values and become a function of the input history alone. A
readout trained on these activities, as skcomplex.analysis.ReservoirAnalysis does, turns the reservoir
into a forecaster.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_units
|
int
|
The number of units. |
200
|
spectral_radius
|
float
|
The largest modulus of the eigenvalues of the recurrent weights. |
0.9
|
leak
|
float
|
The leak rate of every unit, 1 for units without memory of their own. |
0.3
|
connectivity
|
float
|
The share of the recurrent weights that are not zero. |
0.1
|
input_scaling
|
float
|
The scale of the input weights, drawn uniformly from |
1.0
|
amplitude
|
float
|
The amplitude of the sine input. |
1.0
|
frequency
|
float
|
The angular frequency of the sine input, per step. |
0.2
|
random_state
|
int | Generator | None
|
The seed or generator of the weights and of the initial activities. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The model, with the group |
Examples:
>>> from skcomplex.models.computer_science.neural_networks import echo_state_network
>>> echo_state_network(50).elements[0].check().prepare().size_
50
Source code in src/skcomplex/models/computer_science/neural_networks/_echo_state.py
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | |
elman_network(n_hidden=4, *, n_bits=3000, window=12, batch_size=16, learning_rate=0.05, truncation=None, random_state=0)
Return Elman's simple recurrent network, which learns to predict the next bit of a temporal XOR stream.
The nested discrete map net holds one input unit, n_hidden hidden units, and one output unit. The input sets
the drive u = D x of the hidden units, the hidden units take s <- sigmoid(A s + u + b) (Gros 2015 Eq. 10.18),
and the output predicts y <- sigmoid(W s + c), in three phases of every step, so the prediction of a step reads
its input. The training interaction training trains D, A, W, b, and c with Adam on the squared error
of predicting the next input from the inputs so far, over windows of window bits that start at every third bit of
a stream in which every third bit is the exclusive or of the two before it. Only those bits can be predicted, so
the metric xor_error falls toward 0 while random_error, the error on the other bits, stays near 0.25. One step
of the system is one epoch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_hidden
|
int
|
The number of hidden units. |
4
|
n_bits
|
int
|
The length of the stream. |
3000
|
window
|
int
|
The number of bits of a sequence. |
12
|
batch_size
|
int
|
The number of sequences of a batch. |
16
|
learning_rate
|
float
|
The learning rate of Adam. |
0.05
|
truncation
|
int | None
|
The number of steps the gradient flows back through the hidden activities, 1 for Elman's original rule
that holds the previous activities as constant context, or |
None
|
random_state
|
int | Generator | None
|
The seed or generator of the stream and of the initial weights. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The model, with the nested system |
Examples:
>>> from skcomplex.models.computer_science.neural_networks import elman_network
>>> [item.label for item in elman_network().systems]
['net']
Source code in src/skcomplex/models/computer_science/neural_networks/_elman.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | |
hopfield(patterns=None, *, n_neurons=64, n_patterns=3, noise=0.2, random_state=0)
Return a Hopfield network that stores patterns with Hebb's rule and recalls the first from a corrupted copy.
Neurons update one at a time in random order, so the energy -Σ w_ij s_i s_j / 2 never increases and the network
settles in a stored pattern when few patterns are stored, about fewer than 0.14 n for n neurons.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
patterns
|
ArrayLike | None
|
The stored patterns of -1 and 1, one row per pattern, or |
None
|
n_neurons
|
int
|
The number of neurons of random patterns. |
64
|
n_patterns
|
int
|
The number of random patterns. |
3
|
noise
|
float
|
The probability that a neuron starts flipped from the first pattern. |
0.2
|
random_state
|
int | Generator | None
|
The seed or generator of the random patterns and of the corruption. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The model, with the group |
Examples:
>>> from skcomplex.models.computer_science.neural_networks import hopfield
>>> hopfield(n_neurons=16, n_patterns=2).elements[0].check().prepare().size_
16
Source code in src/skcomplex/models/computer_science/neural_networks/_hopfield.py
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | |
perceptron_satisfiability(n_weights=21, *, load=1.5, random_state=0)
Return a binary perceptron that must store random patterns, revealed one per step, as cardinality constraints.
A pattern xi of output sigma holds when sigma sum_i w_i xi_i > 0, so with an odd number N of weights
w_i = +-1, when at least (N + 1) / 2 of the literals w_i = sigma xi_i hold. The patterns are satisfiable up to
the critical load p / N of about 0.83 in the limit of many weights (Bertin 2021 §6.3.3, Ex. 6.4). The patterns are
drawn from random_state, so a disorder average sweeps it through GridDesign.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_weights
|
int
|
The number of weights, which is odd. |
21
|
load
|
float
|
The number of patterns over the number of weights. |
1.5
|
random_state
|
int | Generator | None
|
The seed or generator of the patterns. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The model, with the group |
Raises:
| Type | Description |
|---|---|
ValidationError
|
The number of weights is even, so a pattern can tie. |
Examples:
>>> from skcomplex.models.computer_science.neural_networks import perceptron_satisfiability
>>> perceptron_satisfiability(3, load=1.0).interactions[0].constraints[0].bound
2
Source code in src/skcomplex/models/computer_science/neural_networks/_perceptron.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |