<s> from __future__ import absolute_import , print_function , division <EOL> import numpy as N <EOL> from six . moves import xrange <EOL> import theano <EOL> from theano . tensor import basic as T <EOL> from theano . tensor . blas_headers import blas_header_text , blas_header_version <EOL> from theano . tensor . blas import ldflags <EOL> from theano . misc import strutil <EOL> from theano . gradient import grad_undefined <EOL> class Conv3D ( theano . Op ) : <EOL> """<STR_LIT>""" <EOL> __props__ = ( ) <EOL> def c_code_cache_version ( self ) : <EOL> return ( <NUM_LIT:3> , blas_header_version ( ) ) <EOL> def make_node ( self , V , W , b , d ) : <EOL> """<STR_LIT>""" <EOL> V_ = T . as_tensor_variable ( V ) <EOL> W_ = T . as_tensor_variable ( W ) <EOL> b_ = T . as_tensor_variable ( b ) <EOL> d_ = T . as_tensor_variable ( d ) <EOL> bcast = ( V_ . broadcastable [ <NUM_LIT:0> ] , False , False , False , W_ . broadcastable [ <NUM_LIT:0> ] ) <EOL> node = theano . Apply ( self , inputs = [ V_ , W_ , b_ , d_ ] , <EOL> outputs = [ T . TensorType ( V_ . dtype , bcast ) ( ) ] ) <EOL> return node <EOL> def grad ( self , inputs , output_gradients ) : <EOL> V , W , b , d = inputs <EOL> dCdH , = output_gradients <EOL> dCdV = theano . tensor . nnet . convTransp3D ( <EOL> W , T . zeros_like ( V [ <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , : ] ) , d , dCdH , V . shape [ <NUM_LIT:1> : <NUM_LIT:4> ] ) <EOL> dCdV = T . patternbroadcast ( dCdV , V . broadcastable ) <EOL> WShape = W . shape <EOL> dCdW = theano . tensor . nnet . convGrad3D ( V , d , WShape , dCdH ) <EOL> dCdW = T . patternbroadcast ( dCdW , W . broadcastable ) <EOL> dCdb = T . sum ( dCdH , axis = ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:2> , <NUM_LIT:3> ) ) <EOL> dCdb = T . patternbroadcast ( dCdb , b . broadcastable ) <EOL> dCdd = grad_undefined ( <EOL> self , <NUM_LIT:3> , inputs [ <NUM_LIT:3> ] , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if '<STR_LIT:name>' in dir ( dCdH ) and dCdH . name is not None : <EOL> dCdH_name = dCdH . name <EOL> else : <EOL> dCdH_name = '<STR_LIT>' <EOL> if '<STR_LIT:name>' in dir ( V ) and V . name is not None : <EOL> V_name = V . name <EOL> else : <EOL> V_name = '<STR_LIT>' <EOL> if '<STR_LIT:name>' in dir ( W ) and W . name is not None : <EOL> W_name = W . name <EOL> else : <EOL> W_name = '<STR_LIT>' <EOL> if '<STR_LIT:name>' in dir ( b ) and b . name is not None : <EOL> b_name = b . name <EOL> else : <EOL> b_name = '<STR_LIT>' <EOL> dCdV . name = '<STR_LIT>' + dCdH_name + '<STR_LIT>' + V_name + '<STR_LIT:)>' <EOL> dCdW . name = ( '<STR_LIT>' + dCdH_name + '<STR_LIT>' + V_name + <EOL> '<STR_LIT>' + W_name + '<STR_LIT:)>' ) <EOL> dCdb . name = ( '<STR_LIT>' + dCdH_name + '<STR_LIT>' + V_name + <EOL> '<STR_LIT>' + W_name + '<STR_LIT>' + b_name + '<STR_LIT:)>' ) <EOL> return [ dCdV , dCdW , dCdb , dCdd ] <EOL> def perform ( self , node , inputs , output_storage ) : <EOL> V , W , b , d = inputs <EOL> output_storage [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] = computeH ( V , W , b , d ) <EOL> def infer_shape ( self , node , input_shapes ) : <EOL> V , W , b , d = node . inputs <EOL> V_shape , W_shape , b_shape , d_shape = input_shapes <EOL> dr = d [ <NUM_LIT:0> ] <EOL> dc = d [ <NUM_LIT:1> ] <EOL> dt = d [ <NUM_LIT:2> ] <EOL> batch_size = V_shape [ <NUM_LIT:0> ] <EOL> output_channels = W_shape [ <NUM_LIT:0> ] <EOL> vidHeight = V_shape [ <NUM_LIT:1> ] <EOL> filterHeight = W_shape [ <NUM_LIT:1> ] <EOL> vidWidth = V_shape [ <NUM_LIT:2> ] <EOL> filterWidth = W_shape [ <NUM_LIT:2> ] <EOL> vidDur = V_shape [ <NUM_LIT:3> ] <EOL> filterDur = W_shape [ <NUM_LIT:3> ] <EOL> output_height = ( ( vidHeight - filterHeight ) // dr ) + <NUM_LIT:1> <EOL> output_width = ( ( vidWidth - filterWidth ) // dc ) + <NUM_LIT:1> <EOL> output_dur = ( ( vidDur - filterDur ) // dt ) + <NUM_LIT:1> <EOL> rval = ( batch_size , output_height , output_width , output_dur , output_channels ) <EOL> return [ rval ] <EOL> def c_support_code ( self ) : <EOL> return blas_header_text ( ) <EOL> def c_libraries ( self ) : <EOL> return ldflags ( ) <EOL> def c_compile_args ( self ) : <EOL> flags = ldflags ( libs = False , flags = True ) <EOL> return flags <EOL> def c_lib_dirs ( self ) : <EOL> return ldflags ( libs = False , libs_dir = True ) <EOL> def c_header_dirs ( self ) : <EOL> return ldflags ( libs = False , include_dir = True ) <EOL> def c_code ( self , node , nodename , inputs , outputs , sub ) : <EOL> V , W , b , d = inputs <EOL> fail = sub [ '<STR_LIT>' ] <EOL> H = outputs [ <NUM_LIT:0> ] <EOL> codeSource = """<STR_LIT>""" <EOL> VV , WV , bv , dv = node . inputs <EOL> HV = node . outputs [ <NUM_LIT:0> ] <EOL> if ( theano . config . blas . ldflags and <EOL> VV . dtype == WV . dtype and HV . dtype == VV . dtype ) : <EOL> if VV . dtype == '<STR_LIT>' : <EOL> gemv = '<STR_LIT>' <EOL> elif VV . dtype == '<STR_LIT>' : <EOL> gemv = '<STR_LIT>' <EOL> else : <EOL> raise Exception ( '<STR_LIT>' + V . value . dtype ) <EOL> codeSource += """<STR_LIT>""" <EOL> codeSource += """<STR_LIT>""" <EOL> return strutil . render_string ( codeSource , locals ( ) ) <EOL> _conv3D = Conv3D ( ) <EOL> def conv3D ( V , W , b , d ) : <EOL> """<STR_LIT>""" <EOL> return _conv3D ( V , W , b , d ) <EOL> def computeH ( V , W , b , d ) : <EOL> assert len ( W . shape ) == <NUM_LIT:5> <EOL> assert len ( V . shape ) == <NUM_LIT:5> <EOL> if len ( b . shape ) != <NUM_LIT:1> : <EOL> print ( b . shape ) <EOL> assert False <EOL> assert len ( d ) == <NUM_LIT:3> <EOL> batchSize = V . shape [ <NUM_LIT:0> ] <EOL> outputChannels = W . shape [ <NUM_LIT:0> ] <EOL> inputChannels = V . shape [ <NUM_LIT:4> ] <EOL> if W . shape [ <NUM_LIT:4> ] != inputChannels : <EOL> raise Exception ( "<STR_LIT>" + str ( W . shape [ <NUM_LIT:4> ] ) + "<STR_LIT>" + str ( inputChannels ) ) <EOL> filterHeight = W . shape [ <NUM_LIT:1> ] <EOL> filterWidth = W . shape [ <NUM_LIT:2> ] <EOL> filterDur = W . shape [ <NUM_LIT:3> ] <EOL> vidHeight = V . shape [ <NUM_LIT:1> ] <EOL> vidWidth = V . shape [ <NUM_LIT:2> ] <EOL> vidDur = V . shape [ <NUM_LIT:3> ] <EOL> assert vidHeight >= filterHeight <EOL> assert vidWidth >= filterWidth <EOL> assert vidDur >= filterDur <EOL> dx , dy , dt = d <EOL> assert dx > <NUM_LIT:0> <EOL> assert dy > <NUM_LIT:0> <EOL> assert dt > <NUM_LIT:0> <EOL> outputHeight = int ( ( vidHeight - filterHeight ) / dx ) + <NUM_LIT:1> <EOL> outputWidth = int ( ( vidWidth - filterWidth ) / dy ) + <NUM_LIT:1> <EOL> outputDur = int ( ( vidDur - filterDur ) / dt ) + <NUM_LIT:1> <EOL> H = N . zeros ( ( batchSize , outputHeight , <EOL> outputWidth , outputDur , outputChannels ) , dtype = V . dtype ) <EOL> for i in xrange ( <NUM_LIT:0> , H . shape [ <NUM_LIT:0> ] ) : <EOL> for j in xrange ( <NUM_LIT:0> , H . shape [ <NUM_LIT:4> ] ) : <EOL> for x in xrange ( <NUM_LIT:0> , H . shape [ <NUM_LIT:1> ] ) : <EOL> for y in xrange ( <NUM_LIT:0> , H . shape [ <NUM_LIT:2> ] ) : <EOL> for t in xrange ( <NUM_LIT:0> , H . shape [ <NUM_LIT:3> ] ) : <EOL> H [ i , x , y , t , j ] = b [ j ] <EOL> for k in xrange ( <NUM_LIT:0> , filterHeight ) : <EOL> for l in xrange ( <NUM_LIT:0> , filterWidth ) : <EOL> for m in xrange ( <NUM_LIT:0> , filterDur ) : <EOL> for z in xrange ( <NUM_LIT:0> , inputChannels ) : <EOL> w = W [ j , k , l , m , z ] <EOL> v = V [ i , d [ <NUM_LIT:0> ] * x + k , d [ <NUM_LIT:1> ] * y + l , d [ <NUM_LIT:2> ] * t + m , z ] <EOL> H [ i , x , y , t , j ] += w * v <EOL> return H </s>
