67 lines
2.3 KiB
Nim
67 lines
2.3 KiB
Nim
# Copyright 2022 Mattia Giambirtone & All Contributors
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import layer
|
|
import util/matrix
|
|
import util/activations
|
|
import util/losses
|
|
|
|
export layer, matrix, losses, activations
|
|
|
|
|
|
import std/sequtils
|
|
import std/strformat
|
|
|
|
|
|
type
|
|
NeuralNetwork* = ref object
|
|
## A generic feed-forward
|
|
## neural network
|
|
layers: seq[Layer]
|
|
|
|
|
|
proc newNeuralNetwork*(layers: seq[int], activationFunc: Activation, lossFunc: Loss, learnRate: float,
|
|
weightRange: tuple[start, stop: float]): NeuralNetwork =
|
|
## Initializes a new neural network
|
|
## with the given layer layout
|
|
new(result)
|
|
result.layers = newSeqOfCap[Layer](len(layers))
|
|
for i in 0..<layers.high():
|
|
result.layers.add(newLayer(layers[i], layers[i + 1], activationFunc, lossFunc, learnRate, weightRange))
|
|
|
|
|
|
proc predict*(self: NeuralNetwork, data: Matrix[float]): Matrix[float] =
|
|
## Performs a prediction and returns a 1D array
|
|
## with the output
|
|
when not defined(release):
|
|
if data.shape.rows > 1:
|
|
raise newException(ValueError, "input data must be one-dimensional")
|
|
if data.shape.cols != self.layers[0].inputSize:
|
|
raise newException(ValueError, &"input is of the wrong shape (expecting (1, {self.layers[0].inputSize}), got ({data.shape.rows}, {data.shape.cols}) instead)")
|
|
result = data
|
|
for layer in self.layers:
|
|
result = layer.compute(result)
|
|
|
|
|
|
proc classify*(self: NeuralNetwork, data: Matrix[float]): int =
|
|
## Performs a prediction and returns the label
|
|
## with the highest likelyhood
|
|
result = maxIndex(self.predict(data).raw[])
|
|
|
|
|
|
proc cost*(self: NeuralNetwork, x, y: Matrix[float]): float =
|
|
## Returns the total average cost of the network
|
|
for layer in self.layers:
|
|
result += layer.cost(x, y)
|
|
result /= float(self.layers.len()) |