Репликация результатов с использованием Keras - PullRequest
2 голосов
/ 26 апреля 2019

Я пытаюсь повторить результаты моих экспериментов, используя Tensorflow и Keras (с TF backend). Когда я использую TF, я вначале устанавливаю случайные начальные числа для графиков numpy и tenorflow прямо вверху скрипта. Я не использую какие-либо выпадающие слои или другие методы, которые могут привести к случайности (о чем я могу думать).

При запуске таких моделей, независимо от размера сети, всегда дает одинаковые результаты.

TF Эксперимент 1:

(«Эпоха», 99, «завершено из», 100, «потеря:», 289,8982433080673, «точность:», 0,6875)

TF Эксперимент 2:

(«Эпоха», 99, «завершено из», 100, «потеря:», 289.8982433080673, «точность:», 0,6875)

Когда я попытался воспроизвести эти результаты, используя Keras с одинаковыми конфигурациями, у меня не получилось. Кроме того, каждый отдельный прогон дает разную производительность.

Мой код TF, который может повторять результаты, выглядит следующим образом: Ссылка на фрагмент: https://www.youtube.com/watch?v=BhpvH5DuVu8&list=PLQVvvaa0QuDfKTOs3Keq_kaG2P55YRn5v&index=46

from numpy.random import seed                                                                                                                           
seed(1)                                                                                                                                                 
from tensorflow import set_random_seed                                                                                                                  
set_random_seed(2)                                                                                                                                      

## import system modules                                                                                                                                
#
import os                                                                                                                                               
import sys                                                                                                                                              

## import ML modules                                                                                                                                    
#
import tensorflow as tf                                                                                                                                 
import numpy as np                                                                                                                                      
from keras.utils import to_categorical                                                                                                                  
from sklearn import preprocessing                                                                                                                       

logs_path = '../logs/'                                                                                                                                                                                                    

## Default constants                                                                                                                                    
#
NO_OF_CLASSES = 2                                                                                                                                       
BATCH_SIZE = 32                                                                                                                                         
FEAT_DIM = 26                                                                                                                                           
N_nodes_hl1 = 300                                                                                                                                       
N_nodes_hl2 = 30                                                                                                                                        
N_nodes_hl3 = 30                                                                                                                                        

## define the network architecture                                                                                                                      
#                                                                                                                                                       
## This model is a simple multilayer perceptron network with 3 hidden layers.                                                                           
## Input to the layer has the dimensions equal to feature dimensions.                                                                                   
## We create a complete graph in this method with input placeholder as an input argument and                                                            
## output placeholder as an returning argument                                                                                                          
#
def neural_network_model(data):                                                                                                                         

    ## defining dictionaries specifying the specification of each layer.                                                                                
    #
    hidden_1_layer = {'weights': tf.Variable(tf.random_normal([FEAT_DIM, N_nodes_hl1]), name='w1'),\                                                    
                      'biases': tf.Variable(tf.random_normal([N_nodes_hl1]), name='b1')}                                                                

    hidden_2_layer = {'weights': tf.Variable(tf.random_normal([N_nodes_hl1, N_nodes_hl2]), name='w2'), \                                                
                      'biases': tf.Variable(tf.random_normal([N_nodes_hl2]), name='b2')}                                                                

    hidden_3_layer = {'weights': tf.Variable(tf.random_normal([N_nodes_hl2, N_nodes_hl3]), name='w3'),\                                                 
                      'biases': tf.Variable(tf.random_normal([N_nodes_hl3]), name='b3')}                                                                

    output_layer = {'weights': tf.Variable(tf.random_normal([N_nodes_hl3, NO_OF_CLASSES]), name='w4'), \                                                
                      'biases': tf.Variable(tf.random_normal([NO_OF_CLASSES]), name='b4')}                                                              

    l1 = tf.add(tf.matmul(data, hidden_1_layer['weights']), hidden_1_layer['biases'])                                                                   
    l1 = tf.nn.relu(l1)                                                                                 

    l2 = tf.add(tf.matmul(l1, hidden_2_layer['weights']), hidden_2_layer['biases'])                                                                     
    l2 = tf.nn.relu(l2)                                                                                

    l3 = tf.add(tf.matmul(l2, hidden_3_layer['weights']), hidden_3_layer['biases'])                                                                     
    l3 = tf.nn.relu(l3)                                                                                  

    output = tf.add(tf.matmul(l3, output_layer['weights']), output_layer['biases'], name="last_layer")                                                  

    ## return the final layer's output gracefully                                                                                                       
    #                                                                                                                                                   
    return output    

## end of method                                                                                                                                        
#                                                                                                                                                       

## This method trains a neural network along with collecting statistics related to                                                                      
## the graphs.                                                                                                                                          
#
def train_neural_network(xtrain, ytrain, odir):                                                                                                         

    learning_rate = 0.0008                                                                                                                              
    epoch_iter = 100                                                                                                                                    

    ## input/ output  placeholders where data would be plugged in...                                                                                    
    #
    x = tf.placeholder('float', [None, FEAT_DIM], name="input")                                                                                         
    y_ = tf.placeholder('float', name="output")                                                                                                         

    ## define the network                                                                                                                               
    #
    logits = neural_network_model(x)                                                                                                                    
    prediction = tf.nn.softmax(logits, name="op_to_restore") ## softmax normalizes the output results

    loss = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits(logits = logits, labels = y_) )                                                      

    ## Major OP for the training procedure. The "train" op defined here tries to minimize loss                                                          
    #
    with tf.name_scope('ADAM'):                                                                                                                         
        # Gradient Descent                                                                                                                              
        optimizer = tf.train.AdamOptimizer(learning_rate)                                                                                               
        train = optimizer.minimize(loss)                                                                                                                                                                                                       

    with tf.name_scope('Accuracy'):                                                                                                                     
        ## Accuracy calculation by comparing the predicted and detected labels                                                                          
        #
        acc = tf.equal(tf.argmax(logits, 1), tf.argmax(y_, 1))                                                                                          
        acc = tf.reduce_mean(tf.cast(acc, tf.float32))                                                                                                  

    ## summary and display variables                                                                                                                    
    #                                                                                                                                                   
    loss_sum = tf.summary.scalar("loss", loss)                                                                                                          
    acc_sum = tf.summary.scalar("accuracy", acc)                                                                                                        

   ## Merge all summaries into a single variable. This summaries will be displayed using Tensorboard                                                   
    #                                                                                                                                                   
    merged_summary_op = tf.summary.merge([loss_sum, acc_sum])                                                                                

    ## create a session for the graph (graph initialization)                                                                                            
    #                                                                                                                                                   
    with tf.Session() as sess:                                                                                                                          

        ## initialize all the variables. Note that before this point, all the variables were empty buckets !!                                           
        #
        sess.run(tf.global_variables_initializer())                                                                                                     

        ## initialize the summary writer (For tensorboard)                                                                                              
        #
        summary_writer = tf.summary.FileWriter(logs_path, graph=tf.get_default_graph())                                                                 

        ## iterate over epochs (complete forward-backward for the entire training set)                                                                  
        #                                                                                                                                               
        for epoch in range(epoch_iter):                                                                                                                 

            ## initialize some variables to keep track of progress during training                                                                      
            #                                                                                                                                           
            epoch_loss = 0                                                                                                                              
            epoch_accuracy = 0                                                                                                                          

            ## minibatch training. Splitting input data in to smaller chunks is better                                                                  
            #                                                                                                                                           
            for i in range( int(len(xtrain)/ BATCH_SIZE) ):                                                                                             
                epoch_x = xtrain[ i * BATCH_SIZE : i * BATCH_SIZE + BATCH_SIZE]                                                                         
                epoch_y = ytrain[ i * BATCH_SIZE : i * BATCH_SIZE + BATCH_SIZE]                                                                         

                ## run the session and collect the intermediate stats. Feed dict kwarg takes in input/output placeholdar names as                       
                ## a key and features/labels as values                                                                                                  
                #                                                                                                                                       
                _, ac, ls, summary = sess.run([train, acc, loss, merged_summary_op], feed_dict = {x: epoch_x, y_: epoch_y})                             

                ## write the the summary in logs to visualize it later                                                                                     
                #                                                                                                                                       
                summary_writer.add_summary(summary, epoch * int(len(xtrain)/BATCH_SIZE)+i)                                                              

                ## update stats                                                                                                                         
                #                                                                                                                                       
                epoch_loss += ls                                                                                                                        
                epoch_accuracy += ac                                                                                                                    

            print ("Epoch ", epoch, " completed out of ", epoch_iter, " loss: ", epoch_loss, "accuracy: ", ac)                                          
        ## saver module to save tf graph variables.. etc....                                                                                                   

Мой сценарий Keras для репликации результатов выглядит следующим образом:

from numpy.random import seed                                                                                                                           
seed(1)                                                                                                                                                 
from tensorflow import set_random_seed                                                                                                                  
set_random_seed(2)                                                                                                                                      


## import system modules                                                                                                                                
#                                                                                                                                                       
import os                                                                                                                                               
import sys                                                                                                                                              

## import ML and datatype modules                                                                                                                       
#                                                                                                                                                       
import numpy as np                                                                                                                                                                                                                                                                         
import keras                                                                                                                                            
from keras.models import Sequential                                                                                                                     
from keras.layers import Dense, Dropout                                                                                                                 
from keras.callbacks import ModelCheckpoint                                                                                                             
from keras.optimizers import SGD                                                                                                                        
from keras.utils import to_categorical                                                                                                                  
from sklearn import preprocessing                                                                                                                       

## Default constants                                                                                                                                    
#                                                                                                                                                       
NO_OF_CLASSES = 2                                                                                                                                       
BATCH_SIZE = 32                                                                                                                                         
FEAT_DIM = 26                                                                                                                                           
N_nodes_hl1 = 300                                                                                                                                       
N_nodes_hl2 = 30                                                                                                                                        
N_nodes_hl3 = 30                                                                                                                                        


## This method defines the NN architecture as well as performs training and saves the model info                                                        
#                                                                                                                                                       
def train_neural_network(xtrain, ytrain, odir):                                                                                                         
    learning_rate = 0.009                                                                                                                               

    ## Define the network (MLP)                                                                                                                         
    #                                                                                                                                                   
    model = Sequential()                                                                                                                                
    model.add(Dense(N_nodes_hl1, input_dim=FEAT_DIM, activation="relu"))                                                                                
    model.add(Dense(N_nodes_hl2, activation="relu"))                                                                                                    
    model.add(Dense(N_nodes_hl3, activation="relu"))                                                                                                    
    model.add(Dense(NO_OF_CLASSES, activation="softmax"))                                                                                               

    ## optimizer                                                                                                                                        
    #                                                                                                                                                   
    sgd = SGD(lr=learning_rate)                                                                                                                         
    model.compile(loss="categorical_crossentropy", optimizer=sgd, metrics=['accuracy'])                                                                 
    print model.summary()                                                                                                                               
    ## train the model                                                                                                                                  
    model.fit(x=xtrain, y=ytrain, epochs=100)

Keras эксперимент1: потери: 0,5964 - в соответствии с 0,6725

Керас эксперимент2: потери: 0,5974 - в соответствии с 0,6712

Единственная разница между двумя скриптами - это оптимизатор. Я не думаю, что это внесло бы какую-либо случайность во время тренировки. Кроме того, я считаю, что архитектура NN должна давать те же результаты с точностью до float64 на процессорах (и float32 на графических процессорах благодаря аппаратным возможностям).

Чего мне не хватает в моем сценарии Keras? Кроме того, исправьте меня, если мое понимание неверно где-то в этом запросе.

Наряду с этим, дополнительные ссылки (кроме следующих) о том, как копировать результаты NN будут высоко оценены.

https://machinelearningmastery.com/reproducible-results-neural-networks-keras/

Как получить стабильные результаты с TensorFlow, установив случайное начальное число

Получение воспроизводимых результатов с использованием tenorflow-GPU

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...