Skip to content

Commit

Permalink
Support Keras 3 with TF backend (#1908)
Browse files Browse the repository at this point in the history
* initial renaming

* renaming tree

* rename tensorflow.keras

* update

* update version numbers

* update imports to keras

* now the tests can run bug failed some

* fix more tests

* fix more tests

* fix more tests

* removed structured data and time series, object detection, and segmentation

* remove structured data from docs

* fix docs

* minor fix

* fix more tests

* fix more tests

* fix more tests

* update docs

* update

* fix more tests

* add notes & improve coverage

* fix tests

* update

* update

* update input block

* fix coverage

* update the tutorials
  • Loading branch information
haifeng-jin authored Mar 20, 2024
1 parent ec4ebd1 commit cbffa8b
Show file tree
Hide file tree
Showing 114 changed files with 514 additions and 6,756 deletions.
22 changes: 22 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# Release v2.0.0

## Breaking changes

* Requires `keras>=3.0.0` instead of `tf.keras`.
* Removed the structured data related tasks by removing the following public
APIs:
* `CategoricalToNumerical`
* `MultiCategoryEncoding`
* `StructuredDataInput`
* `StructuredDataBlock`
* `StructuredDataClassifier`
* `StructuredDataRegressor`
* Removed the Time series related tasks by removing the following public APIs:
* `TimeseriesInput`
* `TimeseriesForecaster`
* Reduced search space of Text related tasks by removing the following blocks.
* `Embedding`
* `TextToIntSequence`
* `TextToNgramVector`
* `Transformer`

# Release v1.1.0

## Breaking changes
Expand Down
20 changes: 1 addition & 19 deletions autokeras/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@

from autokeras.auto_model import AutoModel
from autokeras.blocks import BertBlock
from autokeras.blocks import CategoricalToNumerical
from autokeras.blocks import ClassificationHead
from autokeras.blocks import ConvBlock
from autokeras.blocks import DenseBlock
from autokeras.blocks import EfficientNetBlock
from autokeras.blocks import Embedding
from autokeras.blocks import Flatten
from autokeras.blocks import ImageAugmentation
from autokeras.blocks import ImageBlock
Expand All @@ -31,49 +29,33 @@
from autokeras.blocks import ResNetBlock
from autokeras.blocks import RNNBlock
from autokeras.blocks import SpatialReduction
from autokeras.blocks import StructuredDataBlock
from autokeras.blocks import TemporalReduction
from autokeras.blocks import TextBlock
from autokeras.blocks import TextToIntSequence
from autokeras.blocks import TextToNgramVector
from autokeras.blocks import Transformer
from autokeras.blocks import XceptionBlock
from autokeras.engine.block import Block
from autokeras.engine.head import Head
from autokeras.engine.node import Node
from autokeras.keras_layers import CastToFloat32
from autokeras.keras_layers import ExpandLastDim
from autokeras.keras_layers import MultiCategoryEncoding
from autokeras.nodes import ImageInput
from autokeras.nodes import Input
from autokeras.nodes import StructuredDataInput
from autokeras.nodes import TextInput
from autokeras.nodes import TimeseriesInput
from autokeras.tasks import ImageClassifier
from autokeras.tasks import ImageRegressor
from autokeras.tasks import StructuredDataClassifier
from autokeras.tasks import StructuredDataRegressor
from autokeras.tasks import TextClassifier
from autokeras.tasks import TextRegressor
from autokeras.tasks import TimeseriesForecaster
from autokeras.tuners import BayesianOptimization
from autokeras.tuners import Greedy
from autokeras.tuners import Hyperband
from autokeras.tuners import RandomSearch
from autokeras.utils.io_utils import image_dataset_from_directory
from autokeras.utils.io_utils import text_dataset_from_directory
from autokeras.utils.utils import check_kt_version
from autokeras.utils.utils import check_tf_version

__version__ = "1.1.1dev"

check_tf_version()
check_kt_version()
__version__ = "2.0.0dev"

CUSTOM_OBJECTS = {
"BertPreprocessor": keras_nlp.models.BertPreprocessor,
"BertBackbone": keras_nlp.models.BertBackbone,
"CastToFloat32": CastToFloat32,
"ExpandLastDim": ExpandLastDim,
"MultiCategoryEncoding": MultiCategoryEncoding,
}
3 changes: 0 additions & 3 deletions autokeras/adapters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@

from autokeras.adapters.input_adapters import ImageAdapter
from autokeras.adapters.input_adapters import InputAdapter
from autokeras.adapters.input_adapters import StructuredDataAdapter
from autokeras.adapters.input_adapters import TextAdapter
from autokeras.adapters.input_adapters import TimeseriesAdapter
from autokeras.adapters.output_adapters import ClassificationAdapter
from autokeras.adapters.output_adapters import RegressionAdapter
from autokeras.adapters.output_adapters import SegmentationHeadAdapter
38 changes: 0 additions & 38 deletions autokeras/adapters/input_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.

import numpy as np
import pandas as pd
import tensorflow as tf

from autokeras.engine import adapter as adapter_module
Expand Down Expand Up @@ -57,40 +56,3 @@ def check(self, x):
"Expect the data to TextInput to be numpy.ndarray or "
"tf.data.Dataset, but got {type}.".format(type=type(x))
)


class StructuredDataAdapter(adapter_module.Adapter):
def check(self, x):
if not isinstance(x, (pd.DataFrame, np.ndarray, tf.data.Dataset)):
raise TypeError(
"Unsupported type {type} for "
"{name}.".format(type=type(x), name=self.__class__.__name__)
)

def convert_to_dataset(self, dataset, batch_size):
if isinstance(dataset, pd.DataFrame):
dataset = dataset.values
if isinstance(dataset, np.ndarray) and dataset.dtype == object:
dataset = dataset.astype(str)
return super().convert_to_dataset(dataset, batch_size)


class TimeseriesAdapter(adapter_module.Adapter):
def __init__(self, lookback=None, **kwargs):
super().__init__(**kwargs)
self.lookback = lookback

def check(self, x):
"""Record any information needed by transform."""
if not isinstance(x, (pd.DataFrame, np.ndarray, tf.data.Dataset)):
raise TypeError(
"Expect the data in TimeseriesInput to be numpy.ndarray"
" or tf.data.Dataset or pd.DataFrame, but got {type}.".format(
type=type(x)
)
)

def convert_to_dataset(self, dataset, batch_size):
if isinstance(dataset, pd.DataFrame):
dataset = dataset.values
return super().convert_to_dataset(dataset, batch_size)
36 changes: 0 additions & 36 deletions autokeras/adapters/input_adapters_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@


import numpy as np
import pandas as pd
import pytest
import tensorflow as tf

Expand All @@ -23,25 +22,6 @@
from autokeras.utils import data_utils


def test_structured_data_input_unsupported_type_error():
with pytest.raises(TypeError) as info:
adapter = input_adapters.StructuredDataAdapter()
adapter.adapt("unknown", batch_size=32)

assert "Unsupported type" in str(info.value)


def test_structured_data_input_transform_to_dataset():
x = tf.data.Dataset.from_tensor_slices(
pd.read_csv(test_utils.TRAIN_CSV_PATH).to_numpy().astype(str)
)
adapter = input_adapters.StructuredDataAdapter()

x = adapter.adapt(x, batch_size=32)

assert isinstance(x, tf.data.Dataset)


def test_image_input_adapter_transform_to_dataset():
x = test_utils.generate_data()
adapter = input_adapters.ImageAdapter()
Expand Down Expand Up @@ -115,19 +95,3 @@ def test_text_input_type_error():
with pytest.raises(TypeError) as info:
x = adapter.adapt(x, batch_size=32)
assert "Expect the data to TextInput to be numpy" in str(info.value)


def test_time_series_input_type_error():
x = "unknown"
adapter = input_adapters.TimeseriesAdapter()
with pytest.raises(TypeError) as info:
x = adapter.adapt(x, batch_size=32)
assert "Expect the data in TimeseriesInput to be numpy" in str(info.value)


def test_time_series_input_transform_df_to_dataset():
adapter = input_adapters.TimeseriesAdapter()

x = adapter.adapt(pd.DataFrame(np.random.rand(100, 32)), batch_size=32)

assert isinstance(x, tf.data.Dataset)
14 changes: 2 additions & 12 deletions autokeras/adapters/output_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.

import numpy as np
import pandas as pd
import tensorflow as tf

from autokeras.engine import adapter as adapter_module
Expand All @@ -25,19 +24,14 @@ def __init__(self, name, **kwargs):
self.name = name

def check(self, dataset):
supported_types = (tf.data.Dataset, np.ndarray, pd.DataFrame, pd.Series)
supported_types = (tf.data.Dataset, np.ndarray)
if not isinstance(dataset, supported_types):
raise TypeError(
f"Expect the target data of {self.name} to be tf.data.Dataset,"
f" np.ndarray, pd.DataFrame or pd.Series, "
f"but got {type(dataset)}."
f" np.ndarray, but got {type(dataset)}."
)

def convert_to_dataset(self, dataset, batch_size):
if isinstance(dataset, pd.DataFrame):
dataset = dataset.values
if isinstance(dataset, pd.Series):
dataset = dataset.values
return super().convert_to_dataset(dataset, batch_size)


Expand All @@ -47,7 +41,3 @@ class ClassificationAdapter(HeadAdapter):

class RegressionAdapter(HeadAdapter):
pass


class SegmentationHeadAdapter(ClassificationAdapter):
pass
35 changes: 0 additions & 35 deletions autokeras/adapters/output_adapters_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,12 @@
# limitations under the License.

import numpy as np
import pandas as pd
import pytest
import tensorflow as tf

from autokeras import test_utils
from autokeras.adapters import output_adapters


def test_clf_head_transform_pd_series_to_dataset():
adapter = output_adapters.ClassificationAdapter(name="a")

y = adapter.adapt(
pd.read_csv(test_utils.TEST_CSV_PATH).pop("survived"), batch_size=32
)

assert isinstance(y, tf.data.Dataset)


def test_clf_head_transform_df_to_dataset():
adapter = output_adapters.ClassificationAdapter(name="a")

y = adapter.adapt(
pd.DataFrame(
test_utils.generate_one_hot_labels(dtype="np", num_classes=10)
),
batch_size=32,
)

assert isinstance(y, tf.data.Dataset)


def test_unsupported_types_error():
adapter = output_adapters.ClassificationAdapter(name="a")

Expand All @@ -53,16 +28,6 @@ def test_unsupported_types_error():
assert "Expect the target data of a to be tf" in str(info.value)


def test_reg_head_transform_pd_series():
adapter = output_adapters.RegressionAdapter(name="a")

y = adapter.adapt(
pd.read_csv(test_utils.TEST_CSV_PATH).pop("survived"), batch_size=32
)

assert isinstance(y, tf.data.Dataset)


def test_reg_head_transform_1d_np():
adapter = output_adapters.RegressionAdapter(name="a")

Expand Down
4 changes: 0 additions & 4 deletions autokeras/analysers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from autokeras.analysers.input_analysers import CATEGORICAL
from autokeras.analysers.input_analysers import NUMERICAL
from autokeras.analysers.input_analysers import ImageAnalyser
from autokeras.analysers.input_analysers import InputAnalyser
from autokeras.analysers.input_analysers import StructuredDataAnalyser
from autokeras.analysers.input_analysers import TextAnalyser
from autokeras.analysers.input_analysers import TimeseriesAnalyser
from autokeras.analysers.output_analysers import ClassificationAnalyser
from autokeras.analysers.output_analysers import RegressionAnalyser
Loading

0 comments on commit cbffa8b

Please sign in to comment.