使用 TensorFlow 进行训练和预测出了什么问题?

2024-03-14

请看下面写的代码。

x = tf.placeholder("float", [None, 80])
W = tf.Variable(tf.zeros([80,2]))
b = tf.Variable(tf.zeros([2]))

y = tf.nn.softmax(tf.matmul(x,W) + b)

y_ = tf.placeholder("float", [None,2])

所以在这里我们看到数据中有 80 个特征,只有 2 个可能的输出。我设置了cross_entropytrain_step像这样。

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(tf.matmul(x, W) + b, y_)
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

初始化所有变量。

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

然后我使用这段代码来“训练”我的神经网络。

g = 0
for i in range(len(x_train)):

    _, w_out, b_out = sess.run([train_step, W, b], feed_dict={x: [x_train[g]], y_: [y_train[g]]})

    g += 1

print "...Trained..."

训练网络后,无论我训练多少次,它总是产生相同的准确率。则准确率是0.856067我用这段代码达到了这种准确性-

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print sess.run(accuracy, feed_dict={x: x_test, y_: y_test})
0.856067

所以这就是问题所在。是因为我的尺寸太小了吗?也许我应该将这些特征分解成 10x8 矩阵?也许是 4x20 矩阵? ETC。

然后我尝试获取实际测试数据产生 0 或 1 的概率,如下所示 -

test_data_actual = genfromtxt('clean-test-actual.csv',delimiter=',')  # Actual Test data

x_test_actual = []
for i in test_data_actual:
    x_test_actual.append(i)
x_test_actual = np.array(x_test_actual)

ans = sess.run(y, feed_dict={x: x_test_actual})

并打印出概率:

print ans[0:10]
[[ 1.  0.]
 [ 1.  0.]
 [ 1.  0.]
 [ 1.  0.]
 [ 1.  0.]
 [ 1.  0.]
 [ 1.  0.]
 [ 1.  0.]
 [ 1.  0.]
 [ 1.  0.]]

(注:它确实产生[ 0. 1.]有时。)

然后我尝试看看应用专家方法是否会产生更好的结果。请看下面的代码。

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

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

def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1, 1, 1, 1],
                        strides=[1, 1, 1, 1], padding='SAME')

(请注意我如何更改strides以避免错误)。

W_conv1 = weight_variable([1, 80, 1, 1])
b_conv1 = bias_variable([1])

这就是问题再次出现的地方。我将张量(向量/矩阵,如果你愿意的话)定义为 80x1(因此 1 行包含 80 个特征);我在其余代码中继续这样做(请参见下文)。

x_ = tf.reshape(x, [-1,1,80,1])
h_conv1 = tf.nn.relu(conv2d(x_, W_conv1) + b_conv1)

第二卷积层

h_pool1 = max_pool_2x2(h_conv1)
W_conv2 = weight_variable([1, 80, 1, 1])
b_conv2 = bias_variable([1])

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

密集连接层

W_fc1 = weight_variable([80, 1024])
b_fc1 = bias_variable([1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 80])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

Dropout

keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

Readout

W_fc2 = weight_variable([1024, 2])
b_fc2 = bias_variable([2])

y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

在上面你会看到我将输出定义为 2 个可能的答案(也是为了避免错误)。

Then cross_entropytrain_step.

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(tf.matmul(h_fc1_drop, W_fc2) + b_fc2, y_)

train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

开始会话。

sess.run(tf.initialize_all_variables())

“训练”神经网络。

g = 0

for i in range(len(x_train)):
    if i%100 == 0:
        train_accuracy = accuracy.eval(session=sess, feed_dict={x: [x_train[g]], y_: [y_train[g]], keep_prob: 1.0})

    train_step.run(session=sess, feed_dict={x: [x_train[g]], y_: [y_train[g]], keep_prob: 0.5})

    g += 1

print "test accuracy %g"%accuracy.eval(session=sess, feed_dict={
    x: x_test, y_: y_test, keep_prob: 1.0})
test accuracy 0.929267

而且,再一次,它总是产生0.929267作为输出。

实际数据产生 0 或 1 的概率如下:

[[ 0.92820859  0.07179145]
 [ 0.92820859  0.07179145]
 [ 0.92820859  0.07179145]
 [ 0.92820859  0.07179145]
 [ 0.92820859  0.07179145]
 [ 0.92820859  0.07179145]
 [ 0.96712834  0.03287172]
 [ 0.92820859  0.07179145]
 [ 0.92820859  0.07179145]
 [ 0.92820859  0.07179145]]

如你所见,有some这些概率存在差异,但通常结果相同。

我知道这不是深度学习问题。这显然是一个训练问题。我知道每次重新初始化变量并重新训练网络时,训练准确性总是会存在一些差异,但我只是不知道为什么或哪里出了问题。


答案是2倍。

问题之一是尺寸/参数。另一个问题是这些功能被放置在错误的位置。

W_conv1 = weight_variable([1, 2, 1, 80])
b_conv1 = bias_variable([80])

注意其中的前两个数字weight_variable对应于输入的尺寸。后两个数字对应于特征张量的维度。这bias_variable总是取最后一个数字weight_variable.

第二卷积层

W_conv2 = weight_variable([1, 2, 80, 160])
b_conv2 = bias_variable([160])

这里前两个数字仍然对应于输入的维度。后两个数字对应于特征数量以及由之前 80 个特征产生的加权网络。在这种情况下,我们将加权网络加倍。 80x2=160。这bias_variable然后取最后的数字weight_variable。如果您此时要完成代码,则最后一个数字weight_variable将为 1,以防止由于输入张量和输出张量的形状而导致的尺寸错误。但是,为了更好的预测,我们添加第三个卷积层。

第三卷积层

W_conv3 = weight_variable([1, 2, 160, 1])
b_conv3 = bias_variable([1])

再次,前两个数字weight_variable采取输入的形状。第三个数字对应于我们在第二个卷积层中建立的加权变量的数量。中的最后一个数字weight_variable现在变为 1,因此我们预测的输出不会遇到任何尺寸错误。在这种情况下,输出的尺寸为1, 2.

W_fc2 = weight_variable([80, 1024])
b_fc2 = bias_variable([1024])

这里,神经元的数量是1024这是完全任意的,但是第一个数字weight_variable需要是我们的特征矩阵的维度需要被整除的东西。在这种情况下,它可以是任何数字(例如2, 4, 10, 20, 40, 80)。再一次,bias_variable取最后一个数字weight_variable.

此时,请确保最后一个数字h_pool3_flat = tf.reshape(h_pool3, [-1, 80])对应于第一个数字W_fc2 weight_variable.

现在,当您运行训练程序时,您会注意到结果会有所不同,并且不会总是猜测全 1 或全 0。

当你想预测概率时,你必须输入x to the softmax变量->y_conv=tf.nn.softmax(tf.matmul(h_fc2_drop, W_fc3) + b_fc3)就像这样-

ans = sess.run(y_conv, feed_dict={x: x_test_actual, keep_prob: 1.0})

您可以更改keep_prob变量,但将其保持在1.0总是产生最好的结果。现在,如果你打印出ans你会得到看起来像这样的东西-

[[ 0.90855026  0.09144982]
 [ 0.93020624  0.06979381]
 [ 0.98385173  0.0161483 ]
 [ 0.93948185  0.06051811]
 [ 0.90705943  0.09294061]
 [ 0.95702559  0.04297439]
 [ 0.95543593  0.04456403]
 [ 0.95944828  0.0405517 ]
 [ 0.99154049  0.00845954]
 [ 0.84375167  0.1562483 ]
 [ 0.98449463  0.01550537]
 [ 0.97772813  0.02227189]
 [ 0.98341942  0.01658053]
 [ 0.93026513  0.06973486]
 [ 0.93376994  0.06623009]
 [ 0.98026556  0.01973441]
 [ 0.93210858  0.06789146]

注意概率如何变化。您的训练现在正常进行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 TensorFlow 进行训练和预测出了什么问题? 的相关文章

随机推荐