Python 为什么Tensorflow中的逻辑回归分类器没有学习?

Python 为什么Tensorflow中的逻辑回归分类器没有学习?,python,tensorflow,machine-learning,logistic-regression,Python,Tensorflow,Machine Learning,Logistic Regression,我正在学习Tensorflow,通过实现逻辑回归分类器对二进制MNIst数字数据集进行分类。我使用的是tensorflow 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_opti

我正在学习Tensorflow,通过实现逻辑回归分类器对二进制MNIst数字数据集进行分类。我使用的是tensorflow 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)]:
从这些形状中,我为输入定义了占位符,为权重定义了变量(我希望它们是正确的)

现在,我定义损失、优化器并计算类概率,如下所示

#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)
现在,我开始分离训练集和测试集

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)))
通过打印predict_函数(X_-train)或predict_函数(X_-test)的输出,我看到预测总是0。因此,有些事情我可能没有理解或做得不对。我错过了什么


编辑:我还尝试将学习率提高到0.1,并按照建议将迭代次数提高到50000次,损失很快变为零,但训练和测试AUC均为0.5,这意味着分类器仅预测一个类。我确信我的代码有问题,具体是什么?

这里有两个不同的错误:

predicted_y = tf.nn.softmax(logits)
probas=tf.argmax(predicted_y, axis=1)
第一个是,由于您的
y
不是一个热编码,因此您不应该使用
softmax
,而应该使用
sigmoid
(您在
丢失定义中正确地做了这件事);所以,第一行应该是

predicted_y = tf.nn.sigmoid(logits)
第二行,同样是因为你的
y
不是一个热编码的,它不会做你认为它会做的事情:因为你的预测是单元素数组,
argmax
根据定义是0,所以你不能得到从概率到硬预测的正确转换(在任何情况下,这些硬预测都不用于计算ROC——您需要这方面的概率)

您应该完全删除
probas
,并将
prediction\u函数更改为:

prediction_function=lambda vector1: predicted_y.eval({input_x:vector1})
这样,对于
learning\u rate=0.1
,AUC从第一次迭代开始变为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列车进行正确的预测:

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)

损失正在下降,尽管速度很慢。你可以尝试提高学习速度。更重要的是,5次迭代算不了什么,你需要更多的时间才能看到结果。开始尝试500次左右。@xdurch0我将学习速度提高到0.1次,迭代次数提高到5000次,但问题仍然存在。奇怪的是,损失最终变成了零st,但分类器一直在预测同一类的训练和测试数据。感谢您的帮助。auc分数函数的输入可能是错误的。据我理解,您应该提供概率(即
predicted_y
,softmax输出),但您提供的是“硬”类(softmax的argmax)@xdurch0问题已解决;)
prediction_function=lambda vector1: predicted_y.eval({input_x:vector1})
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
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)