#NEWLINE# @ opt . register_specialize ( 'fast_compile_gpu' ) #NEWLINE# @ gof . local_optimizer ( [ softmax_grad ] ) #NEWLINE# def local_advanced_indexing_crossentropy_onehot_grad( node ) : #NEWLINE# #INDENT# if ( not ( node . op == softmax_grad ) ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# sm = None #NEWLINE# try : #NEWLINE# #INDENT# ( d_sm , sm ) = node . inputs #NEWLINE# #UNINDENT# except Exception : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# if ( ( sm is not None ) and sm . owner and ( sm . owner . op in ( softmax_op , softmax_with_bias ) ) ) : #NEWLINE# #INDENT# sm_w_bias = local_softmax_with_bias . transform ( sm . owner ) #NEWLINE# if sm_w_bias : #NEWLINE# #INDENT# assert ( sm_w_bias [ 0 ] . owner . op == softmax_with_bias ) #NEWLINE# ( x_var , b_var ) = sm_w_bias [ 0 ] . owner . inputs #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# x_var = sm . owner . inputs [ 0 ] #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# vector_softmax = False #NEWLINE# if ( d_sm . owner and isinstance ( d_sm . owner . op , tensor . DimShuffle ) ) : #NEWLINE# #INDENT# ds_op = d_sm . owner . op #NEWLINE# if ( ( ds_op . input_broadcastable == ( False , ) ) and ( ds_op . new_order == ( 'x' , 0 ) ) ) : #NEWLINE# #INDENT# maybe_sum = d_sm . owner . inputs [ 0 ] #NEWLINE# if ( maybe_sum . owner and isinstance ( maybe_sum . owner . op , tensor . Sum ) ) : #NEWLINE# #INDENT# if ( ( sm . broadcastable == ( True , False ) ) and ( maybe_sum . owner . op . axis == ( 0 , ) ) and ( len ( maybe_sum . owner . inputs ) == 1 ) ) : #NEWLINE# #INDENT# vector_softmax = True #NEWLINE# d_sm = maybe_sum . owner . inputs [ 0 ] #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# if ( d_sm . owner and isinstance ( d_sm . owner . op , subtensor . AdvancedIncSubtensor ) ) : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# ( z , incr , rows , labels ) = d_sm . owner . inputs #NEWLINE# #UNINDENT# except Exception : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# if ( not _is_const ( z , 0 ) ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# adv_subtensor = None #NEWLINE# out_grad = 1.0 #NEWLINE# if ( incr . owner and ( incr . owner . op == tensor . neg ) ) : #NEWLINE# #INDENT# out_grad = ( - out_grad ) #NEWLINE# incr = incr . owner . inputs [ 0 ] #NEWLINE# #UNINDENT# if ( incr . owner and ( incr . owner . op == tensor . true_div ) ) : #NEWLINE# #INDENT# ( num , denom ) = incr . owner . inputs #NEWLINE# if ( ( num . ndim == 1 ) or numpy . all ( num . broadcastable ) ) : #NEWLINE# #INDENT# out_grad *= ( - num ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# if ( not denom . owner ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# if isinstance ( denom . owner . op , subtensor . AdvancedSubtensor ) : #NEWLINE# #INDENT# adv_subtensor = denom #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( denom . owner . op == tensor . mul ) : #NEWLINE# #INDENT# for ( i , input ) in enumerate ( denom . owner . inputs ) : #NEWLINE# #INDENT# if ( input . owner and isinstance ( input . owner . op , subtensor . AdvancedSubtensor ) ) : #NEWLINE# #INDENT# other_inputs = [ in_ for ( j , in_ ) in enumerate ( denom . owner . inputs ) if ( j != i ) ] #NEWLINE# if ( len ( other_inputs ) == 1 ) : #NEWLINE# #INDENT# rest = other_inputs [ 0 ] #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# rest = tensor . mul ( * [ other_inputs ] ) #NEWLINE# #UNINDENT# if ( ( rest . ndim == 1 ) or numpy . all ( rest . broadcastable ) ) : #NEWLINE# #INDENT# adv_subtensor = input #NEWLINE# out_grad /= rest #NEWLINE# break #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# #UNINDENT# out_grad = tensor . fill ( x_var [ : , 0 ] , out_grad ) #NEWLINE# if ( adv_subtensor is not None ) : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# ( maybe_sm , maybe_rows , maybe_labels ) = adv_subtensor . owner . inputs #NEWLINE# #UNINDENT# except Exception : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# if ( not ( ( maybe_sm is sm ) and ( maybe_rows is rows ) and ( maybe_labels is labels ) ) ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# if ( not _check_rows_is_arange_len_labels ( rows , labels ) ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( d_sm . owner and ( d_sm . owner . op == tensor . true_div ) ) : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# ( num , denom ) = d_sm . owner . inputs #NEWLINE# #UNINDENT# except Exception : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# if ( denom != sm ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# if ( num . owner and isinstance ( num . owner . op , subtensor . AdvancedIncSubtensor ) ) : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# ( z , incr , rows , labels ) = num . owner . inputs #NEWLINE# #UNINDENT# except Exception : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# if ( not _is_const ( z , 0 ) ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# if ( z . broadcastable != ( False , False ) ) : #NEWLINE# #INDENT# if ( not ( vector_softmax and ( z . broadcastable == ( True , False ) ) ) ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# #UNINDENT# if ( ( incr . ndim != 1 ) or ( incr . dtype not in tensor . float_dtypes ) ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# out_grad = ( - incr ) #NEWLINE# if ( not _check_rows_is_arange_len_labels ( rows , labels ) ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# #UNINDENT# if ( ( labels . ndim == 1 ) and ( x_var . ndim == 2 ) ) : #NEWLINE# #INDENT# ret = crossentropy_softmax_1hot_with_bias_dx ( out_grad , sm , labels ) #NEWLINE# copy_stack_trace ( node . outputs [ 0 ] , ret ) #NEWLINE# return [ ret ] #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return