Как читать CSV-файл и обучать данные с помощью регрессии Softmax в Tensorflow

Я только начинаю изучать Tensorflow, и у меня есть одна проблема при обучении данных. Моя проблема заключается в чтении CSV-файла, а затем использовании классификации softmax для оценки оценки учащегося (A, B или C) на основе их времени обучения и посещаемости класса.

Оценка учащегося

Я определяю, а затем загружаю CSV-файл как

COLUMNS = ["studytime", "attendance", "A", "B", "C"]
FEATURES = ["studytime", "attendance"]
LABEL = ["A", "B", "C"]
training_set = pd.read_csv("hw1.csv", skipinitialspace=True,
                       skiprows=1, names=COLUMNS)

После этого я определяю тензор для функций и маркировки, как это

feature_cols = [tf.contrib.layers.real_valued_column(k) for k in FEATURES]
labels = [tf.contrib.layers.real_valued_column(k) for k in LABEL]

Затем я следую способу обучения softmax с данными MNIST по адресу Tensorflow для MNIST

Но я не знаю, как определить batch_xs и batch_ys для обучения этому циклу.

for _ in range(1000):
batch_xs=????
batch_ys=????
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

и Как я могу определить функцию для оценки оценки трех студентов, если их время обучения и посещаемости, например, [11,7], [3,4],[1,0]

Не могли бы вы помочь мне разобраться с этой проблемой?

Заранее спасибо,


person Chuong Nguyen    schedule 13.05.2017    source источник


Ответы (2)


Похоже, вы читаете свой CSV в DataFrame? Конечно, вы можете реализовать пакетный процесс вручную, но в TF есть эффективный встроенный способ создания очередей и пакетов. Это немного запутанно, но хорошо работает для обслуживания строк как последовательно, так и случайным образом, что довольно удобно. Просто убедитесь, что все ваши строки имеют одинаковую длину, и таким образом вы можете легко указать, какие продажи представляют X, а какие Y.

Для этого вам понадобятся две функции: tf.decode_csv и tf.train.shuffle_batch (или tf.train.batch, если вам не нужна случайная перетасовка).

Мы подробно обсудили это в этом посте, который включает в себя полный пример рабочего кода: data/42373487?noredirect=1#comment71990719_42373487">Пример пакетной обработки TF CSV

Похоже, что все ваши данные являются числовыми, а Y в формате one-hot, поэтому пример MNIST должен подойти для реализации вашей функции оценки.

*** ОБНОВЛЕНИЕ. Вот примерный порядок операций: 1. определить две функции, как показано в связанном примере — одну для чтения CSV-файла построчно, а другую — для упаковки каждой из этих строк в пакеты N (случайно или последовательно) 2. запустить цикл чтения с помощью while not coord.should_stop(): этот цикл будет работать до тех пор, пока он не исчерпает содержимое всех ваших CSV-файлов, которые вы загружаете в очереди 3. В каждой итерации цикла, выполняя sess.run в этих переменных дает вам ваши пакеты X и Y, а также любое дополнительное содержимое метатипа, которое вы можете захотеть от каждой строки вашего файла CSV, например, метку даты в этом примере (в вашем случае это может быть имя студента или что-то еще :

dateLbl_batch, feature_batch, label_batch = sess.run([dateLbl, features, labels])   

Когда TF достигает конца вашего файла (файлов), он выдает исключение, поэтому весь приведенный выше код находится в блоке try/catch — поймав это исключение, вы знаете, что все готово.

Вышеупомянутая функциональность дает вам очень детальный доступ к вашим CSV-файлам на уровне ячеек и позволяет вам группировать их в пакеты по N, в нужное вам количество эпох и т. д.

***** ОБНОВЛЕНИЕ 2**

Вот полный код, который должен считывать ваш CSV-файл партиями в том формате, который у вас есть. Он просто печатает содержимое каждой партии. Отсюда вы можете легко связать этот код с вашим кодом, который фактически выполняет обучение и т. д.

import tensorflow as tf

fileName = 'data/study.csv'

try_epochs = 1
batch_size = 3

S = 1 # this is your Student label
F = 2 # this is the list of your features
L = 3 # this is one-hot vector of 3 representing the label

# set defaults to something (TF requires defaults for the number of cells you are going to read)
rDefaults = [['a'] for row in range((S+F+L))]

# function that reads the input file, line-by-line
def read_from_csv(filename_queue):
    reader = tf.TextLineReader(skip_header_lines=True) # skipt the header line
    _, csv_row = reader.read(filename_queue) # read one line
    data = tf.decode_csv(csv_row, record_defaults=rDefaults) # use defaults for this line (in case of missing data)
    studentLbl = tf.slice(data, [0], [S]) # first cell is my 'date-label' for internal pruposes
    features = tf.string_to_number(tf.slice(data, [S], [F]), tf.float32) # cells 2-480 is the list of features
    label = tf.string_to_number(tf.slice(data, [S+F], [L]), tf.float32) # the remainin 3 cells is the list for one-hot label
    return studentLbl, features, label

# function that packs each read line into batches of specified size
def input_pipeline(fName, batch_size, num_epochs=None):
    filename_queue = tf.train.string_input_producer(
        [fName],
        num_epochs=num_epochs,
        shuffle=True)  # this refers to multiple files, not line items within files
    dateLbl, features, label = read_from_csv(filename_queue)
    min_after_dequeue = 10000 # min of where to start loading into memory
    capacity = min_after_dequeue + 3 * batch_size # max of how much to load into memory
    # this packs the above lines into a batch of size you specify:
    dateLbl_batch, feature_batch, label_batch = tf.train.shuffle_batch(
        [dateLbl, features, label],
        batch_size=batch_size,
        capacity=capacity,
        min_after_dequeue=min_after_dequeue)
    return dateLbl_batch, feature_batch, label_batch

# these are the student label, features, and label:
studentLbl, features, labels = input_pipeline(fileName, batch_size, try_epochs)

with tf.Session() as sess:

    gInit = tf.global_variables_initializer().run()
    lInit = tf.local_variables_initializer().run()

    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(coord=coord)

    try:
        while not coord.should_stop():
            # load student-label, features, and label as a batch:
            studentLbl_batch, feature_batch, label_batch = sess.run([studentLbl, features, labels])

            print(studentLbl_batch);
            print(feature_batch);
            print(label_batch);
            print('----------');

    except tf.errors.OutOfRangeError:
        print("Done looping through the file")

    finally:
        coord.request_stop()

    coord.join(threads)

Предположим, что ваш CSV-файл выглядит примерно так:

name    studytime   attendance  A   B   C
S1  2   1   0   1   0
S2  3   2   1   0   0
S3  4   3   0   0   1
S4  3   5   0   0   1
S5  4   4   0   1   0
S6  2   1   1   0   0

Приведенный выше код должен вывести следующий вывод:

[[b'S5']
 [b'S6']
 [b'S3']]
[[ 4.  4.]
 [ 2.  1.]
 [ 4.  3.]]
[[ 0.  1.  0.]
 [ 1.  0.  0.]
 [ 0.  0.  1.]]
----------
[[b'S2']
 [b'S1']
 [b'S4']]
[[ 3.  2.]
 [ 2.  1.]
 [ 3.  5.]]
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]
----------
Done looping through the file

Таким образом, вместо того, чтобы печатать содержимое пакетов, просто используйте их как X и Y для обучения в feed_dict

person VS_FF    schedule 13.05.2017
comment
Спасибо за ваше предложение, мистер VS_FF. Я только что прочитал вышеупомянутый пост, о котором вы упомянули, я понимаю некоторые основные моменты, но на самом деле это кажется мне сложным. В моем вопросе вы сказали, что мне нужно использовать tf.train. batch, но я все еще не понимаю, как его можно применить для определения batch_xs и batch_ys? Не могли бы вы показать мне более четко. Потому что в MNIST они использовали код mnist.train.next_batch(), но в моей задаче я не знаю, как его переделать для моего случая. - person Chuong Nguyen; 13.05.2017
comment
Я обновил исходный ответ, чтобы дать вам представление о том, что делают части этого кода. В примере с MNIST они делают это по-разному, но я нахожу этот подход удобным, когда речь идет конкретно о чтении CSV-файлов, особенно для рандомизированных пакетов, и особенно если у вас есть несколько CSV-файлов, которые вы хотите перетасовать вместе. - person VS_FF; 13.05.2017
comment
Г-н VS_FF: Спасибо за ваше сообщение. Я только что прочитал приведенный выше код, который вы упомянули. Конечно, я запускаю его напрямую, только меняя имя файла и ставя TS = 2. Однако в моем случае ваш код не работал для чтения файла csv. Я обнаружил, что ваш код работает хорошо, пока я не дойду до последней строки: coord.join(threads). Некоторые из этих ошибок, например: StringToNumberOp не может правильно преобразовать строку. Не могли бы вы помочь мне разобраться? - person Chuong Nguyen; 14.05.2017
comment
Одна вещь, упомянутая в этой заметке, заключается в том, что в моем случае каждая строка содержит как строки, так и числа. Поскольку вам необходимо предоставить значения по умолчанию для каждой ячейки в каждой строке, чтобы TF мог прочитать строку, проще предоставить значения по умолчанию в виде строк, а затем преобразовать необходимые ячейки в числа. Безусловно, это не будет работать наоборот (т. Е. Если вы предоставляете значения по умолчанию как числа с плавающей запятой, но имеете несколько строковых ячеек, TF выдаст ошибку). Поэтому, если все ваши данные числовые, вы можете пропустить всю эту логику и просто прочитать их как числа с плавающей запятой или целые числа. - person VS_FF; 14.05.2017
comment
Но что касается вашей ошибки, я подозреваю, что вы либо получаете ее, потому что достигаете какого-то EOF, либо, возможно, у вас есть некоторые символы, которые он не распознает, или, может быть, это проблема с кодировкой. Как я уже сказал, этот процесс немного груб, потому что он сигнализирует EOF как исключение, которое вы должны обработать. Может что-то с этим связано? Трудно сказать, не зная содержимого вашего CSV - person VS_FF; 14.05.2017
comment
Мистер VS_FF. Спасибо за Ваш ответ. Вот ссылка на мой CSV: i.stack.imgur.com/93kQh.png Он содержит строку в качестве имени ученика для каждой строки. - person Chuong Nguyen; 14.05.2017
comment
Я обновил свой первоначальный ответ полным кодом, который должен запускать ваш CSV-файл партиями и печатать их содержимое, включая ярлык ученика. Я подозреваю, что единственная проблема, которая у вас возникла с исходным кодом в связанном ответе, заключается в том, что при чтении CSV-файла не предполагалось строки заголовка (как было указано в комментарии), тогда как здесь у вас есть строка заголовка в вашем CSV-файле. Поэтому я изменил код, чтобы сказать skip_header_lines=True. Я воспроизвел содержимое вашего CSV, и код работает хорошо. - person VS_FF; 14.05.2017
comment
Еще одна вещь на всякий случай: в прошлом я замечал, что у TF есть проблема с чтением CSV-файлов, которые были изменены/сохранены в Excel. Я не знаю, является ли это проблемой с Excel или TF, но у меня есть простой обходной путь: просто загрузить CSV в Pandas DataFrame, а затем повторно сбросить его в другой CSV. Форма есть, ТФ читает нормально. Так что будьте осторожны, если вы редактируете файлы CSV в Excel. - person VS_FF; 14.05.2017
comment
@ Mr.VS_FF: Спасибо за ваш ответ, теперь код работает очень хорошо, это здорово. Однако у меня возникает проблема, что точность теперь очень низкая 37,5%, используя код: print(sess.run(accuracy, feed_dict={x: feature_batch, y_: label_batch})), я не знаю, почему точность такая низкая. Не могли бы вы помочь мне разобраться? - person Chuong Nguyen; 14.05.2017
comment
Просто чтобы убедиться, вы также используете sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})? Выполнение sess.run только с точностью не приведет к автоматическому выполнению вашего train_step. Кроме того, имейте в виду, что выполнение sess.run дважды, один раз для train_step и один раз для точности, приведет к двойному чтению из ваших очередей, поэтому ваши данные будут потрачены впустую. Лучше всего было бы одновременно выполнять sess.run как для train_step, так и для точности и продолжать следить за тем, как ваша точность меняется с течением времени. Что-то вроде tp, acc = sess.run([train_step, точность], feed_dict={x: feature_batch, y_: label_batch}), а затем print(acc). - person VS_FF; 14.05.2017
comment
Если ваша точность не улучшается с течением времени, вам просто нужно подумать о том, действительно ли ваши данные подходят для проблемы/и т. д. Нет никакой магии. Обязательно используйте Tensorboard, чтобы следить за тем, как ваша точность, потери и т. д. ведут себя с течением времени, и запуская различные попытки с разными гиперпараметрами (тип оптимизатора, скорость обучения, отсев, количество эпох, размер пакета и т. д.). это очень полезно - person VS_FF; 14.05.2017
comment
@Mr.VS_FF: Спасибо за ответ. Я делаю sess.run дважды, как вы сказали, и меняю с разной скоростью обучения, но результат не улучшается. Я просто размещаю свой код в следующем. Не могли бы вы помочь мне показать, где я не прав? - person Chuong Nguyen; 15.05.2017
comment
Насколько велик ваш набор данных? Можно ссылку на полные данные? Попробую попробовать.... - person VS_FF; 15.05.2017
comment
@@ Mr.VS_FF: Большое спасибо. Вот мои тренировочные данные. Это небольшой размер:. данные для обучения - person Chuong Nguyen; 15.05.2017
comment
Весь смысл этого упражнения в том, чтобы иметь тысячи или, лучше, сотни тысяч наблюдений для обучения вашей модели. На нескольких наблюдениях далеко не уедешь. Проблема в том, что даже если вы получите точность ~ 100% (что вы легко можете сделать с правильным количеством весов/и т. д.), ваша сеть будет просто отлично запоминать данные, что сделает ее бесполезной для данных, которых у нее нет. видно, независимо от точности. - person VS_FF; 15.05.2017
comment
Получите как минимум ›1000 наблюдений, прежде чем что-либо пробовать - person VS_FF; 15.05.2017
comment
@ Mr.VS_FF: Большое спасибо, мне удалось обучить данные, как вы предлагаете. Я не могу сделать это без вашей помощи. Это большая помощь для моего начала в TF. - person Chuong Nguyen; 16.05.2017
comment
@ Mr.VS_FF: Я просто более глубоко думаю о том, как работает Softmax, и пытаюсь найти следующий код: correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) print(sess.run(correct_prediction, feed_dict={x: feature_batch, y_: label_batch})). И результат [ True True False False True True True True]. Я много думаю, но не могу объяснить, почему в результате 8 записей. Не могли бы вы помочь мне разобраться? - person Chuong Nguyen; 16.05.2017
comment
У вас есть 8 наблюдений в вашем наборе данных. tf.argmax с y дает вам индекс горячего вектора, который включен в прогнозе. tf.argmax с y_ дает вам индекс горячего вектора, который находится в фактической метке. Затем tf.equal сравнивает, для каких из ваших 8 записей сравнение верно, а для каких нет. Итак, у вас есть 8 значений true/false. Это то, что вы спрашивали? - person VS_FF; 16.05.2017
comment
Еще раз, я действительно не обращал бы слишком много внимания на этот результат. Это бессмысленно только с 8 наблюдениями. Вы должны выполнять этот же шаг на тысячах наблюдений, чтобы ваши веса и смещения корректировались с каждым прогоном. Только после этого ваши прогнозы (будем надеяться) начнут обретать какой-либо смысл. На этом этапе вы получаете свои истинные/ложные результаты либо случайно (поскольку ваши веса и смещения инициализируются случайным образом), либо просто потому, что у вас достаточно параметров (количество весов/смещений), чтобы просто запомнить, какая комбинация дает лучший результат. - person VS_FF; 16.05.2017
comment
Каким бы точным он ни был, он бесполезен, потому что не сможет обобщить данные, которых не видел. Как я уже говорил ранее, сделайте несколько тысяч наблюдений и только потом возвращайтесь к этой проблеме. - person VS_FF; 16.05.2017

Вот моя попытка. Но точность не высока, как я ожидаю.

import tensorflow as tf

fileName = 'hw1.csv'

try_epochs = 1
batch_size = 8

S = 1 # this is your Student label
F = 2 # this is the list of your features
L = 3 # this is one-hot vector of 3 representing the label

# set defaults to something (TF requires defaults for the number of cells you are going to read)
rDefaults = [['a'] for row in range((S+F+L))]

# function that reads the input file, line-by-line
def read_from_csv(filename_queue):
     reader = tf.TextLineReader(skip_header_lines=True) # skipt the header line
     _, csv_row = reader.read(filename_queue) # read one line
     data = tf.decode_csv(csv_row, record_defaults=rDefaults) # use defaults for this line (in case of missing data)
     studentLbl = tf.slice(data, [0], [S]) # first cell is my 'date-label' for internal pruposes
     features = tf.string_to_number(tf.slice(data, [S], [F]), tf.float32) # cells 2-480 is the list of features
     label = tf.string_to_number(tf.slice(data, [S+F], [L]), tf.float32) # the remainin 3 cells is the list for one-hot label
     return studentLbl, features, label

# function that packs each read line into batches of specified size
def input_pipeline(fName, batch_size, num_epochs=None):
    filename_queue = tf.train.string_input_producer(
       [fName],
       num_epochs=num_epochs,
       shuffle=True)  # this refers to multiple files, not line items within files
    dateLbl, features, label = read_from_csv(filename_queue)
    min_after_dequeue = 10000 # min of where to start loading into memory
    capacity = min_after_dequeue + 3 * batch_size # max of how much to load into memory
    # this packs the above lines into a batch of size you specify:
    dateLbl_batch, feature_batch, label_batch = tf.train.shuffle_batch(
       [dateLbl, features, label],
       batch_size=batch_size,
       capacity=capacity,
       min_after_dequeue=min_after_dequeue)
    return dateLbl_batch, feature_batch, label_batch

# these are the student label, features, and label:
studentLbl, features, labels = input_pipeline(fileName, batch_size, 
 try_epochs)

x = tf.placeholder(tf.float32, [None, 2])

W = tf.Variable(tf.zeros([2, 3]))

b = tf.Variable(tf.zeros([3]))

y = tf.nn.softmax(tf.matmul(x, W) + b)

y_ = tf.placeholder(tf.float32, [None, 3])

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

train_step = tf.train.GradientDescentOptimizer(0.1).minimize(cross_entropy)


sess = tf.InteractiveSession()

tf.global_variables_initializer().run()


with tf.Session() as sess:

   gInit = tf.global_variables_initializer().run()
   lInit = tf.local_variables_initializer().run()

   coord = tf.train.Coordinator()
   threads = tf.train.start_queue_runners(coord=coord)

   try:
      while not coord.should_stop():
        # load student-label, features, and label as a batch:
        studentLbl_batch, feature_batch, label_batch = sess.run([studentLbl, features, labels])

        print(studentLbl_batch);
        print(feature_batch);
        print(label_batch);
        print('----------');
        batch_xs = feature_batch
        batch_ys = label_batch
        sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})  # feeding data

  except tf.errors.OutOfRangeError:
     print("Done looping through the file")

  finally:
     coord.request_stop()

  coord.join(threads)


  correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

  accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

  print(sess.run(accuracy, feed_dict={x: feature_batch, y_: label_batch}))

  print(sess.run(W))
  print(sess.run(b))

Точность

  0.375

W,b

    [[ 0.00555556  0.00972222 -0.01527778] [ 0.00555556  0.01388889 -0.01944444]]
    [-0.00277778  0.00138889  0.00138889]
person Chuong Nguyen    schedule 14.05.2017