38

Sto giocando con una ANN che fa parte del corso Udacity DeepLearning.TensorFlow - regolarizzazione con perdita L2, come applicare a tutti i pesi, non solo all'ultimo?

Ho un incarico che comporta l'introduzione della generalizzazione alla rete con uno strato ReLU nascosto utilizzando la perdita L2. Mi chiedo come introdurlo correttamente in modo che TUTTI i pesi siano penalizzati, non solo i pesi del livello di output.

Codice per rete senza la generalizzazione è nella parte inferiore del post (il codice per eseguire effettivamente la formazione è fuori dallo scopo della domanda).

modo ovvio per introdurre la L2 è di sostituire il calcolo della perdita con qualcosa di simile (se beta è 0,01):

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(out_layer, tf_train_labels) + 0.01*tf.nn.l2_loss(out_weights)) 

Ma in tal caso prenderà in considerazione i valori dei pesi del livello di uscita. Non sono sicuro, come possiamo penalizzare correttamente i pesi che entrano nello strato ReLU nascosto. È necessario o l'introduzione della penalizzazione del livello di output in qualche modo terrà sotto controllo anche i pesi nascosti?

#some importing 
from __future__ import print_function 
import numpy as np 
import tensorflow as tf 
from six.moves import cPickle as pickle 
from six.moves import range 

#loading data 
pickle_file = '/home/maxkhk/Documents/Udacity/DeepLearningCourse/SourceCode/tensorflow/examples/udacity/notMNIST.pickle' 

with open(pickle_file, 'rb') as f: 
    save = pickle.load(f) 
    train_dataset = save['train_dataset'] 
    train_labels = save['train_labels'] 
    valid_dataset = save['valid_dataset'] 
    valid_labels = save['valid_labels'] 
    test_dataset = save['test_dataset'] 
    test_labels = save['test_labels'] 
    del save # hint to help gc free up memory 
    print('Training set', train_dataset.shape, train_labels.shape) 
    print('Validation set', valid_dataset.shape, valid_labels.shape) 
    print('Test set', test_dataset.shape, test_labels.shape) 


#prepare data to have right format for tensorflow 
#i.e. data is flat matrix, labels are onehot 

image_size = 28 
num_labels = 10 

def reformat(dataset, labels): 
    dataset = dataset.reshape((-1, image_size * image_size)).astype(np.float32) 
    # Map 0 to [1.0, 0.0, 0.0 ...], 1 to [0.0, 1.0, 0.0 ...] 
    labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32) 
    return dataset, labels 
train_dataset, train_labels = reformat(train_dataset, train_labels) 
valid_dataset, valid_labels = reformat(valid_dataset, valid_labels) 
test_dataset, test_labels = reformat(test_dataset, test_labels) 
print('Training set', train_dataset.shape, train_labels.shape) 
print('Validation set', valid_dataset.shape, valid_labels.shape) 
print('Test set', test_dataset.shape, test_labels.shape) 


#now is the interesting part - we are building a network with 
#one hidden ReLU layer and out usual output linear layer 

#we are going to use SGD so here is our size of batch 
batch_size = 128 

#building tensorflow graph 
graph = tf.Graph() 
with graph.as_default(): 
     # Input data. For the training data, we use a placeholder that will be fed 
    # at run time with a training minibatch. 
    tf_train_dataset = tf.placeholder(tf.float32, 
            shape=(batch_size, image_size * image_size)) 
    tf_train_labels = tf.placeholder(tf.float32, shape=(batch_size, num_labels)) 
    tf_valid_dataset = tf.constant(valid_dataset) 
    tf_test_dataset = tf.constant(test_dataset) 

    #now let's build our new hidden layer 
    #that's how many hidden neurons we want 
    num_hidden_neurons = 1024 
    #its weights 
    hidden_weights = tf.Variable(
    tf.truncated_normal([image_size * image_size, num_hidden_neurons])) 
    hidden_biases = tf.Variable(tf.zeros([num_hidden_neurons])) 

    #now the layer itself. It multiplies data by weights, adds biases 
    #and takes ReLU over result 
    hidden_layer = tf.nn.relu(tf.matmul(tf_train_dataset, hidden_weights) + hidden_biases) 

    #time to go for output linear layer 
    #out weights connect hidden neurons to output labels 
    #biases are added to output labels 
    out_weights = tf.Variable(
    tf.truncated_normal([num_hidden_neurons, num_labels])) 

    out_biases = tf.Variable(tf.zeros([num_labels])) 

    #compute output 
    out_layer = tf.matmul(hidden_layer,out_weights) + out_biases 
    #our real output is a softmax of prior result 
    #and we also compute its cross-entropy to get our loss 
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(out_layer, tf_train_labels)) 

    #now we just minimize this loss to actually train the network 
    optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss) 

    #nice, now let's calculate the predictions on each dataset for evaluating the 
    #performance so far 
    # Predictions for the training, validation, and test data. 
    train_prediction = tf.nn.softmax(out_layer) 
    valid_relu = tf.nn.relu( tf.matmul(tf_valid_dataset, hidden_weights) + hidden_biases) 
    valid_prediction = tf.nn.softmax(tf.matmul(valid_relu, out_weights) + out_biases) 

    test_relu = tf.nn.relu(tf.matmul(tf_test_dataset, hidden_weights) + hidden_biases) 
    test_prediction = tf.nn.softmax(tf.matmul(test_relu, out_weights) + out_biases) 
+2

Un'alternativa alla raccolta manuale di tutte le variabili di peso è di aggiungerli a una raccolta, in genere "tf.GraphKeys.REGULARIZATION_LOSSES". Vedi [questa domanda] (http://stackoverflow.com/q/37107223/1804173) per esempio soluzioni. – bluenote10

risposta

38

hidden_weights, hidden_biases, out_weights, e out_biases sono tutti i parametri del modello che si sta creando. È possibile aggiungere la regolarizzazione L2 a TUTTI questi parametri come segue:

loss = (tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
    logits=out_layer, labels=tf_train_labels)) + 
    0.01*tf.nn.l2_loss(hidden_weights) + 
    0.01*tf.nn.l2_loss(hidden_biases) + 
    0.01*tf.nn.l2_loss(out_weights) + 
    0.01*tf.nn.l2_loss(out_biases)) 
+5

Salve, perché dovremmo aggiungere la regolarizzazione l2 ai bias, penso che non sia necessario aggiungere la regolarizzazione l2 al termine dei bias. –

+26

Non dovresti regolarizzare i bias, solo i pesi. –

+4

@AlexanderYau: hai ragione: "... Per questi motivi di solito non includiamo termini di bias durante la regolarizzazione" (vedi [qui] (http://neuralnetworksanddeeplearning.com/chap3.html)) – johndodo

52

Un modo più breve e scalabile di farlo sarebbe;

vars = tf.trainable_variables() 
lossL2 = tf.add_n([ tf.nn.l2_loss(v) for v in vars ]) * 0.001 

Questo in sostanza somma il l2_loss di tutte le variabili trainabili. È anche possibile creare un dizionario in cui si specificano solo le variabili che si desidera aggiungere al costo e utilizzare la seconda riga in alto. Quindi è possibile aggiungere la perdita L2 con il valore cross entropy di softmax per calcolare la perdita totale.

Edit: Come già detto da Piotr Dabkowski, il codice qui sopra sarà anche regolarizzare pregiudizi. Questo può essere evitato aggiungendo un'istruzione if nella seconda riga;

lossL2 = tf.add_n([ tf.nn.l2_loss(v) for v in vars 
        if 'bias' not in v.name ]) * 0.001 

Questo può essere utilizzato per escludere altre variabili.

+3

Si noti che per la comprensione della lista che seleziona i bias, dipende dall'effettivo/nome/della variabile tf, quindi se non lo si chiama con "bias", l'esempio non lo selezionerà lontano. – stolsvik

+0

Assolutamente! Ecco perché ho specificato che "Questo può essere usato per escludere altre variabili". È bene indicarlo comunque, grazie. – PhABC

9

In realtà, di solito non regolarizziamo i termini di bias (intercetta). Così, andare per:

loss = (tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
    logits=out_layer, labels=tf_train_labels)) + 
    0.01*tf.nn.l2_loss(hidden_weights) + 
    0.01*tf.nn.l2_loss(out_weights)) 

penalizzando termine di intercetta, come l'intercetta viene aggiunta valori y, il risultato sarà cambiare i valori y, aggiungendo una costante c ai intercettazioni. Avere o meno non cambierà i risultati, ma compie alcuni calcoli

Problemi correlati