2017-02-17 3 views
1

Я пытаюсь использовать тензорный поток для обучения нейронной сети (LeNet) с использованием изображений дорожных знаков. Я хочу проверить влияние метода предварительной обработки на производительность nn. Итак, я предварительно обработал изображения и сохранил результаты (обучающие изображения, валидационные изображения, показания, заключительные свидетельства) как кортеж в dict.Модель Tensorflow не тренируется при изменении входных данных

Затем я попытался перебрать этот Словарь, а затем использовать операции подготовки и проверок на tensorflow следующих

import tensorflow as tf 
from sklearn.utils import shuffle 


output_data = [] 
EPOCHS = 5 
BATCH_SIZE = 128 
rate = 0.0005 

for key in finalInputdata.keys(): 
    for procTypes in range(0,(len(finalInputdata[key]))): 
     if np.shape(finalInputdata[key][procTypes][0]) !=(): 
      X_train = finalInputdata[key][procTypes][0] 
      X_valid = finalInputdata[key][procTypes][1] 
      X_test = finalInputdata[key][procTypes][2] 
      X_finaltest = finalInputdata[key][procTypes][3] 


      x = tf.placeholder(tf.float32, (None, 32, 32,np.shape(X_train)[-1])) 
      y = tf.placeholder(tf.int32, (None)) 
      one_hot_y = tf.one_hot(y,43) 

      # Tensor Operations 
      logits = LeNet(x,np.shape(X_train)[-1]) 

      cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits,one_hot_y) 
      softmax_probability = tf.nn.softmax(logits) 

      loss_operation = tf.reduce_mean(cross_entropy) 
      optimizer = tf.train.AdamOptimizer(learning_rate=rate) 
      training_operation = optimizer.minimize(loss_operation) 
      correct_prediction = tf.equal(tf.argmax(logits,1), tf.argmax(one_hot_y,1)) 
      accuracy_operation = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 


       # Pipeline for training and evaluation 

      sess = tf.InteractiveSession() 

      sess.run(tf.global_variables_initializer()) 
      num_examples = len(X_train) 

      print("Training on %s images processed as %s" %(key,dict_fornames['proctypes'][procTypes])) 
      print() 
      for i in range(EPOCHS): 
       X_train, y_train = shuffle(X_train, y_train) 
       for offset in range(0, num_examples, BATCH_SIZE): 
        end = offset + BATCH_SIZE 
        batch_x, batch_y = X_train[offset:end], y_train[offset:end] 
        sess.run(training_operation, feed_dict = {x: batch_x, y: batch_y}) 

       training_accuracy = evaluate(X_train,y_train) 

       validation_accuracy = evaluate(X_valid, y_valid) 

       testing_accuracy = evaluate(X_test, y_test) 

       final_accuracy = evaluate(X_finaltest, y_finalTest) 

       print("EPOCH {} ...".format(i+1)) 
       print("Training Accuracy = {:.3f}".format(training_accuracy)) 
       print("Validation Accuracy = {:.3f}".format(validation_accuracy)) 
       print() 
       output_data.append({'EPOCHS':EPOCHS, 'LearningRate':rate, 'ImageType': 'RGB',\ 
            'PreprocType': dict_fornames['proctypes'][0],\ 
            'TrainingAccuracy':training_accuracy, 'ValidationAccuracy':validation_accuracy, \ 
            'TestingAccuracy': testing_accuracy}) 


      sess.close() 

оценки функции выглядит следующим образом

def evaluate(X_data, y_data): 
    num_examples = len(X_data) 
    total_accuracy = 0 
    sess = tf.get_default_session() 
    for offset in range(0,num_examples, BATCH_SIZE): 
     batch_x, batch_y = X_data[offset:offset+BATCH_SIZE], y_data[offset:offset+BATCH_SIZE] 
     accuracy = sess.run(accuracy_operation, feed_dict = {x:batch_x, y:batch_y}) 
     total_accuracy += (accuracy * len(batch_x)) 
    return total_accuracy/num_examples 

Как только я выполнить программу , он работает хорошо для первой итерации набора данных, но со второй итерации сеть не тренируется и продолжает делать это для всех других итераций.

Training on RGB images processed as Original 

EPOCH 1 ... 
Training Accuracy = 0.525 
Validation Accuracy = 0.474 

EPOCH 2 ... 
Training Accuracy = 0.763 
Validation Accuracy = 0.682 

EPOCH 3 ... 
Training Accuracy = 0.844 
Validation Accuracy = 0.723 

EPOCH 4 ... 
Training Accuracy = 0.888 
Validation Accuracy = 0.779 

EPOCH 5 ... 
Training Accuracy = 0.913 
Validation Accuracy = 0.795 

Training on RGB images processed as Mean Subtracted Data 

EPOCH 1 ... 
Training Accuracy = 0.056 
Validation Accuracy = 0.057 

EPOCH 2 ... 
Training Accuracy = 0.057 
Validation Accuracy = 0.057 

EPOCH 3 ... 
Training Accuracy = 0.057 
Validation Accuracy = 0.056 

EPOCH 4 ... 
Training Accuracy = 0.058 
Validation Accuracy = 0.056 

EPOCH 5 ... 
Training Accuracy = 0.058 
Validation Accuracy = 0.058 

Training on RGB images processed as Normalized Data 

EPOCH 1 ... 
Training Accuracy = 0.058 
Validation Accuracy = 0.054 

EPOCH 2 ... 
Training Accuracy = 0.058 
Validation Accuracy = 0.054 

EPOCH 3 ... 
Training Accuracy = 0.058 
Validation Accuracy = 0.054 

EPOCH 4 ... 
Training Accuracy = 0.058 
Validation Accuracy = 0.054 

EPOCH 5 ... 
Training Accuracy = 0.058 
Validation Accuracy = 0.054 

Однако, если я перезапускаю ядро ​​и использую любой тип данных (любая итерация), он работает. Я понял, что я должен очистить график или запустить несколько сеансов для нескольких типов данных, но я пока не понимаю, как это сделать. Я пробовал использовать tf.reset_default_graph(), но кажется, что он не имеет никакого эффекта. Может кто-нибудь указать мне в правильном направлении?

Благодаря

+0

Не могли бы вы уточнить, в чем проблема? – drpng

+1

Как я уже упоминал в названии, сеть не тренируется. Точность обучения остается на уровне 0,05 даже после многих итераций – Mechanic

ответ

1

Вы можете сделать попробовать с данными, которые нормированы к нулевому среднему и единичной дисперсии перед подачей его в сеть, например, путем масштабирования изображений до -1..1; это сказал, 0..1 диапазон в основном звучит нормальный. В зависимости от активизации, используемой в сети, диапазон значений может иметь значение: ReLUs, например, вымирают для входов ниже нуля, сигмоиды начинают насыщаться, когда значения ниже -4 или выше +4, а активация tanh пропускает половину их диапазон значений, если значение никогда не ниже 0 - если диапазон значений слишком велик, градиенты также могут взорваться, предотвращая обучение вообще. Из this paper авторы, по-видимому, вычитают среднее (среднее) изображение вместо среднего значения.

Вы можете использовать курс обучения (хотя лично я обычно начинаю экспериментировать вокруг 0.0001 для Адама).

Что касается ваших нескольких сеансов, часть вопроса: способ, которым он в настоящее время реализован в вашем коде, вы в основном загромождаете граф по умолчанию. Позвонив

for key in finalInputdata.keys(): 
    for procTypes in range(0,(len(finalInputdata[key]))): 
     if np.shape(finalInputdata[key][procTypes][0]) !=(): 

    # ... 

    x = tf.placeholder(tf.float32, (None, 32, 32,np.shape(X_train)[-1])) 
    y = tf.placeholder(tf.int32, (None)) 
    one_hot_y = tf.one_hot(y,43) 

    # Tensor Operations 
    logits = LeNet(x,np.shape(X_train)[-1]) 

    # ... etc ... 

вы создаете len(finalInputdata) * Nразличных экземпляров LeNet, все в пределах графа по умолчанию. Это может быть проблемой, когда переменные внутренне повторно используются в сети.

Если вы хотите сбросить график по умолчанию для того, чтобы попробовать различные гиперпараметры, попробуйте

for key in finalInputdata.keys(): 
    for procTypes in range(0,(len(finalInputdata[key]))): 

     tf.reset_default_graph() 
     # define the graph 

     sess = tf.InteractiveSession() 
     # train 

, но это, вероятно, лучше Явно создавать графики и Sessions, как так:

for key in finalInputdata.keys(): 
    for procTypes in range(0,(len(finalInputdata[key]))): 

     with tf.Graph().as_default() as graph: 
      # define the graph 

     with tf.Session(graph=graph) as sess: 
      # train 

Вместо того, чтобы звонить sess = tf.get_default_session(), вы бы прямо использовали ссылку sess.

Я также обнаружил, что ядра Jupyter и GPU, поддерживающие TensorFlow, не работают вместе, когда они повторяются в сетях, иногда возникают ошибки памяти или просто сбой на вкладке браузера.

Смежные вопросы