我已经将逻辑回归模型定义为具有一层的网络,然后使用tf.layers
进行sigmoid激活。预测结果为形状(n,1)
的二维张量,n
是批量的大小。但是,为了计算损失函数,我需要1D张量的形状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)
答案 0 :(得分:0)
有tf.squeeze
(docs)。这将删除所有大小为1的轴。所以
y2 = tf.squeeze(y)
但请注意,如果某些可变维度(例如批量大小)也恰好为1 - squeeze
也会删除此类轴(这可能是您不想要的),这可能会导致问题。你可以使用
y2 = tf.squeeze(y, axis=1)
以防止这种情况(请注意,如果轴1的大小不是1,则会崩溃!)。
有趣的是,似乎tf.squeeze
总是会产生至少1d的张量,而不是标量。这与numpy版本不同。即。
tf.squeeze([[1]]) -> array([1])
np.squeeze([[1]]) -> array(1)
希望这足够优雅。