@@ -0,0 +1,70 @@
1+{-# LANGUAGE BangPatterns #-}
2+{-# LANGUAGE DataKinds #-}
3+{-# LANGUAGE ScopedTypeVariables #-}
4+{-# LANGUAGE StandaloneDeriving #-}
6+{-# LANGUAGE TypeOperators #-}
7+{-# LANGUAGE TypeFamilies #-}
8+{-# LANGUAGE MultiParamTypeClasses #-}
9+{-# LANGUAGE FlexibleInstances #-}
10+{-# LANGUAGE FlexibleContexts #-}
11+{-# LANGUAGE PolyKinds #-}
13+module Grenade.Layers.Crop (
19+import Data.Singletons.TypeLits
22+import Grenade.Core.Network
23+import Grenade.Core.Shape
25+import Numeric.LinearAlgebra (konst, subMatrix, diagBlock)
26+import Numeric.LinearAlgebra.Static (extract, create)
28+-- | A cropping layer for a neural network.
33+ Crop :: ( KnownNat cropLeft
36+ , KnownNat cropBottom
37+ ) => Crop cropLeft cropTop cropRight cropBottom
39+instance Show (Crop cropLeft cropTop cropRight cropBottom) where
42+-- | A two dimentional image can be cropped.
47+ , KnownNat cropBottom
49+ , KnownNat inputColumns
50+ , KnownNat outputRows
51+ , KnownNat outputColumns
52+ , (inputRows - cropTop - cropBottom) ~ outputRows
53+ , (inputColumns - cropLeft - cropRight) ~ outputColumns
54+ ) => Layer m (Crop cropLeft cropTop cropRight cropBottom) ('D2 inputRows inputColumns) ('D2 outputRows outputColumns) where
55+ runForwards Crop (S2D' input) =
56+ let cropl = fromIntegral $ natVal (Proxy :: Proxy cropLeft)
57+ cropt = fromIntegral $ natVal (Proxy :: Proxy cropTop)
58+ nrows = fromIntegral $ natVal (Proxy :: Proxy outputRows)
59+ ncols = fromIntegral $ natVal (Proxy :: Proxy outputColumns)
61+ r = subMatrix (cropt, cropl) (nrows, ncols) m
62+ in return . S2D' . fromJust . create $ r
63+ runBackards _ crop _ (S2D' dEdy) =
64+ let cropl = fromIntegral $ natVal (Proxy :: Proxy cropLeft)
65+ cropt = fromIntegral $ natVal (Proxy :: Proxy cropTop)
66+ cropr = fromIntegral $ natVal (Proxy :: Proxy cropRight)
67+ cropb = fromIntegral $ natVal (Proxy :: Proxy cropBottom)
69+ vs = diagBlock [konst 0 (cropt,cropl), eo, konst 0 (cropb,cropr)]
70+ in return (crop, S2D' . fromJust . create $ vs)