Изменение значения точности и отсутствие изменения значения потерь в двоичной классификации с использованием Tensorflow

я пытаюсь использовать глубокую нейронную сетевую архитектуру для классификации по значению двоичной метки – 0 и +1. Вот мой код, чтобы сделать это в тензорном потоке. Также этот вопрос переносится из обсуждения в предыдущем вопросе

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]))} output_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl2, 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'])) output = tf.add(tf.matmul(l2, output_layer['weights']), output_layer['biases']) return output def train_neural_network(x): prediction = tf.sigmoid(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')) 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') ) # 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) 

В частности, (перенося обсуждение с предыдущего вопроса) я удалил один слой – hidden_3_layer . Изменено

prediction = neural_network_model (x)

в

 prediction = tf.sigmoid(neural_network_model(x)) 

и добавил predicted_class, correct, accuracy часть в соответствии с ответом Нила. Я также изменил все -1s на 0s в моем csv.

Это мой след:

 ('Epoch', 0, 'completed out of', 10, 'loss:', 37.312037646770477) ('Epoch', 1, 'completed out of', 10, 'loss:', 37.073578298091888) ('Epoch', 2, 'completed out of', 10, 'loss:', 37.035196363925934) ('Epoch', 3, 'completed out of', 10, 'loss:', 37.035196363925934) ('Epoch', 4, 'completed out of', 10, 'loss:', 37.035196363925934) ('Epoch', 5, 'completed out of', 10, 'loss:', 37.035196363925934) ('Epoch', 6, 'completed out of', 10, 'loss:', 37.035196363925934) ('Epoch', 7, 'completed out of', 10, 'loss:', 37.035196363925934) ('Epoch', 8, 'completed out of', 10, 'loss:', 37.035196363925934) ('Epoch', 9, 'completed out of', 10, 'loss:', 37.035196363925934) ('Accuracy:', 0.42608696) 

Как вы можете видеть, потеря не уменьшается. Поэтому я не знаю, работает ли он по-прежнему.

Вот результаты нескольких повторных запусков. Результаты раскачиваются:

 ('Epoch', 0, 'completed out of', 10, 'loss:', 26.513012945652008) ('Epoch', 1, 'completed out of', 10, 'loss:', 26.513012945652008) ('Epoch', 2, 'completed out of', 10, 'loss:', 26.513012945652008) ('Epoch', 3, 'completed out of', 10, 'loss:', 26.513012945652008) ('Epoch', 4, 'completed out of', 10, 'loss:', 26.513012945652008) ('Epoch', 5, 'completed out of', 10, 'loss:', 26.513012945652008) ('Epoch', 6, 'completed out of', 10, 'loss:', 26.513012945652008) ('Epoch', 7, 'completed out of', 10, 'loss:', 26.513012945652008) ('Epoch', 8, 'completed out of', 10, 'loss:', 26.513012945652008) ('Epoch', 9, 'completed out of', 10, 'loss:', 26.513012945652008) ('Accuracy:', 0.60124224) 

другой:

 ('Epoch', 0, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 1, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 2, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 3, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 4, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 5, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 6, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 7, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 8, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 9, 'completed out of', 10, 'loss:', 22.873702049255371) ('Accuracy:', 1.0) 

и другой:

 ('Epoch', 0, 'completed out of', 10, 'loss:', 23.163824260234833) ('Epoch', 1, 'completed out of', 10, 'loss:', 22.88000351190567) ('Epoch', 2, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 3, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 4, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 5, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 6, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 7, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 8, 'completed out of', 10, 'loss:', 22.873702049255371) ('Epoch', 9, 'completed out of', 10, 'loss:', 22.873702049255371) ('Accuracy:', 0.99627328) 

Я также видел значение точности 0.0 -_-

—————РЕДАКТИРОВАТЬ—————

Некоторые сведения о данных и обработке данных. Я использую ежедневные данные о запасах для IBM от Yahoo! финансирование на 20-летний (почти) период. Это составляет примерно 5200 строк записей.

Вот как я его обрабатываю:

 import numpy as np import pandas as pd from sklearn.preprocessing import MinMaxScaler import csv import pickle def create_feature_sets_and_labels(test_size = 0.2): df = pd.read_csv("ibm.csv") df = df.iloc[::-1] features = df.values testing_size = int(test_size*len(features)) train_x = list(features[1:,1:6][:-testing_size]) train_y = list(features[1:,7][:-testing_size]) test_x = list(features[1:,1:6][-testing_size:]) test_y = list(features[1:,7][-testing_size:]) scaler = MinMaxScaler(feature_range=(-5,5)) train_x = scaler.fit_transform(train_x) train_y = scaler.fit_transform(train_y) test_x = scaler.fit_transform(test_x) test_y = scaler.fit_transform(test_y) return train_x, train_y, test_x, test_y if __name__ == "__main__": train_x, train_y, test_x, test_y = create_feature_sets_and_labels() with open('stockdata.pickle', 'wb') as f: pickle.dump([train_x, train_y, test_x, test_y], f) 

столбец 0 – дата. Таким образом, это не используется как функция. Также не колонка 7. Я нормализовал данные с помощью sklearn MinMaxScaler() в диапазоне от -5 до 5.

————- ИЗМЕНИТЬ 2 ——————-

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

  • Tensorflow Различные способы экспорта и запуска графика в C ++
  • Установка тензорного потока на Windows с помощью anaconda
  • Как создать пользовательскую функцию активации только с Python в Tensorflow?
  • Ошибка Tensorflow с использованием моих собственных данных
  • Tensorflow не показывает «Успешно открытые так называемые библиотеки CUDA локально»
  • Выбор из другой функции стоимости и функции активации нейронной сети
  • Преобразование из кадра данных Pandas в тензорный объект TensorFlow
  • Как определить, использует ли тензорный поток ускорение gpu изнутри оболочки python?
  • One Solution collect form web for “Изменение значения точности и отсутствие изменения значения потерь в двоичной классификации с использованием Tensorflow”

    Как только вы предварительно обработаете свои данные в неправильной форме или диапазоне в задаче обучения ML, остальная часть потока данных пойдет не так. Вы делаете это несколько раз по-разному в коде в вопросе.

    Принимая меры для того, чтобы произошла обработка. Первые проблемы связаны с предварительной обработкой. Ваши цели здесь должны быть:

    • Значения X (входные функции) в табличной форме, каждая строка является примером, каждый столбец является признаком. Значения должны быть численными и масштабированными для использования с нейронной сетью. Тестирование и подготовка данных необходимо масштабировать одинаково – это не означает использование одного и .fit_transform же .fit_transform потому что это повторно подходит для масштабирования.

    • Значения Y (выходные метки) в табличной форме, каждая строка соответствует примеру той же строки X, каждый столбец является истинным значением вывода. Для задач классификации значения обычно равны 0 и 1 и не должны повторно масштабироваться, поскольку они представляют собой членство в классе.

    Эта перезапись вашей функции create_feature_sets_and_labels делает все правильно:

     def create_feature_sets_and_labels(test_size = 0.2): df = pd.read_csv("ibm.csv") df = df.iloc[::-1] features = df.values testing_size = int(test_size*len(features)) train_x = np.array(features[1:,1:6][:-testing_size]).astype(np.float32) train_y = np.array(features[1:,7][:-testing_size]).reshape(-1, 1).astype(np.float32) test_x = np.array(features[1:,1:6][-testing_size:]).astype(np.float32) test_y = np.array(features[1:,7][-testing_size:]).reshape(-1, 1).astype(np.float32) scaler = MinMaxScaler(feature_range=(-5,5)) scaler.fit(train_x) train_x = scaler.transform(train_x) test_x = scaler.transform(test_x) return train_x, train_y, test_x, test_y 

    Важные отличия от вашей версии:

    • Использование np.array , а не list (незначительная разница)

    • y являются табличными [n_examples, n_outputs] (основное отличие, ваша форма вектора строки является причиной многих проблем позже)

    • Скалер подходит после применения к функциям (большая разница, если вы масштабируете поезд и данные теста отдельно, вы не предсказываете ничего значимого)

    • Scaler не применяется к выходам (большая разница для классификатора, вы хотите, чтобы данные поезда и теста были равны 0,1 для значимого обучения и точности отчетности)

    Есть также некоторые проблемы с вашим кодом обучения для этих данных:

    • y = tf.placeholder('float') должен быть y = tf.placeholder('float', [None, 1]) . Это не имеет никакого отношения к обработке, но корректно выдает ошибку, когда y – неправильная форма. Эта ошибка была бы ключом гораздо раньше, что все идет не так.

    • n_nodes_hl1 = 500 и n_nodes_hl2 = 500 могут быть намного ниже, и сеть будет работать намного лучше, например, n_nodes_hl1 = 10 и n_nodes_hl2 = 10 – это происходит из-за того, что вы используете большие начальные значения для весов, вы можете альтернативно масштабировать вес , и для более сложных данных вы, возможно, захотите это сделать. В этом случае проще уменьшить количество скрытых нейронов.

    • Как мы обсуждали в комментариях, начало вашей функции train_neural_network должно выглядеть следующим образом:

       output = neural_network_model(x) prediction = tf.sigmoid(output) cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(output, y)) optimizer = tf.train.AdamOptimizer().minimize(cost) 

      , , , это большая разница. Используя sigmoid_cross_entropy_with_logits вы взяли на себя обязательство использовать значение pre-transform выходного уровня для обучения. Но вы все равно хотите, чтобы предсказанные значения измеряли точность (или для любого другого использования сети, где вы хотите прочитать предсказанное значение).

    • Для последовательной оценки потерь вы хотите иметь среднюю потерю на один пример, поэтому вам нужно разделить сумму средних на партию по количеству партий: 'loss:', epoch_loss/(len(train_x)/batch_size)

    Если я сделаю все эти исправления и запустил это с еще несколькими эпохами – например, 50, то я получаю типичную потерю 0.7 и точность измерения 0.5 – и это происходит разумно надежно, но немного движется из-за изменений начальных весов , Точность не очень стабильна и, возможно, страдает от переполнения, которую вы вообще не допускаете (и вы должны прочитать о методах, чтобы помочь измерять и управлять перегрузкой, это важная часть обучения NN надежно)

    Значение 0.5 может показаться плохим. Это можно улучшить, изменив сетевую архитектуру или метапараметры. Я могу спуститься до 0.43 tf.nn.relu обучения и до 0.83 точности теста, например, путем обмена tf.nn.relu для tf.tanh в скрытых слоях и для 500 эпох.

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

    Python - лучший язык программирования в мире.