|
|
@@ -40,6 +40,7 @@ module Network ( |
|
|
) where |
|
|
) where |
|
|
|
|
|
|
|
|
import Data.List.Split (chunksOf) |
|
|
import Data.List.Split (chunksOf) |
|
|
|
|
|
import Data.List (foldl') |
|
|
import Data.Binary |
|
|
import Data.Binary |
|
|
import Data.Maybe (fromMaybe) |
|
|
import Data.Maybe (fromMaybe) |
|
|
import Text.Read (readMaybe) |
|
|
import Text.Read (readMaybe) |
|
|
@@ -146,7 +147,7 @@ output :: (Numeric a, Num (Vector a)) |
|
|
-> ActivationFunction a |
|
|
-> ActivationFunction a |
|
|
-> Vector a |
|
|
-> Vector a |
|
|
-> Vector a |
|
|
-> Vector a |
|
|
output net act input = foldl f input (layers net) |
|
|
|
|
|
|
|
|
output net act input = foldl' f input (layers net) |
|
|
where f vec layer = cmap act ((weights layer #> vec) + biases layer) |
|
|
where f vec layer = cmap act ((weights layer #> vec) + biases layer) |
|
|
|
|
|
|
|
|
rawOutputs :: (Numeric a, Num (Vector a)) |
|
|
rawOutputs :: (Numeric a, Num (Vector a)) |
|
|
@@ -206,7 +207,7 @@ trainSGD :: (Numeric Double, Floating Double) |
|
|
-> Double |
|
|
-> Double |
|
|
-> Network Double |
|
|
-> Network Double |
|
|
trainSGD net costFunction lambda trainSamples miniBatchSize eta = |
|
|
trainSGD net costFunction lambda trainSamples miniBatchSize eta = |
|
|
foldl updateMiniBatch net (chunksOf miniBatchSize trainSamples) |
|
|
|
|
|
|
|
|
foldl' updateMiniBatch net (chunksOf miniBatchSize trainSamples) |
|
|
where updateMiniBatch = update eta costFunction lambda (length trainSamples) |
|
|
where updateMiniBatch = update eta costFunction lambda (length trainSamples) |
|
|
|
|
|
|
|
|
update :: LearningRate |
|
|
update :: LearningRate |
|
|
@@ -220,10 +221,10 @@ update eta costFunction lambda n net spls = case newNablas of |
|
|
Nothing -> net |
|
|
Nothing -> net |
|
|
Just x -> net { layers = layers' x } |
|
|
Just x -> net { layers = layers' x } |
|
|
where newNablas :: Maybe [Layer Double] |
|
|
where newNablas :: Maybe [Layer Double] |
|
|
newNablas = foldl updateNablas Nothing spls |
|
|
|
|
|
|
|
|
newNablas = foldl' updateNablas Nothing spls |
|
|
updateNablas :: Maybe [Layer Double] -> Sample Double -> Maybe [Layer Double] |
|
|
updateNablas :: Maybe [Layer Double] -> Sample Double -> Maybe [Layer Double] |
|
|
updateNablas mayNablas sample = |
|
|
updateNablas mayNablas sample = |
|
|
let nablasDelta = backprop net costFunction sample |
|
|
|
|
|
|
|
|
let !nablasDelta = backprop net costFunction sample |
|
|
f nabla nablaDelta = |
|
|
f nabla nablaDelta = |
|
|
nabla { weights = weights nabla + weights nablaDelta, |
|
|
nabla { weights = weights nabla + weights nablaDelta, |
|
|
biases = biases nabla + biases nablaDelta } |
|
|
biases = biases nabla + biases nablaDelta } |
|
|
@@ -252,8 +253,9 @@ backprop net costFunction spl = finalNablas |
|
|
(headZ, headA) = head rawFeedforward |
|
|
(headZ, headA) = head rawFeedforward |
|
|
-- get starting delta, based on the activation of the last layer |
|
|
-- get starting delta, based on the activation of the last layer |
|
|
startDelta = getDelta costFunction headZ headA (snd spl) |
|
|
startDelta = getDelta costFunction headZ headA (snd spl) |
|
|
-- calculate weighs of last layer in advance |
|
|
|
|
|
|
|
|
-- calculate nabla of biases |
|
|
lastNablaB = startDelta |
|
|
lastNablaB = startDelta |
|
|
|
|
|
-- calculate nabla of weighs of last layer in advance |
|
|
lastNablaW = startDelta `outer` previousA |
|
|
lastNablaW = startDelta `outer` previousA |
|
|
where previousA |
|
|
where previousA |
|
|
| length rawFeedforward > 1 = snd $ rawFeedforward !! 1 |
|
|
| length rawFeedforward > 1 = snd $ rawFeedforward !! 1 |
|
|
@@ -262,7 +264,7 @@ backprop net costFunction spl = finalNablas |
|
|
-- reverse layers, analogy to the reversed (z, a) list |
|
|
-- reverse layers, analogy to the reversed (z, a) list |
|
|
layersReversed = reverse $ layers net |
|
|
layersReversed = reverse $ layers net |
|
|
-- calculate nablas, beginning at the end of the network (startDelta) |
|
|
-- calculate nablas, beginning at the end of the network (startDelta) |
|
|
(finalNablas, _) = foldl calculate ([lastLayer], startDelta) |
|
|
|
|
|
|
|
|
(finalNablas, _) = foldl' calculate ([lastLayer], startDelta) |
|
|
[1..length layersReversed - 1] |
|
|
[1..length layersReversed - 1] |
|
|
-- takes the index and updates nablas |
|
|
-- takes the index and updates nablas |
|
|
calculate (nablas, oldDelta) idx = |
|
|
calculate (nablas, oldDelta) idx = |
|
|
|