nn
Neural network layers: linear, convolutional, recurrent, transformer, and checkpoints.
import nn
This package has ready made layers for building a model. The weights of every layer live in one ParamStore; make each layer with a New... function and a unique name, and call forward on the tape at every step. Sequential runs several layers one after the other.
Once it is trained with optim, save the model with SaveCheckpoint and load it again later.
Types
Parameter
struct Parameter| Name | Type | Description |
|---|---|---|
name | str = "" | The name. |
value | tensor.Tensor | The value. |
grad | tensor.Tensor | The gradient. |
import nn
import autograd
import optim
import tensor
import os
import compress
func main:
mut store := nn.ParamStore {}
mut rng := tensor.NewRng(3)
fc1 := nn.NewLinear(store, "fc1", 2, 8, rng)
fc2 := nn.NewLinearNoBias(store, "fc2", 8, 1, rng)
mut model := nn.Sequential {}
model.add(fc1)
model.add(nn.TanhLayer {})
model.add(fc2)
println store.count()
mut inputs := tensor.Reshape(tensor.Arange(8), tensor.Shape2(4, 2))
tensor.ScaleInPlace(inputs, 0.25)
mut target := tensor.Zeros2(4, 1)
repeat 4 in i:
target.set_at(i, inputs.at2(i, 0) + inputs.at2(i, 1))
end
mut adam := optim.Adam { lr = 0.05 }
mut tape := autograd.NewTape(1)
mut last := 0.0
repeat 300:
tape.reset()
store.zero_grad()
output := model.forward(tape, store, autograd.Input(tape, inputs))
loss := autograd.MSELoss(tape, output, autograd.Constant(tape, target))
autograd.Backward(tape, loss)
adam.step(store)
last = autograd.Value(tape, loss).at(0)
end
println last < 0.01
mut p := store.at(fc1.w)
println p.name, tensor.ShapeString(p.value), tensor.ShapeString(p.grad)
weight_node := nn.Bind(tape, store, fc1.w)
println tensor.ShapeString(autograd.Value(tape, weight_node))
path := os.TempDir() + "/salam_mlp_en.ckpt"
println nn.SaveCheckpoint(path, store), nn.LoadCheckpoint(path, store)
mut buffer := nn.SaveCheckpointBuf(store)
println nn.LoadCheckpointBuf(buffer, store)
compress.BufFree(buffer)
mut images := tensor.Ones(tensor.Shape4(2, 1, 8, 8))
conv := nn.NewConv2D(store, "conv", 1, 4, 3, 1, 1, rng)
mut batch_norm := nn.NewBatchNorm(store, "bn", 4)
group_norm := nn.NewGroupNorm(store, "gn", 4, 2)
pool := nn.MaxPool2D { size = 2, stride = 2 }
average := nn.AvgPool2D {}
h := conv.forward(tape, store, autograd.Input(tape, images))
h2 := group_norm.forward(tape, store, batch_norm.forward(tape, store, h))
h3 := average.forward(tape, pool.forward(tape, nn.ReluLayer {}.forward(tape, store, h2)))
flat := nn.Flatten(tape, h3)
println tensor.ShapeString(autograd.Value(tape, h)), tensor.ShapeString(autograd.Value(tape, flat))
row := autograd.Input(tape, tensor.Ones(tensor.Shape2(2, 4)))
layer_norm := nn.NewLayerNorm(store, "ln", 4)
rms_norm := nn.NewRMSNorm(store, "rms", 4)
drop := nn.Dropout { p = 0.0 }
gelu := nn.GeluLayer {}
out := gelu.forward(tape, store, drop.forward(tape, rms_norm.forward(tape, store, layer_norm.forward(tape, store, row))))
println tensor.ShapeString(autograd.Value(tape, out))
mut weight := tensor.Zeros2(64, 64)
nn.XavierUniform(weight, 64, 64, rng)
println tensor.MaxAll(tensor.Abs(weight)) <= 0.22
nn.XavierNormal(weight, 64, 64, rng)
nn.KaimingUniform(weight, 64, rng)
println tensor.MaxAll(tensor.Abs(weight)) <= 0.31
nn.KaimingNormal(weight, 64, rng)
println tensor.MaxAll(tensor.Abs(weight)) > 0.0
tape.free()
adam.free()
model.free()
batch_norm.free()
store.free()
endParamStore
struct ParamStore| Name | Type | Description |
|---|---|---|
items | Vector | The parameters. |
The example for this item is shown with the ones above: nn-Layers.salam
add
func add(name: str, t: tensor.Tensor): intThe example for this item is shown with the ones above: nn-Layers.salam
count
func count(): intThe example for this item is shown with the ones above: nn-Layers.salam
at
func at(h: int): ParameterThe example for this item is shown with the ones above: nn-Layers.salam
zero_grad
func zero_grad()The example for this item is shown with the ones above: nn-Layers.salam
free
func free()The example for this item is shown with the ones above: nn-Layers.salam
Linear
struct Linear| Name | Type | Description |
|---|---|---|
w | int = -1 | The weight index. |
b | int = -1 | The bias index. |
in_features | int = 0 | The input size. |
out_features | int = 0 | The output size. |
has_bias | bool = true | It has a bias. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
LSTM
struct LSTM| Name | Type | Description |
|---|---|---|
wx | Linear | The input weight. |
wh | Linear | The state weight. |
hidden | int = 0 | The state size. |
import nn
import autograd
import tensor
func shape(tape &: autograd.Tape, node: int): str:
ret tensor.ShapeString(autograd.Value(tape, node))
end
func main:
batch := 2
length := 3
dim := 8
mut store := nn.ParamStore {}
mut rng := tensor.NewRng(11)
mut tape := autograd.NewTape(1)
embedding := nn.NewEmbedding(store, "embed", 10, dim, rng)
mut tokens := Vector {} as Vector<int>
each t in [1, 2, 3, 4, 5, 6]:
tokens.push(t)
end
h := embedding.forward(tape, store, tokens)
mut positions := nn.SinusoidalPositions(batch, length, dim)
h2 := autograd.Add(tape, h, autograd.Input(tape, positions))
println shape(tape, h), tensor.ShapeString(positions)
attention := nn.NewMultiHeadAttention(store, "attn", dim, 2, 0.0, rng)
println shape(tape, attention.forward(tape, store, h2, batch, length))
encoder := nn.NewTransformerEncoderLayer(store, "enc", dim, 2, 16, 0.0, rng)
println shape(tape, encoder.forward(tape, store, h2, batch, length))
decoder := nn.NewTransformerDecoderLayer(store, "dec", dim, 2, 16, 0.0, rng)
println shape(tape, decoder.forward(tape, store, h2, batch, length))
mut mask := nn.CausalMask(length)
println tensor.ToString(tensor.LessScalar(mask, -1.0))
mut sequence := tensor.Ones(tensor.Shape2(length * batch, 4))
lstm := nn.NewLSTM(store, "lstm", 4, 6, rng)
gru := nn.NewGRU(store, "gru", 4, 6, rng)
sequence_input := autograd.Input(tape, sequence)
states := lstm.forward(tape, store, sequence_input, length, batch)
states2 := gru.forward(tape, store, sequence_input, length, batch)
println shape(tape, states), shape(tape, states2), shape(tape, nn.LastStep(tape, states, length, batch))
println store.count() > 10
tape.free()
store.free()
endforward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int, seq: int, batch: int): intThe example for this item is shown with the ones above: nn-Sequence.salam
GRU
struct GRU| Name | Type | Description |
|---|---|---|
wx | Linear | The input weight. |
wh | Linear | The state weight. |
hidden | int = 0 | The state size. |
The example for this item is shown with the ones above: nn-Sequence.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int, seq: int, batch: int): intThe example for this item is shown with the ones above: nn-Sequence.salam
Layer
interface LayerThe example for this item is shown with the ones above: nn-Layers.salam
ReluLayer
struct ReluLayer| Name | Type | Description |
|---|---|---|
unused | int = 0 | Unused. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, _ps &: ParamStore, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
GeluLayer
struct GeluLayer| Name | Type | Description |
|---|---|---|
unused | int = 0 | Unused. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, _ps &: ParamStore, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
TanhLayer
struct TanhLayer| Name | Type | Description |
|---|---|---|
unused | int = 0 | Unused. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, _ps &: ParamStore, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
Sequential
struct Sequential| Name | Type | Description |
|---|---|---|
layers | Vector | The layers. |
The example for this item is shown with the ones above: nn-Layers.salam
add
func add(l: dyn Layer)The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
free
func free()The example for this item is shown with the ones above: nn-Layers.salam
Conv2D
struct Conv2D| Name | Type | Description |
|---|---|---|
w | int = -1 | The weight index. |
b | int = -1 | The bias index. |
stride | int = 1 | The stride. |
pad | int = 0 | The padding. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
MaxPool2D
struct MaxPool2D| Name | Type | Description |
|---|---|---|
size | int = 2 | The window size. |
stride | int = 2 | The stride. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
AvgPool2D
struct AvgPool2D| Name | Type | Description |
|---|---|---|
size | int = 2 | The window size. |
stride | int = 2 | The stride. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
MultiHeadAttention
struct MultiHeadAttention| Name | Type | Description |
|---|---|---|
wq | Linear | The query layer. |
wk | Linear | The key layer. |
wv | Linear | The value layer. |
wo | Linear | The output layer. |
dim | int = 0 | The size. |
heads | int = 1 | The number of heads. |
dropout | f64 = 0 | The drop probability. |
causal | bool = false | Each position sees only the ones before it. |
The example for this item is shown with the ones above: nn-Sequence.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int, batch: int, seq: int): intThe example for this item is shown with the ones above: nn-Sequence.salam
TransformerEncoderLayer
struct TransformerEncoderLayer| Name | Type | Description |
|---|---|---|
attn | MultiHeadAttention | The attention. |
ln1 | LayerNorm | The first normalisation. |
ln2 | LayerNorm | The second normalisation. |
ff1 | Linear | The first feed forward layer. |
ff2 | Linear | The second feed forward layer. |
dropout | f64 = 0 | The drop probability. |
The example for this item is shown with the ones above: nn-Sequence.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int, batch: int, seq: int): intThe example for this item is shown with the ones above: nn-Sequence.salam
Dropout
struct Dropout| Name | Type | Description |
|---|---|---|
p | f64 = 0.1 | The drop probability. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
Embedding
struct Embedding| Name | Type | Description |
|---|---|---|
w | int = -1 | The table index. |
vocab | int = 0 | The vocabulary size. |
dim | int = 0 | The vector size. |
The example for this item is shown with the ones above: nn-Sequence.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, indices &: Vector<int>): intThe example for this item is shown with the ones above: nn-Sequence.salam
LayerNorm
struct LayerNorm| Name | Type | Description |
|---|---|---|
gamma | int = -1 | The gamma index. |
beta | int = -1 | The beta index. |
eps | f64 = 1e-05 | The small number for stability. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
BatchNorm
struct BatchNorm| Name | Type | Description |
|---|---|---|
gamma | int = -1 | The gamma index. |
beta | int = -1 | The beta index. |
running_mean | tensor.Tensor | The running mean, for prediction. |
running_var | tensor.Tensor | The running variance. |
momentum | f64 = 0.1 | The coefficient for updating the running statistics. |
eps | f64 = 1e-05 | The small number for stability. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
free
func free()The example for this item is shown with the ones above: nn-Layers.salam
GroupNorm
struct GroupNorm| Name | Type | Description |
|---|---|---|
gamma | int = -1 | The gamma index. |
beta | int = -1 | The beta index. |
groups | int = 1 | The number of groups. |
eps | f64 = 1e-05 | The small number for stability. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
RMSNorm
struct RMSNorm| Name | Type | Description |
|---|---|---|
gamma | int = -1 | The gamma index. |
eps | f64 = 1e-05 | The small number for stability. |
The example for this item is shown with the ones above: nn-Layers.salam
forward
func forward(tp &: autograd.Tape, ps &: ParamStore, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
Functions
Bind
func Bind(tp &: autograd.Tape, ps &: ParamStore, h: int): intThe example for this item is shown with the ones above: nn-Layers.salam
NewLinear
func NewLinear(ps &: ParamStore, name: str, in_f: int, out_f: int, g &: tensor.Rng): LinearThe example for this item is shown with the ones above: nn-Layers.salam
NewLinearNoBias
func NewLinearNoBias(ps &: ParamStore, name: str, in_f: int, out_f: int, g &: tensor.Rng): LinearThe example for this item is shown with the ones above: nn-Layers.salam
NewLSTM
func NewLSTM(ps &: ParamStore, name: str, in_f: int, hidden: int, g &: tensor.Rng): LSTMThe example for this item is shown with the ones above: nn-Sequence.salam
NewGRU
func NewGRU(ps &: ParamStore, name: str, in_f: int, hidden: int, g &: tensor.Rng): GRUThe example for this item is shown with the ones above: nn-Sequence.salam
LastStep
func LastStep(tp &: autograd.Tape, out: int, seq: int, batch: int): intThe example for this item is shown with the ones above: nn-Sequence.salam
NewConv2D
func NewConv2D(ps &: ParamStore, name: str, in_ch: int, out_ch: int, k: int, stride: int, pad: int, g &: tensor.Rng): Conv2DThe example for this item is shown with the ones above: nn-Layers.salam
Flatten
func Flatten(tp &: autograd.Tape, x: int): intThe example for this item is shown with the ones above: nn-Layers.salam
XavierUniform
func XavierUniform(t &: tensor.Tensor, fan_in: int, fan_out: int, g &: tensor.Rng)The example for this item is shown with the ones above: nn-Layers.salam
XavierNormal
func XavierNormal(t &: tensor.Tensor, fan_in: int, fan_out: int, g &: tensor.Rng)The example for this item is shown with the ones above: nn-Layers.salam
KaimingUniform
func KaimingUniform(t &: tensor.Tensor, fan_in: int, g &: tensor.Rng)The example for this item is shown with the ones above: nn-Layers.salam
KaimingNormal
func KaimingNormal(t &: tensor.Tensor, fan_in: int, g &: tensor.Rng)The example for this item is shown with the ones above: nn-Layers.salam
NewMultiHeadAttention
func NewMultiHeadAttention(ps &: ParamStore, name: str, dim: int, heads: int, dropout: f64, g &: tensor.Rng): MultiHeadAttentionThe example for this item is shown with the ones above: nn-Sequence.salam
NewTransformerEncoderLayer
func NewTransformerEncoderLayer(ps &: ParamStore, name: str, dim: int, heads: int, ff_dim: int, dropout: f64, g &: tensor.Rng): TransformerEncoderLayerThe example for this item is shown with the ones above: nn-Sequence.salam
CausalMask
func CausalMask(seq: int): tensor.TensorThe example for this item is shown with the ones above: nn-Sequence.salam
NewTransformerDecoderLayer
func NewTransformerDecoderLayer(ps &: ParamStore, name: str, dim: int, heads: int, ff_dim: int, dropout: f64, g &: tensor.Rng): TransformerEncoderLayerThe example for this item is shown with the ones above: nn-Sequence.salam
NewEmbedding
func NewEmbedding(ps &: ParamStore, name: str, vocab: int, dim: int, g &: tensor.Rng): EmbeddingThe example for this item is shown with the ones above: nn-Sequence.salam
SinusoidalPositions
func SinusoidalPositions(batch: int, seq: int, dim: int): tensor.TensorThe example for this item is shown with the ones above: nn-Sequence.salam
NewLayerNorm
func NewLayerNorm(ps &: ParamStore, name: str, dim: int): LayerNormThe example for this item is shown with the ones above: nn-Layers.salam
NewBatchNorm
func NewBatchNorm(ps &: ParamStore, name: str, channels: int): BatchNormThe example for this item is shown with the ones above: nn-Layers.salam
NewGroupNorm
func NewGroupNorm(ps &: ParamStore, name: str, channels: int, groups: int): GroupNormThe example for this item is shown with the ones above: nn-Layers.salam
NewRMSNorm
func NewRMSNorm(ps &: ParamStore, name: str, dim: int): RMSNormThe example for this item is shown with the ones above: nn-Layers.salam
SaveCheckpointBuf
func SaveCheckpointBuf(ps &: ParamStore): compress.ByteBufThe example for this item is shown with the ones above: nn-Layers.salam
LoadCheckpointBuf
func LoadCheckpointBuf(buf: compress.ByteBuf, ps &: ParamStore): boolThe example for this item is shown with the ones above: nn-Layers.salam
SaveCheckpoint
func SaveCheckpoint(path: str, ps &: ParamStore): boolThe example for this item is shown with the ones above: nn-Layers.salam
LoadCheckpoint
func LoadCheckpoint(path: str, ps &: ParamStore): boolThe example for this item is shown with the ones above: nn-Layers.salam