如果你只是想对事物进行分类,那么在tf.keras.losses.CategoricalCrossentropy[1]或tf.keras.losses.SparseCategoricalCrossentropy[2]中使用from_logit=True,并输出tf.keras.layers.Dense层。 softmax 计算将在这些损失函数中完成。
通过将one_hot层和softmax层合二为一,计算效率更高。您不需要为网络的输出创建自己的 one_hot 层。设置好了
如果你想要自己的 one_hot 矢量转换器层,我有一个想法来保持图微分。在 softmax 中使用称为热力学 beta 的非常大的参数。
import tensorflow as tf
class OneHot(tf.keras.layers.Layer):
def __init__(self, infi=1e9):
super(OneHot, self).__init__()
self.infi = infi
def call(self, x):
return tf.nn.softmax(self.infi * x) # x has shape [B, 9]
def get_config(self):
return {'infi': self.infi}
在下面看看它是如何工作的。
>>> a = tf.constant([[1.,2.], [3., 4.]], dtype=tf.float32)
>>> tf.nn.softmax(a)
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[0.26894143, 0.7310586 ],
[0.26894143, 0.7310586 ]], dtype=float32)>
>>> tf.nn.softmax(1e9 * a)
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[0., 1.],
[0., 1.]], dtype=float32)>
我不确定这个输出层如何让学习变得更好。
== 我在下面的第一个答案。不推荐。
你可以使用tf.one_hot[3]来制作。
import tensorflow as tf
x = tf.constant([0.01,0.41,0.02,0.32,0.01,0.43], dtype=tf.float32)
i = tf.argmax(x)
y = tf.one_hot(i, 6)
# <tf.Tensor: shape=(6,), dtype=float32, numpy=array([0., 0., 0., 0., 0., 1.], dtype=float32)>
如果要制作 keras 层,请制作自定义层[4]。
import tensorflow as tf
class OneHot(tf.keras.layers.Layer):
def __init__(self):
super(OneHot, self).__init__()
def call(self, x):
i = tf.argmax(x, axis=1) # x has shape [B, 9]
return tf.one_hot(i, 9)
[1]https://www.tensorflow.org/api_docs/python/tf/keras/losses/CategoricalCrossentropy
[2]https://www.tensorflow.org/api_docs/python/tf/keras/losses/SparseCategoricalCrossentropy
[3]https://www.tensorflow.org/api_docs/python/tf/one_hot
[4]https://www.tensorflow.org/guide/keras/custom_layers_and_models