From fc98ca493cb364ba5f056221dd4304a18aad3977 Mon Sep 17 00:00:00 2001 From: erichhasl Date: Sun, 27 Aug 2017 12:39:41 +0200 Subject: [PATCH] add docs --- Network.hs | 84 +++++++++++++++++++++++++++++++++++------- docs/Network.html | 22 ++++++++--- docs/doc-index.html | 2 +- docs/mini_Network.html | 2 +- 4 files changed, 89 insertions(+), 21 deletions(-) diff --git a/Network.hs b/Network.hs index c01e5a0..11f85c8 100644 --- a/Network.hs +++ b/Network.hs @@ -1,7 +1,43 @@ {-# LANGUAGE ScopedTypeVariables, FlexibleContexts, BangPatterns #-} {-# OPTIONS -Wall #-} -module Network where +-- | +-- Module : Network +-- Copyright : (c) 2017 Christian Merten +-- Maintainer : c.merten@gmx.net +-- Stability : experimental +-- Portability : GHC +-- +-- An implementation of artifical feed-forward neural networks in pure Haskell. +-- +-- An example is added in /XOR.hs/ + +module Network ( + -- * Network + Network(..), + Layer(..), + newNetwork, + output, + + -- * Learning functions + trainShuffled, + trainNTimes, + CostFunction(..), + getDelta, + LearningRate, + Lambda, + TrainingDataLength, + Sample, Samples, (-->), + + -- * Activation functions + ActivationFunction, ActivationFunctionDerivative, + sigmoid, + sigmoid', + + -- * Network serialization + saveNetwork, + loadNetwork +) where import Data.List.Split (chunksOf) import Data.Binary @@ -20,10 +56,7 @@ import Numeric.LinearAlgebra -- | The generic feedforward network type, a binary instance is implemented. -- It takes a list of layers -- with a minimum of one (output layer). --- It is usually constructed using the `newNetwork` function, initializing the matrices --- with some default random values. --- --- > net <- newNetwork [2, 3, 4] +-- It is usually constructed using the `newNetwork` function. data Network a = Network { layers :: [Layer a] } deriving (Show) @@ -56,20 +89,43 @@ getDelta :: Floating a => CostFunction -> a -> a -> a -> a getDelta QuadraticCost z a y = (a - y) * sigmoid'(z) getDelta CrossEntropyCost _ a y = a - y +-- | Activation function used to calculate the actual output of a neuron. +-- Usually the 'sigmoid' function. type ActivationFunction a = a -> a + +-- | The derivative of an activation function. type ActivationFunctionDerivative a = a -> a +-- | Training sample that can be used for the training functions. +-- +-- > trainingData :: Samples Double +-- > trainingData = [ fromList [0, 0] --> fromList [0], +-- > fromList [0, 1] --> fromList [1], +-- > fromList [1, 0] --> fromList [1], +-- > fromList [1, 1] --> fromList [0]] type Sample a = (Vector a, Vector a) + +-- | A list of 'Sample's type Samples a = [Sample a] -- | A simple synonym for the (,) operator, used to create samples very intuitively. (-->) :: Vector a -> Vector a -> Sample a (-->) = (,) +-- | The learning rate, affects the learning speed, lower learning rate results +-- in slower learning, but usually better results after more epochs. type LearningRate = Double + +-- | Lambda value affecting the regularization while learning. type Lambda = Double + +-- | Wrapper around the training data length. type TrainingDataLength = Int +-- | Initializes a new network with random values for weights and biases +-- in all layers. +-- +-- > net <- newNetwork [2, 3, 4] newNetwork :: [Int] -> IO (Network Double) newNetwork layerSizes | length layerSizes < 2 = error "Network too small!" @@ -83,6 +139,8 @@ newNetwork layerSizes let bs = randomVector seed Gaussian outputSize return $ Layer ws bs +-- | Calculate the output of the network based on the network, a given +-- 'ActivationFunction' and the input vector. output :: (Numeric a, Num (Vector a)) => Network a -> ActivationFunction a @@ -91,14 +149,6 @@ output :: (Numeric a, Num (Vector a)) output net act input = foldl f input (layers net) where f vec layer = cmap act ((weights layer #> vec) + biases layer) -outputs :: (Numeric a, Num (Vector a)) - => Network a - -> ActivationFunction a - -> Vector a - -> [Vector a] -outputs net act input = scanl f input (layers net) - where f vec layer = cmap act ((weights layer #> vec) + biases layer) - rawOutputs :: (Numeric a, Num (Vector a)) => Network a -> ActivationFunction a @@ -129,6 +179,8 @@ trainShuffled epochs debug net costFunction lambda trainSamples miniBatchSize et (trainShuffled (epochs - 1) debug net' costFunction lambda trainSamples miniBatchSize eta) +-- | Pure version of 'trainShuffled', training the network /n/ times without +-- shuffling the training set, resulting in slightly worse results. trainNTimes :: Int -> (Network Double -> Int -> String) -> Network Double @@ -231,9 +283,11 @@ backprop net costFunction spl = finalNablas in (Layer { weights = nablaW, biases = nablaB } : nablas, delta) +-- | The sigmoid function sigmoid :: Floating a => ActivationFunction a sigmoid x = 1 / (1 + exp (-x)) +-- | The derivative of the sigmoid function. sigmoid' :: Floating a => ActivationFunctionDerivative a sigmoid' x = sigmoid x * (1 - sigmoid x) @@ -251,6 +305,9 @@ shuffle xs = do newArr :: Int -> [a] -> IO (IOArray Int a) newArr len lst = newListArray (1,len) lst +-- | Saves the network as the given filename. When the file already exists, +-- it looks for another filename by increasing the version, e.g +-- /mnist.net/ becomes /mnist1.net/. saveNetwork :: (Element a, Binary a) => FilePath -> Network a -> IO () saveNetwork fp net = do ex <- doesFileExist fp @@ -265,5 +322,6 @@ newFileName fp = case fp =~ "(.+[a-z]){0,1}([0-9]*)(\\..*)" :: [[String]] of where version :: String -> Int version xs = fromMaybe 0 (readMaybe xs :: Maybe Int) +-- | Load the network with the given filename. loadNetwork :: (Element a, Binary a) => FilePath -> IO (Network a) loadNetwork = decodeFile diff --git a/docs/Network.html b/docs/Network.html index 52600db..0b765af 100644 --- a/docs/Network.html +++ b/docs/Network.html @@ -1,11 +1,21 @@ Network

 

Safe HaskellNone

Network

Synopsis

Documentation

data Network a

The generic feedforward network type, a binary instance is implemented. +

Copyright(c) 2017 Christian Merten
Maintainerc.merten@gmx.net
Stabilityexperimental
PortabilityGHC
Safe HaskellNone

Network

Description

An implementation of artifical feed-forward neural networks in pure Haskell.

An example is added in XOR.hs

Synopsis

Network

data Network a

The generic feedforward network type, a binary instance is implemented. It takes a list of layers with a minimum of one (output layer). - It is usually constructed using the newNetwork function, initializing the matrices - with some default random values.

net <- newNetwork [2, 3, 4]

Constructors

Network 

Fields

layers :: [Layer a]
 

Instances

(Show a, Element a) => Show (Network a) 
(Element a, Binary a) => Binary (Network a) 

data Layer a

One layer of a network, storing the weights matrix and the biases vector - of this layer.

Constructors

Layer 

Fields

weights :: Matrix a
 
biases :: Vector a
 

Instances

(Show a, Element a) => Show (Layer a) 
(Element a, Binary a) => Binary (Layer a) 

data CostFunction

Cost Function Enum

Instances

getDelta :: Floating a => CostFunction -> a -> a -> a -> a

getDelta based on the raw input, the activated input and the desired output - results in different values depending on the CostFunction type.

type ActivationFunction a = a -> a

type Sample a = (Vector a, Vector a)

type Samples a = [Sample a]

(-->) :: Vector a -> Vector a -> Sample a

A simple synonym for the (,) operator, used to create samples very intuitively.

type LearningRate = Double

type Lambda = Double

newNetwork :: [Int] -> IO (Network Double)

output :: (Numeric a, Num (Vector a)) => Network a -> ActivationFunction a -> Vector a -> Vector a

outputs :: (Numeric a, Num (Vector a)) => Network a -> ActivationFunction a -> Vector a -> [Vector a]

rawOutputs :: (Numeric a, Num (Vector a)) => Network a -> ActivationFunction a -> Vector a -> [(Vector a, Vector a)]

trainShuffled :: Int -> (Network Double -> Int -> String) -> Network Double -> CostFunction -> Lambda -> Samples Double -> Int -> Double -> IO (Network Double)

The most used training function, randomly shuffling the training set before - every training epoch

trainShuffled 30 (\n e -> "") net CrossEntropyCost 0.5 trainData 10 0.1

trainNTimes :: Int -> (Network Double -> Int -> String) -> Network Double -> CostFunction -> Lambda -> Samples Double -> Int -> Double -> Network Double

trainSGD :: (Numeric Double, Floating Double) => Network Double -> CostFunction -> Lambda -> Samples Double -> Int -> Double -> Network Double

backprop :: Network Double -> CostFunction -> Sample Double -> [Layer Double]

sigmoid :: Floating a => ActivationFunction a

shuffle :: [a] -> IO [a]

saveNetwork :: (Element a, Binary a) => FilePath -> Network a -> IO ()

newFileName :: FilePath -> FilePath

loadNetwork :: (Element a, Binary a) => FilePath -> IO (Network a)

\ No newline at end of file + It is usually constructed using the newNetwork function.

Constructors

Network 

Fields

layers :: [Layer a]
 

Instances

(Show a, Element a) => Show (Network a) 
(Element a, Binary a) => Binary (Network a) 

data Layer a

One layer of a network, storing the weights matrix and the biases vector + of this layer.

Constructors

Layer 

Fields

weights :: Matrix a
 
biases :: Vector a
 

Instances

(Show a, Element a) => Show (Layer a) 
(Element a, Binary a) => Binary (Layer a) 

newNetwork :: [Int] -> IO (Network Double)

Initializes a new network with random values for weights and biases + in all layers.

net <- newNetwork [2, 3, 4]

output :: (Numeric a, Num (Vector a)) => Network a -> ActivationFunction a -> Vector a -> Vector a

Calculate the output of the network based on the network, a given + ActivationFunction and the input vector.

Learning functions

trainShuffled :: Int -> (Network Double -> Int -> String) -> Network Double -> CostFunction -> Lambda -> Samples Double -> Int -> Double -> IO (Network Double)

The most used training function, randomly shuffling the training set before + every training epoch

trainShuffled 30 (\n e -> "") net CrossEntropyCost 0.5 trainData 10 0.1

trainNTimes :: Int -> (Network Double -> Int -> String) -> Network Double -> CostFunction -> Lambda -> Samples Double -> Int -> Double -> Network Double

Pure version of trainShuffled, training the network n times without + shuffling the training set, resulting in slightly worse results.

data CostFunction

Cost Function Enum

Instances

getDelta :: Floating a => CostFunction -> a -> a -> a -> a

getDelta based on the raw input, the activated input and the desired output + results in different values depending on the CostFunction type.

type LearningRate = Double

The learning rate, affects the learning speed, lower learning rate results + in slower learning, but usually better results after more epochs.

type Lambda = Double

Lambda value affecting the regularization while learning.

type TrainingDataLength = Int

Wrapper around the training data length.

type Sample a = (Vector a, Vector a)

Training sample that can be used for the training functions.

trainingData :: Samples Double
+trainingData = [ fromList [0, 0] --> fromList [0],
+                 fromList [0, 1] --> fromList [1],
+                 fromList [1, 0] --> fromList [1],
+                 fromList [1, 1] --> fromList [0]]

type Samples a = [Sample a]

A list of Samples

(-->) :: Vector a -> Vector a -> Sample a

A simple synonym for the (,) operator, used to create samples very intuitively.

Activation functions

type ActivationFunction a = a -> a

Activation function used to calculate the actual output of a neuron. + Usually the sigmoid function.

type ActivationFunctionDerivative a = a -> a

The derivative of an activation function.

sigmoid :: Floating a => ActivationFunction a

The sigmoid function

sigmoid' :: Floating a => ActivationFunctionDerivative a

The derivative of the sigmoid function.

Network serialization

saveNetwork :: (Element a, Binary a) => FilePath -> Network a -> IO ()

Saves the network as the given filename. When the file already exists, + it looks for another filename by increasing the version, e.g + mnist.net becomes mnist1.net.

loadNetwork :: (Element a, Binary a) => FilePath -> IO (Network a)

Load the network with the given filename.

\ No newline at end of file diff --git a/docs/doc-index.html b/docs/doc-index.html index 11399f4..10c3528 100644 --- a/docs/doc-index.html +++ b/docs/doc-index.html @@ -1,4 +1,4 @@ (Index)

 

Index

-->Network
ActivationFunctionNetwork
ActivationFunctionDerivativeNetwork
backpropNetwork
biasesNetwork
CostFunctionNetwork
CrossEntropyCostNetwork
getDeltaNetwork
LambdaNetwork
Layer 
1 (Type/Class)Network
2 (Data Constructor)Network
layersNetwork
LearningRateNetwork
loadNetworkNetwork
Network 
1 (Type/Class)Network
2 (Data Constructor)Network
newFileNameNetwork
newNetworkNetwork
outputNetwork
outputsNetwork
QuadraticCostNetwork
rawOutputsNetwork
SampleNetwork
SamplesNetwork
saveNetworkNetwork
shuffleNetwork
sigmoidNetwork
sigmoid'Network
TrainingDataLengthNetwork
trainNTimesNetwork
trainSGDNetwork
trainShuffledNetwork
updateNetwork
weightsNetwork
\ No newline at end of file +

 

Index

-->Network
ActivationFunctionNetwork
ActivationFunctionDerivativeNetwork
biasesNetwork
CostFunctionNetwork
CrossEntropyCostNetwork
getDeltaNetwork
LambdaNetwork
Layer 
1 (Type/Class)Network
2 (Data Constructor)Network
layersNetwork
LearningRateNetwork
loadNetworkNetwork
Network 
1 (Type/Class)Network
2 (Data Constructor)Network
newNetworkNetwork
outputNetwork
QuadraticCostNetwork
SampleNetwork
SamplesNetwork
saveNetworkNetwork
sigmoidNetwork
sigmoid'Network
TrainingDataLengthNetwork
trainNTimesNetwork
trainShuffledNetwork
weightsNetwork
\ No newline at end of file diff --git a/docs/mini_Network.html b/docs/mini_Network.html index b872475..90856ca 100644 --- a/docs/mini_Network.html +++ b/docs/mini_Network.html @@ -1,4 +1,4 @@ Network

Network

data Network a

data Layer a

type Sample a

type Samples a

type Lambda

\ No newline at end of file +

Network

Network

data Network a

data Layer a

Learning functions

type Lambda

type Sample a

type Samples a

Activation functions

Network serialization

\ No newline at end of file