21

Obecnie gram w ANN, który jest częścią kursu Udoskonalanie kursu DeepLearning.TensorFlow - wprowadzenie zarówno regularyzacji L2, jak i rezygnacji z sieci. Czy to ma jakiś sens?

Udało mi się zbudować i zbudować sieć i wprowadziłem regularyzację L2 na wszystkich wagach i błędach. W tej chwili wypróbowuję rezygnację z ukrytej warstwy, aby poprawić generalizację. Zastanawiam się, czy sensowne jest wprowadzenie regularyzacji L2 w ukrytą warstwę i rezygnację z tej samej warstwy? Jeśli tak, jak to zrobić prawidłowo?

Podczas przerywania dosłownie wyłączamy połowę aktywacji ukrytej warstwy i podwojono ilość wytwarzaną przez resztę neuronów. Podczas używania L2 obliczamy normę L2 dla wszystkich ukrytych ciężarów. Ale nie jestem pewien, jak obliczyć L2 w przypadku użycia dropout. Wyłączamy niektóre aktywacje, czy nie powinniśmy teraz usuwać ciężarów, które nie są używane w obliczeniach L2? Wszelkie odniesienia w tej sprawie będą użyteczne, nie znalazłem żadnych informacji.

Tylko w przypadku, jesteś zainteresowany, mój kod na ANN z legalizacji L2 jest poniżej:

#for NeuralNetwork model code is below 
#We will use SGD for training to save our time. Code is from Assignment 2 
#beta is the new parameter - controls level of regularization. Default is 0.01 
#but feel free to play with it 
#notice, we introduce L2 for both biases and weights of all layers 

beta = 0.01 

#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 
    #Notice - we introduce our L2 here 
    loss = (tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
    out_layer, tf_train_labels) + 
    beta*tf.nn.l2_loss(hidden_weights) + 
    beta*tf.nn.l2_loss(hidden_biases) + 
    beta*tf.nn.l2_loss(out_weights) + 
    beta*tf.nn.l2_loss(out_biases))) 

    #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) 



#now is the actual training on the ANN we built 
#we will run it for some number of steps and evaluate the progress after 
#every 500 steps 

#number of steps we will train our ANN 
num_steps = 3001 

#actual training 
with tf.Session(graph=graph) as session: 
    tf.initialize_all_variables().run() 
    print("Initialized") 
    for step in range(num_steps): 
    # Pick an offset within the training data, which has been randomized. 
    # Note: we could use better randomization across epochs. 
    offset = (step * batch_size) % (train_labels.shape[0] - batch_size) 
    # Generate a minibatch. 
    batch_data = train_dataset[offset:(offset + batch_size), :] 
    batch_labels = train_labels[offset:(offset + batch_size), :] 
    # Prepare a dictionary telling the session where to feed the minibatch. 
    # The key of the dictionary is the placeholder node of the graph to be fed, 
    # and the value is the numpy array to feed to it. 
    feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels} 
    _, l, predictions = session.run(
     [optimizer, loss, train_prediction], feed_dict=feed_dict) 
    if (step % 500 == 0): 
     print("Minibatch loss at step %d: %f" % (step, l)) 
     print("Minibatch accuracy: %.1f%%" % accuracy(predictions, batch_labels)) 
     print("Validation accuracy: %.1f%%" % accuracy(
     valid_prediction.eval(), valid_labels)) 
     print("Test accuracy: %.1f%%" % accuracy(test_prediction.eval(), test_labels)) 
+6

Dlaczego regulujesz te uprzedzenia? –

Odpowiedz

15

Ok, po kilku dodatkowych wysiłków udało mi się go rozwiązać i przedstawić zarówno L2 i porzucaniu w mojej sieci, kod jest poniżej. Dostałem niewielką poprawę w tej samej sieci bez przerywania (z L2 na miejscu). Nadal nie jestem pewien, czy naprawdę warto podjąć wysiłek, aby wprowadzić oba, L2 i rezygnację, ale przynajmniej działa i nieznacznie poprawia wyniki.

#ANN with introduced dropout 
#This time we still use the L2 but restrict training dataset 
#to be extremely small 

#get just first 500 of examples, so that our ANN can memorize whole dataset 
train_dataset_2 = train_dataset[:500, :] 
train_labels_2 = train_labels[:500] 

#batch size for SGD and beta parameter for L2 loss 
batch_size = 128 
beta = 0.001 

#that's how many hidden neurons we want 
num_hidden_neurons = 1024 

#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 
    #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) 

    #add dropout on hidden layer 
    #we pick up the probabylity of switching off the activation 
    #and perform the switch off of the activations 
    keep_prob = tf.placeholder("float") 
    hidden_layer_drop = tf.nn.dropout(hidden_layer, keep_prob) 

    #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 
    #notice that upon training we use the switched off activations 
    #i.e. the variaction of hidden_layer with the dropout active 
    out_layer = tf.matmul(hidden_layer_drop,out_weights) + out_biases 
    #our real output is a softmax of prior result 
    #and we also compute its cross-entropy to get our loss 
    #Notice - we introduce our L2 here 
    loss = (tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
    out_layer, tf_train_labels) + 
    beta*tf.nn.l2_loss(hidden_weights) + 
    beta*tf.nn.l2_loss(hidden_biases) + 
    beta*tf.nn.l2_loss(out_weights) + 
    beta*tf.nn.l2_loss(out_biases))) 

    #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) 



#now is the actual training on the ANN we built 
#we will run it for some number of steps and evaluate the progress after 
#every 500 steps 

#number of steps we will train our ANN 
num_steps = 3001 

#actual training 
with tf.Session(graph=graph) as session: 
    tf.initialize_all_variables().run() 
    print("Initialized") 
    for step in range(num_steps): 
    # Pick an offset within the training data, which has been randomized. 
    # Note: we could use better randomization across epochs. 
    offset = (step * batch_size) % (train_labels_2.shape[0] - batch_size) 
    # Generate a minibatch. 
    batch_data = train_dataset_2[offset:(offset + batch_size), :] 
    batch_labels = train_labels_2[offset:(offset + batch_size), :] 
    # Prepare a dictionary telling the session where to feed the minibatch. 
    # The key of the dictionary is the placeholder node of the graph to be fed, 
    # and the value is the numpy array to feed to it. 
    feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels, keep_prob : 0.5} 
    _, l, predictions = session.run(
     [optimizer, loss, train_prediction], feed_dict=feed_dict) 
    if (step % 500 == 0): 
     print("Minibatch loss at step %d: %f" % (step, l)) 
     print("Minibatch accuracy: %.1f%%" % accuracy(predictions, batch_labels)) 
     print("Validation accuracy: %.1f%%" % accuracy(
     valid_prediction.eval(), valid_labels)) 
     print("Test accuracy: %.1f%%" % accuracy(test_prediction.eval(), test_labels)) 
+0

W oryginalnym dokumencie o usunięciu z pamięci konkretnie wywołuje się taką konfigurację, więc prawdopodobnie próbujesz to zrobić w dobrej kondycji. Chociaż mogę zauważyć, że nie uważam za normalne uwzględnianie regularyzacji L2 w uprzedzeniach, tylko w przypadku wag. http://www.jmlr.org/papers/volume15/srivastava14a.old/source/srivastava14a.pdf http://stats.stackexchange.com/questions/153605/no-regularisation-term-for-bias-unit- sieć neuronowa –

+1

@DavidParks Wygląda na to, że musimy uwzględnić L2 również w sprawie błędów.Proszę spojrzeć na przykład tensorflow MNIST tutaj: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/models/image/mnist/convolutional.py Przeszukuj wywołania funkcji 'l2_loss'. –

+1

Jako przykład: Mamy jedną cechę x, a jej wartości y, a my dopasowujemy liniowo do danych, y = mx + b. Jeśli wszystkie punkty danych skupią się wokół y = 1000 przy niewielkiej wariancji, będziemy potrzebować dużego odchylenia, aby przesunąć linię do 1000. Nie ma problemu z przystosowaniem się do tego, to właśnie tam znajdują się dane. Problem polega na tym, że przeważamy funkcję. Ta stronniczość jest tylko przesunięciem. Powiedziawszy to, sporządziłem histogram wag i uprzedzeń na temat problemów z klasyfikacją i regresją, ale w żadnym z nich nie dostrzegłem uprzedzeń, które były duże. Tak więc wątpię, że powoduje zauważalny problem. –

4

Rzeczywiście, przy pracy wykorzystuje maksymalnie normą regularyzacji, nie L2 oprócz widełek. „sieć neuronowa została zoptymalizowana pod przymusem || wag || 2 ≤ C Niniejszy ograniczeniem była narzucone podczas optymalizacji przez rzutowanie na powierzchnię kuli o promieniu c, za każdym razem, gdy z niej wyszło.To jest również nazywane regulacją maksormy, ponieważ implikuje to, że maksymalna wartość, jaką może przyjąć dowolna waga, to c "(http://jmlr.org/papers/volume15/srivastava14a/srivastava14a.pdf)

Możesz znaleźć miłą dyskusję na temat tej metody regularyzacji tutaj: https://plus.google.com/+IanGoodfellow/posts/QUaCJfvDpni

5

Nie ma wad, aby korzystać z wielu korekt. W rzeczywistości jest papier Dropout: A Simple Way to Prevent Neural Networks from Overfitting, w którym autorzy sprawdzali, ile to pomaga. Najwyraźniej dla różnych zestawów danych będzie mieć różne wyniki, ale za MNIST:

enter image description here

widać, że Dropout + Max-norm daje najniższą błąd. Poza tym masz duży błąd w kodzie.

użyć l2_loss na wag i uprzedzeń:

beta*tf.nn.l2_loss(hidden_weights) + 
beta*tf.nn.l2_loss(hidden_biases) + 
beta*tf.nn.l2_loss(out_weights) + 
beta*tf.nn.l2_loss(out_biases))) 

Nie należy karać wysokie uprzedzeń. Usuń więc l2_loss z uprzedzeń.

Powiązane problemy