Python 3.x TensorFlow:训练集和测试集的神经网络精度始终为100%

Python 3.x TensorFlow:训练集和测试集的神经网络精度始终为100%,python-3.x,machine-learning,tensorflow,neural-network,Python 3.x,Machine Learning,Tensorflow,Neural Network,我创建了一个TensorFlow神经网络,它有两个隐藏层,每个层有10个单元,使用ReLU激活和Xavier初始化权重。输出层有1个单元输出二进制分类(0或1),使用sigmoid激活功能根据输入特征分类是否相信泰坦尼克号上的乘客幸存 (省略的唯一代码是load_data函数,该函数填充程序后面使用的变量X_train、Y_train、X_test、Y_test) 参数 # Hyperparams learning_rate = 0.001 lay_dims = [10,10, 1] # O

我创建了一个TensorFlow神经网络,它有两个隐藏层,每个层有10个单元,使用ReLU激活和Xavier初始化权重。输出层有1个单元输出二进制分类(0或1),使用sigmoid激活功能根据输入特征分类是否相信泰坦尼克号上的乘客幸存

(省略的唯一代码是load_data函数,该函数填充程序后面使用的变量X_train、Y_train、X_test、Y_test)

参数

# Hyperparams 
learning_rate = 0.001
lay_dims = [10,10, 1]

# Other params
m = X_train.shape[1] 
n_x = X_train.shape[0]
n_y = Y_train.shape[0]
投入

X = tf.placeholder(tf.float32, shape=[X_train.shape[0], None], name="X")
norm = tf.nn.l2_normalize(X, 0) # normalize inputs

Y = tf.placeholder(tf.float32, shape=[Y_train.shape[0], None], name="Y")
初始化权重和偏差

W1 = tf.get_variable("W1", [lay_dims[0],n_x], initializer=tf.contrib.layers.xavier_initializer())
b1 = tf.get_variable("b1", [lay_dims[0],1], initializer=tf.zeros_initializer())

W2 = tf.get_variable("W2", [lay_dims[1],lay_dims[0]], initializer=tf.contrib.layers.xavier_initializer())
b2 = tf.get_variable("b2", [lay_dims[1],1], initializer=tf.zeros_initializer())

W3 = tf.get_variable("W3", [lay_dims[2],lay_dims[1]], initializer=tf.contrib.layers.xavier_initializer())
b3 = tf.get_variable("b3", [lay_dims[2],1], initializer=tf.zeros_initializer())
前支柱

Z1 = tf.add(tf.matmul(W1,X), b1)
A1 = tf.nn.relu(Z1)

Z2 = tf.add(tf.matmul(W2,A1), b2)
A2 = tf.nn.relu(Z2)

Y_hat = tf.add(tf.matmul(W3,A2), b3)
背撑

cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=tf.transpose(Y_hat), labels=tf.transpose(Y)))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
会议

# Initialize
init = tf.global_variables_initializer()

with tf.Session() as sess:
    # Initialize
    sess.run(init)

    # Normalize Inputs
    sess.run(norm, feed_dict={X:X_train, Y:Y_train})

    # Forward/Backprob and update weights
    for i in range(10000):
        c, _ = sess.run([cost, optimizer], feed_dict={X:X_train, Y:Y_train})
        if i % 100 == 0:
            print(c)

    correct_prediction = tf.equal(tf.argmax(Y_hat), tf.argmax(Y))

    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

    print("Training Set:", sess.run(accuracy, feed_dict={X: X_train, Y: Y_train}))
    print("Testing Set:", sess.run(accuracy, feed_dict={X: X_test, Y: Y_test}))
在运行10000次训练后,每次的成本都会下降,这表明学习率正常,成本函数正常。但是,在训练后,我的所有Y_hat值(训练集上的预测)都是1(预测乘客幸存)。因此,基本上,对于每个训练示例,预测只输出y=1

另外,当我在Y_hat上运行tf.argmax时,结果是所有0的矩阵。当tf.argmax应用于Y(地面真值标签)时也会发生同样的情况,这是奇怪的,因为Y包含训练示例的所有正确标签

非常感谢您的帮助。谢谢。

我假设您的Y_hat是一个(1,m)矩阵,m是培训示例的数量。然后
tf.argmax(Y\u hat)
将给出所有0。根据tensorflow文档,argmax

返回在张量轴上具有最大值的索引


如果未传入轴,则轴设置为0。因为轴0只有一个值,所以返回的索引始终变为0

我知道我迟到了,但我也要指出,因为你的标签矩阵是形状(n,1),也就是说,只有一个类可以预测,因此,交叉熵没有意义。在这种情况下,您应该使用不同的方法来计算成本(可能是均方误差或类似的方法)。
我最近在做我的大学项目时遇到了类似的问题,我找到了一个解决办法,我把这个二进制输出分成了两个类,比如现在和缺席,所以如果它是现在的,它就是[1,0]。我知道这不是最好的方法,但当您需要立即工作时,它会很有帮助。

我不明白“似乎我训练模型的时间越长,我所有来自Y_hat的数据都是1或接近1,我所有Y_hat和Y上的argmax值(基本真理标签为0或1)都显示为0。”这个句子很令人困惑。你能换个说法吗?刚刚编辑好。这样更好吗?这帮了大忙。我认为我对argmax的使用是我在网上发现的每一个精确性示例的产物,这些示例被用来评估使用各种“one_hot”标签的网络。这些示例通常使用tf.argmax(foo,1)给出在一个热向量中选择的标签。您当时可能使用了分类交叉熵损失。二元交叉熵可以很好地解决二元分类问题