【问题标题】:Getting loss value as 0 when training a neural network训练神经网络时将损失值设为 0
【发布时间】:2018-05-30 03:56:54
【问题描述】:

我不确定是否应该粘贴整个代码,但这里是:

import tensorflow as tf 
import numpy as np  
import requests 
from sklearn.model_selection import train_test_split

BATCH_SIZE = 20


#Get data
birthdata_url = 'http://springer.bme.gatech.edu/Ch17.Logistic/Logisticdat/lowbwt.dat'
birth_file = requests.get(birthdata_url)
birth_data = birth_file.text.split('\r\n')[5:]
birth_data = np.array([[x for x in y.split(' ') if len(x)>=1] for y in birth_data[1:] if len(y)>=1])

#Get x and y vals
y_vals = np.array([x[1] for x in birth_data]).reshape((-1,1))
x_vals = np.array([x[2:10] for x in birth_data])

#Split data
x_train, x_test, y_train, y_test = train_test_split(x_vals,y_vals,test_size=0.3)


#Placeholders
x_data = tf.placeholder(dtype=tf.float32,shape=[None,8])
y_data = tf.placeholder(dtype=tf.float32,shape=[None,1])


#Define our Neural Network

def init_weight(shape):
    return tf.Variable(tf.truncated_normal(shape=shape,stddev=0.1))

def init_bias(shape):
    return tf.Variable(tf.constant(0.1,shape=shape))

def fully_connected(inp_layer,weights,biases):
    return tf.nn.relu(tf.matmul(inp_layer,weights)+biases)

def nn(x):
    w1 = init_weight([8,25])
    b1 = init_bias([25])
    layer1 = fully_connected(x,w1,b1)

    w2 = init_weight([25,10])
    b2 = init_bias([10])
    layer2 = fully_connected(layer1,w2,b2)

    w3 = init_weight([10,3])
    b3 = init_bias([3])
    layer3 = fully_connected(layer2,w3,b3)

    w4 = init_weight([3,1])
    b4 = init_bias([1])
    final_output = fully_connected(layer3,w4,b4)


    return final_output




#Predicted values.
y_ = nn(x_data)


#Loss and training step.
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_data,logits=y_))
train_step = tf.train.AdamOptimizer(0.1).minimize(loss)

#Initalize session and global variables
sess = tf.Session()
sess.run(tf.global_variables_initializer())

#Accuracy
def get_accuracy(logits,labels):
    batch_predicitons = np.argmax(logits,axis=1)
    num_correct = np.sum(np.equal(batch_predicitons,labels))
    return(100*num_correct/batch_predicitons.shape[0])



loss_vec = []
for i in range(500):
    #Get random indexes and create batches. 
    rand_index = np.random.choice(len(x_train),size=BATCH_SIZE)

    #x and y batch.
    rand_x = x_train[rand_index]
    rand_y = y_train[rand_index]

    #Run the training step.
    sess.run(train_step,feed_dict={x_data:rand_x,y_data:rand_y})

    #Get the current loss. 
    temp_loss = sess.run(loss,feed_dict={x_data:x_test,y_data:y_test})
    loss_vec.append(temp_loss)

    if(i+1)%20==0:
        print("Current Step is: {}, Loss: {}"
            .format((i+1),
            temp_loss))

    #print("-----Test Accuracy: {}-----".format(get_accuracy(logits=sess.run(y_,feed_dict={x_data:x_test}),labels=y_test)))

当我运行我的程序时,我总是在训练时将损失值设为 0。我不确定问题可能出在哪里。但我有几个想法。

1)这可能是我创建批量数据的方式吗?这似乎是一种不寻常的方式,但就我而言,它应该通过获取 rand_index = np.random.choice(len(x_train),size=BATCH_SIZE) 中的随机索引来工作。

2)这没有意义,但可能是因为数据是“小数据”吗?

3) 代码中有任何简单的错误吗?

4)或者我真的有损失为0。(这是最不可能的情况)

如果您能在上面的代码中另外指出我应该避免做什么,我会非常高兴。

谢谢。

【问题讨论】:

  • 我没有立即看出哪里出了问题,但您为什么不打印出预测以帮助调试。至少这样你可以仔细检查损失的计算。
  • @Aaron 我的形状为零 (20,1) 有趣...
  • 我要调试的另一件事是删除一些隐藏层以使网络更简单。
  • 另外你不应该在最后一层有relu。
  • 因为您已经在使用 softmax 作为输出的非线性。

标签: python tensorflow neural-network loss


【解决方案1】:

我运行了你的代码,这些是我发现的错误。

  1. 看起来您的输入数据是字符串。您应该将其转换为浮点数。
  2. 不要在最后一层使用 relu。它应该直接输入到损失函数中,没有非线性。
  3. 您应该使用sigmoid_cross_entropy_with_logits 函数而不是softmax 函数。 Sigmoid 用于二分类,softmax 用于多类分类。
  4. 您的学习率可能太高。我会试试低一点的。

【讨论】:

  • 感谢您指出错误。它有很大帮助。现在我知道熵函数的选择有多重要了。
  • 我已经多次进行了调整。但我还是失败了。你能得到一个合法的结果吗?在每个训练步骤中,我总是获得 100% 的准确率。
  • 啊,我明白了。现在我可以看到我的错误了。非常感谢您的努力和帮助!我可以再问一个问题。训练完成后,NN 不应该返回 0 或 1 吗?因为它返回的值范围从 -3 到 1。对此有什么想法吗?再次感谢十亿
  • 您可以从 y_ 获取输出,如果它小于 0,则认为它是 0,如果大于零,则认为它是 1。或者,您可以计算 probs = tf .sigmoid(y_) 然后你会得到属于正类的估计概率。
猜你喜欢
  • 2021-12-12
  • 2020-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
  • 2020-06-07
相关资源
最近更新 更多