webdevqa.jp.net

Tensorflow Keras RMSEメトリックは、自分で作成したRMSE損失関数とは異なる結果を返します

これは回帰問題です

私のカスタムRMSE損失:

def root_mean_squared_error_loss(y_true, y_pred):
    return tf.keras.backend.sqrt(tf.keras.losses.MSE(y_true, y_pred))

トレーニングコードサンプル。create_modelは、完全に接続された密な順次モデルを返します。

from tensorflow.keras.metrics import RootMeanSquaredError
model = create_model()
model.compile(loss=root_mean_squared_error_loss, optimizer='adam', metrics=[RootMeanSquaredError()])

model.fit(train_.values,
          targets,
          validation_split=0.1,
          verbose=1,
          batch_size=32)
Train on 3478 samples, validate on 387 samples
Epoch 1/100
3478/3478 [==============================] - 2s 544us/sample - loss: 1.1983 - root_mean_squared_error: 0.7294 - val_loss: 0.7372 - val_root_mean_squared_error: 0.1274
Epoch 2/100
3478/3478 [==============================] - 1s 199us/sample - loss: 0.8371 - root_mean_squared_error: 0.3337 - val_loss: 0.7090 - val_root_mean_squared_error: 0.1288
Epoch 3/100
3478/3478 [==============================] - 1s 187us/sample - loss: 0.7336 - root_mean_squared_error: 0.2468 - val_loss: 0.6366 - val_root_mean_squared_error: 0.1062
Epoch 4/100
3478/3478 [==============================] - 1s 187us/sample - loss: 0.6668 - root_mean_squared_error: 0.2177 - val_loss: 0.5823 - val_root_mean_squared_error: 0.0818

Lossとroot_mean_squared_errorの両方が同じ値であると予想しましたが、なぜ違いがあるのですか?

3
ma7555

ソースコード からの2つの主な違い:

  1. RMSEstatefulメトリックです(メモリを保持します)-あなたはステートレスです
  2. 平方根が適用されます _axis=-1_平均の前ではなく、グローバル平均を取る MSEが行う
    • 1の結果、2はより複雑になります。別の実行量totalに対して、実行量の平均countが取得されます。両方の量は RMSE.reset_states() によってリセットされます。

生の式の修正は簡単ですが、この質問の範囲を超えているため、ステートフル性を統合するには作業が必要になります。ソースコードを参照して 方法 を確認してください。以下の比較付きの2の修正。


_import numpy as np
import tensorflow as tf
from tensorflow.keras.metrics import RootMeanSquaredError as RMSE

def root_mean_squared_error_loss(y_true, y_pred):
    return tf.sqrt(tf.reduce_mean(tf.math.squared_difference(y_true, y_pred)))

np.random.seed(0)

#%%###########################################################################
rmse = RMSE(dtype='float64')
rmsel = root_mean_squared_error_loss

x1 = np.random.randn(32, 10)
y1 = np.random.randn(32, 10)
x2 = np.random.randn(32, 10)
y2 = np.random.randn(32, 10)

#%%###########################################################################
print("TensorFlow RMSE:")
print(rmse(x1, y1))
print(rmse(x2, y2))
print("=" * 46)
print(rmse(x1, y1))
print(rmse(x2, y2))

print("\nMy RMSE:")
print(rmsel(x1, y1))
print(rmsel(x2, y2))
_
_TensorFlow RMSE:
tf.Tensor(1.4132492562096124, shape=(), dtype=float64)
tf.Tensor(1.3875944990740972, shape=(), dtype=float64)
==============================================
tf.Tensor(1.3961984634354354, shape=(), dtype=float64)  # same inputs, different result
tf.Tensor(1.3875944990740972, shape=(), dtype=float64)  # same inputs, different result

My RMSE:
tf.Tensor(1.4132492562096124, shape=(), dtype=float64)  # first result agrees
tf.Tensor(1.3614563994283353, shape=(), dtype=float64)  # second differs since stateless
_
2