2017-07-01 2 views
1

D'abord, je suis très nouveau pour Keras et Theano. J'implémente un CNN qui utilise la normalisation de réponse locale (LRN). Pour autant que je sache, il n'y a pas une telle couche implémentée dans la fonctionnalité de base de keras et theano. J'ai donc essayé d'utiliser une couche keras lambda pour implémenter LRN.Keras Lambda Layer & Theano Code: Accès aux dimensions et valeurs de TensorVariable

« def local_response_normalization (x): paramètres de #LRN k = 2 n = 5 alpha = 0,0001 bêta = 0,75

result = x.eval() 
x_tmp = x.eval() 


#building functions for the theano computation graph 
scalar_op = T.dscalar('scalar_op') 
matrix1_op = T.dmatrix('matrix1_op') 
matrix2_op = T.dmatrix('matrix2_op') 
mul_result = scalar_op * matrix1_op 
add_result = scalar_op + matrix1_op 
pow_result = matrix1_op ** scalar_op 
div_result = matrix1_op/matrix2_op 

sc_mat_mul_f = function([scalar_op, matrix1_op], mul_result) 
sc_mat_add_f = function([scalar_op, matrix1_op], add_result) 
sc_mat_pow_f = function([scalar_op, matrix1_op], pow_result) 
mat_div_f = function([matrix1_op, matrix2_op], div_result) 

#x is supposed to be a 3-dimensional tensor (a x b x c) 
a_dim = x_tmp.shape[0] 
b_dim = x_tmp.shape[1] 
c_dim = x_tmp.shape[2] 

#iterating through channels 
for i in range(0, a_dim): 
    j_l = max(0, i-(n/2))# j_l(ower_bound) 
    j_u = min(N-1, i+(n/2))# j_u(pper_bound) 

    x_tmp = x.eval() 
    #retrieving set of local 'neurons' 
    x_tmp = x_tmp[j_l:j_u+1,:,:] 
    #building squared sum 
    x_tmp = T.sqr(x_tmp)#TensorVariable 
    x_tmp = T.sum(x_tmp, axis=0)#axis no. 0 = 'channel' axis 
    #x_tmp is now 2-dimensional 
    x_tmp = sc_mat_mul_f(alpha, x_tmp.eval()) 
    x_tmp = sc_mat_add_f(k, x_tmp) 
    x_tmp = sc_mat_pow_f(beta, x_tmp) 
    x_tmp = mat_div_f(result[i], x_tmp) 
    #exchanging channel i with x_tmp (= LRN) 
    result[i] = x_tmp 

return result` 

J'intégration de cette couche dans le modèle en utilisant model.add(local_response_normalization, ...) Lorsque vous essayez de compiler et adapter le modèle que je reçois:

theano.gof.fg.MissingInputError: Input 0 of the graph (indices start from 0), used to compute AbstractConv2d{convdim=2, border_mode='half', subsample=(4, 4), filter_flip=True, imshp=(None, 3, 220, 220), kshp=(96, 3, 11, 11), filter_dilation=(1, 1)}(/conv2d_1_input, InplaceDimShuffle{3,2,0,1}.0), was not provided and not given a value. Use the Theano flag exception_verbosity='high', for more information on this error.

Le problème principal semble être que eval() ne peut pas être appelé lors de la compilation d'un modèle. Je ne peux pas trouver un autre moyen d'accéder et d'opérer sur les éléments de x (étant un tenseur de sortie d'une couche conv2d) autre que de le convertir en un tableau numpy en utilisant eval(), mais cela ne marche pas. Il me semble qu'il me manque un concept principal derrière Lambda Layers et TensorVariables en général.
J'ai passé les deux derniers jours à gérer ce problème et je suis vraiment coincé.

Répondre

0

J'ai trouvé un moyen de faire tous les calculs pour LRN sans évaluer TensorVariables. Ce qui était plutôt évident.