BinaryCrossentropy classkeras.losses.BinaryCrossentropy(
from_logits=False,
label_smoothing=0.0,
axis=-1,
reduction="sum_over_batch_size",
name="binary_crossentropy",
dtype=None,
)
计算真实标签和预测标签之间的交叉熵损失.
在二分类(0 或 1)应用中使用此交叉熵损失.损失函数需要以下输入:
y_true(真实标签):这可以是 0 或 1.y_pred(预测值):这是模型的预测值,即一个浮点值,表示一个
logit(即当 from_logits=True 时,值在 [-inf, inf] 范围内)或概率(即当 from_logits=False 时,值在 [0., 1.] 范围内).参数:
from_logits:是否将 y_pred 解释为 logit 值的张量.默认情况下,我们假设 y_pred 是概率(即,值在 [0, 1] 范围内).
label_smoothing:范围 [0, 1] 内的浮点数.当为 0 时,不进行平滑处理.当大于 0 时,我们计算预测标签和真实标签的平滑版本之间的损失,其中平滑处理将标签向 0.5 挤压.label_smoothing 的值越大,平滑处理越重.
axis:计算交叉熵的轴(特征轴).默认为 -1.
reduction:应用于损失的归约类型.在几乎所有情况下,这应该是 "sum_over_batch_size".
支持的选项有 "sum"、"sum_over_batch_size" 或 None.
name:损失实例的可选名称.
dtype:损失计算的数据类型.默认为 None,这意味着使用 keras.backend.floatx().keras.backend.floatx() 是一个 "float32",除非设置为不同的值
(通过 keras.backend.set_floatx()).如果提供了 keras.DTypePolicy,则将使用 compute_dtype.
示例:
推荐用法:(设置 from_logits=True)
使用 compile() API:
model.compile(
loss=keras.losses.BinaryCrossentropy(from_logits=True),
...
)
作为独立函数:
>>> # 示例 1:(batch_size = 1,样本数量 = 4)
>>> y_true = [0, 1, 0, 0]
>>> y_pred = [-18.6, 0.51, 2.94, -12.8]
>>> bce = keras.losses.BinaryCrossentropy(from_logits=True)
>>> bce(y_true, y_pred)
0.865
>>> # 示例 2:(batch_size = 2,样本数量 = 4)
>>> y_true = [[0, 1], [0, 0]]
>>> y_pred = [[-18.6, 0.51], [2.94, -12.8]]
>>> # 使用默认的 'auto'/'sum_over_batch_size' 归约类型.
>>> bce = keras.losses.BinaryCrossentropy(from_logits=True)
>>> bce(y_true, y_pred)
0.865
>>> # 使用 'sample_weight' 属性
>>> bce(y_true, y_pred, sample_weight=[0.8, 0.2])
0.243
>>> # 使用 'sum' 归约类型.
>>> bce = keras.losses.BinaryCrossentropy(from_logits=True,
... reduction="sum")
>>> bce(y_true, y_pred)
1.730
>>> # 使用 'none' 归约类型.
>>> bce = keras.losses.BinaryCrossentropy(from_logits=True,
... reduction=None)
>>> bce(y_true, y_pred)
array([0.235, 1.496], dtype=float32)
默认用法:(设置 from_logits=False)
>>> # 对上述"推荐用法”部分进行以下更新
>>> # 1. 设置 `from_logits=False`
>>> keras.losses.BinaryCrossentropy() # 或 ...('from_logits=False')
>>> # 2. 更新 `y_pred` 以使用概率而不是 logits
>>> y_pred = [0.6, 0.3, 0.2, 0.8] # 或 [[0.6, 0.3], [0.2, 0.8]]
BinaryFocalCrossentropy classkeras.losses.BinaryFocalCrossentropy(
apply_class_balancing=False,
alpha=0.25,
gamma=2.0,
from_logits=False,
label_smoothing=0.0,
axis=-1,
reduction="sum_over_batch_size",
name="binary_focal_crossentropy",
dtype=None,
)
计算真实标签和预测值之间的焦点交叉熵损失.
二元交叉熵损失通常用于二分类(0或1)任务.该损失函数需要以下输入:
y_true(真实标签):这可以是0或1.y_pred(预测值):这是模型的预测值,即一个浮点值,表示一个
logit(即当from_logits=True时,值在[-inf, inf]范围内)或概率(即当from_logits=False时,值在[0., 1.]范围内).根据Lin et al., 2018,应用一个"焦点因子”有助于降低简单样本的权重,更多地关注困难样本.默认情况下,焦点张量计算如下:
focal_factor = (1 - output) ** gamma 对于类别1
focal_factor = output ** gamma 对于类别0
其中gamma是一个聚焦参数.当gamma=0时,此函数等同于二元交叉熵损失.
参数:
apply_class_balancing:一个布尔值,是否对二类别0和1应用权重平衡.
alpha:类别1的权重平衡因子,默认值为0.25,如参考文献Lin et al., 2018中所述.类别0的权重为1.0 - alpha.
gamma:用于计算焦点因子的聚焦参数,默认值为2.0,如参考文献Lin et al., 2018中所述.
from_logits:是否将y_pred解释为logit值的张量.默认情况下,我们假设y_pred是概率(即,值在[0, 1]范围内).
label_smoothing:[0, 1]范围内的浮点数.当0时,不进行平滑处理.当大于0时,我们计算预测标签与真实标签的平滑版本之间的损失,其中平滑将标签向0.5挤压.
label_smoothing的值越大,平滑程度越大.
axis:计算交叉熵的轴(特征轴).默认为-1.
reduction:应用于损失的归约类型.在几乎所有情况下,这应该是"sum_over_batch_size".
支持的选项有"sum"、"sum_over_batch_size"或None.
name:损失实例的可选名称.
dtype:损失计算的数据类型.默认为None,这意味着使用keras.backend.floatx().keras.backend.floatx()是"float32",除非设置为不同的值
(通过keras.backend.set_floatx()).如果提供了keras.DTypePolicy,则将使用compute_dtype.
示例:
使用compile() API:
model.compile(
loss=keras.losses.BinaryFocalCrossentropy(
gamma=2.0, from_logits=True),
...
)
作为独立函数:
>>> # 示例1:(batch_size = 1,样本数量 = 4)
>>> y_true = [0, 1, 0, 0]
>>> y_pred = [-18.6, 0.51, 2.94, -12.8]
>>> loss = keras.losses.BinaryFocalCrossentropy(
... gamma=2, from_logits=True)
>>> loss(y_true, y_pred)
0.691
>>> # 应用类别权重
>>> loss = keras.losses.BinaryFocalCrossentropy(
... apply_class_balancing=True, gamma=2, from_logits=True)
>>> loss(y_true, y_pred)
0.51
>>> # 示例2:(batch_size = 2,样本数量 = 4)
>>> y_true = [[0, 1], [0, 0]]
>>> y_pred = [[-18.6, 0.51], [2.94, -12.8]]
>>> # 使用默认的'auto'/'sum_over_batch_size'归约类型.
>>> loss = keras.losses.BinaryFocalCrossentropy(
... gamma=3, from_logits=True)
>>> loss(y_true, y_pred)
0.647
>>> # 应用类别权重
>>> loss = keras.losses.BinaryFocalCrossentropy(
... apply_class_balancing=True, gamma=3, from_logits=True)
>>> loss(y_true, y_pred)
0.482
>>> # 使用'sample_weight'属性并带有焦点效应
>>> loss = keras.losses.BinaryFocalCrossentropy(
... gamma=3, from_logits=True)
>>> loss(y_true, y_pred, sample_weight=[0.8, 0.2])
0.133
>>> # 应用类别权重
>>> loss = keras.losses.BinaryFocalCrossentropy(
... apply_class_balancing=True, gamma=3, from_logits=True)
>>> loss(y_true, y_pred, sample_weight=[0.8, 0.2])
0.097
>>> # 使用'sum'归约类型.
>>> loss = keras.losses.BinaryFocalCrossentropy(
... gamma=4, from_logits=True,
... reduction="sum")
>>> loss(y_true, y_pred)
1.222
>>> # 应用类别权重
>>> loss = keras.losses.BinaryFocalCrossentropy(
... apply_class_balancing=True, gamma=4, from_logits=True,
... reduction="sum")
>>> loss(y_true, y_pred)
0.914
>>> # 使用'none'归约类型.
>>> loss = keras.losses.BinaryFocalCrossentropy(
... gamma=5, from_logits=True,
... reduction=None)
>>> loss(y_true, y_pred)
array([0.0017 1.1561], dtype=float32)
>>> # 应用类别权重
>>> loss = keras.losses.BinaryFocalCrossentropy(
... apply_class_balancing=True, gamma=5, from_logits=True,
... reduction=None)
>>> loss(y_true, y_pred)
array([0.0004 0.8670], dtype=float32)
CategoricalCrossentropy classkeras.losses.CategoricalCrossentropy(
from_logits=False,
label_smoothing=0.0,
axis=-1,
reduction="sum_over_batch_size",
name="categorical_crossentropy",
dtype=None,
)
计算标签和预测之间的交叉熵损失.
当有两个或更多标签类别时使用此交叉熵损失函数.我们期望标签以one_hot表示形式提供.如果你想以整数形式提供标签,请使用SparseCategoricalCrossentropy损失.每个特征应有num_classes个浮点值,即y_pred和y_true的形状均为[batch_size, num_classes].
参数:
from_logits: 是否期望y_pred是一个logits张量.默认情况下,我们假设y_pred编码了一个概率分布.
label_smoothing: 浮点数在[0, 1]之间.当> 0时,标签值会被平滑处理,意味着对标签值的置信度会放松.例如,如果0.1,则使用0.1 / num_classes作为非目标标签,使用0.9 + 0.1 / num_classes作为目标标签.
axis: 计算交叉熵的轴(特征轴).默认为-1.
reduction: 应用于损失的归约类型.在几乎所有情况下,这应该是"sum_over_batch_size".
支持的选项有"sum"、"sum_over_batch_size"或None.
name: 损失实例的可选名称.
dtype: 损失计算的数据类型.默认为None,这意味着使用keras.backend.floatx().keras.backend.floatx()是一个"float32",除非设置为不同的值(通过keras.backend.set_floatx()).如果提供了keras.DTypePolicy,则将使用compute_dtype.
示例:
独立使用:
>>> y_true = [[0, 1, 0], [0, 0, 1]]
>>> y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]]
>>> # 使用'auto'/'sum_over_batch_size'归约类型.
>>> cce = keras.losses.CategoricalCrossentropy()
>>> cce(y_true, y_pred)
1.177
>>> # 使用'sample_weight'调用.
>>> cce(y_true, y_pred, sample_weight=np.array([0.3, 0.7]))
0.814
>>> # 使用'sum'归约类型.
>>> cce = keras.losses.CategoricalCrossentropy(
... reduction="sum")
>>> cce(y_true, y_pred)
2.354
>>> # 使用'none'归约类型.
>>> cce = keras.losses.CategoricalCrossentropy(
... reduction=None)
>>> cce(y_true, y_pred)
array([0.0513, 2.303], dtype=float32)
与compile() API一起使用:
model.compile(optimizer='sgd',
loss=keras.losses.CategoricalCrossentropy())
CategoricalFocalCrossentropy classkeras.losses.CategoricalFocalCrossentropy(
alpha=0.25,
gamma=2.0,
from_logits=False,
label_smoothing=0.0,
axis=-1,
reduction="sum_over_batch_size",
name="categorical_focal_crossentropy",
dtype=None,
)
计算alpha平衡的焦点交叉熵损失.
当有两个或更多标签类别并且你想要处理类别不平衡而不使用class_weights时,请使用此交叉熵损失函数.我们期望标签以one_hot表示形式提供.
根据Lin et al., 2018,它有助于应用一个焦点因子来降低简单样本的权重并更多地关注困难样本.焦点损失(FL)的一般公式如下:
FL(p_t) = (1 - p_t) ** gamma * log(p_t)
其中p_t定义如下:
p_t = output if y_true == 1, else 1 - output
(1 - p_t) ** gamma是调制因子,其中gamma是一个聚焦参数.当gamma = 0时,交叉熵上没有焦点效应.gamma以平滑的方式减少对简单样本的重要性.
作者在论文中使用了alpha平衡的焦点损失(FL)变体:
FL(p_t) = -alpha * (1 - p_t) ** gamma * log(p_t)
其中alpha是类别的权重因子.如果alpha = 1,损失将无法正确处理类别不平衡,因为所有类别将有相同的权重.这可以是一个常数或一个常数列表.如果alpha是一个列表,它必须与类别的数量相同长度.
上述公式可以推广为:
FL(p_t) = alpha * (1 - p_t) ** gamma * CrossEntropy(y_true, y_pred)
其中减号来自CrossEntropy(y_true, y_pred)(CE).
将其扩展到多类别情况很简单:
FL(p_t) = alpha * (1 - p_t) ** gamma * CategoricalCE(y_true, y_pred)
在下面的代码片段中,每个示例有num_classes个浮点值.y_pred和y_true的形状都是(batch_size, num_classes).
参数:
alpha:所有类别的权重平衡因子,默认是0.25,如参考文献中所述.它可以是一个浮点数列表或一个标量.在多类别情况下,可以通过使用sklearn.utils中的compute_class_weight按类别频率的倒数设置alpha.
gamma:一个聚焦参数,默认是2.0,如参考文献中所述.它有助于以平滑的方式逐渐减少对简单(容易)样本的重要性.
from_logits:是否期望output是一个logits张量.默认情况下,我们考虑output编码了一个概率分布.
label_smoothing:[0, 1]中的浮点数.当> 0时,标签值被平滑,意味着对标签值的置信度被放宽.例如,如果0.1,对非目标标签使用0.1 / num_classes,对目标标签使用0.9 + 0.1 / num_classes.
axis:计算交叉熵的轴(特征轴).默认为-1.
reduction:应用于损失的归约类型.在几乎所有情况下,这应该是"sum_over_batch_size".
支持的选项是"sum","sum_over_batch_size"或None.
name:损失实例的可选名称.
dtype:损失计算的数据类型.默认为None,这意味着使用keras.backend.floatx().keras.backend.floatx()是一个"float32",除非设置为不同值
(通过keras.backend.set_floatx()).如果提供了keras.DTypePolicy,则将使用compute_dtype.
示例:
独立使用:
>>> y_true = [[0., 1., 0.], [0., 0., 1.]]
>>> y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]]
>>> # 使用'auto'/'sum_over_batch_size'归约类型.
>>> cce = keras.losses.CategoricalFocalCrossentropy()
>>> cce(y_true, y_pred)
0.23315276
>>> # 使用'sample_weight'调用.
>>> cce(y_true, y_pred, sample_weight=np.array([0.3, 0.7]))
0.1632
>>> # 使用'sum'归约类型.
>>> cce = keras.losses.CategoricalFocalCrossentropy(
... reduction="sum")
>>> cce(y_true, y_pred)
0.46631
>>> # 使用'none'归约类型.
>>> cce = keras.losses.CategoricalFocalCrossentropy(
... reduction=None)
>>> cce(y_true, y_pred)
array([3.2058331e-05, 4.6627346e-01], dtype=float32)
与compile() API一起使用:
model.compile(optimizer='adam',
loss=keras.losses.CategoricalFocalCrossentropy())
SparseCategoricalCrossentropy classkeras.losses.SparseCategoricalCrossentropy(
from_logits=False,
ignore_class=None,
reduction="sum_over_batch_size",
name="sparse_categorical_crossentropy",
dtype=None,
)
计算标签和预测之间的交叉熵损失.
当有两个或更多标签类别时使用此交叉熵损失函数.我们期望标签以整数形式提供.如果您想使用one-hot表示法提供标签,请使用CategoricalCrossentropy损失.对于y_pred,每个特征应有# classes个浮点值,而对于y_true,每个特征应有一个浮点值.
在下面的代码片段中,y_true每个示例有一个浮点值,而y_pred每个示例有num_classes个浮点值.y_true的形状是[batch_size],而y_pred的形状是[batch_size, num_classes].
参数:
from_logits: 是否期望y_pred是一个logits张量.默认情况下,我们假设y_pred编码了一个概率分布.
reduction: 应用于损失的缩减类型.在几乎所有情况下,这应该是"sum_over_batch_size".
支持的选项是"sum"、"sum_over_batch_size"或None.
name: 损失实例的可选名称.
dtype: 损失计算的数据类型.默认为None,这意味着使用keras.backend.floatx().keras.backend.floatx()是一个"float32",除非设置为不同的值
(通过keras.backend.set_floatx()).如果提供了keras.DTypePolicy,则将使用compute_dtype.
示例:
>>> y_true = [1, 2]
>>> y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]]
>>> # 使用'auto'/'sum_over_batch_size'缩减类型.
>>> scce = keras.losses.SparseCategoricalCrossentropy()
>>> scce(y_true, y_pred)
1.177
>>> # 使用'sample_weight'调用.
>>> scce(y_true, y_pred, sample_weight=np.array([0.3, 0.7]))
0.814
>>> # 使用'sum'缩减类型.
>>> scce = keras.losses.SparseCategoricalCrossentropy(
... reduction="sum")
>>> scce(y_true, y_pred)
2.354
>>> # 使用'none'缩减类型.
>>> scce = keras.losses.SparseCategoricalCrossentropy(
... reduction=None)
>>> scce(y_true, y_pred)
array([0.0513, 2.303], dtype=float32)
使用compile() API:
model.compile(optimizer='sgd',
loss=keras.losses.SparseCategoricalCrossentropy())
Poisson classkeras.losses.Poisson(reduction="sum_over_batch_size", name="poisson", dtype=None)
计算 y_true 和 y_pred 之间的泊松损失.
公式:
loss = y_pred - y_true * log(y_pred)
参数:
reduction: 应用于损失的归约类型.在几乎所有情况下,这应该是 "sum_over_batch_size".
支持的选项是 "sum"、"sum_over_batch_size" 或 None.
name: 损失实例的可选名称.
dtype: 损失计算的数据类型.默认为 None,这意味着使用 keras.backend.floatx().keras.backend.floatx() 是 "float32",除非设置为不同的值
(通过 keras.backend.set_floatx()).如果提供了 keras.DTypePolicy,则将使用 compute_dtype.
binary_crossentropy functionkeras.losses.binary_crossentropy(
y_true, y_pred, from_logits=False, label_smoothing=0.0, axis=-1
)
计算二元交叉熵损失.
参数:
y_true: 真实值.形状 = [batch_size, d0, .. dN].
y_pred: 预测值.形状 = [batch_size, d0, .. dN].
from_logits: 是否期望 y_pred 是一个 logits 张量.默认情况下,我们假设 y_pred 编码了一个概率分布.
label_smoothing: [0, 1] 范围内的浮点数.如果 > 0,则通过将标签向 0.5 挤压来平滑标签,即,
使用 1. - 0.5 * label_smoothing 作为目标类别
和 0.5 * label_smoothing 作为非目标类别.
axis: 计算均值的轴.默认为 -1.
返回:
二元交叉熵损失值.形状 = [batch_size, d0, .. dN-1].
示例:
>>> y_true = [[0, 1], [0, 0]]
>>> y_pred = [[0.6, 0.4], [0.4, 0.6]]
>>> loss = keras.losses.binary_crossentropy(y_true, y_pred)
>>> assert loss.shape == (2,)
>>> loss
array([0.916 , 0.714], dtype=float32)
categorical_crossentropy functionkeras.losses.categorical_crossentropy(
y_true, y_pred, from_logits=False, label_smoothing=0.0, axis=-1
)
计算分类交叉熵损失.
参数:
y_true: 独热编码的真实目标张量.
y_pred: 预测目标张量.
from_logits: 是否期望y_pred是一个logits张量.默认情况下,我们假设y_pred编码了一个概率分布.
label_smoothing: [0, 1]之间的浮点数.如果大于0,则平滑标签.例如,如果0.1,则对非目标标签使用0.1 / num_classes,对目标标签使用0.9 + 0.1 / num_classes.
axis: 默认为-1.计算熵的维度.
返回: 分类交叉熵损失值.
示例:
>>> y_true = [[0, 1, 0], [0, 0, 1]]
>>> y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]]
>>> loss = keras.losses.categorical_crossentropy(y_true, y_pred)
>>> assert loss.shape == (2,)
>>> loss
array([0.0513, 2.303], dtype=float32)
sparse_categorical_crossentropy functionkeras.losses.sparse_categorical_crossentropy(
y_true, y_pred, from_logits=False, ignore_class=None, axis=-1
)
计算稀疏分类交叉熵损失.
参数:
y_true: 真实值.
y_pred: 预测值.
from_logits: 是否期望y_pred是一个logits张量.默认情况下,我们假设y_pred编码了一个概率分布.
ignore_class: 可选整数.在计算损失时忽略的类ID.这在分割问题中很有用,例如在分割图中有一个"void”类(通常为-1或255).默认情况下(ignore_class=None),所有类别都会被考虑.
axis: 默认为-1.计算熵的维度.
返回: 稀疏分类交叉熵损失值.
示例:
>>> y_true = [1, 2]
>>> y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]]
>>> loss = keras.losses.sparse_categorical_crossentropy(y_true, y_pred)
>>> assert loss.shape == (2,)
>>> loss
array([0.0513, 2.303], dtype=float32)
poisson functionkeras.losses.poisson(y_true, y_pred)
计算 y_true 和 y_pred 之间的泊松损失.
公式:
loss = y_pred - y_true * log(y_pred)
参数:
y_true: 真实值.形状 = [batch_size, d0, .. dN].
y_pred: 预测值.形状 = [batch_size, d0, .. dN].
返回:
泊松损失值,形状 = [batch_size, d0, .. dN-1].
示例:
>>> y_true = np.random.randint(0, 2, size=(2, 3))
>>> y_pred = np.random.random(size=(2, 3))
>>> loss = keras.losses.poisson(y_true, y_pred)
>>> assert loss.shape == (2,)
>>> y_pred = y_pred + 1e-7
>>> assert np.allclose(
... loss, np.mean(y_pred - y_true * np.log(y_pred), axis=-1),
... atol=1e-5)
KLDivergence classkeras.losses.KLDivergence(
reduction="sum_over_batch_size", name="kl_divergence", dtype=None
)
计算 y_true 和 y_pred 之间的 Kullback-Leibler 散度损失.
公式:
loss = y_true * log(y_true / y_pred)
y_true 和 y_pred 应为概率分布,其值在 0 到 1 之间.它们将被裁剪到 [0, 1] 范围内.
参数:
reduction: 应用于损失的归约类型.在几乎所有情况下,这应该是 "sum_over_batch_size".
支持的选项是 "sum"、"sum_over_batch_size" 或 None.
name: 损失实例的可选名称.
dtype: 损失计算的数据类型.默认为 None,这意味着使用 keras.backend.floatx().keras.backend.floatx() 是 "float32",除非设置为不同的值
(通过 keras.backend.set_floatx()).如果提供了 keras.DTypePolicy,则将使用 compute_dtype.
kl_divergence functionkeras.losses.kl_divergence(y_true, y_pred)
计算 y_true 和 y_pred 之间的 Kullback-Leibler 散度损失.
公式:
loss = y_true * log(y_true / y_pred)
y_true 和 y_pred 应为概率分布,取值范围在 0 到 1 之间.它们将被裁剪到 [0, 1] 范围内.
参数: y_true: 真实目标的张量. y_pred: 预测目标的张量.
返回:
KL 散度损失值,形状为 [batch_size, d0, .. dN-1].
示例:
>>> y_true = np.random.randint(0, 2, size=(2, 3)).astype(np.float32)
>>> y_pred = np.random.random(size=(2, 3))
>>> loss = keras.losses.kl_divergence(y_true, y_pred)
>>> assert loss.shape == (2,)
>>> y_true = ops.clip(y_true, 1e-7, 1)
>>> y_pred = ops.clip(y_pred, 1e-7, 1)
>>> assert np.array_equal(
... loss, np.sum(y_true * np.log(y_true / y_pred), axis=-1))
CTC classkeras.losses.CTC(reduction="sum_over_batch_size", name="ctc", dtype=None)
CTC(连接主义时间分类)损失.
参数:
reduction: 应用于损失的归约类型.在几乎所有情况下,这应该是"sum_over_batch_size".
支持的选项是"sum"、"sum_over_batch_size"或None.
name: 损失实例的可选名称.
dtype: 损失计算的数据类型.默认为None,这意味着使用keras.backend.floatx().keras.backend.floatx()是
"float32",除非设置为不同值(通过keras.backend.set_floatx()).如果提供了keras.DTypePolicy,
则将使用compute_dtype.