keras/keras_core/trainers/compile_utils_test.py

280 lines
10 KiB
Python
Raw Normal View History

2023-04-16 19:21:29 +00:00
import numpy as np
2023-06-12 05:36:06 +00:00
from absl.testing import parameterized
2023-04-16 20:30:21 +00:00
2023-04-16 19:21:29 +00:00
from keras_core import backend
2023-04-17 21:55:17 +00:00
from keras_core import metrics as losses_module
2023-04-17 22:41:48 +00:00
from keras_core import metrics as metrics_module
2023-04-16 20:30:21 +00:00
from keras_core import testing
2023-04-17 21:55:17 +00:00
from keras_core.trainers.compile_utils import CompileLoss
2023-04-17 22:41:48 +00:00
from keras_core.trainers.compile_utils import CompileMetrics
2023-04-16 01:51:10 +00:00
2023-04-16 20:30:21 +00:00
2023-04-16 19:21:29 +00:00
class TestCompileMetrics(testing.TestCase):
def test_single_output_case(self):
compile_metrics = CompileMetrics(
2023-04-17 22:41:48 +00:00
metrics=[metrics_module.MeanSquaredError()],
weighted_metrics=[metrics_module.MeanSquaredError()],
2023-04-16 19:21:29 +00:00
)
# Test symbolic build
2023-04-16 20:30:21 +00:00
y_true, y_pred = backend.KerasTensor((3, 4)), backend.KerasTensor(
(3, 4)
)
2023-04-16 19:21:29 +00:00
compile_metrics.build(y_true, y_pred)
# Test eager build
2023-04-16 20:28:02 +00:00
y_true = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])
y_pred = np.array([[0.4, 0.1], [0.2, 0.6], [0.6, 0.1]])
2023-04-16 20:30:21 +00:00
sample_weight = np.array([1, 0.0, 1])
2023-04-16 19:21:29 +00:00
compile_metrics.build(y_true, y_pred)
2023-04-16 01:51:10 +00:00
2023-04-16 19:21:29 +00:00
# Test update / result / reset flow
2023-04-16 20:30:21 +00:00
compile_metrics.update_state(
y_true, y_pred, sample_weight=sample_weight
)
2023-04-16 20:28:02 +00:00
y_pred = np.array([[0.3, 0.2], [0.1, 0.4], [0.2, 0.3]])
2023-04-16 20:30:21 +00:00
compile_metrics.update_state(
y_true, y_pred, sample_weight=sample_weight
)
2023-04-16 19:21:29 +00:00
result = compile_metrics.result()
self.assertTrue(isinstance(result, dict))
self.assertEqual(len(result), 2)
self.assertAllClose(result["mean_squared_error"], 0.055833336)
self.assertAllClose(result["weighted_mean_squared_error"], 0.0725)
2023-04-16 19:21:29 +00:00
2023-04-16 20:28:02 +00:00
compile_metrics.reset_state()
result = compile_metrics.result()
self.assertTrue(isinstance(result, dict))
self.assertEqual(len(result), 2)
self.assertAllClose(result["mean_squared_error"], 0.0)
self.assertAllClose(result["weighted_mean_squared_error"], 0.0)
2023-04-16 20:28:02 +00:00
def test_list_output_case(self):
compile_metrics = CompileMetrics(
metrics=[
2023-04-16 20:30:21 +00:00
[
2023-04-17 22:41:48 +00:00
metrics_module.MeanSquaredError(),
metrics_module.MeanSquaredError(),
2023-04-16 20:30:21 +00:00
],
[
2023-04-17 22:41:48 +00:00
metrics_module.MeanSquaredError(),
metrics_module.MeanSquaredError(),
2023-04-16 20:30:21 +00:00
],
2023-04-16 20:28:02 +00:00
],
weighted_metrics=[
2023-04-16 20:30:21 +00:00
[
2023-04-17 22:41:48 +00:00
metrics_module.MeanSquaredError(),
metrics_module.MeanSquaredError(),
2023-04-16 20:30:21 +00:00
],
[
2023-04-17 22:41:48 +00:00
metrics_module.MeanSquaredError(),
metrics_module.MeanSquaredError(),
2023-04-16 20:30:21 +00:00
],
2023-04-16 20:28:02 +00:00
],
)
# Test symbolic build
y_true = [backend.KerasTensor((3, 4)), backend.KerasTensor((3, 4))]
y_pred = [backend.KerasTensor((3, 4)), backend.KerasTensor((3, 4))]
compile_metrics.build(y_true, y_pred)
# Test eager build
y_true = [
np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]]),
np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]]),
]
y_pred = [
np.array([[0.4, 0.1], [0.2, 0.6], [0.6, 0.1]]),
np.array([[0.4, 0.1], [0.2, 0.6], [0.6, 0.1]]),
]
2023-04-16 20:30:21 +00:00
sample_weight = np.array([1, 0.0, 1])
2023-04-16 20:28:02 +00:00
compile_metrics.build(y_true, y_pred)
# Test update / result / reset flow
2023-04-16 20:30:21 +00:00
compile_metrics.update_state(
y_true, y_pred, sample_weight=sample_weight
)
2023-04-16 20:28:02 +00:00
y_pred = [
np.array([[0.3, 0.2], [0.1, 0.4], [0.2, 0.3]]),
np.array([[0.3, 0.2], [0.1, 0.4], [0.2, 0.3]]),
]
2023-04-16 20:30:21 +00:00
compile_metrics.update_state(
y_true, y_pred, sample_weight=sample_weight
)
2023-04-16 20:28:02 +00:00
result = compile_metrics.result()
self.assertTrue(isinstance(result, dict))
self.assertEqual(len(result), 8)
self.assertAllClose(result["mean_squared_error"], 0.055833336)
self.assertAllClose(result["weighted_mean_squared_error"], 0.0725)
2023-04-16 20:28:02 +00:00
compile_metrics.reset_state()
result = compile_metrics.result()
self.assertTrue(isinstance(result, dict))
self.assertEqual(len(result), 8)
self.assertAllClose(result["mean_squared_error"], 0.0)
self.assertAllClose(result["weighted_mean_squared_error"], 0.0)
2023-04-16 20:28:02 +00:00
def test_dict_output_case(self):
compile_metrics = CompileMetrics(
metrics={
2023-04-16 20:30:21 +00:00
"output_1": [
2023-04-17 22:41:48 +00:00
metrics_module.MeanSquaredError(),
metrics_module.MeanSquaredError(),
2023-04-16 20:30:21 +00:00
],
"output_2": [
2023-04-17 22:41:48 +00:00
metrics_module.MeanSquaredError(),
metrics_module.MeanSquaredError(),
2023-04-16 20:30:21 +00:00
],
2023-04-16 20:28:02 +00:00
},
weighted_metrics={
2023-04-16 20:30:21 +00:00
"output_1": [
2023-04-17 22:41:48 +00:00
metrics_module.MeanSquaredError(),
metrics_module.MeanSquaredError(),
2023-04-16 20:30:21 +00:00
],
"output_2": [
2023-04-17 22:41:48 +00:00
metrics_module.MeanSquaredError(),
metrics_module.MeanSquaredError(),
2023-04-16 20:30:21 +00:00
],
2023-04-16 20:28:02 +00:00
},
)
# Test symbolic build
y_true = {
"output_1": backend.KerasTensor((3, 4)),
2023-04-16 20:30:21 +00:00
"output_2": backend.KerasTensor((3, 4)),
2023-04-16 20:28:02 +00:00
}
y_pred = {
"output_1": backend.KerasTensor((3, 4)),
2023-04-16 20:30:21 +00:00
"output_2": backend.KerasTensor((3, 4)),
2023-04-16 20:28:02 +00:00
}
compile_metrics.build(y_true, y_pred)
# Test eager build
y_true = {
"output_1": np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]]),
"output_2": np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]]),
}
y_pred = {
"output_1": np.array([[0.4, 0.1], [0.2, 0.6], [0.6, 0.1]]),
"output_2": np.array([[0.4, 0.1], [0.2, 0.6], [0.6, 0.1]]),
}
2023-04-16 20:30:21 +00:00
sample_weight = np.array([1, 0.0, 1])
2023-04-16 20:28:02 +00:00
compile_metrics.build(y_true, y_pred)
# Test update / result / reset flow
2023-04-16 20:30:21 +00:00
compile_metrics.update_state(
y_true, y_pred, sample_weight=sample_weight
)
2023-04-16 20:28:02 +00:00
y_pred = {
"output_1": np.array([[0.3, 0.2], [0.1, 0.4], [0.2, 0.3]]),
"output_2": np.array([[0.3, 0.2], [0.1, 0.4], [0.2, 0.3]]),
}
2023-04-16 20:30:21 +00:00
compile_metrics.update_state(
y_true, y_pred, sample_weight=sample_weight
)
2023-04-16 20:28:02 +00:00
result = compile_metrics.result()
self.assertTrue(isinstance(result, dict))
self.assertEqual(len(result), 8)
self.assertAllClose(result["mean_squared_error"], 0.055833336)
self.assertAllClose(result["weighted_mean_squared_error"], 0.0725)
2023-04-16 20:28:02 +00:00
compile_metrics.reset_state()
result = compile_metrics.result()
self.assertTrue(isinstance(result, dict))
self.assertEqual(len(result), 8)
self.assertAllClose(result["mean_squared_error"], 0.0)
self.assertAllClose(result["weighted_mean_squared_error"], 0.0)
2023-04-16 20:30:21 +00:00
def test_name_conversions(self):
compile_metrics = CompileMetrics(
metrics=["acc", "accuracy"],
weighted_metrics=[],
)
y_true = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])
y_pred = np.array([[0.4, 0.1], [0.2, 0.6], [0.6, 0.1]])
compile_metrics.build(y_true, y_pred)
compile_metrics.update_state(y_true, y_pred, sample_weight=None)
result = compile_metrics.result()
self.assertTrue(isinstance(result, dict))
self.assertEqual(len(result), 2)
self.assertAllClose(result["acc"], 0.333333)
self.assertAllClose(result["accuracy"], 0.333333)
2023-04-16 19:21:29 +00:00
2023-06-12 05:36:06 +00:00
class TestCompileLoss(testing.TestCase, parameterized.TestCase):
2023-04-16 20:30:21 +00:00
def test_single_output_case(self):
2023-04-17 21:55:17 +00:00
compile_loss = CompileLoss(
2023-04-17 22:41:48 +00:00
loss=losses_module.MeanSquaredError(),
2023-04-17 21:55:17 +00:00
)
# Test symbolic build
y_true, y_pred = backend.KerasTensor((3, 4)), backend.KerasTensor(
(3, 4)
)
compile_loss.build(y_true, y_pred)
# Test eager build
y_true = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])
y_pred = np.array([[0.4, 0.1], [0.2, 0.6], [0.6, 0.1]])
compile_loss.build(y_true, y_pred)
value = compile_loss(y_true, y_pred)
2023-04-17 22:41:48 +00:00
self.assertAllClose(value, 0.068333, atol=1e-5)
2023-06-12 05:36:06 +00:00
@parameterized.parameters(True, False)
def test_list_output_case(self, broadcast):
if broadcast:
# Test broadcasting single loss to all outputs
compile_loss = CompileLoss(
loss="mse",
)
else:
compile_loss = CompileLoss(
loss=["mse", "mse"],
)
# Test symbolic build
y_true = [backend.KerasTensor((3, 4)), backend.KerasTensor((3, 4))]
y_pred = [backend.KerasTensor((3, 4)), backend.KerasTensor((3, 4))]
compile_loss.build(y_true, y_pred)
# Test eager build
y_true = [
np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]]),
np.array([[0.7, 0.8], [0.9, 1.0], [1.1, 1.2]]),
]
y_pred = [
np.array([[1.2, 1.1], [1.0, 0.9], [0.8, 0.7]]),
np.array([[0.6, 0.5], [0.4, 0.3], [0.2, 0.1]]),
]
compile_loss.build(y_true, y_pred)
value = compile_loss(y_true, y_pred)
self.assertAllClose(value, 0.953333, atol=1e-5)
@parameterized.parameters(True, False)
def test_dict_output_case(self, broadcast):
if broadcast:
# Test broadcasting single loss to all outputs
compile_loss = CompileLoss(
loss="mse",
)
else:
compile_loss = CompileLoss(
loss={"a": "mse", "b": "mse"},
)
# Test symbolic build
y_true = {
"a": backend.KerasTensor((3, 4)),
"b": backend.KerasTensor((3, 4)),
}
y_pred = {
"a": backend.KerasTensor((3, 4)),
"b": backend.KerasTensor((3, 4)),
}
compile_loss.build(y_true, y_pred)
# Test eager build
y_true = {
"a": np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]]),
"b": np.array([[0.7, 0.8], [0.9, 1.0], [1.1, 1.2]]),
}
y_pred = {
"a": np.array([[1.2, 1.1], [1.0, 0.9], [0.8, 0.7]]),
"b": np.array([[0.6, 0.5], [0.4, 0.3], [0.2, 0.1]]),
}
sample_weight = {
"a": np.array([1.0, 2.0, 3.0]),
"b": np.array([3.0, 2.0, 1.0]),
}
2023-06-12 05:36:06 +00:00
compile_loss.build(y_true, y_pred)
value = compile_loss(y_true, y_pred, sample_weight)
self.assertAllClose(value, 1.266666, atol=1e-5)