使用Tensorflow的神经网络不会更新权重/偏差

时间:2019-03-18 03:31:39

标签: python tensorflow neural-network

问题

我正在尝试将一些64x64图像归类为黑匣子练习。我写的神经网络不会改变我的体重。第一次编写类似这样的代码,但是在 MNIST 字母输入上可以正常工作,但是在此代码上,它不会像应该这样训练:

import tensorflow as tf
import numpy as np


path = ""

# x is a holder for the 64x64 image
x = tf.placeholder(tf.float32, shape=[None, 4096])

# y_ is a 1 element vector, containing the predicted probability of the label
y_ = tf.placeholder(tf.float32, [None, 1])

# define weights and balances
W = tf.Variable(tf.zeros([4096, 1]))
b = tf.Variable(tf.zeros([1]))

# define our model
y = tf.nn.softmax(tf.matmul(x, W) + b)

# loss is cross entropy
cross_entropy = tf.reduce_mean(
                tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))

# each training step in gradient decent we want to minimize cross entropy
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

train_labels = np.reshape(np.genfromtxt(path + "train_labels.csv", delimiter=',', skip_header=1), (14999, 1))
train_data = np.genfromtxt(path + "train_samples.csv", delimiter=',', skip_header=1)

# perform 150 training steps with each taking 100 train data
for i in range(0, 15000, 100):
    sess.run(train_step, feed_dict={x: train_data[i:i+100], y_: train_labels[i:i+100]})
    if i % 500 == 0:
        print(sess.run(cross_entropy, feed_dict={x: train_data[i:i+100], y_: train_labels[i:i+100]}))
        print(sess.run(b), sess.run(W))

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))


sess.close()

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

所有初始权重均为零。当您采用这种方式时,NN不会很好地学习。您需要使用随机值初始化所有初始权重。

请参见Why should weights of Neural Networks be initialized to random numbers?

为什么不将权重设置为零? 每次训练网络时,我们可以使用相同的权重集;例如,您可以为所有权重使用0.0的值。

在这种情况下,学习算法的方程式将无法对网络权重进行任何更改,并且模型将被卡住。重要的是要注意,每个神经元中的偏差权重默认设置为零,而不是小的随机值。 “

请参阅 https://machinelearningmastery.com/why-initialize-a-neural-network-with-random-weights/

答案 1 :(得分:0)

问题的关键在于,您输出的y_y的类号为1。使用{{1}时应采用one-hot模式}关于张量流中的分类问题。 tf.nn.softmax_cross_entropy_with_logits将首先计算tf.nn.softmax_cross_entropy_with_logits。当班级编号为tf.nn.softmax时,您的结果将完全相同。例如:

1

这意味着无论您的输出import tensorflow as tf y = tf.constant([[1],[0],[1]],dtype=tf.float32) y_ = tf.constant([[1],[2],[3]],dtype=tf.float32) softmax_var = tf.nn.softmax(logits=y_) cross_entropy = tf.multiply(y, tf.log(softmax_var)) errors = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y) with tf.Session() as sess: print(sess.run(softmax_var)) print(sess.run(cross_entropy)) print(sess.run(errors)) [[1.] [1.] [1.]] [[0.] [0.] [0.]] [0. 0. 0.] 是什么,您的损失将为零。因此,您的y_weights尚未更新。

解决方案是修改biasy_的类号。

我想您的班级编号是y

第一次处理:您可以在Feed数据之前将数据更改为n,然后使用以下代码。

one-hot

第二个方法:在Feed数据之后将数据更改为y_ = tf.placeholder(tf.float32, [None, n]) W = tf.Variable(tf.zeros([4096, n])) b = tf.Variable(tf.zeros([n]))

one-hot