Почему мой классификатор регрессии logisti c в Tensorflow не изучает? - PullRequest
1 голос
/ 08 апреля 2020

Я изучаю Tensorflow, внедряя классификатор регрессии logisti c для классификации двоичного набора данных MNIst di git. Я использую tenorflow 1.13, поскольку приведенный ниже код показывает

import tensorflow as tf
gpu_options = tf.GPUOptions(allow_growth=True, per_process_gpu_memory_fraction=0.1)
s = tf.InteractiveSession(config=tf.ConfigProto(gpu_options=gpu_options))
print("We're using TF", tf.__version__)

Набор данных выглядит следующим образом:

from sklearn.datasets import load_digits
mnist = load_digits(2)

X,y = mnist.data, mnist.target

Следующий набор данных имеет следующие формы

>> print("y [shape - %s]:" % (str(y.shape)), y[:10])
y [shape - (360,)]: [0 1 0 1 0 1 0 0 1 1]

>> print("X [shape - %s]:" % (str(X.shape)))
X [shape - (360, 64)]:

Из этих фигур я определил заполнители для входных данных и переменную для весов (надеюсь, они правильные)

weights = tf.Variable(tf.zeros([X.shape[1],1]), name="weights")
input_x = tf.placeholder('float32', shape=[None, X.shape[1]], name="input_x")
input_y = tf.placeholder('float32', shape=[None, 1], name="input_y")

Теперь я определяю потери, оптимизатор и вычисляю вероятности класса, как показано ниже

#predicted_y = <predicted probabilities for input_X>
logits = tf.matmul(input_x, weights)
predicted_y = tf.nn.softmax(logits)
probas=tf.argmax(predicted_y, axis=1)

#loss = <logistic loss (scalar, mean over sample)>
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=input_y))

#optimizer = <optimizer that minimizes loss>
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.0001).minimize(loss)

Затем я создаю функцию для вызова вычисления класса из вероятностей

predict_function=lambda vector1: probas.eval({input_x:vector1})

Теперь я начинаю разделять обучающие и тестовые наборы

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y)

Наконец, я обучать и тестировать для каждой итерации

from sklearn.metrics import roc_auc_score

y_train_reshaped=np.reshape(y_train, (y_train.shape[0], 1))
s.run(tf.global_variables_initializer())

for i in range(5):

    #<run optimizer operation>
    s.run(optimizer, feed_dict={input_x:X_train,input_y:y_train_reshaped})

    #loss_i = <compute loss at iteration i>
    loss_i = loss.eval({input_x:X_train, input_y:y_train_reshaped})

    print("loss at iter %i:%.4f" % (i, loss_i))

    #My problem starts here
    print("train auc:",roc_auc_score(y_train, predict_function(X_train)))
    print("test auc:",roc_auc_score(y_test, predict_function(X_test)))

Моя проблема с приведенным выше кодом состоит в том, что, хотя я вижу, что потери уменьшаются на каждой итерации, RO C metri c остается тем же. Выходные данные этого l oop выглядят следующим образом:

loss at iter 0:0.6820
train auc: 0.5
test auc: 0.5
loss at iter 1:0.6712
train auc: 0.5
test auc: 0.5
loss at iter 2:0.6606
train auc: 0.5
test auc: 0.5
loss at iter 3:0.6503
train auc: 0.5
test auc: 0.5
loss at iter 4:0.6403
train auc: 0.5
test auc: 0.5

Распечатав выходные данные функцииgnast_function (X_train) или Forex_Function (X_test), я вижу, что прогноз всегда равен 0. Следовательно, существует что-то, что я могу не понимать или делать неправильно. Чего мне здесь не хватает?

РЕДАКТИРОВАТЬ: Я также пытался увеличить скорость обучения до 0,1 и количество итераций до 50000, как и предполагалось, потери очень быстро обнуляются, но оба тренируются и тест AU C равен 0,5, что означает, что классификатор предсказывает только один класс. Я уверен, что что-то не так с моим кодом, что именно это будет?

1 Ответ

1 голос
/ 08 апреля 2020

Здесь есть две разные ошибки:

predicted_y = tf.nn.softmax(logits)
probas=tf.argmax(predicted_y, axis=1)

Первая состоит в том, что, поскольку ваш y не закодирован как горячий код, вы не должны использовать softmax, но sigmoid (что-то вы правильно делаете в своем loss определении); Итак, первая строка должна быть

predicted_y = tf.nn.sigmoid(logits)

Вторая строка, опять же, поскольку ваш y не кодируется в одноразовом формате, не выполняет то, что вы думаете, так как ваши предсказания являются одноэлементными массивами argmax по определению 0, поэтому вы не получите правильное преобразование вероятностей в сложные прогнозы (какие жесткие прогнозы в любом случае не используются для расчета RO C - для этого вам нужны вероятности) .

Вы должны сбросить probas в целом и изменить свой prediction_function на:

prediction_function=lambda vector1: predicted_y.eval({input_x:vector1})

Таким образом, а для learning_rate=0.1 AU C перейдет в 1.0 от самая первая итерация:

loss at iter 0:0.0085
train auc: 0.9998902365402557
test auc: 1.0
loss at iter 1:0.0066
train auc: 1.0
test auc: 1.0
loss at iter 2:0.0052
train auc: 1.0
test auc: 1.0
loss at iter 3:0.0042
train auc: 1.0
test auc: 1.0
loss at iter 4:0.0035
train auc: 1.0
test auc: 1.0

и вы получите правильные прогнозы для X_train:

np.round(prediction_function(X_train)).reshape(1,-1)
# result:
array([[0., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1., 1.,
        1., 1., 0., 0., 1., 0., 0., 0., 0., 0., 0., 1., 0., 1., 0., 0.,
        1., 1., 0., 1., 1., 0., 0., 0., 0., 1., 1., 0., 0., 1., 0., 0.,
        1., 1., 0., 0., 1., 1., 1., 0., 0., 1., 0., 1., 0., 0., 0., 1.,
        0., 1., 1., 1., 0., 1., 0., 1., 0., 0., 1., 0., 1., 1., 1., 1.,
        0., 0., 1., 1., 0., 1., 1., 0., 1., 0., 0., 0., 1., 0., 1., 1.,
        0., 1., 1., 0., 1., 1., 1., 1., 0., 1., 0., 1., 0., 1., 1., 1.,
        1., 0., 0., 1., 0., 0., 1., 0., 1., 0., 0., 0., 1., 1., 0., 0.,
        0., 0., 0., 1., 0., 1., 1., 1., 1., 1., 0., 0., 0., 1., 1., 1.,
        0., 0., 0., 1., 1., 1., 1., 0., 0., 1., 1., 0., 1., 1., 1., 0.,
        1., 1., 0., 1., 1., 1., 0., 1., 0., 1., 1., 0., 0., 1., 1., 0.,
        1., 1., 1., 1., 0., 0., 1., 1., 0., 0., 0., 0., 1., 1., 0., 0.,
        0., 0., 1., 0., 0., 1., 1., 0., 1., 0., 0., 1., 1., 0., 0., 1.,
        1., 0., 0., 1., 0., 1., 0., 1., 0., 0., 0., 0., 0., 0., 0., 1.,
        1., 0., 1., 1., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0.,
        1., 1., 1., 1., 0., 0., 0., 1., 1., 1., 1., 0., 0., 0., 1., 1.,
        0., 1., 1., 0., 1., 0., 1., 0., 0., 0., 1., 0., 0., 1.]],
      dtype=float32)
...