#NEWLINE# def get_output_for( self , input , get_details = False , **kwargs ) : #NEWLINE# #INDENT# input = input . dimshuffle ( 1 , 0 , 2 ) #NEWLINE# num_write_heads = len ( self . write_heads ) #NEWLINE# num_read_heads = len ( self . read_heads ) #NEWLINE# def step( x_t , M_tm1 , h_tm1 , state_tm1 , * params ) : #NEWLINE# #INDENT# M_t = M_tm1 #NEWLINE# for i in range ( num_write_heads ) : #NEWLINE# #INDENT# erase = self . write_heads [ i ] . erase . get_output_for ( h_tm1 , ** kwargs ) #NEWLINE# ( erasing , _ ) = theano . map ( T . outer , sequences = [ params [ i ] , erase ] ) #NEWLINE# M_t *= ( 1.0 - erasing ) #NEWLINE# #UNINDENT# for i in range ( num_write_heads ) : #NEWLINE# #INDENT# if ( self . write_heads [ i ] . sign_add is not None ) : #NEWLINE# #INDENT# sign = self . write_heads [ i ] . sign_add . get_output_for ( h_tm1 , ** kwargs ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# sign = 1.0 #NEWLINE# #UNINDENT# add = self . write_heads [ i ] . add . get_output_for ( h_tm1 , ** kwargs ) #NEWLINE# ( adding , _ ) = theano . map ( T . outer , sequences = [ params [ i ] , ( sign * add ) ] ) #NEWLINE# M_t += adding #NEWLINE# #UNINDENT# read_vectors = [ ] #NEWLINE# for i in range ( num_write_heads , ( num_write_heads + num_read_heads ) ) : #NEWLINE# #INDENT# ( reading , _ ) = theano . map ( T . dot , sequences = [ params [ i ] , M_t ] ) #NEWLINE# read_vectors . append ( reading ) #NEWLINE# #UNINDENT# r_t = T . stack ( read_vectors , axis = 1 ) #NEWLINE# ( h_t , state_t ) = self . controller . step ( x_t , r_t , h_tm1 , state_tm1 ) #NEWLINE# ( write_weights_t , read_weights_t ) = ( [ ] , [ ] ) #NEWLINE# for i in range ( num_write_heads ) : #NEWLINE# #INDENT# weights = self . write_heads [ i ] . get_output_for ( h_t , params [ i ] , M_t , ** kwargs ) #NEWLINE# write_weights_t . append ( weights ) #NEWLINE# #UNINDENT# for i in range ( num_read_heads ) : #NEWLINE# #INDENT# weights = self . read_heads [ i ] . get_output_for ( h_t , params [ ( num_write_heads + i ) ] , M_t , ** kwargs ) #NEWLINE# read_weights_t . append ( weights ) #NEWLINE# #UNINDENT# return ( ( [ M_t , h_t , state_t ] + write_weights_t ) + read_weights_t ) #NEWLINE# #UNINDENT# memory_init = T . tile ( self . memory . memory_init , ( self . input_shape [ 0 ] , 1 , 1 ) ) #NEWLINE# memory_init = T . unbroadcast ( memory_init , 0 ) #NEWLINE# ones_vector = T . ones ( ( self . input_shape [ 0 ] , 1 ) ) #NEWLINE# write_weights_init = [ T . unbroadcast ( T . dot ( ones_vector , head . weights_init ) , 0 ) for head in self . write_heads ] #NEWLINE# read_weights_init = [ T . unbroadcast ( T . dot ( ones_vector , head . weights_init ) , 0 ) for head in self . read_heads ] #NEWLINE# non_seqs = ( self . controller . get_params ( ) + self . memory . get_params ( ) ) #NEWLINE# for head in self . heads : #NEWLINE# #INDENT# non_seqs += head . get_params ( ) #NEWLINE# #UNINDENT# ( hids , _ ) = theano . scan ( fn = step , sequences = input , outputs_info = ( ( ( [ memory_init ] + self . controller . outputs_info ) + write_weights_init ) + read_weights_init ) , non_sequences = non_seqs , strict = True ) #NEWLINE# if get_details : #NEWLINE# #INDENT# hid_out = [ hids [ 0 ] . dimshuffle ( 1 , 0 , 2 , 3 ) ] #NEWLINE# hid_out += [ hid . dimshuffle ( 1 , 0 , 2 ) for hid in hids [ 1 : ] ] #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if self . only_return_final : #NEWLINE# #INDENT# hid_out = hids [ 1 ] [ ( - 1 ) ] #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# hid_out = hids [ 1 ] . dimshuffle ( 1 , 0 , 2 ) #NEWLINE# #UNINDENT# #UNINDENT# return hid_out