<s> """<STR_LIT>""" <EOL> import logging <EOL> import theano <EOL> from theano . tensor import as_tensor_variable , patternbroadcast <EOL> from theano . gof import Apply , Op <EOL> from six . moves import xrange <EOL> import numpy <EOL> try : <EOL> from scipy . signal . signaltools import _valfrommode , _bvalfromboundary <EOL> from scipy . signal . sigtools import _convolve2d <EOL> imported_scipy_signal = True <EOL> except ImportError : <EOL> imported_scipy_signal = False <EOL> __docformat__ = "<STR_LIT>" <EOL> _logger = logging . getLogger ( "<STR_LIT>" ) <EOL> def get_conv_output_shape ( image_shape , kernel_shape , <EOL> border_mode , subsample ) : <EOL> """<STR_LIT>""" <EOL> bsize , imshp = image_shape [ <NUM_LIT:0> ] , image_shape [ <NUM_LIT:2> : ] <EOL> nkern , kshp = kernel_shape [ <NUM_LIT:0> ] , kernel_shape [ <NUM_LIT:2> : ] <EOL> if isinstance ( border_mode , tuple ) : <EOL> out_shp = tuple ( get_conv_shape_1axis ( <EOL> imshp [ i ] , kshp [ i ] , border_mode [ i ] , subsample [ i ] ) <EOL> for i in range ( len ( subsample ) ) ) <EOL> else : <EOL> out_shp = tuple ( get_conv_shape_1axis ( <EOL> imshp [ i ] , kshp [ i ] , border_mode , subsample [ i ] ) <EOL> for i in range ( len ( subsample ) ) ) <EOL> return ( bsize , nkern ) + out_shp <EOL> def get_conv_shape_1axis ( image_shape , kernel_shape , <EOL> border_mode , subsample ) : <EOL> """<STR_LIT>""" <EOL> if None in [ image_shape , kernel_shape , border_mode , subsample ] : <EOL> return None <EOL> if border_mode == "<STR_LIT>" : <EOL> pad = kernel_shape // <NUM_LIT:2> <EOL> elif border_mode == "<STR_LIT>" : <EOL> pad = kernel_shape - <NUM_LIT:1> <EOL> elif border_mode == "<STR_LIT>" : <EOL> pad = <NUM_LIT:0> <EOL> else : <EOL> pad = border_mode <EOL> if pad < <NUM_LIT:0> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> out_shp = ( image_shape + <NUM_LIT:2> * pad - kernel_shape ) // subsample + <NUM_LIT:1> <EOL> return out_shp <EOL> def conv2d ( input , <EOL> filters , <EOL> input_shape = None , <EOL> filter_shape = None , <EOL> border_mode = '<STR_LIT>' , <EOL> subsample = ( <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> filter_flip = True ) : <EOL> """<STR_LIT>""" <EOL> conv_op = AbstractConv2d ( imshp = input_shape , <EOL> kshp = filter_shape , <EOL> border_mode = border_mode , <EOL> subsample = subsample , <EOL> filter_flip = filter_flip ) <EOL> return conv_op ( input , filters ) <EOL> def conv2d_grad_wrt_inputs ( output_grad , <EOL> filters , <EOL> output_grad_shape = None , <EOL> input_shape = None , <EOL> filter_shape = None , <EOL> border_mode = '<STR_LIT>' , <EOL> subsample = ( <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> filter_flip = True ) : <EOL> """<STR_LIT>""" <EOL> grad_input_op = AbstractConv2d_gradInputs ( imshp = input_shape , <EOL> kshp = filter_shape , <EOL> border_mode = border_mode , <EOL> subsample = subsample , <EOL> filter_flip = filter_flip ) <EOL> return grad_input_op ( filters , output_grad , input_shape ) <EOL> def conv2d_grad_wrt_weights ( input , <EOL> output_grad , <EOL> input_shape = None , <EOL> output_grad_shape = None , <EOL> filter_shape = None , <EOL> border_mode = '<STR_LIT>' , <EOL> subsample = ( <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> filter_flip = True ) : <EOL> """<STR_LIT>""" <EOL> gradWeight_op = AbstractConv2d_gradWeights ( imshp = input_shape , <EOL> kshp = filter_shape , <EOL> border_mode = border_mode , <EOL> subsample = subsample , <EOL> filter_flip = filter_flip ) <EOL> return gradWeight_op ( input , output_grad , filter_shape ) <EOL> class BaseAbstractConv2d ( Op ) : <EOL> """<STR_LIT>""" <EOL> check_broadcast = False <EOL> __props__ = ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> def __init__ ( self , <EOL> imshp = None , kshp = None , <EOL> border_mode = "<STR_LIT>" , subsample = ( <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> filter_flip = True ) : <EOL> if isinstance ( border_mode , int ) : <EOL> border_mode = ( border_mode , border_mode ) <EOL> if isinstance ( border_mode , tuple ) : <EOL> pad_h , pad_w = map ( int , border_mode ) <EOL> border_mode = ( pad_h , pad_w ) <EOL> if border_mode == ( <NUM_LIT:0> , <NUM_LIT:0> ) : <EOL> border_mode = '<STR_LIT>' <EOL> if not ( ( isinstance ( border_mode , tuple ) and min ( border_mode ) >= <NUM_LIT:0> ) or <EOL> border_mode in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) ) : <EOL> raise ValueError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( border_mode ) ) <EOL> self . imshp = tuple ( imshp ) if imshp else None <EOL> self . kshp = tuple ( kshp ) if kshp else None <EOL> self . border_mode = border_mode <EOL> self . filter_flip = filter_flip <EOL> if len ( subsample ) != <NUM_LIT:2> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . subsample = tuple ( subsample ) <EOL> def flops ( self , inp , outp ) : <EOL> """<STR_LIT>""" <EOL> inputs , filters = inp <EOL> outputs , = outp <EOL> assert inputs [ <NUM_LIT:1> ] == filters [ <NUM_LIT:1> ] <EOL> flops = filters [ <NUM_LIT:2> ] * filters [ <NUM_LIT:3> ] * <NUM_LIT:2> <EOL> flops *= outputs [ <NUM_LIT:2> ] * outputs [ <NUM_LIT:3> ] <EOL> flops *= inputs [ <NUM_LIT:1> ] * filters [ <NUM_LIT:0> ] * inputs [ <NUM_LIT:0> ] <EOL> return flops <EOL> def do_constant_folding ( self , node ) : <EOL> return False <EOL> def conv2d ( self , img , kern , mode = "<STR_LIT>" ) : <EOL> """<STR_LIT>""" <EOL> if not imported_scipy_signal : <EOL> raise NotImplementedError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if not ( mode in ( '<STR_LIT>' , '<STR_LIT>' ) ) : <EOL> raise ValueError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( mode ) ) <EOL> out_shape = get_conv_output_shape ( img . shape , kern . shape , mode , [ <NUM_LIT:1> , <NUM_LIT:1> ] ) <EOL> out = numpy . zeros ( out_shape , dtype = img . dtype ) <EOL> val = _valfrommode ( mode ) <EOL> bval = _bvalfromboundary ( '<STR_LIT>' ) <EOL> for b in xrange ( img . shape [ <NUM_LIT:0> ] ) : <EOL> for n in xrange ( kern . shape [ <NUM_LIT:0> ] ) : <EOL> for im0 in xrange ( img . shape [ <NUM_LIT:1> ] ) : <EOL> out [ b , n , ... ] += _convolve2d ( img [ b , im0 , ... ] , <EOL> kern [ n , im0 , ... ] , <EOL> <NUM_LIT:1> , val , bval , <NUM_LIT:0> ) <EOL> return out <EOL> class AbstractConv2d ( BaseAbstractConv2d ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , <EOL> imshp = None , <EOL> kshp = None , <EOL> border_mode = "<STR_LIT>" , <EOL> subsample = ( <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> filter_flip = True ) : <EOL> super ( AbstractConv2d , self ) . __init__ ( imshp , kshp , <EOL> border_mode , subsample , <EOL> filter_flip ) <EOL> def make_node ( self , img , kern ) : <EOL> ktype = img . type . clone ( dtype = kern . dtype , <EOL> broadcastable = kern . broadcastable ) <EOL> kern = ktype . filter_variable ( kern ) <EOL> if img . type . ndim != <NUM_LIT:4> : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> if kern . type . ndim != <NUM_LIT:4> : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> broadcastable = [ img . broadcastable [ <NUM_LIT:0> ] , <EOL> kern . broadcastable [ <NUM_LIT:0> ] , <EOL> False , False ] <EOL> output = img . type . clone ( broadcastable = broadcastable ) ( ) <EOL> return Apply ( self , [ img , kern ] , [ output ] ) <EOL> def perform ( self , node , inp , out_ ) : <EOL> img , kern = inp <EOL> img = numpy . asarray ( img ) <EOL> kern = numpy . asarray ( kern ) <EOL> o , = out_ <EOL> mode = self . border_mode <EOL> if not ( ( isinstance ( mode , tuple ) and min ( mode ) >= <NUM_LIT:0> ) or <EOL> mode in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) ) : <EOL> raise ValueError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( mode ) ) <EOL> if mode == "<STR_LIT>" : <EOL> mode = ( kern . shape [ <NUM_LIT:2> ] - <NUM_LIT:1> , kern . shape [ <NUM_LIT:3> ] - <NUM_LIT:1> ) <EOL> elif mode == "<STR_LIT>" : <EOL> mode = ( kern . shape [ <NUM_LIT:2> ] // <NUM_LIT:2> , kern . shape [ <NUM_LIT:3> ] // <NUM_LIT:2> ) <EOL> if isinstance ( mode , tuple ) : <EOL> pad_h , pad_w = map ( int , mode ) <EOL> mode = "<STR_LIT>" <EOL> new_img = numpy . zeros ( ( img . shape [ <NUM_LIT:0> ] , img . shape [ <NUM_LIT:1> ] , <EOL> img . shape [ <NUM_LIT:2> ] + <NUM_LIT:2> * pad_h , <EOL> img . shape [ <NUM_LIT:3> ] + <NUM_LIT:2> * pad_w ) , dtype = img . dtype ) <EOL> new_img [ : , : , pad_h : img . shape [ <NUM_LIT:2> ] + pad_h , pad_w : img . shape [ <NUM_LIT:3> ] + pad_w ] = img <EOL> img = new_img <EOL> if not self . filter_flip : <EOL> kern = kern [ : , : , : : - <NUM_LIT:1> , : : - <NUM_LIT:1> ] <EOL> conv_out = self . conv2d ( img , kern , mode = "<STR_LIT>" ) <EOL> conv_out = conv_out [ : , : , : : self . subsample [ <NUM_LIT:0> ] , : : self . subsample [ <NUM_LIT:1> ] ] <EOL> o [ <NUM_LIT:0> ] = node . outputs [ <NUM_LIT:0> ] . type . filter ( conv_out ) <EOL> def R_op ( self , inputs , eval_points ) : <EOL> rval = None <EOL> if eval_points [ <NUM_LIT:0> ] is not None : <EOL> rval = self . make_node ( eval_points [ <NUM_LIT:0> ] , inputs [ <NUM_LIT:1> ] ) . outputs [ <NUM_LIT:0> ] <EOL> if eval_points [ <NUM_LIT:1> ] is not None : <EOL> if rval is None : <EOL> rval = self . make_node ( inputs [ <NUM_LIT:0> ] , eval_points [ <NUM_LIT:1> ] ) . outputs [ <NUM_LIT:0> ] <EOL> else : <EOL> rval += self . make_node ( inputs [ <NUM_LIT:0> ] , eval_points [ <NUM_LIT:1> ] ) . outputs [ <NUM_LIT:0> ] <EOL> return [ rval ] <EOL> def grad ( self , inp , grads ) : <EOL> bottom , weights = inp <EOL> top , = grads <EOL> d_bottom = AbstractConv2d_gradInputs ( self . imshp , self . kshp , <EOL> self . border_mode , <EOL> self . subsample , <EOL> self . filter_flip ) ( <EOL> weights , top , bottom . shape [ - <NUM_LIT:2> : ] ) <EOL> d_weights = AbstractConv2d_gradWeights ( self . imshp , self . kshp , <EOL> self . border_mode , <EOL> self . subsample , <EOL> self . filter_flip ) ( <EOL> bottom , top , weights . shape [ - <NUM_LIT:2> : ] ) <EOL> d_bottom = patternbroadcast ( d_bottom , bottom . broadcastable ) <EOL> d_bottom = bottom . type . filter_variable ( d_bottom ) <EOL> d_weights = patternbroadcast ( d_weights , weights . broadcastable ) <EOL> d_weights = weights . type . filter_variable ( d_weights ) <EOL> return d_bottom , d_weights <EOL> def infer_shape ( self , node , input_shapes ) : <EOL> imshp = input_shapes [ <NUM_LIT:0> ] <EOL> kshp = input_shapes [ <NUM_LIT:1> ] <EOL> if self . imshp is not None : <EOL> imshp = [ imshp [ i ] if self . imshp [ i ] is None else self . imshp [ i ] <EOL> for i in range ( <NUM_LIT:4> ) ] <EOL> if self . kshp is not None : <EOL> kshp = [ kshp [ i ] if self . kshp [ i ] is None else self . kshp [ i ] <EOL> for i in range ( <NUM_LIT:4> ) ] <EOL> res = get_conv_output_shape ( imshp , kshp , self . border_mode , <EOL> self . subsample ) <EOL> return [ res ] <EOL> class AbstractConv2d_gradWeights ( BaseAbstractConv2d ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , <EOL> imshp = None , <EOL> kshp = None , <EOL> border_mode = "<STR_LIT>" , <EOL> subsample = ( <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> filter_flip = True ) : <EOL> super ( AbstractConv2d_gradWeights , self ) . __init__ ( imshp , kshp , <EOL> border_mode , <EOL> subsample , <EOL> filter_flip ) <EOL> def make_node ( self , img , topgrad , shape ) : <EOL> gtype = img . type . clone ( dtype = topgrad . dtype , <EOL> broadcastable = topgrad . broadcastable ) <EOL> topgrad = gtype . filter_variable ( topgrad ) <EOL> if img . type . ndim != <NUM_LIT:4> : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> if topgrad . type . ndim != <NUM_LIT:4> : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> shape = as_tensor_variable ( shape ) <EOL> broadcastable = [ topgrad . broadcastable [ <NUM_LIT:1> ] , <EOL> img . broadcastable [ <NUM_LIT:1> ] , <EOL> False , False ] <EOL> output = img . type . clone ( broadcastable = broadcastable ) ( ) <EOL> return Apply ( self , [ img , topgrad , shape ] , [ output ] ) <EOL> def perform ( self , node , inp , out_ ) : <EOL> img , topgrad , shape = inp <EOL> img = numpy . asarray ( img ) <EOL> topgrad = numpy . asarray ( topgrad ) <EOL> o , = out_ <EOL> mode = self . border_mode <EOL> if not ( ( isinstance ( mode , tuple ) and min ( mode ) >= <NUM_LIT:0> ) or <EOL> mode in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) ) : <EOL> raise ValueError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( mode ) ) <EOL> if mode == "<STR_LIT>" : <EOL> mode = ( shape [ <NUM_LIT:0> ] - <NUM_LIT:1> , shape [ <NUM_LIT:1> ] - <NUM_LIT:1> ) <EOL> elif mode == "<STR_LIT>" : <EOL> mode = ( shape [ <NUM_LIT:0> ] // <NUM_LIT:2> , shape [ <NUM_LIT:1> ] // <NUM_LIT:2> ) <EOL> if isinstance ( mode , tuple ) : <EOL> pad_h , pad_w = map ( int , mode ) <EOL> mode = "<STR_LIT>" <EOL> new_img = numpy . zeros ( ( img . shape [ <NUM_LIT:0> ] , img . shape [ <NUM_LIT:1> ] , <EOL> img . shape [ <NUM_LIT:2> ] + <NUM_LIT:2> * pad_h , <EOL> img . shape [ <NUM_LIT:3> ] + <NUM_LIT:2> * pad_w ) , dtype = img . dtype ) <EOL> new_img [ : , : , pad_h : img . shape [ <NUM_LIT:2> ] + pad_h , pad_w : img . shape [ <NUM_LIT:3> ] + pad_w ] = img <EOL> img = new_img <EOL> if self . subsample [ <NUM_LIT:0> ] > <NUM_LIT:1> or self . subsample [ <NUM_LIT:1> ] > <NUM_LIT:1> : <EOL> new_shape = ( topgrad . shape [ <NUM_LIT:0> ] , topgrad . shape [ <NUM_LIT:1> ] , <EOL> img . shape [ <NUM_LIT:2> ] - shape [ <NUM_LIT:0> ] + <NUM_LIT:1> , <EOL> img . shape [ <NUM_LIT:3> ] - shape [ <NUM_LIT:1> ] + <NUM_LIT:1> ) <EOL> new_topgrad = numpy . zeros ( ( new_shape ) , dtype = topgrad . dtype ) <EOL> new_topgrad [ : , : , : : self . subsample [ <NUM_LIT:0> ] , : : self . subsample [ <NUM_LIT:1> ] ] = topgrad <EOL> topgrad = new_topgrad <EOL> topgrad = topgrad . transpose ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:2> , <NUM_LIT:3> ) [ : , : , : : - <NUM_LIT:1> , : : - <NUM_LIT:1> ] <EOL> img = img . transpose ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:2> , <NUM_LIT:3> ) <EOL> kern = self . conv2d ( img , topgrad , mode = "<STR_LIT>" ) <EOL> if self . filter_flip : <EOL> kern = kern . transpose ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:2> , <NUM_LIT:3> ) [ : , : , : : - <NUM_LIT:1> , : : - <NUM_LIT:1> ] <EOL> else : <EOL> kern = kern . transpose ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:2> , <NUM_LIT:3> ) <EOL> o [ <NUM_LIT:0> ] = node . outputs [ <NUM_LIT:0> ] . type . filter ( kern ) <EOL> def grad ( self , inp , grads ) : <EOL> bottom , top = inp [ : <NUM_LIT:2> ] <EOL> weights , = grads <EOL> d_bottom = AbstractConv2d_gradInputs ( self . imshp , self . kshp , <EOL> self . border_mode , <EOL> self . subsample , <EOL> self . filter_flip ) ( <EOL> weights , <EOL> top , <EOL> bottom . shape [ - <NUM_LIT:2> : ] ) <EOL> d_top = AbstractConv2d ( self . imshp , <EOL> self . kshp , <EOL> self . border_mode , <EOL> self . subsample , <EOL> self . filter_flip ) ( bottom , weights ) <EOL> d_bottom = patternbroadcast ( d_bottom , bottom . broadcastable ) <EOL> d_bottom = bottom . type . filter_variable ( d_bottom ) <EOL> d_top = patternbroadcast ( d_top , top . broadcastable ) <EOL> d_top = top . type . filter_variable ( d_top ) <EOL> d_height_width = ( theano . gradient . DisconnectedType ( ) ( ) , ) <EOL> return ( d_bottom , d_top ) + d_height_width <EOL> def connection_pattern ( self , node ) : <EOL> return [ [ <NUM_LIT:1> ] , [ <NUM_LIT:1> ] , [ <NUM_LIT:0> ] ] <EOL> def infer_shape ( self , node , input_shapes ) : <EOL> imshp = input_shapes [ <NUM_LIT:0> ] <EOL> topshp = input_shapes [ <NUM_LIT:1> ] <EOL> kshp = self . kshp [ : ] if self . kshp is not None else [ None ] * <NUM_LIT:4> <EOL> fallback_kshp = [ topshp [ <NUM_LIT:1> ] , imshp [ <NUM_LIT:1> ] , node . inputs [ <NUM_LIT:2> ] [ <NUM_LIT:0> ] , node . inputs [ <NUM_LIT:2> ] [ <NUM_LIT:1> ] ] <EOL> kshp = [ fallback_kshp [ i ] if kshp [ i ] is None else kshp [ i ] <EOL> for i in range ( <NUM_LIT:4> ) ] <EOL> return [ kshp ] <EOL> class AbstractConv2d_gradInputs ( BaseAbstractConv2d ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , <EOL> imshp = None , <EOL> kshp = None , <EOL> border_mode = "<STR_LIT>" , <EOL> subsample = ( <NUM_LIT:1> , <NUM_LIT:1> ) , <EOL> filter_flip = True ) : <EOL> super ( AbstractConv2d_gradInputs , self ) . __init__ ( imshp , kshp , <EOL> border_mode , <EOL> subsample , <EOL> filter_flip ) <EOL> def make_node ( self , kern , topgrad , shape ) : <EOL> gtype = kern . type . clone ( dtype = topgrad . dtype , <EOL> broadcastable = topgrad . broadcastable ) <EOL> topgrad = gtype . filter_variable ( topgrad ) <EOL> if kern . type . ndim != <NUM_LIT:4> : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> if topgrad . type . ndim != <NUM_LIT:4> : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> shape = as_tensor_variable ( shape ) <EOL> broadcastable = [ topgrad . type . broadcastable [ <NUM_LIT:0> ] , <EOL> kern . type . broadcastable [ <NUM_LIT:1> ] , <EOL> False , False ] <EOL> output = kern . type . clone ( broadcastable = broadcastable ) ( ) <EOL> return Apply ( self , [ kern , topgrad , shape ] , [ output ] ) <EOL> def perform ( self , node , inp , out_ ) : <EOL> kern , topgrad , shape = inp <EOL> kern = numpy . asarray ( kern ) <EOL> topgrad = numpy . asarray ( topgrad ) <EOL> o , = out_ <EOL> mode = self . border_mode <EOL> if not ( ( isinstance ( mode , tuple ) and min ( mode ) >= <NUM_LIT:0> ) or <EOL> mode in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) ) : <EOL> raise ValueError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( mode ) ) <EOL> pad_h , pad_w = <NUM_LIT:0> , <NUM_LIT:0> <EOL> if mode == "<STR_LIT>" : <EOL> pad_h , pad_w = ( kern . shape [ <NUM_LIT:2> ] - <NUM_LIT:1> , kern . shape [ <NUM_LIT:3> ] - <NUM_LIT:1> ) <EOL> elif mode == "<STR_LIT>" : <EOL> pad_h , pad_w = ( kern . shape [ <NUM_LIT:2> ] // <NUM_LIT:2> , kern . shape [ <NUM_LIT:3> ] // <NUM_LIT:2> ) <EOL> elif isinstance ( mode , tuple ) : <EOL> pad_h , pad_w = map ( int , self . border_mode ) <EOL> if self . subsample [ <NUM_LIT:0> ] > <NUM_LIT:1> or self . subsample [ <NUM_LIT:1> ] > <NUM_LIT:1> : <EOL> new_shape = ( topgrad . shape [ <NUM_LIT:0> ] , topgrad . shape [ <NUM_LIT:1> ] , <EOL> shape [ <NUM_LIT:0> ] + <NUM_LIT:2> * pad_h - kern . shape [ <NUM_LIT:2> ] + <NUM_LIT:1> , <EOL> shape [ <NUM_LIT:1> ] + <NUM_LIT:2> * pad_w - kern . shape [ <NUM_LIT:3> ] + <NUM_LIT:1> ) <EOL> new_topgrad = numpy . zeros ( ( new_shape ) , dtype = topgrad . dtype ) <EOL> new_topgrad [ : , : , : : self . subsample [ <NUM_LIT:0> ] , : : self . subsample [ <NUM_LIT:1> ] ] = topgrad <EOL> topgrad = new_topgrad <EOL> kern = kern . transpose ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:2> , <NUM_LIT:3> ) <EOL> if self . filter_flip : <EOL> topgrad = topgrad [ : , : , : : - <NUM_LIT:1> , : : - <NUM_LIT:1> ] <EOL> img = self . conv2d ( topgrad , kern , mode = "<STR_LIT>" ) <EOL> if self . filter_flip : <EOL> img = img [ : , : , : : - <NUM_LIT:1> , : : - <NUM_LIT:1> ] <EOL> if pad_h > <NUM_LIT:0> or pad_w > <NUM_LIT:0> : <EOL> img = img [ : , : , pad_h : img . shape [ <NUM_LIT:2> ] - pad_h , pad_w : img . shape [ <NUM_LIT:3> ] - pad_w ] <EOL> o [ <NUM_LIT:0> ] = node . outputs [ <NUM_LIT:0> ] . type . filter ( img ) <EOL> def grad ( self , inp , grads ) : <EOL> weights , top = inp [ : <NUM_LIT:2> ] <EOL> bottom , = grads <EOL> d_weights = AbstractConv2d_gradWeights ( self . imshp , self . kshp , <EOL> self . border_mode , <EOL> self . subsample ) ( <EOL> bottom , top , <EOL> weights . shape [ - <NUM_LIT:2> : ] ) <EOL> d_top = AbstractConv2d ( self . imshp , self . kshp , <EOL> self . border_mode , self . subsample ) ( <EOL> bottom , weights ) <EOL> d_weights = patternbroadcast ( d_weights , weights . broadcastable ) <EOL> d_weights = weights . type . filter_variable ( d_weights ) <EOL> d_top = patternbroadcast ( d_top , top . broadcastable ) <EOL> d_top = top . type . filter_variable ( d_top ) <EOL> d_height_width = ( theano . gradient . DisconnectedType ( ) ( ) , ) <EOL> return ( d_weights , d_top ) + d_height_width <EOL> def connection_pattern ( self , node ) : <EOL> return [ [ <NUM_LIT:1> ] , [ <NUM_LIT:1> ] , [ <NUM_LIT:0> ] ] <EOL> def infer_shape ( self , node , input_shapes ) : <EOL> kshp = input_shapes [ <NUM_LIT:0> ] <EOL> topshp = input_shapes [ <NUM_LIT:1> ] <EOL> imshp = self . imshp [ : ] if self . imshp is not None else [ None ] * <NUM_LIT:4> <EOL> fallback_imshp = [ topshp [ <NUM_LIT:0> ] , kshp [ <NUM_LIT:1> ] , node . inputs [ <NUM_LIT:2> ] [ <NUM_LIT:0> ] , <EOL> node . inputs [ <NUM_LIT:2> ] [ <NUM_LIT:1> ] ] <EOL> imshp = [ fallback_imshp [ i ] if imshp [ i ] is None else imshp [ i ] <EOL> for i in range ( <NUM_LIT:4> ) ] <EOL> return [ imshp ] </s>
