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é.