tensorflow:具有单个神经元的输出层,预期浮点输出[0.0,1.0]

时间:2019-01-11 12:39:06

标签: python tensorflow

我尝试使用仅包含单个神经元的输出层构建nn。我的输入数据包含分配给“ 0”或“ 1”的500个浮点数。最终的nn应该输出“概率”值[0.0,1.0]。 由于我是Tensorflow的新手,所以我从AurélienGéron的优秀著作中借鉴了MNIST的示例,并根据需要对其进行了修改。但是,我仍停留在几点。基本上,他在某些时候使用了“ softmax”函数,这对于我的示例来说是不正确的。此外,他的评估功能(“ tf.nn.in_top_k”)也不正确。最后,我想知道我是否需要用于输出层的激活功能(“ Sigmoid”?)。 非常感谢您的反馈!

这是我的代码:

import tensorflow as tf
import numpy as np

n_inputs = 500

n_hidden1 = 400
n_hidden2 = 300

n_outputs = 1


# import training, test and validation data...
X_train,y_train = <import my training data as "np.array" objects>
X_valid,y_valid = <import my validation data as "np.array" objects>
X_test,y_test   = <import my testing data as "np.array" objects>


seed    = 42
tf.reset_default_graph()
tf.set_random_seed(seed)
np.random.seed(seed)

X = tf.placeholder(tf.float32, shape=(None, n_inputs), name="X")
y = tf.placeholder(tf.float32, shape=(None), name="y")

def neuron_layer(X, n_neurons, name, activation=None):
    with tf.name_scope(name):
        n_inputs = int(X.get_shape()[1])
        stddev = 2 / np.sqrt(n_inputs)
        init = tf.truncated_normal((n_inputs, n_neurons), stddev=stddev)
        W = tf.Variable(init, name="kernel")
        b = tf.Variable(tf.zeros([n_neurons]), name="bias")
        Z = tf.matmul(X, W) + b
        if activation is not None:
            return activation(Z)
        else:
            return Z

with tf.name_scope("dnn"):
    hidden1 = neuron_layer(X, n_hidden1, name="hidden1",activation=tf.nn.relu)
    hidden2 = neuron_layer(hidden1, n_hidden2, name="hidden2",activation=tf.nn.relu)
    # do I need an activation function here?
    logits = neuron_layer(hidden2, n_outputs, name="outputs")


with tf.name_scope("loss"):
    # this is probably not correct - I should most likely use something like "sigmoid"... but how exactly do I do that?
    xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=logits)
    loss = tf.reduce_mean(xentropy, name="loss")

learning_rate = 0.01

with tf.name_scope("train"):
    optimizer = tf.train.GradientDescentOptimizer(learning_rate)
    training_op = optimizer.minimize(loss)


with tf.name_scope("eval"):
    # same thing here. what is the right function to be used here?
    correct = tf.nn.in_top_k(logits, y, 1)
    accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))


init = tf.global_variables_initializer()
saver = tf.train.Saver()

n_epochs = 100
batch_size = 50

def shuffle_batch(X, y, batch_size):
    rnd_idx = np.random.permutation(len(X))
    n_batches = len(X) // batch_size
    for batch_idx in np.array_split(rnd_idx, n_batches):
        X_batch, y_batch = X[batch_idx], y[batch_idx]
        yield X_batch, y_batch

with tf.Session() as sess:
    init.run()
    for epoch in range(n_epochs):
        for X_batch, y_batch in shuffle_batch(X_train, y_train, batch_size):
            sess.run(training_op, feed_dict={X: X_batch, y: y_batch})
        acc_batch = accuracy.eval(feed_dict={X: X_batch, y: y_batch})
        acc_val = accuracy.eval(feed_dict={X: X_valid, y: y_valid})
        print(epoch, "Batch accuracy:", acc_batch, "Val accuracy:", acc_val)

    save_path = saver.save(sess, "./my_model_final.ckpt")

其他信息:

非常感谢您的回复。引入“ S型”功能是朝正确方向迈出的一步。但是,仍然存在一些问题:

1。)训练nn时,精度不是很好:

(95, 'Batch accuracy:', 0.54, 'Val accuracy:', 0.558)
(96, 'Batch accuracy:', 0.52, 'Val accuracy:', 0.558)
(97, 'Batch accuracy:', 0.56, 'Val accuracy:', 0.558)
(98, 'Batch accuracy:', 0.58, 'Val accuracy:', 0.558)
(99, 'Batch accuracy:', 0.52, 'Val accuracy:', 0.558)

2。)似乎在测试训练好的模型时返回的结果太低。值都在[0.0,0.3]之间:

('Predicted classes:', array([[0.2000685 ],[0.17176622],[0.14039296],[0.15600625],[0.15928227],[0.15543781],[0.1348885 ],[0.17185831],[0.170376],[0.17732298],[0.17864114],[0.16391528],[0.18579942],[0.12997991],[0.13886571],[0.24408364],       [0.17308617],[0.16365634],[0.1782803 ],[0.11332873]], dtype=float32))
('Actual classes:   ', array([0., 0., 0., 1., 0., 0., 1., 1., 1., 1., 1., 1., 0., 0., 1., 1., 1.,1., 0., 0.]))

我想我的验证功能仍然不正确:

with tf.name_scope("eval"):
    predicted = tf.nn.sigmoid(logits)
    correct_pred = tf.equal(tf.round(predicted), y)
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

正确的验证功能应如何显示?

再次,非常感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

  1. 登录名不应激活。
  2. 亏损应为能够处理logit的S形,tf.nn.sigmoid_cross_entropy_with_logits就是这样。
  3. 您可以通过检查最终logit小于零还是大于零来计算准确性。如果是第一种情况,则将其分类为0;如果是第二种情况,则将其分类为1。我不确定在tf中是否对此具有内置功能。<​​/ li>

答案 1 :(得分:0)

我认为我找到了一个使用keras的简单解决方案-对于我来说,对于初学者来说似乎更直观。在YouTube(https://www.youtube.com/watch?v=T91fsaG2L0s)上找到了“”:

PS>git filter-branch --tree-filter 'py C:/Scripts/myscript.py' -- --all
WARNING: Ref 'refs/heads/master' is unchanged