4 votes

Comment créer un nombre variable de couches dans un MLP ?

Récemment, j'ai travaillé avec Tensorflow. J'ai exploré comment implémenter un Perceptron multicouche dans Tensorflow.

Je suis tombé sur de nombreux tutoriels en ligne. La plupart d'entre eux utilisent une ou deux couches cachées. Un exemple simple est tiré de aquí

def forwardprop(X, w_1, w_2):
    """
    Forward-propagation.
    IMPORTANT: yhat is not softmax since TensorFlow's 
    softmax_cross_entropy_with_logits() does that internally.
    """
    h    = tf.nn.sigmoid(tf.matmul(X, w_1))  # The \sigma function
    yhat = tf.matmul(h, w_2)  # The \varphi function
    return yhat

X = tf.placeholder("float", shape=[None, x_size])
y = tf.placeholder("float", shape=[None, y_size])

# Weight initializations
w_1 = init_weights((x_size, h_size))
w_2 = init_weights((h_size, y_size))

# Forward propagation
out    = forwardprop(X, w_1, w_2)

Dans ce code, il y a une couche cachée. Je me demande maintenant si je veux construire un réseau neuronal entièrement connecté à nombre variable de couches.

Supposons une liste h_archi=[100 150 100 50] où chacune des valeurs représente un nombre de neurones dans la couche i (dans ce cas, le nombre total de couches est de 4). Donc pour l'implémentation du nombre variable de couches, j'ai codé le vilain code suivant,

    emb_vec = tf.Variable(tf.random_normal([vocabulary_size, EMBEDDING_DIM]), name="emb_vec")

    tot_layer = len(h_archi)
    op = np.zeros(tot_layer+1)
    hid_rep = np.zeros(tot_layer+1)
    bias = np.zeros(tot_layer+1)

    op[0] = tf.matmul(x, emb_vec)

    for idx,tot_neu in enumerate(h_archi):
        assert( tot_neu > 0 )
        layer_no = idx+1
        r,c = op[layer_no-1].get_shape()
        hid_rep[layer_no] = tf.Variable(tf.random_normal([c,tot_neu]),name="hid_{0}_{1}".format(layer_no-1,layer_no))
        bias[layer_no] = tf.Variable(tf.random_normal([tot_neu]), name="bias_{0}".format(layer_no))
        op[layer_no] = tf.add(tf.matmul(op[layer_no-1],hid_rep[layer_no]),bias[layer_no])

    r,c = op[tot_layer].get_shape()
    last_layer = tf.Variable(tf.random_normal([c,output_size]),name="hid_{0}_{1}".format(tot_layer,"last_layer"))
    bias_last = tf.Variable(tf.random_normal([output_size]), name="bias_last")
    output = tf.add(tf.matmul(op[tot_layer],last_layer))
    prediction = tf.nn.softmax(output) 

Ce code est complètement faux car tensorflow ne supporte pas les opérations d'affectation. Alors, quelle pourrait être la bonne façon de concevoir une telle chose.

2voto

gdelab Points 3673

Vous pourriez faire quelque chose comme ça à la place de votre boucle :

    last_layer=x
    for idx,tot_neu in enumerate(h_archi):
        assert( tot_neu > 0 )
        layer_no = idx+1
        r,c = last_layer.get_shape()
        weights_ = tf.Variable(tf.random_normal([c,tot_neu]),name="hid_{0}_{1}".format(layer_no-1,layer_no))
        bias_ = tf.Variable(tf.random_normal([tot_neu]), name="bias_{0}".format(layer_no))
        last_layer = tf.add(tf.matmul(last_layer,weights_),bias_)
    r,c = last_layer.get_shape()

Si vous avez besoin d'accéder aux tenseurs intermédiaires (biais, poids, couches, etc), vous pouvez simplement les stocker à chaque étape dans une liste, par exemple

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X