fei-datasets-1.0.0: src/MXNet/NN/DataIter/Common.hs
{-# LANGUAGE DataKinds #-}
module MXNet.NN.DataIter.Common where
import Data.Array.Repa ((:.) (..), Array, D, DIM1, DIM2, DIM3, U,
Z (..), fromListUnboxed, (*^), (+^), (-^),
(/^))
import qualified Data.Array.Repa as Repa
import GHC.TypeLits (Symbol)
import RIO
import qualified RIO.Vector.Boxed as V
type ImageTensor = Array U DIM3 Float
type ImageInfo = Array U DIM1 Float
type GTBoxes = V.Vector (Array U DIM1 Float)
type Masks = V.Vector (Array U DIM2 Word8)
data family Configuration (dataset :: Symbol)
class ImageDataset (a :: Symbol) where
imagesMean :: Getting (Float, Float, Float) (Configuration a) (Float, Float, Float)
imagesStdDev :: Getting (Float, Float, Float) (Configuration a) (Float, Float, Float)
class HasDatasetConfig env where
type DatasetTag env :: Symbol
datasetConfig :: Lens' env (Configuration (DatasetTag env))
-- transform HWC -> CHW
transform :: (HasDatasetConfig env,
ImageDataset (DatasetTag env),
MonadReader env m,
Repa.Source r Float)
=> Array r DIM3 Float -> m (Array D DIM3 Float)
transform img = do
mean <- view (datasetConfig . imagesMean)
std <- view (datasetConfig . imagesStdDev)
let broadcast = Repa.extend (Repa.Any :. height :. width)
mean' = broadcast $ fromTuple mean
std' = broadcast $ fromTuple std
chnFirst = Repa.backpermute newShape (\ (Z :. c :. h :. w) -> Z :. h :. w :. c) img
return $ (chnFirst -^ mean') /^ std'
where
Z :. height :. width :. chn = Repa.extent img
newShape = Z:. chn :. height :. width
-- transform CHW -> HWC
transformInv :: (ImageDataset s, MonadReader (Configuration s) m, Repa.Source r Float) =>
Array r DIM3 Float -> m (Array D DIM3 Float)
transformInv img = do
mean <- view imagesMean
std <- view imagesStdDev
let broadcast = Repa.extend (Repa.Any :. height :. width)
mean' = broadcast $ fromTuple mean
std' = broadcast $ fromTuple std
addMean = img *^ std' +^ mean'
return $ Repa.backpermute newShape (\ (Z :. h :. w :. c) -> Z :. c :. h :. w) addMean
where
(Z :. chn :. height :. width) = Repa.extent img
newShape = Z :. height :. width :. chn
fromTuple (a, b, c) = fromListUnboxed (Z :. (3 :: Int)) [a,b,c]
raiseLeft :: (MonadThrow m, Exception e) => (a -> e) -> m (Either a b) -> m b
raiseLeft exc act = act >>= either (throwM . exc) return
instance (Repa.Shape sh, Unbox e) => NFData (Array U sh e) where
rnf arr = Repa.deepSeqArray arr ()