【问题标题】:Reshaping the output of a logistic regression重塑逻辑回归的输出
【发布时间】:2018-05-18 15:18:04
【问题描述】:

我已将逻辑回归模型定义为具有一层的网络,然后使用 tf.layers 进行 sigmoid 激活。预测结果是形状为(n,1)n 的二维张量,即批次的大小。但是,为了计算损失函数,我需要一个形状为n 的一维张量。当然,我可以重塑张量(这就是我目前所做的),但不知何故,感觉应该做一些更优雅的事情。有吗?


重现问题的代码

import tensorflow as tf
import numpy as np

data = np.random.random((20, 6))
data[:, -1] = data[:, -1] > 0.5

e = tf.data.Dataset.from_tensor_slices(data).batch(2).make_one_shot_iterator().get_next()
x, y_ = e[:, :-1], e[:, -1]

y = tf.layers.dense(x, 1, activation=tf.nn.sigmoid)
loss_wrong = - tf.reduce_mean(tf.add(tf.multiply(y_, tf.log(y)), tf.multiply((1. - y_), tf.log(1. - y))))

y2 = tf.reshape(y, [-1])  # ugly reshape I would like to get rid of
loss_correct = - tf.reduce_mean(tf.add(tf.multiply(y_, tf.log(y2)), tf.multiply((1. - y_), tf.log(1. - y2))))

with tf.Session() as sess:
    tf.global_variables_initializer().run()

    a, b, b2, lw, lc = sess.run([y_, y, y2, loss_wrong, loss_correct])
    print(a)  # a 1D array with the real labels
    print(b)  # a dangerous array of arrays!
    print(b2)  # notice how nice and flat this is
    print(lw)  # wrong when all labels are not the same
    print(lc)  # correct (can test by hand with the data printed)

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    tf.squeeze (docs)。这会删除所有大小为 1 的轴。所以

    y2 = tf.squeeze(y)
    

    但是请注意,如果某些可变维度(例如批量大小)也恰好为 1,这可能会导致问题——squeeze 也会删除此类轴(您可能不希望这样做)。你可以使用

    y2 = tf.squeeze(y, axis=1)
    

    为了防止这种情况(请注意,如果轴 1 的大小不是 1,这将崩溃!)。

    有趣的是,tf.squeeze 似乎总是会产生至少一个一维张量,而不是一个标量。这与 numpy 版本不同。即

    tf.squeeze([[1]]) -> array([1])
    np.squeeze([[1]]) -> array(1)
    

    希望这足够优雅。

    【讨论】:

    • 感谢您的回答,尤其是 tf 和 np.然而,在这种情况下,挤压似乎与重塑非常相似。有什么理由比另一个更喜欢一个吗?
    • 我怀疑两者之间是否存在很大差异,因为两者都只是对张量的形状进行操作。我想如果你愿意,你也可以做类似 y[:, 0] 的事情作为替代,但我个人觉得squeeze 是最明确的选择......
    猜你喜欢
    • 2020-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    • 2020-09-16
    • 2011-03-27
    • 2020-11-08
    相关资源
    最近更新 更多