正如Tensorflow documentation 中所解释的,MSE 是通过对整个张量大小(SUM 损失减少)或整个批次大小(SUM_OVER_BATCH_SIZE 损失减少)的平方误差进行平均来计算的。下面的代码显示了如何复制两个 MSE 计算的一些示例。
import tensorflow as tf
y_true = [[0.0, 1.0, 0.0], [0.8, 0.9, 1.0], [1.0, 1.0, 1.0], [1.0, 0.0, 0.0]]
y_pred = [[0.0, 0.8, 0.9], [0.5, 0.7, 0.6], [0.8, 0.7, 0.5], [0.9, 0.1, 0.3]]
##############################################
# Loss reduction: "SUM"
##############################################
reduction = tf.keras.losses.Reduction.SUM
mse_1 = tf.keras.losses.MeanSquaredError(reduction=reduction)
print(mse_1(y_true, y_pred))
# tf.Tensor(0.54333335, shape=(), dtype=float32)
def MSE_1(y_true, y_pred):
x = tf.reduce_sum(tf.square(tf.subtract(y_true, y_pred)))
y = tf.cast(tf.shape(y_true)[1], tf.float32) # divide by the shape of the tensor
return tf.divide(x, y)
print(MSE_1(y_true, y_pred))
# tf.Tensor(0.54333335, shape=(), dtype=float32)
##############################################
# Loss reduction: "SUM_OVER_BATCH_SIZE"
##############################################
reduction = tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE
mse_2 = tf.keras.losses.MeanSquaredError(reduction=reduction)
print(mse_2(y_true, y_pred))
# tf.Tensor(0.13583334, shape=(), dtype=float32)
def MSE_2(y_true, y_pred):
x = tf.reduce_sum(tf.square(tf.subtract(y_true, y_pred)))
y = tf.cast(tf.multiply(tf.shape(y_true)[0], tf.shape(y_true)[1]), tf.float32) # divide by the size of the tensor
return tf.divide(x, y)
print(MSE_2(y_true, y_pred))
# tf.Tensor(0.13583334, shape=(), dtype=float32)
##############################################
# Loss reduction: "NONE"
##############################################
reduction = tf.keras.losses.Reduction.NONE
mse_3 = tf.keras.losses.MeanSquaredError(reduction=reduction)
print(mse_3(y_true, y_pred))
# tf.Tensor([0.28333333 0.09666666 0.12666667 0.03666667], shape=(4,), dtype=float32)
def MSE_3(y_true, y_pred):
x = tf.reduce_sum(tf.square(tf.subtract(y_true, y_pred)), axis=1)
y = tf.cast(tf.shape(y_true)[1], tf.float32) # divide by the shape of the tensor
return tf.divide(x, y)
print(MSE_3(y_true, y_pred))
# tf.Tensor([0.28333333 0.09666666 0.12666667 0.03666667], shape=(4,), dtype=float32)
# recover "SUM" loss reduction
print(tf.reduce_sum(mse_3(y_true, y_pred)))
# tf.Tensor(0.54333335, shape=(), dtype=float32)
print(tf.reduce_sum(MSE_3(y_true, y_pred)))
# tf.Tensor(0.54333335, shape=(), dtype=float32)
# recover "SUM_OVER_BATCH_SIZE" loss reduction
print(tf.divide(tf.reduce_sum(mse_3(y_true, y_pred)), tf.cast(tf.shape(y_true)[0], tf.float32)))
# tf.Tensor(0.13583334, shape=(), dtype=float32)
print(tf.divide(tf.reduce_sum(MSE_3(y_true, y_pred)), tf.cast(tf.shape(y_true)[0], tf.float32)))
# tf.Tensor(0.13583334, shape=(), dtype=float32)