【问题标题】:Neural Network with Tensorflow doesn't update weights/bias带有 Tensorflow 的神经网络不会更新权重/偏差
【发布时间】:2019-03-18 03:31:38
【问题描述】:

问题

我正在尝试将一些 64x64 图像分类为黑盒练习。我写的NN不会改变我的体重。第一次写这样的东西,同样的代码,但是 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()

我该如何解决这个问题?

【问题讨论】:

  • 你能定义一下吗? “没有像应有的那样训练”。您究竟期望什么是您无法解决的?
  • 它应该改变权重和偏差以最小化损失函数

标签: python tensorflow neural-network


【解决方案1】:

问题的关键在于你输出y_y的类号是1。在tensorflow中使用tf.nn.softmax_cross_entropy_with_logits进行分类问题时应该采用one-hot模式。 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_,你的损失都将是零。所以你的weightsbias 还没有更新。

解决办法是修改y_y的班级号。

我想你的班级号码是n

第一个方法:你可以在feed数据之前将数据更改为one-hot。然后使用以下代码。

y_ = tf.placeholder(tf.float32, [None, n])
W = tf.Variable(tf.zeros([4096, n]))
b = tf.Variable(tf.zeros([n]))

第二种方法:在feed数据后将数据改为one-hot

y_ = tf.placeholder(tf.int32, [None, 1])
y_ = tf.one_hot(y_,n) # your dtype of y_ need to be tf.int32
W = tf.Variable(tf.zeros([4096, n]))
b = tf.Variable(tf.zeros([n]))

【讨论】:

  • 如何修改类?或者我如何使用一种热门方法?
  • @Samuel 我已将其添加到答案中。
  • 如果我做第一个,那么它无法读取数据,因为标签有 (?, 1) 形状(忘了在 labels.csv 文件中提到每行都有一个标签)和y_ 现在是 (?, 8) 如果我做第二个,它会说“无法为张量‘one_hot:0’提供形状 (100, 1) 的值,它的形状为‘(?, 8, 8)’”跨度>
  • @Samuel 使用第一种方法时,您需要在馈送数据之前和读取文件之后将数据更改为 (?,8)。使用第二种方法时,需要保持标签的形状为 (?,1)。
  • 我无法弄清楚如何编写代码......以及思考过程是什么
【解决方案2】:

你所有的初始权重都是零。当你有这种方式时,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/

【讨论】:

    猜你喜欢
    • 2014-11-26
    • 2018-03-01
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 2019-04-10
    • 2015-05-03
    • 1970-01-01
    • 2016-09-08
    相关资源
    最近更新 更多