diff --git a/docs/Examples/tf_image_classification_Indoorscenes_dataset.py b/docs/Examples/tf_image_classification_Indoorscenes_dataset.py index 25841e5..db63944 100644 --- a/docs/Examples/tf_image_classification_Indoorscenes_dataset.py +++ b/docs/Examples/tf_image_classification_Indoorscenes_dataset.py @@ -41,15 +41,23 @@ ############################################################################ -openml_tensorflow.config.epoch = 10 # small epoch for test runs +openml_tensorflow.config.epoch = 1 # small epoch for test runs IMG_SIZE = (128, 128) IMG_SHAPE = IMG_SIZE + (3,) base_learning_rate = 0.0001 -# dataset = openml.datasets.get_dataset(45936, download_all_files=True, download_data=True) - # Toy example +datagen = ImageDataGenerator( + rotation_range=25, + width_shift_range=0.01, + height_shift_range=0.01, + brightness_range=(0.9, 1.1), + zoom_range=0.1, + horizontal_flip=True, + vertical_flip=True, +) + openml_tensorflow.config.datagen = datagen openml_tensorflow.config.dir = openml.config.get_cache_directory()+'/datasets/45936/Images/' openml_tensorflow.config.x_col = "Filename" @@ -69,16 +77,6 @@ ############################################################################ # Large CNN -datagen = ImageDataGenerator( - rotation_range=25, - width_shift_range=0.01, - height_shift_range=0.01, - brightness_range=(0.9, 1.1), - zoom_range=0.1, - horizontal_flip=True, - vertical_flip=True, -) - IMG_SIZE = 128 NUM_CLASSES = 67 @@ -144,7 +142,7 @@ # Careful to not call this function when another run_model_on_task is called in between, # as during publish later, only the last trained model (from last run_model_on_task call) is uploaded. run = openml_tensorflow.add_onnx_to_run(run) -# breakpoint() + run.publish() print('URL for run: %s/run/%d?api_key=%s' % (openml.config.server, run.run_id, openml.config.apikey)) diff --git a/model.onnx b/model.onnx new file mode 100644 index 0000000..f74aa10 Binary files /dev/null and b/model.onnx differ diff --git a/openml_tensorflow/extension.py b/openml_tensorflow/extension.py index 5d79888..f305241 100644 --- a/openml_tensorflow/extension.py +++ b/openml_tensorflow/extension.py @@ -430,8 +430,8 @@ def _from_parameters(self, parameters: 'OrderedDict[str, Any]') -> Any: # Recover loss functions and metrics loss = training_config['loss'] metrics = training_config['metrics'] - sample_weight_mode = training_config['sample_weight_mode'] - loss_weights = training_config['loss_weights'] + sample_weight_mode = training_config.get('sample_weight_mode', None) + loss_weights = training_config.get('loss_weights', None) # Compile model model.compile(optimizer=optimizer, diff --git a/tests/test_compare_onnx_models.py b/tests/test_compare_onnx_models.py index 562a57e..6f0d68c 100644 --- a/tests/test_compare_onnx_models.py +++ b/tests/test_compare_onnx_models.py @@ -1,5 +1,16 @@ +""" +Below pytest test compares two onnx models for identical structure and parameters. +""" import onnx import numpy as np +import os +import pytest + +# Paths to ONNX models +MODEL_PATH1 = "model1.onnx" +MODEL_PATH2 = "model2.onnx" + +# Helper function to compare graph structures def compare_graphs(graph1, graph2): nodes1 = graph1.node nodes2 = graph2.node @@ -17,12 +28,12 @@ def compare_graphs(graph1, graph2): print("Graph structures are identical.") return True -def compare_models(model_path1, model_path2): +# Helper function to compare model parameters +def compare_parameters(model_path1, model_path2): # Load ONNX models model1 = onnx.load(model_path1) model2 = onnx.load(model_path2) - # Compare graph structures # Compare graph structures if not compare_graphs(model1.graph, model2.graph): return False @@ -40,9 +51,19 @@ def compare_models(model_path1, model_path2): print("Models are identical.") return True -# Paths to ONNX models -model_path1 = "model1.onnx" -model_path2 = "model2.onnx" -# Compare models -compare_models(model_path1, model_path2) +@pytest.mark.skipif( + not (os.path.exists("model1.onnx") and os.path.exists("model2.onnx")), + reason="ONNX models are not available" +) +def test_compare_onnx_models(): + # Load ONNX models + model1 = onnx.load(MODEL_PATH1) + model2 = onnx.load(MODEL_PATH2) + + # Perform comparisons + assert compare_graphs(model1.graph, model2.graph), "Graph structures are different." + assert compare_parameters(model1, model2), "Model parameters are different." + + print("ONNX models are identical.") + diff --git a/tests/test_keras_extension.py b/tests/test_keras_extension.py deleted file mode 100644 index 6f40e15..0000000 --- a/tests/test_keras_extension.py +++ /dev/null @@ -1,71 +0,0 @@ -import sys -import os -import openml -from openml_keras import KerasExtension -from openml.exceptions import PyOpenMLError -from openml.flows import OpenMLFlow -from openml.flows.functions import assert_flows_equal -from openml.runs.trace import OpenMLRunTrace -from openml.testing import TestBase, SimpleImputer -import keras -from collections import OrderedDict -import unittest - - -this_directory = os.path.dirname(os.path.abspath(__file__)) -sys.path.append(this_directory) - -__version__ = 0.1 - - -class TestKerasExtensionFlowFunctions(unittest.TestCase): - # def setUp(self): - # super().setUp(n_levels=2) - # self.extension = KerasExtension() - - def test_serialize_model(self): - self.extension = KerasExtension() - - model = keras.models.Sequential([ - keras.layers.BatchNormalization(), - keras.layers.Dense(units=1024, activation=keras.activations.relu), - keras.layers.Dropout(rate=0.4), - keras.layers.Dense(units=2, activation=keras.activations.softmax), - ]) - - # We will compile using the Adam optimizer while targeting accuracy. - model.compile(optimizer='adam', - loss='sparse_categorical_crossentropy', - metrics=['accuracy']) - fixture_name = 'keras.engine.sequential.Sequential.3004bddd' - fixture_description = 'Automatically created keras flow.' - version_fixture = 'keras==2.2.4' \ - 'numpy>=1.6.1' \ - 'scipy>=0.9 ' - fixture_parameters = OrderedDict((('backend','"tensorflow"'), - ('class_name','"Sequential"'), - ('config','{"name": "sequential_1"}'), - ('keras_version','"2.2.4"'), - ('layer0_batch_normalization_1','{"class_name": "BatchNormalization", "config": {"axis": -1, "beta_constraint": null, "beta_initializer": {"class_name": "Zeros", "config": {}}, "beta_regularizer": null, "center": true, "epsilon": 0.001, "gamma_constraint": null, "gamma_initializer": {"class_name": "Ones", "config": {}}, "gamma_regularizer": null, "momentum": 0.99, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "name": "batch_normalization_1", "scale": true, "trainable": true}}'), - ('layer1_dense_1','{"class_name": "Dense", "config": {"activation": "relu", "activity_regularizer": null, "bias_constraint": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "bias_regularizer": null, "kernel_constraint": null, "kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "mode": "fan_avg", "scale": 1.0, "seed": null}}, "kernel_regularizer": null, "name": "dense_1", "trainable": true, "units": 1024, "use_bias": true}}'), - ('layer2_dropout_1','{"class_name": "Dropout", "config": {"name": "dropout_1", "noise_shape": null, "rate": 0.4, "seed": null, "trainable": true}}'), - ('layer3_dense_2','{"class_name": "Dense", "config": {"activation": "softmax", "activity_regularizer": null, "bias_constraint": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "bias_regularizer": null, "kernel_constraint": null, "kernel_initializer": {"class_name": "VarianceScaling", "config": {"distribution": "uniform", "mode": "fan_avg", "scale": 1.0, "seed": null}}, "kernel_regularizer": null, "name": "dense_2", "trainable": true, "units": 2, "use_bias": true}}'), - ('optimizer','{"loss": "sparse_categorical_crossentropy", "loss_weights": null, "metrics": ["accuracy"], "optimizer_config": {"class_name": "Adam", "config": {"amsgrad": false, "beta_1": 0.8999999761581421, "beta_2": 0.9990000128746033, "decay": 0.0, "epsilon": 1e-07, "lr": 0.0010000000474974513}}, "sample_weight_mode": null, "weighted_metrics": null}') - )) - structure_fixture = {'keras.engine.sequential.Sequential.3004bddd':[]} - serialization = self.extension.model_to_flow(model) - structure = serialization.get_structure('name') - print(serialization.dependencies) - assert serialization.name == fixture_name - self.assertEqual(serialization.name, fixture_name) - self.assertEqual(serialization.class_name, fixture_name) - self.assertEqual(serialization.description, fixture_description) - self.assertEqual(serialization.parameters, fixture_parameters) - # self.assertEqual(serialization.dependencies, version_fixture) - self.assertDictEqual(structure, structure_fixture) - - new_model = self.extension.flow_to_model(serialization) - - self.assertEqual(type(new_model), type(model)) - self.assertIsNot(new_model, model) -