{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE CPP #-}
#if MIN_VERSION_base(4,12,0)
{-# LANGUAGE NoStarIsType #-}
#endif
{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}
{-# OPTIONS_GHC -fno-cse #-}
module Torch.Indef.Static.NN.Conv1d
( Conv1d(..)
, weights
, bias
, featureSize
, kernelWidth
, stepSize
, conv1d
, conv1d_forward
, conv1d_backwardGradInput
, conv1d_updGradParams
, conv1dBatch
, conv1d_forwardBatch
, conv1d_backwardGradInputBatch
, conv1d_updGradParamsBatch
, _temporalRowConvolution_updateOutput
, _temporalRowConvolution_updateGradInput
, _temporalRowConvolution_updGradParameters
) where
import Numeric.Backprop
import Numeric.Dimensions
import Data.Kind (Type)
import Data.List (intercalate)
import Data.Singletons.Prelude (type (>), type (<))
import Data.Singletons.TypeLits
import System.IO.Unsafe
import Torch.Indef.Types
import Torch.Indef.Static.Tensor
import Torch.Indef.Static.Tensor.Copy
import Torch.Indef.Static.Tensor.Math
import Torch.Indef.Static.Tensor.Math.CompareT
import Torch.Indef.Static.NN.Backprop ()
import qualified Torch.Indef.Dynamic.NN as Dynamic
newtype Conv1d f o kW dW
= Conv1d { getTensors :: (Tensor '[o, f*kW], Tensor '[o]) }
instance (KnownDim f, KnownDim o, KnownDim kW, KnownDim dW)
=> Show (Conv1d f o kW dW) where
show c = intercalate ","
[ "Conv1d ("
++ "features: " ++ show (featureSize c)
, " output: " ++ show (outputSize c)
, " kernel: " ++ show (kernelWidth c)
, " step: " ++ show (stepSize c)
++ ")"
]
instance (KnownDim (f*kW), KnownDim o) => Backprop (Conv1d f o kW dW) where
zero = const . Conv1d $ (constant 0, constant 0)
one = const . Conv1d $ (constant 1, constant 1)
add c0 c1 = Conv1d (weights c0 + weights c1, bias c0 + bias c1)
weights :: Conv1d f o kW dW -> Tensor '[o, f*kW]
weights (Conv1d (w, _)) = w
bias :: Conv1d f o kW dW -> Tensor '[o]
bias (Conv1d (_, b)) = b
featureSize :: forall f o kW dW . KnownDim f => Conv1d f o kW dW -> Int
featureSize _ = fromIntegral (dimVal (dim :: Dim f))
outputSize :: forall f o kW dW . KnownDim o => Conv1d f o kW dW -> Int
outputSize _ = fromIntegral (dimVal (dim :: Dim o))
kernelWidth :: forall f o kW dW . KnownDim kW => Conv1d f o kW dW -> Int
kernelWidth _ = fromIntegral (dimVal (dim :: Dim kW))
stepSize :: forall f o kW dW . KnownDim dW => Conv1d f o kW dW -> Int
stepSize _ = fromIntegral (dimVal (dim :: Dim dW))
type TemporalConvC s f kW dW o =
( All KnownDim '[s,f,kW,dW,o]
, (s > kW) ~ 'True
, (kW > 0) ~ 'True
, (dW > 0) ~ 'True
)
conv1d
:: forall s seq f kW dW o
. Reifies s W
=> KnownDim (f*kW)
=> TemporalConvC seq f kW dW o
=> Double
-> BVar s (Conv1d f o kW dW)
-> BVar s (Tensor '[seq, f])
-> BVar s (Tensor '[seq, o])
conv1d = _conv1d
conv1dBatch
:: forall s seq f kW dW o b
. Reifies s W
=> KnownDim b
=> KnownDim (f*kW)
=> TemporalConvC seq f kW dW o
=> Double
-> BVar s (Conv1d f o kW dW)
-> BVar s (Tensor '[b, seq, f])
-> BVar s (Tensor '[b, seq, o])
conv1dBatch = _conv1d
_conv1d
:: Reifies s W
=> KnownDim (f*kW)
=> All KnownDim '[f,kW,dW,o]
=> All Dimensions '[d,d']
=> Double
-> BVar s (Conv1d f o kW dW)
-> BVar s (Tensor d)
-> BVar s (Tensor d')
_conv1d lr = liftOp2 . op2 $ \c inp ->
(unsafePerformIO $ _conv1d_forward c inp, \gout ->
( unsafePerformIO $ _conv1d_updGradParams c inp gout lr
, unsafePerformIO $ _conv1d_backwardGradInput c inp gout
) )
conv1d_forward
:: TemporalConvC s f kW dW o
=> Conv1d f o kW dW
-> Tensor '[s, f]
-> IO (Tensor '[s, o])
conv1d_forward = _conv1d_forward
conv1d_backwardGradInput
:: TemporalConvC seq f kW dW o
=> Conv1d f o kW dW
-> Tensor '[seq, f]
-> Tensor '[seq, o]
-> IO (Tensor '[seq, f])
conv1d_backwardGradInput = _conv1d_backwardGradInput
conv1d_updGradParams
:: TemporalConvC s f kW dW o
=> Conv1d f o kW dW
-> Tensor '[s, f]
-> Tensor '[s, o]
-> Double
-> IO (Conv1d f o kW dW)
conv1d_updGradParams = _conv1d_updGradParams
conv1d_forwardBatch
:: TemporalConvC s f kW dW o
=> Conv1d f o kW dW
-> Tensor '[b,s,f]
-> IO (Tensor '[b,s,o])
conv1d_forwardBatch = _conv1d_forward
conv1d_backwardGradInputBatch
:: TemporalConvC s f kW dW o
=> KnownDim b
=> Conv1d f o kW dW
-> Tensor '[b, s, f]
-> Tensor '[b, s, o]
-> IO (Tensor '[b, s, f])
conv1d_backwardGradInputBatch = _conv1d_backwardGradInput
conv1d_updGradParamsBatch
:: TemporalConvC s f kW dW o
=> KnownDim b
=> Conv1d f o kW dW
-> Tensor '[b, s, f]
-> Tensor '[b, s, o]
-> Double
-> IO (Conv1d f o kW dW)
conv1d_updGradParamsBatch = _conv1d_updGradParams
{-# NOINLINE _conv1d_forward #-}
_conv1d_forward :: All KnownDim '[f,kW,dW,o] => Conv1d f o kW dW -> Tensor d -> IO (Tensor d')
_conv1d_forward conv inp = do
let out = empty
Dynamic._temporalConvolution_updateOutput
(asDynamic inp) (asDynamic out)
(asDynamic (weights conv)) (asDynamic (bias conv))
(kernelWidth conv) (stepSize conv)
(featureSize conv) (outputSize conv)
pure out
{-# NOINLINE _conv1d_backwardGradInput #-}
_conv1d_backwardGradInput
:: forall f o kW dW inputDim goutDim
. All KnownDim '[f,kW,dW,o]
=> All Dimensions '[inputDim,goutDim]
=> Conv1d f o kW dW
-> Tensor inputDim
-> Tensor goutDim
-> IO (Tensor inputDim)
_conv1d_backwardGradInput conv input gradOut = do
let gradIn = empty
Dynamic._temporalConvolution_updateGradInput
(asDynamic input) (asDynamic gradOut)
(asDynamic gradIn) (asDynamic (weights conv))
(kernelWidth conv) (stepSize conv)
pure gradIn
{-# NOINLINE _conv1d_updGradParams #-}
_conv1d_updGradParams
:: forall f o kW dW inputDim gOutDim
. All KnownDim '[f,kW,dW,o]
=> All Dimensions '[inputDim,gOutDim]
=> Conv1d f o kW dW
-> Tensor inputDim
-> Tensor gOutDim
-> Double
-> IO (Conv1d f o kW dW)
_conv1d_updGradParams c@(Conv1d (w, b)) input gout scale = do
let w' = copy w
let b' = copy b
Dynamic._temporalConvolution_accGradParameters
(asDynamic input) (asDynamic gout) (asDynamic w') (asDynamic b')
(kernelWidth c) (stepSize c) scale
pure $ Conv1d (w', b')
_temporalRowConvolution_updateOutput :: Tensor d -> Tensor d' -> Tensor d'' -> Tensor d''' -> Tensor d -> Tensor d -> Int -> Int -> Int -> Bool -> IO ()
_temporalRowConvolution_updateOutput t0 t1 t2 t3 t4 t5 = Dynamic._temporalRowConvolution_updateOutput (asDynamic t0) (asDynamic t1) (asDynamic t2) (asDynamic t3) (asDynamic t4) (asDynamic t5)
_temporalRowConvolution_updateGradInput :: Tensor d -> Tensor d' -> Tensor d'' -> Tensor d''' -> Tensor d -> Tensor d -> Int -> Int -> Int -> Bool -> IO ()
_temporalRowConvolution_updateGradInput t0 t1 t2 t3 t4 t5 = Dynamic._temporalRowConvolution_updateGradInput (asDynamic t0) (asDynamic t1) (asDynamic t2) (asDynamic t3) (asDynamic t4) (asDynamic t5)
_temporalRowConvolution_updGradParameters :: Tensor d -> Tensor d' -> Tensor d'' -> Tensor d''' -> Tensor d -> Tensor d -> Int -> Int -> Int -> Bool -> Double -> IO ()
_temporalRowConvolution_updGradParameters t0 t1 t2 t3 t4 t5 = Dynamic._temporalRowConvolution_accGradParameters (asDynamic t0) (asDynamic t1) (asDynamic t2) (asDynamic t3) (asDynamic t4) (asDynamic t5)