diff --git a/.github/workflows/install_learnware_with_pip.yaml b/.github/workflows/install_learnware_with_pip.yaml new file mode 100644 index 0000000..137909e --- /dev/null +++ b/.github/workflows/install_learnware_with_pip.yaml @@ -0,0 +1,54 @@ +name: Test leanrnware from pip + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + timeout-minutes: 120 + + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest, ubuntu-20.04, ubuntu-22.04, macos-11, macos-latest] + python-version: [3.8, 3.9, 3.10] + + steps: + - name: Test learnware from pip + uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Add conda to system path + run: | + # $CONDA is an environment variable pointing to the root of the miniconda directory + echo $CONDA/bin >> $GITHUB_PATH + + - name: Create conda env for macos + run: | + conda create -n learnware python=${{ matrix.python-version }} + conda create activate learnware + + - name: Update pip to the latest version + run: | + python -m pip install --upgrade pip + python -m pip install pytest + + - name: Install faiss for MacOS + if: ${{ matrix.os == 'macos-11' || matrix.os == 'macos-latest' }} + run: | + conda install -c pytorch faiss + + - name: Install learnware + run: | + python -m pip install learnware + + - name: Test workflow + run: | + pytest tests/test_workflow/test_workflow.py \ No newline at end of file diff --git a/.github/workflows/install_learnware_with_source.yaml b/.github/workflows/install_learnware_with_source.yaml new file mode 100644 index 0000000..e9589e3 --- /dev/null +++ b/.github/workflows/install_learnware_with_source.yaml @@ -0,0 +1,59 @@ +name: Test leanrnware from source code + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + timeout-minutes: 120 + + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest, ubuntu-20.04, ubuntu-22.04, macos-11, macos-latest] + python-version: [3.8, 3.9, 3.10] + + steps: + - name: Test learnware from pip + uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Add conda to system path + run: | + # $CONDA is an environment variable pointing to the root of the miniconda directory + echo $CONDA/bin >> $GITHUB_PATH + + - name: Create conda env for macos + run: | + conda create -n learnware python=${{ matrix.python-version }} + conda create activate learnware + + - name: Update pip to the latest version + run: | + python -m pip install --upgrade pip + python -m pip install flake8 pytest + + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + + - name: Install faiss for MacOS + if: ${{ matrix.os == 'macos-11' || matrix.os == 'macos-latest' }} + run: | + conda install -c pytorch faiss + + - name: Install learnware + run: | + python -m pip install . + + - name: Test workflow + run: | + pytest tests/test_workflow/test_workflow.py \ No newline at end of file diff --git a/learnware/client/learnware_client.py b/learnware/client/learnware_client.py index b466be7..266d45f 100644 --- a/learnware/client/learnware_client.py +++ b/learnware/client/learnware_client.py @@ -408,7 +408,8 @@ class LearnwareClient: try: for key in ["Data", "Task", "Library"]: value = semantic_spec[key]["Values"] - if len(value) != 1 and value[0] not in key_list: + key_list = C["semantic_specs"][key]["Values"] + if len(value) != 1 or value[0] not in key_list: logger.error(f"{key} must be in {key_list}!") return False diff --git a/learnware/specification/__init__.py b/learnware/specification/__init__.py index 935210b..c54cafc 100644 --- a/learnware/specification/__init__.py +++ b/learnware/specification/__init__.py @@ -1,4 +1,3 @@ from .utils import generate_stat_spec, generate_rkme_spec, generate_rkme_image_spec from .base import Specification, BaseStatSpecification -from .image import RKMEImageStatSpecification -from .table import RKMEStatSpecification +from .regular import RKMEStatSpecification, RKMEImageStatSpecification diff --git a/learnware/specification/base.py b/learnware/specification/base.py index 655e5a4..1c340fa 100644 --- a/learnware/specification/base.py +++ b/learnware/specification/base.py @@ -15,11 +15,8 @@ class BaseStatSpecification: """ self.type = type - def generate_stat_spec_from_data(self, **kwargs): - """Construct statistical specification from raw dataset - - kwargs may include the feature, label and model - - kwargs also can include hyperparameters of specific method for specifaction generation - """ + def generate_stat_spec(self, **kwargs): + """Construct statistical specification""" raise NotImplementedError("generate_stat_spec_from_data is not implemented") def save(self, filepath: str): diff --git a/learnware/specification/regular/__init__.py b/learnware/specification/regular/__init__.py new file mode 100644 index 0000000..ba6c866 --- /dev/null +++ b/learnware/specification/regular/__init__.py @@ -0,0 +1,2 @@ +from .table import RKMEStatSpecification +from .image import RKMEImageStatSpecification diff --git a/learnware/specification/regular/base.py b/learnware/specification/regular/base.py new file mode 100644 index 0000000..48a7e1f --- /dev/null +++ b/learnware/specification/regular/base.py @@ -0,0 +1,13 @@ +from ..base import BaseStatSpecification + + +class RegularStatsSpecification(BaseStatSpecification): + def generate_stat_spec(self, **kwargs): + self.generate_stat_spec_from_data(**kwargs) + + def generate_stat_spec_from_data(self, **kwargs): + """Construct statistical specification from raw dataset + - kwargs may include the feature, label and model + - kwargs also can include hyperparameters of specific method for specifaction generation + """ + raise NotImplementedError("generate_stat_spec_from_data is not implemented") diff --git a/learnware/specification/image/__init__.py b/learnware/specification/regular/image/__init__.py similarity index 100% rename from learnware/specification/image/__init__.py rename to learnware/specification/regular/image/__init__.py diff --git a/learnware/specification/image/cnn_gp.py b/learnware/specification/regular/image/cnn_gp.py similarity index 100% rename from learnware/specification/image/cnn_gp.py rename to learnware/specification/regular/image/cnn_gp.py diff --git a/learnware/specification/image/rkme.py b/learnware/specification/regular/image/rkme.py similarity index 99% rename from learnware/specification/image/rkme.py rename to learnware/specification/regular/image/rkme.py index d651b6a..e65dc27 100644 --- a/learnware/specification/image/rkme.py +++ b/learnware/specification/regular/image/rkme.py @@ -122,7 +122,9 @@ class RKMEImageStatSpecification(BaseStatSpecification): X[i] = torch.where(is_nan, img_mean, img) if X.shape[2] != RKMEImageStatSpecification.IMAGE_WIDTH or X.shape[3] != RKMEImageStatSpecification.IMAGE_WIDTH: - X = Resize((RKMEImageStatSpecification.IMAGE_WIDTH, RKMEImageStatSpecification.IMAGE_WIDTH), antialias=None)(X) + X = Resize( + (RKMEImageStatSpecification.IMAGE_WIDTH, RKMEImageStatSpecification.IMAGE_WIDTH), antialias=None + )(X) num_points = X.shape[0] X_shape = X.shape diff --git a/learnware/specification/table/__init__.py b/learnware/specification/regular/table/__init__.py similarity index 100% rename from learnware/specification/table/__init__.py rename to learnware/specification/regular/table/__init__.py diff --git a/learnware/specification/table/rkme.py b/learnware/specification/regular/table/rkme.py similarity index 99% rename from learnware/specification/table/rkme.py rename to learnware/specification/regular/table/rkme.py index a0422ae..e001dd5 100644 --- a/learnware/specification/table/rkme.py +++ b/learnware/specification/regular/table/rkme.py @@ -20,8 +20,8 @@ try: except ImportError: _FAISS_INSTALLED = False -from ..base import BaseStatSpecification -from ...logger import get_module_logger +from ..base import RegularStatsSpecification +from ....logger import get_module_logger logger = get_module_logger("rkme") @@ -30,7 +30,7 @@ if not _FAISS_INSTALLED: logger.warning('Please run "conda install -c pytorch faiss-cpu" first.') -class RKMEStatSpecification(BaseStatSpecification): +class RKMEStatSpecification(RegularStatsSpecification): """Reduced Kernel Mean Embedding (RKME) Specification""" def __init__(self, gamma: float = 0.1, cuda_idx: int = -1): diff --git a/learnware/specification/system/__init__.py b/learnware/specification/system/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/learnware/specification/system/heter_table.py b/learnware/specification/system/heter_table.py new file mode 100644 index 0000000..ae24a1c --- /dev/null +++ b/learnware/specification/system/heter_table.py @@ -0,0 +1,15 @@ +from ..base import BaseStatSpecification + + +class HeterMapTableSpecification(BaseStatSpecification): + def generate_stat_spec(self, **kwargs): + pass + + def save(self, filepath: str): + pass + + def load(self, filepath: str): + pass + + def dist(self, other_spec): + pass diff --git a/learnware/specification/utils.py b/learnware/specification/utils.py index d480de9..f0108ab 100644 --- a/learnware/specification/utils.py +++ b/learnware/specification/utils.py @@ -3,9 +3,8 @@ import numpy as np import pandas as pd from typing import Union -from .image import RKMEImageStatSpecification from .base import BaseStatSpecification -from .table import RKMEStatSpecification +from .regular import RKMEStatSpecification, RKMEImageStatSpecification from ..config import C