Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/pythonci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8"]
python-version: ["3.10"]

steps:
- uses: actions/checkout@v2
Expand All @@ -27,7 +27,7 @@ jobs:
- uses: Gr1N/setup-poetry@v8
- name: Install dependencies
run: |
poetry install --no-interaction --no-ansi --remove-untracked -E nlp -E vision
poetry install --no-interaction --no-ansi -E nlp -E vision --with dev
- name: Test with pytest/flake8/mypy
run: |
make test bandit
4 changes: 2 additions & 2 deletions .github/workflows/test-import.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8"]
python-version: ["3.10"]

steps:
- uses: actions/checkout@v2
Expand All @@ -27,7 +27,7 @@ jobs:
- uses: Gr1N/setup-poetry@v8
- name: Install dependencies no dev
run: |
poetry install --no-interaction --no-ansi --no-dev
poetry install --no-interaction --no-ansi
- name: Test imports
run: |
poetry run python -c "import baal; import baal.active.dataset; \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ For a quick introduction to Baal and Bayesian active learning, please see these

## Installation and requirements

Baal requires `Python>=3.8`.
Baal requires `Python>=3.10`.

To install Baal using pip: `pip install baal`

Expand Down
4 changes: 2 additions & 2 deletions baal/utils/plot_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def make_animation_from_data(
ax.legend(loc="best", ncol=1, prop={"size": 15}, markerscale=3, fancybox=True, shadow=True)
fig.set_size_inches(15, 10.0)
fig.canvas.draw()
image = np.frombuffer(fig.canvas.tostring_rgb(), dtype="uint8")
image = image.reshape(fig.canvas.get_width_height()[::-1] + (3,))
image = np.frombuffer(fig.canvas.tostring_argb(), dtype="uint8")
image = image.reshape(fig.canvas.get_width_height()[::-1] + (4,))
frames.append(image)
plt.close(fig)
return frames
Expand Down
2 changes: 1 addition & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Global options:

[mypy]
python_version = 3.8
python_version = 3.10
warn_return_any = True
warn_unused_configs = True
warn_redundant_casts = True
Expand Down
5,937 changes: 3,124 additions & 2,813 deletions poetry.lock

Large diffs are not rendered by default.

19 changes: 8 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "baal"
version = "2.0.0"
version = "2.1.0"
description = "Library to enable Bayesian active learning in your research or labeling work."
authors = ["Parmida Atighehchian <parmida.atighehchian@servicenow.com>",
"Frederic Branchaud-Charron <frederic.branchaud-charron@servicenow.com>",
Expand All @@ -14,11 +14,10 @@ documentation = "https://baal.readthedocs.io"
repository = "https://github.com/ElementAI/baal/"

[tool.poetry.dependencies]
python = ">=3.8,<4"
python = ">=3.10,<4"
torch = ">=1.6.0"
torchmetrics = "^0.9.3"
h5py = "^3.4.0"
numpy = "^1.21.2"
torchmetrics = "^1.7.3"
numpy = ">=2.0.0"
matplotlib = "^3.4.3"
Pillow = ">=6.2.0"
tqdm = "^4.62.2"
Expand All @@ -32,15 +31,14 @@ lightning-flash = { version = ">=0.7.5", optional=true }

# NLP
transformers = {version = ">=4.10.2", optional=true}
accelerate = {version = "^0.28.0", optional=true}
accelerate = {version = "^1.8.0", optional=true}
datasets = {version = ">=2.14.6", optional=true}
jupyter = "^1.0.0"

[tool.poetry.dev-dependencies]
[tool.poetry.group.dev.dependencies]
pytest = "^6.2.5"
pytest-cov = "^2.12.1"
torch-hypothesis = "0.2.0"
hypothesis = "4.24.0"
hypothesis = "^6.135.14"
flake8 = "^3.9.2"
pytest-mock = "^3.6.1"
black = "^22.3.0"
Expand All @@ -57,13 +55,12 @@ mkdocs-material = "^9.5.0"
Pygments = "^2.12.0"
mkdocstrings = {extras = ["python"], version = "^0.18.1"}
mkdocs-exclude-search = "^0.6.4"
neoteroi-mkdocs = "^1.0.5"

[tool.poetry.extras]
vision = ["torchvision", "lightning-flash"]
nlp = ["transformers", "datasets", "accelerate"]

[tool.poetry.group.dev.dependencies]
neoteroi-mkdocs = "^1.0.5"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
2 changes: 1 addition & 1 deletion tests/active/file_dataset_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def __init__(self, side):
def __call__(self, x, **kwargs):
x, canvas = x # x is a [int, ndarray]
canvas[:self.side, :self.side] = x
return canvas
return canvas.astype(np.uint8)

target_trans = BaaLCompose(
[GetCanvas(), DrawSquare(3), ToPILImage(mode=None), Resize(60, interpolation=0),
Expand Down
4 changes: 2 additions & 2 deletions tests/active/heuristic_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import numpy as np
import pytest
from hypothesis import given
from torch_hypothesis import class_logits

from baal.active import get_heuristic
from baal.active.heuristics import (
Expand All @@ -21,6 +20,7 @@
CombineHeuristics,
)
from tests.test_utils import make_fake_dist, make_3d_fake_dist, make_5d_fake_dist
from tests.torch_hypothesis import class_logits

N_CLASS = 10

Expand Down Expand Up @@ -228,7 +228,7 @@ def wrapped(_, logits, target_predictions=None):
return logits

probability_distribution = wrapped(None, logits)
assert np.alltrue((probability_distribution >= 0) & (probability_distribution <= 1)).all()
assert np.all((probability_distribution >= 0) & (probability_distribution <= 1)).all()


def test_that_precomputed_passes_back_predictions():
Expand Down
148 changes: 148 additions & 0 deletions tests/torch_hypothesis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
"""DISCLAIMER

This work has been done by Jan Freyberg here: https://github.com/janfreyberg/torch-hypothesis
But this repo is no longer maintained so we copied it here.
All credits goes to Jan Freyberg.
"""

from typing import Any, Sequence
import torch
import numpy as np

from hypothesis import strategies as st
from hypothesis.extra import numpy as npst


def torch_dtype_to_numpy_dtype(dtype):
return np.dtype(str(dtype).replace("torch.", ""))


def is_numeric(val: Any) -> bool:
try:
float(val)
return True
except ValueError:
return False


def from_range_value_or_choice(parameter, draw):
# if strategy, just draw:
if isinstance(parameter, st.SearchStrategy):
return draw(parameter)
# if len 2 sequence of numbers, draw from strat:
if (
isinstance(parameter, Sequence)
and len(parameter) == 2
and all(is_numeric(param) or param is None for param in parameter)
):
if all(isinstance(param, int) or param is None for param in parameter):
return draw(
st.integers(min_value=parameter[0], max_value=parameter[1])
)
elif all(
isinstance(param, float) or param is None for param in parameter
):
return draw(
st.floats(min_value=parameter[0], max_value=parameter[1])
)
# if some other sequence, return one element from it:
elif isinstance(parameter, Sequence):
return draw(st.sampled_from(parameter))
else:
return parameter


@st.composite
def torch_tensor(draw, shape, values, dtype):
shape = (from_range_value_or_choice(size, draw) for size in shape)
dtype = from_range_value_or_choice(dtype, draw)
np_array = draw(
npst.arrays(torch_dtype_to_numpy_dtype(dtype), shape, elements=values)
)
return torch.as_tensor(np_array)


@st.composite
def linear_layer_input(
draw,
batch_size=(1, 256),
dimensionality=(1, 2000),
values=st.floats(allow_nan=False, allow_infinity=False, width=32),
dtype=torch.float,
):
"""Produce linear layer input.

Parameters
----------
batch_size : tuple, optional
The batch size. Can be an integer, a tuple defining a range of ints
(e.g. (1, 32)), or a hypothesis strategy.
dimensionality : tuple, optional
[description], by default (1, 2000)
values : [type], optional
dtype : [type], optional
[description], by default torch.float

Returns
-------
torch.Tensor
batch_size x dimensionality
"""
return draw(
torch_tensor((batch_size, dimensionality), values, torch.float)
)


@st.composite
def class_logits(draw, batch_size=(1, 256), n_classes=(1, 2000)):
"""Return logits - the standard output of a standard classification net.

Parameters
----------
batch_size : tuple, optional
[description], by default (1, 256)
n_classes : tuple, optional
[description], by default (1, 2000)

Returns
-------
torch.Tensor
A float-tensor of size batch_size x n_classes.
"""
logits = draw(
linear_layer_input(batch_size=batch_size, dimensionality=n_classes)
)
logits = logits
return logits


@st.composite
def class_labels(draw, batch_size=(1, 256), n_classes=(1, 2000)):
"""[summary]

Parameters
----------
batch_size : tuple, optional
[description], by default (1, 256)
n_classes : tuple, optional
[description], by default (1, 2000)
"""

shape = (from_range_value_or_choice(batch_size, draw),)
n_classes = from_range_value_or_choice(n_classes, draw)
labels = npst.arrays(
dtype=int, shape=shape, elements=st.integers(min_value=0, max_value=n_classes - 1)
)
return torch.as_tensor(draw(labels)).to(torch.long)


@st.composite
def classification_logits_and_labels(
draw, batch_size=(1, 256), n_classes=(1, 2000)
):
batch_size = from_range_value_or_choice(batch_size, draw)
n_classes = from_range_value_or_choice(n_classes, draw)
return (
draw(class_logits(batch_size=batch_size, n_classes=n_classes)),
draw(class_labels(batch_size=batch_size, n_classes=n_classes)),
)
2 changes: 1 addition & 1 deletion tests/transformers_trainer_wrapper_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def test_predict_on_dataset_generator(self):
assert next(l_gen).dtype == np.float16
assert l.dtype == np.float16

def test_load_state_dic(self):
def test_load_state_dict(self):
wrapper = BaalTransformersTrainer(model=self.model,
args=self.args,
train_dataset=self.dataset,
Expand Down
2 changes: 1 addition & 1 deletion tests/utils/metrics_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import shutil
import torch
from hypothesis import given
from torch_hypothesis import classification_logits_and_labels

from baal.utils.metrics import Loss, Accuracy, Precision, ECE, ClassificationReport, PRAuC, ECE_PerCLs
from tests.torch_hypothesis import classification_logits_and_labels


def test_loss():
Expand Down
2 changes: 1 addition & 1 deletion tests/utils/plotutils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def test_make_animation_from_data():

result = make_animation_from_data(x, y, labelled_at, classes)
assert isinstance(result, list)
assert result[0].shape[2] == 3
assert result[0].shape[2] == 4


if __name__ == '__main__':
Expand Down