From b26347e19f38550ad6e7beddd16ba3e2bf20eba7 Mon Sep 17 00:00:00 2001 From: Mahdi Dibaiee Date: Sat, 10 Sep 2016 00:36:15 +0430 Subject: [PATCH] feat(notmnist): notmnist example using SGD + learning rate decay --- .gitmodules | 3 + examples/424encoder.hs | 49 ++++ examples/naivebayes-doc-classifier.hs | 5 +- examples/naivebayes-sentiment-analysis.hs | 54 ----- examples/notMNIST | 1 + examples/notmnist.hs | 111 ++++++++++ examples/recurrent-doc-classifier.hs | 0 examples/sentiment-analysis-data | 5 - examples/sin.hs | 35 +++ examples/xor.hs | 29 ++- notmnist-0.png | Bin 0 -> 33444 bytes notmnist-1.png | Bin 0 -> 26808 bytes notmnist-2.png | Bin 0 -> 25250 bytes notmnist.png | Bin 0 -> 24815 bytes sgd.png | Bin 0 -> 24815 bytes sibe.cabal | 73 ++++-- src/Sibe.hs | 258 +++++++++++++++++----- src/Sibe/LogisticRegression.hs | 0 src/Sibe/NLP.hs | 129 +++++++++++ src/Sibe/NaiveBayes.hs | 113 +--------- stack.yaml | 74 +------ 21 files changed, 619 insertions(+), 320 deletions(-) create mode 100644 examples/424encoder.hs delete mode 100644 examples/naivebayes-sentiment-analysis.hs create mode 160000 examples/notMNIST create mode 100644 examples/notmnist.hs create mode 100644 examples/recurrent-doc-classifier.hs delete mode 100755 examples/sentiment-analysis-data create mode 100644 examples/sin.hs create mode 100644 notmnist-0.png create mode 100644 notmnist-1.png create mode 100644 notmnist-2.png create mode 100644 notmnist.png create mode 100644 sgd.png create mode 100644 src/Sibe/LogisticRegression.hs create mode 100644 src/Sibe/NLP.hs diff --git a/.gitmodules b/.gitmodules index ff2a935..17f4304 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "examples/doc-classifier-data"] path = examples/doc-classifier-data url = git@github.com:mdibaiee/doc-classifier-data +[submodule "examples/notMNIST"] + path = examples/notMNIST + url = git@github.com:mdibaiee/notMNIST diff --git a/examples/424encoder.hs b/examples/424encoder.hs new file mode 100644 index 0000000..4b93941 --- /dev/null +++ b/examples/424encoder.hs @@ -0,0 +1,49 @@ +module Main where + import Sibe + import Numeric.LinearAlgebra + import Data.List + import Debug.Trace + import Data.Default.Class + + main = do + let alpha = 0.5 + epochs = 1000 + a = (sigmoid, sigmoid') + rnetwork = randomNetwork 0 (-0.1, 0.1) 4 [(2, a)] (4, a) + + inputs = [vector [1, 0, 0, 0], + vector [0, 1, 0, 0], + vector [0, 0, 1, 0], + vector [0, 0, 0, 1]] + + labels = [vector [1, 0, 0, 0], + vector [0, 1, 0, 0], + vector [0, 0, 1, 0], + vector [0, 0, 0, 1]] + + session = def { network = rnetwork + , learningRate = 0.5 + , epochs = 1000 + , training = zip inputs labels + , test = zip inputs labels + } :: Session + + let initialCost = crossEntropy session + + newsession <- run gd session + + let results = map (`forward` newsession) inputs + rounded = map (map round . toList) results + + cost = crossEntropy newsession + + putStrLn "parameters: " + putStrLn $ "- inputs: " ++ show inputs + putStrLn $ "- labels: " ++ show labels + putStrLn $ "- learning rate: " ++ show alpha + putStrLn $ "- epochs: " ++ show epochs + putStrLn $ "- initial cost (cross-entropy): " ++ show initialCost + putStrLn "results: " + putStrLn $ "- actual result: " ++ show results + putStrLn $ "- rounded result: " ++ show rounded + putStrLn $ "- cost (cross-entropy): " ++ show cost diff --git a/examples/naivebayes-doc-classifier.hs b/examples/naivebayes-doc-classifier.hs index f0d4985..0e7581e 100644 --- a/examples/naivebayes-doc-classifier.hs +++ b/examples/naivebayes-doc-classifier.hs @@ -1,6 +1,7 @@ module Main where -- import Sibe + import Sibe.NLP import Sibe.NaiveBayes import Text.Printf import Data.List @@ -28,14 +29,14 @@ module Main documents = cleanDocuments . removeWords sws $ createDocuments classes dataset testDocuments = cleanDocuments $ createDocuments classes test - nb = train documents intClasses + nb = initialize documents intClasses -- top-ten topClasses = take 10 . reverse $ sortBy (compare `on` (length . snd)) (cd nb) filtered = map (\(c, ds) -> (c, take 100 ds)) topClasses filteredClasses = map fst filtered ttDocs = concatMap snd filtered - ttNB = train ttDocs filteredClasses + ttNB = initialize ttDocs filteredClasses ttTestDocuments = filter ((`elem` filteredClasses) . c) . cleanDocuments $ createDocuments classes test diff --git a/examples/naivebayes-sentiment-analysis.hs b/examples/naivebayes-sentiment-analysis.hs deleted file mode 100644 index b97f83d..0000000 --- a/examples/naivebayes-sentiment-analysis.hs +++ /dev/null @@ -1,54 +0,0 @@ -{-# LANGUAGE BangPatterns #-} -module Main - where - -- import Sibe - import Sibe.NaiveBayes - import Text.Printf - import Data.List - import Data.Maybe - import Debug.Trace - import Data.List.Split - import System.Directory - import Control.DeepSeq - import System.IO - - main = do - putStr "Reading documents... " - neg_documents <- createDocuments "examples/sentiment-analysis-data/train/neg/" - pos_documents <- createDocuments "examples/sentiment-analysis-data/train/pos/" - - test_neg_documents <- createDocuments "examples/sentiment-analysis-data/test/neg/" - test_pos_documents <- createDocuments "examples/sentiment-analysis-data/test/pos/" - putStrLn "done" - - let classes = [0..9] -- rating, from 0 to 9 (1 to 10) - documents = neg_documents ++ pos_documents - nb = train documents classes - - testDocuments = neg_documents ++ pos_documents - - results = map (\(Document text c) -> (c, run text nb)) testDocuments - -- results = map (\(Document text c) -> (c, determine text nb intClasses documents)) devTestDocuments - print results - - -- let showResults (c, r) = putStrLn (show (classes !! c) ++ " ~ " ++ show (classes !! r)) - -- mapM_ showResults results - -- - -- putStrLn $ "Recall: " ++ show (recall results) - -- putStrLn $ "Precision: " ++ show (precision results) - -- putStrLn $ "F Measure: " ++ show (fmeasure results) - -- putStrLn $ "Accuracy: " ++ show (accuracy results) - - createDocuments :: FilePath -> IO [Document] - createDocuments path = do - files <- drop 2 <$> getDirectoryContents path - let ratings = map (subtract 1 . read . take 1 . last . splitOn "_") files :: [Int] - contents <- mapM (forceReadFile . (path ++)) files - return $ zipWith Document contents ratings - - forceReadFile :: FilePath -> IO String - forceReadFile file = do - handle <- openFile file ReadMode - content <- hGetContents handle - content `deepseq` hClose handle - return content diff --git a/examples/notMNIST b/examples/notMNIST new file mode 160000 index 0000000..0dbdfd4 --- /dev/null +++ b/examples/notMNIST @@ -0,0 +1 @@ +Subproject commit 0dbdfd43ffb8e90a3657ed040fd1fb3d25654b51 diff --git a/examples/notmnist.hs b/examples/notmnist.hs new file mode 100644 index 0000000..d913377 --- /dev/null +++ b/examples/notmnist.hs @@ -0,0 +1,111 @@ +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE ScopedTypeVariables #-} + +module Main where + import Sibe + import Numeric.LinearAlgebra + import Data.List + import Debug.Trace + import System.IO + import System.Directory + import Codec.Picture + import Codec.Picture.Types + import qualified Data.Vector.Storable as V + import Data.Either + import System.Random + import System.Random.Shuffle + import Data.Default.Class + + import qualified Graphics.Rendering.Chart.Easy as Chart + import Graphics.Rendering.Chart.Backend.Cairo + + main = do + setStdGen (mkStdGen 100) + + let a = (sigmoid, sigmoid') + o = (softmax, one) + rnetwork = randomNetwork 0 (-1, 1) (28*28) [(100, a)] (10, a) + + (inputs, labels) <- dataset + + let trp = length inputs * 70 `div` 100 + tep = length inputs * 30 `div` 100 + + -- training data + trinputs = take trp inputs + trlabels = take trp labels + + -- test data + teinputs = take tep . drop trp $ inputs + telabels = take tep . drop trp $ labels + + let session = def { learningRate = 0.5 + , batchSize = 32 + , epochs = 35 + , network = rnetwork + , training = zip trinputs trlabels + , test = zip teinputs telabels + } :: Session + + let initialCost = crossEntropy session + + newsession <- run (sgd . learningRateDecay (1.1, 5e-2)) session + + let el = map (\(e, l, _) -> (e, l)) (chart newsession) + ea = map (\(e, _, a) -> (e, a)) (chart newsession) + toFile Chart.def "notmnist.png" $ do + Chart.layoutlr_title Chart..= "loss over time" + Chart.plotLeft (Chart.line "loss" [el]) + Chart.plotRight (Chart.line "learningRate" [ea]) + + + let cost = crossEntropy newsession + + putStrLn "parameters: " + putStrLn $ "- batch size: " ++ show (batchSize session) + putStrLn $ "- learning rate: " ++ show (learningRate session) + putStrLn $ "- epochs: " ++ show (epochs session) + putStrLn $ "- initial cost (cross-entropy): " ++ show initialCost + putStrLn "results: " + putStrLn $ "- accuracy: " ++ show (accuracy newsession) + putStrLn $ "- cost (cross-entropy): " ++ show cost + + dataset :: IO ([Vector Double], [Vector Double]) + dataset = do + let dir = "examples/notMNIST/" + + groups <- filter ((/= '.') . head) <$> listDirectory dir + + inputFiles <- mapM (listDirectory . (dir ++)) groups + + let n = 512 {-- minimum (map length inputFiles) --} + numbers = map (`div` n) [0..n * length groups - 1] + inputFilesFull = map (\(i, g) -> map ((dir ++ i ++ "/") ++) g) (zip groups inputFiles) + + + inputImages <- mapM (mapM readImage . take n) inputFilesFull + + let names = map (take n) inputFilesFull + + let (l, r) = partitionEithers $ concat inputImages + inputs = map (fromPixels . convertRGB8) r + labels = map (\i -> V.replicate i 0 `V.snoc` 1 V.++ V.replicate (9 - i) 0) numbers + + pairs = zip inputs labels + + shuffled <- shuffleM pairs + return (map fst shuffled, map snd shuffled) + + where + fromPixels :: Image PixelRGB8 -> Vector Double + fromPixels img@Image { .. } = + let pairs = [(x, y) | x <- [0..imageWidth - 1], y <- [0..imageHeight - 1]] + in V.fromList $ map iter pairs + where + iter (x, y) = + let (PixelRGB8 r g b) = convertPixel $ pixelAt img x y + in + if r == 0 && g == 0 && b == 0 then 0 else 1 + + diff --git a/examples/recurrent-doc-classifier.hs b/examples/recurrent-doc-classifier.hs new file mode 100644 index 0000000..e69de29 diff --git a/examples/sentiment-analysis-data b/examples/sentiment-analysis-data deleted file mode 100755 index f0a3f50..0000000 --- a/examples/sentiment-analysis-data +++ /dev/null @@ -1,5 +0,0 @@ -XSym -0040 -3666c4cacaf995ebd11ef25aab70de99 -../../sibe-repos/sentiment-analysis-data - \ No newline at end of file diff --git a/examples/sin.hs b/examples/sin.hs new file mode 100644 index 0000000..8dc2616 --- /dev/null +++ b/examples/sin.hs @@ -0,0 +1,35 @@ +module Main where + import Sibe + import Numeric.LinearAlgebra + import Data.List + import Debug.Trace + + main = do + let alpha = 0.5 + epochs = 1000 + a = (sigmoid, sigmoid') + lo = (sigmoid, (\_ -> 1)) -- cross entropy + -- a = (relu, relu') + rnetwork = randomNetwork 0 (-1, 1) 1 [(50, a)] (1, lo) + + inputs = map (\a -> vector [a]) (reverse [0, 30, 45, 60, 90]) + labels = map (\deg -> vector $ [sin $ deg * pi/180]) (reverse [0, 30, 45, 60, 90]) + + initial_cost = zipWith crossEntropy (map (`forward` rnetwork) inputs) labels + + network <- run session inputs rnetwork labels alpha epochs + + let results = map (`forward` network) inputs + rounded = map (map round . toList) results + + cost = zipWith crossEntropy (map (`forward` network) inputs) labels + + putStrLn "parameters: " + putStrLn $ "- inputs: " ++ show inputs + putStrLn $ "- labels: " ++ show labels + putStrLn $ "- learning rate: " ++ show alpha + putStrLn $ "- epochs: " ++ show epochs + {-putStrLn $ "- initial cost (cross-entropy): " ++ show initial_cost-} + putStrLn "results: " + putStrLn $ "- actual result: " ++ show results + {-putStrLn $ "- cost (cross-entropy): " ++ show cost-} diff --git a/examples/xor.hs b/examples/xor.hs index 5ed8d27..92eedcf 100644 --- a/examples/xor.hs +++ b/examples/xor.hs @@ -3,30 +3,37 @@ module Main where import Numeric.LinearAlgebra import Data.List import Debug.Trace + import Data.Default.Class main = do - let learning_rate = 0.5 - (iterations, epochs) = (2, 1000) - a = (sigmoid, sigmoid') - rnetwork = randomNetwork 0 2 [(8, a)] (1, a) -- two inputs, 8 nodes in a single hidden layer, 1 output + let a = (sigmoid, sigmoid') + rnetwork = randomNetwork 0 (-1, 1) 2 [(2, a)] (1, a) -- two inputs, 8 nodes in a single hidden layer, 1 output inputs = [vector [0, 1], vector [1, 0], vector [1, 1], vector [0, 0]] labels = [vector [1], vector [1], vector [0], vector [0]] - initial_cost = zipWith crossEntropy (map (`forward` rnetwork) inputs) labels + session = def { network = rnetwork + , learningRate = 0.5 + , epochs = 1000 + , training = zip inputs labels + , test = zip inputs labels + } :: Session - network = session inputs rnetwork labels learning_rate (iterations, epochs) - results = map (`forward` network) inputs + initialCost = crossEntropy session + + newsession <- run gd session + + let results = map (`forward` newsession) inputs rounded = map (map round . toList) results - cost = zipWith crossEntropy (map (`forward` network) inputs) labels + cost = crossEntropy newsession putStrLn "parameters: " putStrLn $ "- inputs: " ++ show inputs putStrLn $ "- labels: " ++ show labels - putStrLn $ "- learning rate: " ++ show learning_rate - putStrLn $ "- iterations/epochs: " ++ show (iterations, epochs) - putStrLn $ "- initial cost (cross-entropy): " ++ show initial_cost + putStrLn $ "- learning rate: " ++ show (learningRate session) + putStrLn $ "- epochs: " ++ show (epochs session) + putStrLn $ "- initial cost (cross-entropy): " ++ show initialCost putStrLn "results: " putStrLn $ "- actual result: " ++ show results putStrLn $ "- rounded result: " ++ show rounded diff --git a/notmnist-0.png b/notmnist-0.png new file mode 100644 index 0000000000000000000000000000000000000000..1bc696783ce83a4b91a157c5e4d9e242911a7b91 GIT binary patch literal 33444 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 literal 0 HcmV?d00001 diff --git a/notmnist-1.png b/notmnist-1.png new file mode 100644 index 0000000000000000000000000000000000000000..a6aa76193a7b645a814353f486c8a84f6829bf97 GIT binary patch literal 26808 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%0A8?Z9w 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 Bt&9Kw literal 0 HcmV?d00001 diff --git a/notmnist.png b/notmnist.png new file mode 100644 index 0000000000000000000000000000000000000000..867fd5f01c9c8ca43141b222483108f036f4dfd8 GIT binary patch literal 24815 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 literal 0 HcmV?d00001 diff --git a/sgd.png b/sgd.png new file mode 100644 index 0000000000000000000000000000000000000000..1c0c683c5ab1e9d20f66b4f3218d0d04e7f8e2f1 GIT binary patch literal 24815 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.10 library hs-source-dirs: src - exposed-modules: Sibe, Sibe.NaiveBayes + exposed-modules: Sibe, Sibe.NaiveBayes, Sibe.NLP build-depends: base >= 4.7 && < 5 , hmatrix , random @@ -26,16 +26,21 @@ library , regex-pcre , text , stemmer + , vector + , random-shuffle + , data-default-class + , Chart + , Chart-cairo default-language: Haskell2010 -executable sibe-exe - hs-source-dirs: app - main-is: Main.hs - ghc-options: -threaded -rtsopts -with-rtsopts=-N - build-depends: base - , sibe - , hmatrix - default-language: Haskell2010 +--executable sibe-exe + --hs-source-dirs: app + --main-is: Main.hs + --ghc-options: -threaded -rtsopts -with-rtsopts=-N + --build-depends: base + --, sibe + --, hmatrix + --default-language: Haskell2010 executable example-xor hs-source-dirs: examples @@ -44,6 +49,43 @@ executable example-xor build-depends: base , sibe , hmatrix + , data-default-class + default-language: Haskell2010 + +--executable example-sin + --hs-source-dirs: examples + --main-is: sin.hs + --ghc-options: -threaded -rtsopts -with-rtsopts=-N + --build-depends: base + --, sibe + --, hmatrix + --default-language: Haskell2010 + +executable example-424 + hs-source-dirs: examples + main-is: 424encoder.hs + ghc-options: -threaded -rtsopts -with-rtsopts=-N + build-depends: base + , sibe + , hmatrix + , data-default-class + default-language: Haskell2010 + +executable example-notmnist + hs-source-dirs: examples + main-is: notmnist.hs + ghc-options: -threaded -rtsopts -with-rtsopts=-N + build-depends: base + , sibe + , hmatrix + , directory >= 1.2.5.0 + , JuicyPixels == 3.2.7.2 + , vector == 0.11.0.0 + , random + , random-shuffle + , data-default-class + , Chart + , Chart-cairo default-language: Haskell2010 executable example-naivebayes-doc-classifier @@ -57,19 +99,6 @@ executable example-naivebayes-doc-classifier , split default-language: Haskell2010 -executable example-naivebayes-sentiment-analysis - hs-source-dirs: examples - main-is: naivebayes-sentiment-analysis.hs - ghc-options: -threaded -rtsopts -with-rtsopts=-N - build-depends: base - , sibe - , hmatrix - , containers - , split - , directory - , deepseq - default-language: Haskell2010 - test-suite sibe-test type: exitcode-stdio-1.0 hs-source-dirs: test diff --git a/src/Sibe.hs b/src/Sibe.hs index 79d4f08..46a0673 100644 --- a/src/Sibe.hs +++ b/src/Sibe.hs @@ -15,22 +15,37 @@ module Sibe saveNetwork, loadNetwork, train, - session, - shuffle, + gd, + sgd, + run, sigmoid, sigmoid', + softmax, + softmax', + one, relu, relu', crossEntropy, genSeed, - replaceVector + replaceVector, + Session(..), + accuracy, + learningRateDecay ) where import Numeric.LinearAlgebra import System.Random + import System.Random.Shuffle import Debug.Trace - import Data.List (foldl', sortBy) + import Data.List (foldl', sortBy, genericLength, permutations) import System.IO import Control.DeepSeq + import Control.Monad + import qualified Data.Vector.Storable as V + import Data.Default.Class + import System.Exit + + import qualified Graphics.Rendering.Chart.Easy as Chart + import Graphics.Rendering.Chart.Backend.Cairo type LearningRate = Double type Input = Vector Double @@ -48,8 +63,33 @@ module Sibe data Network = O Layer | Layer :- Network deriving (Show) + infixr 5 :- + data Session = Session { network :: Network + , training :: [(Vector Double, Vector Double)] + , test :: [(Vector Double, Vector Double)] + , learningRate :: Double + , epochs :: Int + , epoch :: Int + , batchSize :: Int + , chart :: [(Int, Double, Double)] + , momentum :: Double + } + + emptyNetwork = randomNetwork 0 (0, 0) 0 [] (0, (id, id)) + instance Default Session where + def = Session { network = seq (die "You have not specified a network parameter") emptyNetwork + , training = seq (die "You have not specified training data") [] + , test = seq (die "You have not specified test data") [] + , learningRate = 0.5 + , epochs = 35 + , epoch = 0 + , batchSize = 0 + , chart = [] + , momentum = 0 + } + saveNetwork :: Network -> String -> IO () saveNetwork network file = writeFile file ((show . reverse) (gen network [])) @@ -73,22 +113,24 @@ module Sibe runLayer :: Input -> Layer -> Output runLayer input (Layer !biases !weights _) = input <# weights + biases - forward :: Input -> Network -> Output - forward input (O l@(Layer _ _ (fn, _))) = fn $ runLayer input l - forward input (l@(Layer _ _ (fn, _)) :- n) = forward ((fst . activation $ l) $ runLayer input l) n + forward :: Input -> Session -> Output + forward input session = compute input (network session) + where + compute input (O l@(Layer _ _ (fn, _))) = fn $ runLayer input l + compute input (l@(Layer _ _ (fn, _)) :- n) = compute ((fst . activation $ l) $ runLayer input l) n - randomLayer :: Seed -> (Int, Int) -> Activation -> Layer - randomLayer seed (wr, wc) = - let weights = uniformSample seed wr $ replicate wc (-1, 1) - biases = randomVector seed Uniform wc * 2 - 1 + randomLayer :: Seed -> (Int, Int) -> (Double, Double) -> Activation -> Layer + randomLayer seed (wr, wc) (l, u) = + let weights = uniformSample seed wr $ replicate wc (l, u) + biases = randomVector seed Uniform wc * realToFrac u - realToFrac l in Layer biases weights - randomNetwork :: Seed -> Int -> [(Int, Activation)] -> (Int, Activation) -> Network - randomNetwork seed input [] (output, a) = - O $ randomLayer seed (input, output) a - randomNetwork seed input ((h, a):hs) output = - randomLayer seed (input, h) a :- - randomNetwork (seed + 1) h hs output + randomNetwork :: Seed -> (Double, Double) -> Int -> [(Int, Activation)] -> (Int, Activation) -> Network + randomNetwork seed bound input [] (output, a) = + O $ randomLayer seed (input, output) bound a + randomNetwork seed bound input ((h, a):hs) output = + randomLayer seed (input, h) bound a :- + randomNetwork (seed + 1) bound h hs output sigmoid :: Vector Double -> Vector Double sigmoid x = 1 / max (1 + exp (-x)) 1e-10 @@ -96,18 +138,37 @@ module Sibe sigmoid' :: Vector Double -> Vector Double sigmoid' x = sigmoid x * (1 - sigmoid x) + softmax :: Vector Double -> Vector Double + softmax x = cmap (\a -> exp a / s) x + where + s = V.sum $ exp x + + one :: a -> Double + one x = 1 + + softmax' :: Vector Double -> Vector Double + softmax' x = softmax x * (1 - softmax x) + relu :: Vector Double -> Vector Double - relu x = log (max (1 + exp x) 1e-10) + relu = cmap (max 0.1) relu' :: Vector Double -> Vector Double - relu' = sigmoid + relu' = cmap dev + where dev x + | x < 0 = 0 + | otherwise = 1 - crossEntropy :: Output -> Output -> Double - crossEntropy output target = - let pairs = zip (toList output) (toList target) - n = fromIntegral (length pairs) - in (-1 / n) * sum (map f pairs) + crossEntropy :: Session -> Double + crossEntropy session = + let inputs = map fst (test session) + labels = map (toList . snd) (test session) + outputs = map (toList . (`forward` session)) inputs + pairs = zip outputs labels + n = genericLength pairs + + in sum (map set pairs) / n where + set (os, ls) = (-1 / genericLength os) * sum (zipWith (curry f) os ls) f (a, y) = y * log (max 1e-10 a) + (1 - y) * log (max (1 - a) 1e-10) train :: Input @@ -138,35 +199,137 @@ module Sibe o = fn y (n', delta) = run o n - de = delta * fn' y -- quadratic cost + de = delta * fn' y - biases' = biases - scale alpha de - weights' = weights - scale alpha (input `outer` de) + biases' = biases - cmap (*alpha) de + weights' = weights - cmap (*alpha) (input `outer` de) layer = Layer biases' weights' (fn, fn') pass = weights #> de -- pass = weights #> de in (layer :- n', pass) - session :: [Input] -> Network -> [Output] -> Double -> (Int, Int) -> Network - session inputs network labels alpha (iterations, epochs) = - let n = length inputs - indexes = shuffle n (map (`mod` n) [0..n * epochs]) - in foldl' iter network indexes + {-trainMomentum :: Input + -> Network + -> Output -- target + -> Double -- learning rate + -> (Double, Double) -- momentum + -> Network -- network's output + trainMomentum input network target alpha (m, v) = fst $ run input network where - iter net i = - let n = length inputs - index = i `mod` n - input = inputs !! index - label = labels !! index - in foldl' (\net _ -> train input net label alpha) net [0..iterations] + run :: Input -> Network -> (Network, Vector Double) + run input (O l@(Layer biases weights (fn, fn'))) = + let y = runLayer input l + o = fn y + delta = o - target + de = delta * fn' y + v = + -- de = delta -- cross entropy cost - shuffle :: Seed -> [a] -> [a] - shuffle seed list = - let ords = map ord $ take (length list) (randomRs (0, 1) (mkStdGen seed) :: [Int]) - in map snd $ sortBy (\x y -> fst x) (zip ords list) - where ord x | x == 0 = LT - | x == 1 = GT + biases' = biases - scale alpha de + weights' = weights - scale alpha (input `outer` de) -- small inputs learn slowly + layer = Layer biases' weights' (fn, fn') -- updated layer + + pass = weights #> de + -- pass = weights #> de + + in (O layer, pass) + run input (l@(Layer biases weights (fn, fn')) :- n) = + let y = runLayer input l + o = fn y + (n', delta) = run o n + + de = delta * fn' y + + biases' = biases - cmap (*alpha) de + weights' = weights - cmap (*alpha) (input `outer` de) + layer = Layer biases' weights' (fn, fn') + + pass = weights #> de + -- pass = weights #> de + in (layer :- n', pass)-} + + gd :: Session -> IO Session + gd session = do + seed <- newStdGen + + let pairs = training session + alpha = learningRate session + net = network session + + let n = length pairs + + shuffled <- shuffleM pairs + + let newnet = foldl' (\n (input, label) -> train input n label alpha) net pairs + + return session { network = newnet + , epoch = epoch session + 1 + } + + sgd :: Session -> IO Session + sgd session = do + seed <- newStdGen + + let pairs = training session + bsize = batchSize session + alpha = learningRate session + net = network session + + let n = length pairs + iterations = n `div` bsize - 1 + + shuffled <- shuffleM pairs + + let iter net i = + let n = length pairs + batch = take bsize . drop (i * bsize) $ shuffled + batchInputs = map fst batch + batchLabels = map snd batch + batchPair = zip batchInputs batchLabels + in foldl' (\n (input, label) -> train input n label alpha) net batchPair + + let newnet = foldl' iter net [0..iterations] + cost = crossEntropy (session { network = newnet }) + + let el = map (\(e, l, _) -> (e, l)) (chart session) + ea = map (\(e, _, a) -> (e, a)) (chart session) + + putStrLn $ (show $ epoch session) ++ " => " ++ (show cost) ++ " @ " ++ (show $ learningRate session) + + toFile Chart.def "sgd.png" $ do + Chart.layoutlr_title Chart..= "loss over time" + Chart.plotLeft (Chart.line "loss" [el]) + Chart.plotRight (Chart.line "learningRate" [ea]) + + return session { network = newnet + , epoch = epoch session + 1 + , chart = (epoch session, cost, learningRate session):chart session + } + + + accuracy :: Session -> Double + accuracy session = + let inputs = map fst (test session) + labels = map snd (test session) + + results = map (`forward` session) inputs + rounded = map (map round . toList) results + + equals = zipWith (==) rounded (map (map round . toList) labels) + in genericLength (filter (== True) equals) / genericLength inputs + + learningRateDecay :: (Double, Double) -> Session -> Session + learningRateDecay (step, m) session = + session { learningRate = max m $ learningRate session / step } + + run :: (Session -> IO Session) + -> Session -> IO Session + run fn session = foldM (\s i -> fn s) session [0..epochs session] + + factorial :: Int -> Int + factorial 0 = 1 + factorial x = x * factorial (x - 1) genSeed :: IO Seed genSeed = do @@ -176,12 +339,7 @@ module Sibe replaceVector :: Vector Double -> Int -> Double -> Vector Double replaceVector vec index value = let list = toList vec - in fromList $ rrow index list - where - rrow index [] = [] - rrow index (x:xs) - | index == index = value:xs - | otherwise = x : rrow (index + 1) xs + in fromList $ take index list ++ value : drop (index + 1) list clip :: Double -> (Double, Double) -> Double clip x (l, u) = min u (max l x) diff --git a/src/Sibe/LogisticRegression.hs b/src/Sibe/LogisticRegression.hs new file mode 100644 index 0000000..e69de29 diff --git a/src/Sibe/NLP.hs b/src/Sibe/NLP.hs new file mode 100644 index 0000000..29e63c5 --- /dev/null +++ b/src/Sibe/NLP.hs @@ -0,0 +1,129 @@ +module Sibe.NLP + (Class, + Document(..), + ordNub, + accuracy, + recall, + precision, + fmeasure, + cleanText, + cleanDocuments, + removeWords, + removeStopwords, + ngram, + ngramText, + ) + where + import Data.List + import Debug.Trace + import qualified Data.Set as Set + import Data.List.Split + import Data.Maybe + import Control.Arrow ((&&&)) + import Text.Regex.PCRE + import Data.Char (isSpace, isNumber, toLower) + import NLP.Stemmer + + type Class = Int; + + data Document = Document { text :: String + , c :: Class + } deriving (Eq, Show, Read) + + + cleanText :: String -> String + cleanText string = + let puncs = filter (`notElem` ['!', '"', '#', '$', '%', '(', ')', '.', '?']) (trim string) + spacify = foldl (\acc x -> replace x ' ' acc) puncs [',', '/', '-', '\n', '\r'] + stemmed = unwords $ map (stem Porter) (words spacify) + nonumber = filter (not . isNumber) stemmed + lower = map toLower nonumber + in (unwords . words) lower -- remove unnecessary spaces + where + trim = f . f + where + f = reverse . dropWhile isSpace + replace needle replacement = + map (\c -> if c == needle then replacement else c) + + cleanDocuments :: [Document] -> [Document] + cleanDocuments documents = + let cleaned = map (\(Document text c) -> Document (cleanText text) c) documents + in cleaned + + removeWords :: [String] -> [Document] -> [Document] + removeWords ws documents = + map (\(Document text c) -> Document (rm ws text) c) documents + where + rm list text = + unwords $ filter (`notElem` list) (words text) + + removeStopwords :: Int -> [Document] -> [Document] + removeStopwords i documents = + let wc = wordCounts (concatDocs documents) + wlist = sortBy (\(_, a) (_, b) -> b `compare` a) wc + stopwords = map fst (take i wlist) + in removeWords stopwords documents + where + vocabulary x = ordNub (words x) + countWordInDoc d w = genericLength (filter (==w) d) + wordCounts x = + let voc = vocabulary x + in zip voc $ map (countWordInDoc (words x)) voc + + concatDocs = concatMap (\(Document text _) -> text ++ " ") + + ordNub :: (Ord a) => [a] -> [a] + ordNub = go Set.empty + where + go _ [] = [] + go s (x:xs) = if x `Set.member` s then go s xs + else x : go (Set.insert x s) xs + + accuracy :: [(Int, (Int, Double))] -> Double + accuracy results = + let pairs = map (\(a, b) -> (a, fst b)) results + correct = filter (uncurry (==)) pairs + in genericLength correct / genericLength results + + recall :: [(Int, (Int, Double))] -> Double + recall results = + let classes = ordNub (map fst results) + s = sum (map rec classes) / genericLength classes + in s + where + rec a = + let t = genericLength $ filter (\(c, (r, _)) -> c == r && c == a) results + y = genericLength $ filter (\(c, (r, _)) -> c == a) results + in t / y + + precision :: [(Int, (Int, Double))] -> Double + precision results = + let classes = ordNub (map fst results) + s = sum (map prec classes) / genericLength classes + in s + where + prec a = + let t = genericLength $ filter (\(c, (r, _)) -> c == r && c == a) results + y = genericLength $ filter (\(c, (r, _)) -> r == a) results + in + if y == 0 + then 0 + else t / y + + fmeasure :: [(Int, (Int, Double))] -> Double + fmeasure results = + let r = recall results + p = precision results + in (2 * p * r) / (p + r) + + ngram :: Int -> [Document] -> [Document] + ngram n documents = + map (\(Document text c) -> Document (ngramText n text) c) documents + + ngramText :: Int -> String -> String + ngramText n text = + let ws = words text + pairs = zip [0..] ws + grams = map (\(i, w) -> concat . intersperse "_" $ w:((take (n - 1) . drop (i+1)) ws)) pairs + in unwords ("_":grams) diff --git a/src/Sibe/NaiveBayes.hs b/src/Sibe/NaiveBayes.hs index 7afe1f6..85657c4 100644 --- a/src/Sibe/NaiveBayes.hs +++ b/src/Sibe/NaiveBayes.hs @@ -1,7 +1,7 @@ module Sibe.NaiveBayes (Document(..), NB(..), - train, + initialize, run, session, ordNub, @@ -19,21 +19,13 @@ module Sibe.NaiveBayes removeStopwords, ) where + import Sibe.NLP import Data.List import Debug.Trace import qualified Data.Set as Set import Data.List.Split import Data.Maybe import Control.Arrow ((&&&)) - import Text.Regex.PCRE - import Data.Char (isSpace, isNumber, toLower) - import NLP.Stemmer - - type Class = Int; - - data Document = Document { text :: String - , c :: Class - } deriving (Eq, Show, Read) data NB = NB { documents :: [Document] , classes :: [(Class, Double)] @@ -44,8 +36,8 @@ module Sibe.NaiveBayes , cgram :: [(Class, [(String, Int)])] } deriving (Eq, Show, Read) - train :: [Document] -> [Class] -> NB - train documents classes = + initialize :: [Document] -> [Class] -> NB + initialize documents classes = let megadoc = concatDocs documents vocabulary = genericLength ((ordNub . words) megadoc) -- (class, prior probability) @@ -83,17 +75,6 @@ module Sibe.NaiveBayes classWordsCounts x = wordsCount (classWords x) (classVocabulary x) classNGramCounts x = wordsCount (classNGramWords x) (ordNub $ classNGramWords x) - ngram :: Int -> [Document] -> [Document] - ngram n documents = - map (\(Document text c) -> Document (ngramText n text) c) documents - - ngramText :: Int -> String -> String - ngramText n text = - let ws = words text - pairs = zip [0..] ws - grams = map (\(i, w) -> concat . intersperse "_" $ w:((take (n - 1) . drop (i+1)) ws)) pairs - in unwords ("_":grams) - session :: [Document] -> NB -> [(Class, (Class, Double))] session docs nb = let results = map (\(Document text c) -> (c, run text nb)) docs @@ -143,91 +124,5 @@ module Sibe.NaiveBayes variance = sum (map ((^2) . subtract avg) x) / (genericLength x - 1) in sqrt variance - cleanText :: String -> String - cleanText string = - let puncs = filter (`notElem` ['!', '"', '#', '$', '%', '(', ')', '.', '?']) (trim string) - spacify = foldl (\acc x -> replace x ' ' acc) puncs [',', '/', '-', '\n', '\r'] - stemmed = unwords $ map (stem Porter) (words spacify) - nonumber = filter (not . isNumber) stemmed - lower = map toLower nonumber - in (unwords . words) lower -- remove unnecessary spaces - where - trim = f . f - where - f = reverse . dropWhile isSpace - replace needle replacement = - map (\c -> if c == needle then replacement else c) - - cleanDocuments :: [Document] -> [Document] - cleanDocuments documents = - let cleaned = map (\(Document text c) -> Document (cleanText text) c) documents - in cleaned - - removeWords :: [String] -> [Document] -> [Document] - removeWords ws documents = - map (\(Document text c) -> Document (rm ws text) c) documents - where - rm list text = - unwords $ filter (`notElem` list) (words text) - - removeStopwords :: Int -> [Document] -> [Document] - removeStopwords i documents = - let wc = wordCounts (concatDocs documents) - wlist = sortBy (\(_, a) (_, b) -> b `compare` a) wc - stopwords = map fst (take i wlist) - in removeWords stopwords documents - where - vocabulary x = ordNub (words x) - countWordInDoc d w = genericLength (filter (==w) d) - wordCounts x = - let voc = vocabulary x - in zip voc $ map (countWordInDoc (words x)) voc - - concatDocs = concatMap (\(Document text _) -> text ++ " ") - l :: (Show a) => a -> a l a = trace (show a) a - - ordNub :: (Ord a) => [a] -> [a] - ordNub = go Set.empty - where - go _ [] = [] - go s (x:xs) = if x `Set.member` s then go s xs - else x : go (Set.insert x s) xs - - accuracy :: [(Int, (Int, Double))] -> Double - accuracy results = - let pairs = map (\(a, b) -> (a, fst b)) results - correct = filter (uncurry (==)) pairs - in genericLength correct / genericLength results - - recall :: [(Int, (Int, Double))] -> Double - recall results = - let classes = ordNub (map fst results) - s = sum (map rec classes) / genericLength classes - in s - where - rec a = - let t = genericLength $ filter (\(c, (r, _)) -> c == r && c == a) results - y = genericLength $ filter (\(c, (r, _)) -> c == a) results - in t / y - - precision :: [(Int, (Int, Double))] -> Double - precision results = - let classes = ordNub (map fst results) - s = sum (map prec classes) / genericLength classes - in s - where - prec a = - let t = genericLength $ filter (\(c, (r, _)) -> c == r && c == a) results - y = genericLength $ filter (\(c, (r, _)) -> r == a) results - in - if y == 0 - then 0 - else t / y - - fmeasure :: [(Int, (Int, Double))] -> Double - fmeasure results = - let r = recall results - p = precision results - in (2 * p * r) / (p + r) diff --git a/stack.yaml b/stack.yaml index d02fe3e..5960cdb 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,40 +1,5 @@ -# This file was automatically generated by 'stack init' -# -# Some commonly used options have been documented as comments in this file. -# For advanced use and comprehensive documentation of the format, please see: -# http://docs.haskellstack.org/en/stable/yaml_configuration/ - -# Resolver to choose a 'specific' stackage snapshot or a compiler version. -# A snapshot resolver dictates the compiler version and the set of packages -# to be used for project dependencies. For example: -# -# resolver: lts-3.5 -# resolver: nightly-2015-09-21 -# resolver: ghc-7.10.2 -# resolver: ghcjs-0.1.0_ghc-7.10.2 -# resolver: -# name: custom-snapshot -# location: "./custom-snapshot.yaml" resolver: lts-6.7 -# User packages to be built. -# Various formats can be used as shown in the example below. -# -# packages: -# - some-directory -# - https://example.com/foo/bar/baz-0.0.2.tar.gz -# - location: -# git: https://github.com/commercialhaskell/stack.git -# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a -# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a -# extra-dep: true -# subdirs: -# - auto-update -# - wai -# -# A package marked 'extra-dep: true' will only be built if demanded by a -# non-dependency (i.e. a user package), and its test suites and benchmarks -# will not be run. This is useful for tweaking upstream packages. packages: - location: git: git@github.com:albertoruiz/hmatrix.git @@ -42,36 +7,11 @@ packages: subdirs: - packages/base - . -- http://hackage.haskell.org/package/containers-0.5.7.1/containers-0.5.7.1.tar.gz -- http://hackage.haskell.org/package/text-1.2.2.1/text-1.2.2.1.tar.gz -- http://hackage.haskell.org/package/stemmer-0.5.2/stemmer-0.5.2.tar.gz -# Dependency packages to be pulled from upstream that are not in the resolver -# (e.g., acme-missiles-0.3) -extra-deps: [] - -# Override default flag values for local packages and extra-deps -flags: {} - -# Extra package databases containing global packages -extra-package-dbs: [] - -# Control whether we use the GHC we find on the path -# system-ghc: true -# -# Require a specific version of stack, using version ranges -# require-stack-version: -any # Default -# require-stack-version: ">=1.1" -# -# Override the architecture used by stack, especially useful on Windows -# arch: i386 -# arch: x86_64 -# -# Extra directories used by stack for building -# extra-include-dirs: [/path/to/dir] -# extra-lib-dirs: [/path/to/dir] -# -# Allow a newer minor version of GHC than the snapshot specifies -# compiler-check: newer-minor - -system-ghc: false +extra-deps: + - directory-1.2.7.0 + - text-1.2.2.1 + - stemmer-0.5.2 + - containers-0.5.7.1 + - Chart-1.8 + - Chart-cairo-1.8