python plot - Comment ajouter des régularisations dans TensorFlow?




title matplotlib (6)

Certaines réponses me rendent plus confus. Ici, je donne deux méthodes pour le rendre clair.

#1.adding all regs by hand
var1 = tf.get_variable(name='v1',shape=[1],dtype=tf.float32)
var2 = tf.Variable(name='v2',initial_value=1.0,dtype=tf.float32)
regularizer = tf.contrib.layers.l1_regularizer(0.1)
reg_term = tf.contrib.layers.apply_regularization(regularizer,[var1,var2])
#here reg_term is a scalar

#2.auto added and read,but using get_variable
with tf.variable_scope('x',
        regularizer=tf.contrib.layers.l2_regularizer(0.1)):
    var1 = tf.get_variable(name='v1',shape=[1],dtype=tf.float32)
    var2 = tf.get_variable(name='v2',shape=[1],dtype=tf.float32)
reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
#here reg_losses is a list,should be summed 

Ensuite, il peut être ajouté dans la perte totale

J'ai trouvé dans beaucoup de code de réseau neuronal disponible implémenté en utilisant TensorFlow que les termes de régularisation sont souvent implémentés en ajoutant manuellement un terme supplémentaire à la valeur de perte.

Mes questions sont:

  1. Existe-t-il un moyen de régularisation plus élégant ou recommandé que de le faire manuellement?

  2. Je trouve aussi que get_variable a un argument regularizer . Comment devrait-il être utilisé? Selon mon observation, si nous lui passons un regularizer (comme tf.contrib.layers.l2_regularizer , un tenseur représentant un terme régularisé sera calculé et ajouté à une collection de graphes nommée tf.GraphKeys.REGULARIZATOIN_LOSSES . par TensorFlow (par exemple utilisé par les optimiseurs lors de la formation) Ou est-il prévu que je devrais utiliser cette collection par moi-même?


Je vais fournir une réponse simple et correcte puisque je n'en ai pas trouvé. Vous avez besoin de deux étapes simples, le reste est fait par la magie tensorflow:

  1. Ajoutez des régularisateurs lors de la création de variables ou de calques:

    tf.layers.dense(x, kernel_regularizer=tf.contrib.layers.l2_regularizer(0.001))
    # or
    tf.get_variable('a', regularizer=tf.contrib.layers.l2_regularizer(0.001))
    
  2. Ajoutez le terme de régularisation lors de la définition de la perte:

    loss = ordinary_loss + tf.losses.get_regularization_loss()
    

Quelques aspects de la réponse existante n'étaient pas immédiatement clairs pour moi, alors voici un guide pas-à-pas:

  1. Définir un régularisateur. C'est ici que la constante de régularisation peut être définie, par exemple:

    regularizer = tf.contrib.layers.l2_regularizer(scale=0.1)
    
  2. Créer des variables via:

        weights = tf.get_variable(
            name="weights",
            regularizer=regularizer,
            ...
        )
    

    De manière équivalente, les variables peuvent être créées via le constructeur normal weights = tf.Variable(...) , suivi de tf.add_to_collection(tf.GraphKeys.REGULARIZATION_LOSSES, weights) .

  3. Définir un terme de loss et ajouter le terme de régularisation:

    reg_variables = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
    reg_term = tf.contrib.layers.apply_regularization(regularizer, reg_variables)
    loss += reg_term
    

    Note: Il semble que tf.contrib.layers.apply_regularization soit implémenté comme AddN , donc plus ou moins équivalent à sum(reg_variables) .


Comme vous le dites dans le deuxième point, l'utilisation de l'argument regularizer est recommandée. Vous pouvez l'utiliser dans get_variable , ou le définir une fois dans votre variable_scope et avoir toutes vos variables régularisées.

Les pertes sont collectées dans le graphique et vous devez les ajouter manuellement à votre fonction de coût comme ceci.

  reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
  reg_constant = 0.01  # Choose an appropriate one.
  loss = my_normal_loss + reg_constant * sum(reg_losses)

J'espère que cela pourra aider!


Une autre option pour ce faire avec la bibliothèque contrib.learn est la suivante, basée sur le tutoriel Deep MNIST sur le site Tensorflow. Tout d'abord, en supposant que vous avez importé les bibliothèques appropriées (telles que l' import tensorflow.contrib.layers as layers ), vous pouvez définir un réseau dans une méthode séparée:

def easier_network(x, reg):
    """ A network based on tf.contrib.learn, with input `x`. """
    with tf.variable_scope('EasyNet'):
        out = layers.flatten(x)
        out = layers.fully_connected(out, 
                num_outputs=200,
                weights_initializer = layers.xavier_initializer(uniform=True),
                weights_regularizer = layers.l2_regularizer(scale=reg),
                activation_fn = tf.nn.tanh)
        out = layers.fully_connected(out, 
                num_outputs=200,
                weights_initializer = layers.xavier_initializer(uniform=True),
                weights_regularizer = layers.l2_regularizer(scale=reg),
                activation_fn = tf.nn.tanh)
        out = layers.fully_connected(out, 
                num_outputs=10, # Because there are ten digits!
                weights_initializer = layers.xavier_initializer(uniform=True),
                weights_regularizer = layers.l2_regularizer(scale=reg),
                activation_fn = None)
        return out 

Ensuite, dans une méthode principale, vous pouvez utiliser l'extrait de code suivant:

def main(_):
    mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
    x = tf.placeholder(tf.float32, [None, 784])
    y_ = tf.placeholder(tf.float32, [None, 10])

    # Make a network with regularization
    y_conv = easier_network(x, FLAGS.regu)
    weights = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'EasyNet') 
    print("")
    for w in weights:
        shp = w.get_shape().as_list()
        print("- {} shape:{} size:{}".format(w.name, shp, np.prod(shp)))
    print("")
    reg_ws = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES, 'EasyNet')
    for w in reg_ws:
        shp = w.get_shape().as_list()
        print("- {} shape:{} size:{}".format(w.name, shp, np.prod(shp)))
    print("")

    # Make the loss function `loss_fn` with regularization.
    cross_entropy = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))
    loss_fn = cross_entropy + tf.reduce_sum(reg_ws)
    train_step = tf.train.AdamOptimizer(1e-4).minimize(loss_fn)

Pour que cela fonctionne, vous devez suivre le tutoriel MNIST auquel je me suis connecté plus tôt et importer les bibliothèques appropriées, mais c'est un bon exercice pour apprendre TensorFlow et il est facile de voir comment la régularisation affecte la sortie. Si vous appliquez une régularisation en tant qu'argument, vous pouvez voir ce qui suit:

- EasyNet/fully_connected/weights:0 shape:[784, 200] size:156800
- EasyNet/fully_connected/biases:0 shape:[200] size:200
- EasyNet/fully_connected_1/weights:0 shape:[200, 200] size:40000
- EasyNet/fully_connected_1/biases:0 shape:[200] size:200
- EasyNet/fully_connected_2/weights:0 shape:[200, 10] size:2000
- EasyNet/fully_connected_2/biases:0 shape:[10] size:10

- EasyNet/fully_connected/kernel/Regularizer/l2_regularizer:0 shape:[] size:1.0
- EasyNet/fully_connected_1/kernel/Regularizer/l2_regularizer:0 shape:[] size:1.0
- EasyNet/fully_connected_2/kernel/Regularizer/l2_regularizer:0 shape:[] size:1.0

Notez que la partie régularisation vous donne trois éléments, en fonction des éléments disponibles.

Avec des régularisations de 0, 0,0001, 0,01 et 1,0, j'obtiens des valeurs de précision de test de 0,9468, 0,9476, 0,9183 et 0,1113, respectivement, montrant les dangers de termes de régularisation élevés.


import os
import os.path


def get_files(target_dir):
    item_list = os.listdir(target_dir)

    file_list = list()
    for item in item_list:
        item_dir = os.path.join(target_dir,item)
        if os.path.isdir(item_dir):
            file_list += get_files(item_dir)
        else:
            file_list.append(item_dir)
    return file_list

Ici, j'utilise une structure récursive.





python neural-network tensorflow deep-learning