3

Я пытаюсь использовать глубокую нейронную сетевую архитектуру для классификации по значению двоичной метки - -1 и +1. Вот мой код, чтобы сделать это в tensorflow.Двоичная классификация в TensorFlow, неожиданные большие значения потери и точности

import tensorflow as tf 
import numpy as np 
from preprocess import create_feature_sets_and_labels 

train_x,train_y,test_x,test_y = create_feature_sets_and_labels() 

x = tf.placeholder('float', [None, 5]) 
y = tf.placeholder('float') 

n_nodes_hl1 = 500 
n_nodes_hl2 = 500 
n_nodes_hl3 = 500 

n_classes = 1 
batch_size = 100 

def neural_network_model(data): 

    hidden_1_layer = {'weights':tf.Variable(tf.random_normal([5, n_nodes_hl1])), 
         'biases':tf.Variable(tf.random_normal([n_nodes_hl1]))} 

    hidden_2_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl1, n_nodes_hl2])), 
         'biases':tf.Variable(tf.random_normal([n_nodes_hl2]))} 

    hidden_3_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl2, n_nodes_hl3])), 
         'biases':tf.Variable(tf.random_normal([n_nodes_hl3]))} 

    output_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl3, n_classes])), 
         'biases':tf.Variable(tf.random_normal([n_classes]))} 


    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.transpose(tf.add(tf.matmul(l3, output_layer['weights']), output_layer['biases'])) 
    return output 



def train_neural_network(x): 
    prediction = neural_network_model(x) 
    cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(prediction, y)) 
    optimizer = tf.train.AdamOptimizer().minimize(cost) 

    hm_epochs = 10 

    with tf.Session() as sess: 
     sess.run(tf.initialize_all_variables()) 

     for epoch in range(hm_epochs): 
      epoch_loss = 0 
      i = 0 
      while i < len(train_x): 
       start = i 
       end = i + batch_size 
       batch_x = np.array(train_x[start:end]) 
       batch_y = np.array(train_y[start:end]) 

       _, c = sess.run([optimizer, cost], feed_dict={x: batch_x, 
               y: batch_y}) 
       epoch_loss += c 
       i+=batch_size 

      print('Epoch', epoch, 'completed out of', hm_epochs, 'loss:', epoch_loss) 

     # correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1)) 
     # accuracy = tf.reduce_mean(tf.cast(correct, 'float')) 

     print (test_x.shape) 
     accuracy = tf.nn.l2_loss(prediction-y,name="squared_error_test_cost")/test_x.shape[0] 
     print('Accuracy:', accuracy.eval({x: test_x, y: test_y})) 

train_neural_network(x) 

Это выход я получаю, когда я запускаю это:

('Epoch', 0, 'completed out of', 10, 'loss:', -8400.2424869537354) 
('Epoch', 1, 'completed out of', 10, 'loss:', -78980.956665039062) 
('Epoch', 2, 'completed out of', 10, 'loss:', -152401.86713409424) 
('Epoch', 3, 'completed out of', 10, 'loss:', -184913.46441650391) 
('Epoch', 4, 'completed out of', 10, 'loss:', -165563.44775390625) 
('Epoch', 5, 'completed out of', 10, 'loss:', -360394.44857788086) 
('Epoch', 6, 'completed out of', 10, 'loss:', -475697.51550292969) 
('Epoch', 7, 'completed out of', 10, 'loss:', -588638.92993164062) 
('Epoch', 8, 'completed out of', 10, 'loss:', -745006.15966796875) 
('Epoch', 9, 'completed out of', 10, 'loss:', -900172.41955566406) 
(805, 5) 
('Accuracy:', 5.8077128e+09) 

Я не понимаю, если значения я получаю правильно, поскольку есть реальный недостаток, не MNIST бинарной классификации Примеры. Точность не похожа на то, что я ожидал. Я ожидал процент, а не большую ценность.

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

Может кто-нибудь, пожалуйста, скажите, правильно ли мой подход к двоичной классификации? Также является частью точности моего кода правильно?

+0

Кажется, что ваша сеть нестабильна. Попробуйте выполнить вычисления с меньшими уровнями или с помощью инициализации xavier-glorot? – martianwars

+0

Я думаю, что ваш отступ не подходит для Python в вопросе. Не могли бы вы исправить это, чтобы быть таким же, как ваш исходный код (я думаю, что я вижу, какой код вы пытались вставить, но отладка Python становится намного сложнее, если вы не скопируете отступ правильно)? –

+1

@NeilSlater фиксированный отступ. –

ответ

5

Отсюда:

двоичное значение метки - -1 и +1

. , , Я предполагаю, что ваши ценности в train_y и test_y фактически -1,0 и +1,0

Это не будет работать очень хорошо с выбранной функции потерь sigmoid_cross_entropy_with_logits - которая предполагает 0,0 и +1,0. Отрицательные значения y вызывают хаос! Однако выбор функции потерь хорош для двоичной классификации. Я предлагаю изменить ваши значения y на 0 и 1.

Кроме того, технически выход вашей сети не является окончательным прогнозом. Функция потерь sigmoid_cross_entropy_with_logits предназначена для работы с сетью с функцией передачи сигмоида в выходном слое, хотя вы правильно поняли, что функция потерь применяется до. Таким образом, ваш код обучения отображается правильно

Я не уверен на 100% относительно tf.transpose, хотя - я бы увидел, что произойдет, если вы удалите это, лично I.e.

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

В любом случае, это выход «logit», но не ваш прогноз. Значение output может стать высоким для очень уверенных прогнозов, что, вероятно, объясняет ваши очень высокие значения позже из-за отсутствия сигмовидной функции. Так добавить тензор предсказания (это означает вероятность/уверенность, что пример в положительном классе):

prediction = tf.sigmoid(output) 

Вы можете использовать, чтобы вычислить точность. Расчет точности не должен основываться на ошибке L2, но сумма правильных значений - ближе к коду, который вы закомментировали (который, как представляется, относится к многоклассовой классификации). Для сравнения с истинным/ложным для двоичной классификации вам нужно порождать предсказания и сравнивать с истинными метками. Что-то вроде этого:

predicted_class = tf.greater(prediction,0.5) 
correct = tf.equal(predicted_class, tf.equal(y,1.0)) 
accuracy = tf.reduce_mean(tf.cast(correct, 'float')) 

Значение точности должно быть между 0.0 и 1.0. Если вы хотите в процентах, просто умножьте на 100, конечно.

+0

Спасибо большое Нейл! Однако есть еще некоторые проблемы. Обновление вопроса с подробностями. –

+0

@ VineetKaushik: Пожалуйста * не меняйте свой вопрос, если он делает его другим. Например, не добавляйте мое исправление и не спрашивайте, почему он сейчас не работает. Потому что это недействительно мой ответ - то есть всю мою работу и выгоду для кого-то другого с той же проблемой. –

+0

@VineetKaushik: Если мой ответ помог вам преодолеть проблему с большими неправильными значениями при обучении и тестировании, то вместо этого задайте новый вопрос с новая проблема. –

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

  • Нет связанных вопросов^_^