diff --git a/README.md b/README.md index cdb9d8b..0160fc6 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ EQUINE was created to simplify two kinds of uncertainty quantification for super 2) An in-distribution score, indicating whether any of the model's known labels should be trusted. Dive into our [documentation examples](https://mit-ll-responsible-ai.github.io/equine/) -to get started. Additionally, we provide a [companion web application](https://mit-ll-responsible-ai.github.io/equine-webapp/). +to get started. Additionally, we provide a [companion web application](https://github.com/mit-ll-responsible-ai/equine-webapp). ## Installation Users are recommended to install a virtual environment such as Anaconda, as is also recommended diff --git a/docs/example_notebooks/vnat_example.ipynb b/docs/example_notebooks/vnat_example.ipynb index 30c3af6..a473094 100755 --- a/docs/example_notebooks/vnat_example.ipynb +++ b/docs/example_notebooks/vnat_example.ipynb @@ -22,8 +22,8 @@ "# This notebook requires additional pythom modules and a dataset to run. \n", "# You can uncomment the following lines to install them in your environment.\n", "# !curl -o VNAT_Dataframe_release_1.h5 https://archive.ll.mit.edu/datasets/vnat/VNAT_Dataframe_release_1.h5 \n", - "# !conda install pytables\n", - "# !pip install scikit-learn pandas" + "# !conda install -y pytables\n", + "# !pip install scikit-learn pandas matplotlib " ] }, { @@ -32,9 +32,9 @@ "metadata": {}, "outputs": [], "source": [ + "import torch\n", "import numpy as np\n", "import pandas as pd\n", - "import torch\n", "from sklearn.preprocessing import LabelEncoder\n", "from sklearn.metrics import RocCurveDisplay\n", "import matplotlib.pyplot as plt\n", @@ -603,10 +603,12 @@ "metadata": {}, "outputs": [], "source": [ - "num_deep_features = 32\n", + "num_deep_features = 16\n", "class EmbeddingModel(torch.nn.Module):\n", - " def __init__(self):\n", + " def __init__(self, train_means, train_deviations):\n", " super(EmbeddingModel, self).__init__()\n", + " self.train_means = train_means\n", + " self.train_deviations = train_deviations\n", " self.linear_relu_stack = torch.nn.Sequential(\n", " torch.nn.Linear(input_dim, num_deep_features),\n", " torch.nn.ReLU(),\n", @@ -618,7 +620,7 @@ " )\n", "\n", " def forward(self, x):\n", - " x = (x - train_means ) / train_deviations\n", + " x = (x - self.train_means ) / self.train_deviations\n", " logits = self.linear_relu_stack(x)\n", " return logits" ] @@ -641,31 +643,24 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1000/1000 [00:02<00:00, 469.65it/s]\n" + " 0%| | 0/1000 [00:00" ] @@ -732,13 +727,6 @@ "RocCurveDisplay.from_predictions(in_out, all_oods, name=\"EQUINE In-Distribution\", ax=ax[1])\n", "plt.show()\n" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -757,7 +745,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.10.12" }, "vscode": { "interpreter": { diff --git a/src/equine/utils.py b/src/equine/utils.py index 5548888..3d9eedd 100644 --- a/src/equine/utils.py +++ b/src/equine/utils.py @@ -241,6 +241,11 @@ def generate_episode( Tuple of support examples, query examples, and query labels. """ labels = torch.unique(train_y) + if way > len(labels): + raise ValueError( + f"The way (#classes in each episode), {way}, must be <= number of labels, {len(labels)}" + ) + selected_labels = sorted( labels[torch.randperm(labels.shape[0])][:way].tolist() ) # need to be in same order every time diff --git a/tests/test_utils.py b/tests/test_utils.py index e8d127f..25532e7 100755 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -7,6 +7,7 @@ from hypothesis import given from hypothesis import strategies as st import hypothesis.extra.numpy as hnp +import pytest @st.composite @@ -40,10 +41,21 @@ def support_dataset(draw): @given(dataset=support_dataset()) def test_generate_support(dataset) -> None: - train_x, train_y, support_sz, tasks, way = dataset + train_x, train_y, support_sz, tasks, _ = dataset eq.utils.generate_support(train_x, train_y, support_sz, tasks) +@given(dataset=support_dataset()) +def test_generate_episode(dataset) -> None: + train_x, train_y, support_sz, tasks, way = dataset + episode_size = max(len(tasks), train_x.shape[0] // 4) + eq.utils.generate_episode(train_x, train_y, support_sz, way, episode_size) + with pytest.raises(ValueError): + eq.utils.generate_episode( + train_x, train_y, support_sz, len(tasks) + 1, episode_size + ) + + @st.composite def draw_two_tensors(draw): num_classes = draw(st.integers(min_value=2, max_value=128))