active-vision 0.3.0__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- active_vision-0.4.1/.github/workflows/docs.yml +32 -0
- active_vision-0.4.1/.github/workflows/pypi.yaml +27 -0
- active_vision-0.4.1/.gitignore +186 -0
- active_vision-0.4.1/.python-version +1 -0
- {active_vision-0.3.0/src/active_vision.egg-info → active_vision-0.4.1}/PKG-INFO +78 -30
- active_vision-0.3.0/PKG-INFO → active_vision-0.4.1/README.md +46 -45
- active_vision-0.4.1/assets/data_flywheel.gif +0 -0
- active_vision-0.4.1/assets/labeling_ui.png +0 -0
- active_vision-0.4.1/assets/logo.png +0 -0
- active_vision-0.4.1/assets/zero_shot_ui.png +0 -0
- active_vision-0.4.1/docs/active_learning.ipynb +3016 -0
- active_vision-0.4.1/docs/overrides/main.html +11 -0
- active_vision-0.4.1/docs/preparing_data.ipynb +784 -0
- active_vision-0.4.1/docs/train.ipynb +676 -0
- active_vision-0.4.1/mkdocs.yml +96 -0
- active_vision-0.4.1/nbs/00_create_dataset.ipynb +899 -0
- active_vision-0.4.1/nbs/02_inference_unlabeled.ipynb +1855 -0
- active_vision-0.4.1/nbs/03_retrain_model.ipynb +1893 -0
- active_vision-0.4.1/nbs/04_relabel_loop.ipynb +2148 -0
- active_vision-0.4.1/nbs/05_retrain_larger.ipynb +648 -0
- active_vision-0.4.1/nbs/dog_food_dataset/00_eda.ipynb +940 -0
- active_vision-0.4.1/nbs/dog_food_dataset/01_label.ipynb +737 -0
- active_vision-0.4.1/nbs/dog_food_dataset/02_train.ipynb +647 -0
- active_vision-0.4.1/nbs/download_hf_dataset.ipynb +394 -0
- active_vision-0.4.1/nbs/end-to-end.ipynb +2198 -0
- active_vision-0.4.1/nbs/eurosat_rgb/00_eda.ipynb +1038 -0
- active_vision-0.4.1/nbs/eurosat_rgb/01_label.ipynb +1205 -0
- active_vision-0.4.1/nbs/eurosat_rgb/02_train.ipynb +665 -0
- active_vision-0.4.1/nbs/eurosat_rgb/03_train_all.ipynb +617 -0
- active_vision-0.4.1/nbs/fastai_hooks.ipynb +60892 -0
- active_vision-0.4.1/nbs/get_embeddings.ipynb +3924 -0
- active_vision-0.4.1/nbs/gradio_annotator.ipynb +333 -0
- active_vision-0.4.1/nbs/imagenette/active_learning.ipynb +3034 -0
- active_vision-0.4.1/nbs/imagenette/iterate.ipynb +1304 -0
- active_vision-0.4.1/nbs/imagenette/preparing_data.ipynb +764 -0
- active_vision-0.4.1/nbs/imagenette/quickstart.ipynb +3552 -0
- active_vision-0.4.1/nbs/imagenette/train.ipynb +674 -0
- active_vision-0.4.1/nbs/initial_sampling.ipynb +3200 -0
- active_vision-0.4.1/nbs/oxford_iiit_pets/00_eda.ipynb +1352 -0
- active_vision-0.4.1/nbs/oxford_iiit_pets/01_label.ipynb +869 -0
- active_vision-0.4.1/nbs/oxford_iiit_pets/02_train.ipynb +682 -0
- active_vision-0.4.1/nbs/oxford_iiit_pets/03_train_vit.ipynb +1208 -0
- active_vision-0.4.1/nbs/oxford_iiit_pets/plot_pred_conf_ranked.ipynb +401 -0
- active_vision-0.4.1/nbs/oxford_iiit_pets/testing.ipynb +756 -0
- active_vision-0.4.1/pyproject.toml +58 -0
- active_vision-0.4.1/src/active_vision/__init__.py +3 -0
- {active_vision-0.3.0 → active_vision-0.4.1}/src/active_vision/core.py +364 -74
- active_vision-0.4.1/uv.lock +4307 -0
- active_vision-0.3.0/pyproject.toml +0 -19
- active_vision-0.3.0/setup.cfg +0 -4
- active_vision-0.3.0/src/active_vision/__init__.py +0 -3
- active_vision-0.3.0/src/active_vision.egg-info/SOURCES.txt +0 -10
- active_vision-0.3.0/src/active_vision.egg-info/dependency_links.txt +0 -1
- active_vision-0.3.0/src/active_vision.egg-info/requires.txt +0 -11
- active_vision-0.3.0/src/active_vision.egg-info/top_level.txt +0 -1
- {active_vision-0.3.0 → active_vision-0.4.1}/LICENSE +0 -0
- /active_vision-0.3.0/README.md → /active_vision-0.4.1/docs/index.md +0 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
name: docs
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
branches:
|
5
|
+
- main
|
6
|
+
jobs:
|
7
|
+
deploy:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
steps:
|
10
|
+
- uses: actions/checkout@v4
|
11
|
+
with:
|
12
|
+
fetch-depth: 0
|
13
|
+
- uses: actions/setup-python@v5
|
14
|
+
with:
|
15
|
+
python-version: "3.12"
|
16
|
+
|
17
|
+
- name: Install dependencies
|
18
|
+
run: |
|
19
|
+
python -m pip install --upgrade pip
|
20
|
+
pip install --no-deps ".[docs]"
|
21
|
+
pip install jupyter ipykernel livereload nbconvert nbformat sphinx watchdog mkdocs \
|
22
|
+
mkdocs-git-revision-date-plugin mkdocs-git-revision-date-localized-plugin \
|
23
|
+
"mkdocs-jupyter>=0.24.0" "mkdocs-material>=9.1.3" mkdocs-pdf-export-plugin \
|
24
|
+
mkdocstrings mkdocstrings-crystal mkdocstrings-python-legacy pygments \
|
25
|
+
pymdown-extensions mkdocs-mermaid2-plugin ansi2html
|
26
|
+
|
27
|
+
- name: Generate docs
|
28
|
+
run: |
|
29
|
+
cp README.md docs/index.md
|
30
|
+
|
31
|
+
- name: Deploy
|
32
|
+
run: mkdocs gh-deploy --force
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: pypi
|
2
|
+
|
3
|
+
on:
|
4
|
+
release:
|
5
|
+
types: [created]
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
deploy:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
|
11
|
+
steps:
|
12
|
+
- uses: actions/checkout@v4
|
13
|
+
- name: Set up Python
|
14
|
+
uses: actions/setup-python@v5
|
15
|
+
with:
|
16
|
+
python-version: "3.x"
|
17
|
+
- name: Install dependencies
|
18
|
+
run: |
|
19
|
+
python -m pip install --upgrade pip
|
20
|
+
pip install setuptools wheel twine build
|
21
|
+
- name: Build and publish
|
22
|
+
env:
|
23
|
+
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
|
24
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
25
|
+
run: |
|
26
|
+
python -m build
|
27
|
+
twine upload dist/*
|
@@ -0,0 +1,186 @@
|
|
1
|
+
# models
|
2
|
+
models/
|
3
|
+
*.pkl
|
4
|
+
*.pth
|
5
|
+
*.pkl
|
6
|
+
|
7
|
+
# Data
|
8
|
+
data/
|
9
|
+
*.parquet
|
10
|
+
*.csv
|
11
|
+
|
12
|
+
private/
|
13
|
+
|
14
|
+
.DS_Store
|
15
|
+
|
16
|
+
# Byte-compiled / optimized / DLL files
|
17
|
+
__pycache__/
|
18
|
+
*.py[cod]
|
19
|
+
*$py.class
|
20
|
+
|
21
|
+
# C extensions
|
22
|
+
*.so
|
23
|
+
|
24
|
+
# Distribution / packaging
|
25
|
+
.Python
|
26
|
+
build/
|
27
|
+
develop-eggs/
|
28
|
+
dist/
|
29
|
+
downloads/
|
30
|
+
eggs/
|
31
|
+
.eggs/
|
32
|
+
lib/
|
33
|
+
lib64/
|
34
|
+
parts/
|
35
|
+
sdist/
|
36
|
+
var/
|
37
|
+
wheels/
|
38
|
+
share/python-wheels/
|
39
|
+
*.egg-info/
|
40
|
+
.installed.cfg
|
41
|
+
*.egg
|
42
|
+
MANIFEST
|
43
|
+
|
44
|
+
# PyInstaller
|
45
|
+
# Usually these files are written by a python script from a template
|
46
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
47
|
+
*.manifest
|
48
|
+
*.spec
|
49
|
+
|
50
|
+
# Installer logs
|
51
|
+
pip-log.txt
|
52
|
+
pip-delete-this-directory.txt
|
53
|
+
|
54
|
+
# Unit test / coverage reports
|
55
|
+
htmlcov/
|
56
|
+
.tox/
|
57
|
+
.nox/
|
58
|
+
.coverage
|
59
|
+
.coverage.*
|
60
|
+
.cache
|
61
|
+
nosetests.xml
|
62
|
+
coverage.xml
|
63
|
+
*.cover
|
64
|
+
*.py,cover
|
65
|
+
.hypothesis/
|
66
|
+
.pytest_cache/
|
67
|
+
cover/
|
68
|
+
|
69
|
+
# Translations
|
70
|
+
*.mo
|
71
|
+
*.pot
|
72
|
+
|
73
|
+
# Django stuff:
|
74
|
+
*.log
|
75
|
+
local_settings.py
|
76
|
+
db.sqlite3
|
77
|
+
db.sqlite3-journal
|
78
|
+
|
79
|
+
# Flask stuff:
|
80
|
+
instance/
|
81
|
+
.webassets-cache
|
82
|
+
|
83
|
+
# Scrapy stuff:
|
84
|
+
.scrapy
|
85
|
+
|
86
|
+
# Sphinx documentation
|
87
|
+
docs/_build/
|
88
|
+
|
89
|
+
# PyBuilder
|
90
|
+
.pybuilder/
|
91
|
+
target/
|
92
|
+
|
93
|
+
# Jupyter Notebook
|
94
|
+
.ipynb_checkpoints
|
95
|
+
|
96
|
+
# IPython
|
97
|
+
profile_default/
|
98
|
+
ipython_config.py
|
99
|
+
|
100
|
+
# pyenv
|
101
|
+
# For a library or package, you might want to ignore these files since the code is
|
102
|
+
# intended to run in multiple environments; otherwise, check them in:
|
103
|
+
# .python-version
|
104
|
+
|
105
|
+
# pipenv
|
106
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
107
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
108
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
109
|
+
# install all needed dependencies.
|
110
|
+
#Pipfile.lock
|
111
|
+
|
112
|
+
# UV
|
113
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
114
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
115
|
+
# commonly ignored for libraries.
|
116
|
+
#uv.lock
|
117
|
+
|
118
|
+
# poetry
|
119
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
120
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
121
|
+
# commonly ignored for libraries.
|
122
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
123
|
+
#poetry.lock
|
124
|
+
|
125
|
+
# pdm
|
126
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
127
|
+
#pdm.lock
|
128
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
129
|
+
# in version control.
|
130
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
131
|
+
.pdm.toml
|
132
|
+
.pdm-python
|
133
|
+
.pdm-build/
|
134
|
+
|
135
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
136
|
+
__pypackages__/
|
137
|
+
|
138
|
+
# Celery stuff
|
139
|
+
celerybeat-schedule
|
140
|
+
celerybeat.pid
|
141
|
+
|
142
|
+
# SageMath parsed files
|
143
|
+
*.sage.py
|
144
|
+
|
145
|
+
# Environments
|
146
|
+
.env
|
147
|
+
.venv
|
148
|
+
env/
|
149
|
+
venv/
|
150
|
+
ENV/
|
151
|
+
env.bak/
|
152
|
+
venv.bak/
|
153
|
+
|
154
|
+
# Spyder project settings
|
155
|
+
.spyderproject
|
156
|
+
.spyproject
|
157
|
+
|
158
|
+
# Rope project settings
|
159
|
+
.ropeproject
|
160
|
+
|
161
|
+
# mkdocs documentation
|
162
|
+
/site
|
163
|
+
|
164
|
+
# mypy
|
165
|
+
.mypy_cache/
|
166
|
+
.dmypy.json
|
167
|
+
dmypy.json
|
168
|
+
|
169
|
+
# Pyre type checker
|
170
|
+
.pyre/
|
171
|
+
|
172
|
+
# pytype static type analyzer
|
173
|
+
.pytype/
|
174
|
+
|
175
|
+
# Cython debug symbols
|
176
|
+
cython_debug/
|
177
|
+
|
178
|
+
# PyCharm
|
179
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
180
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
181
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
182
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
183
|
+
#.idea/
|
184
|
+
|
185
|
+
# PyPI configuration file
|
186
|
+
.pypirc
|
@@ -0,0 +1 @@
|
|
1
|
+
3.12
|
@@ -1,10 +1,11 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: active-vision
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.4.1
|
4
4
|
Summary: Active learning for computer vision.
|
5
|
-
|
6
|
-
|
5
|
+
Project-URL: Homepage, https://github.com/dnth/active-vision
|
6
|
+
Project-URL: Bug Tracker, https://github.com/dnth/active-vision/issues
|
7
7
|
License-File: LICENSE
|
8
|
+
Requires-Python: >=3.10
|
8
9
|
Requires-Dist: accelerate>=1.2.1
|
9
10
|
Requires-Dist: datasets>=3.2.0
|
10
11
|
Requires-Dist: fastai>=2.7.18
|
@@ -16,14 +17,57 @@ Requires-Dist: seaborn>=0.13.2
|
|
16
17
|
Requires-Dist: timm>=1.0.13
|
17
18
|
Requires-Dist: transformers>=4.48.0
|
18
19
|
Requires-Dist: xinfer>=0.3.2
|
20
|
+
Provides-Extra: dev
|
21
|
+
Requires-Dist: black>=22.0; extra == 'dev'
|
22
|
+
Requires-Dist: flake8>=4.0; extra == 'dev'
|
23
|
+
Requires-Dist: isort>=5.0; extra == 'dev'
|
24
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
25
|
+
Provides-Extra: docs
|
26
|
+
Requires-Dist: ansi2html; extra == 'docs'
|
27
|
+
Requires-Dist: ipykernel; extra == 'docs'
|
28
|
+
Requires-Dist: jupyter; extra == 'docs'
|
29
|
+
Requires-Dist: livereload; extra == 'docs'
|
30
|
+
Requires-Dist: mkdocs; extra == 'docs'
|
31
|
+
Requires-Dist: mkdocs-git-revision-date-localized-plugin; extra == 'docs'
|
32
|
+
Requires-Dist: mkdocs-git-revision-date-plugin; extra == 'docs'
|
33
|
+
Requires-Dist: mkdocs-jupyter>=0.24.0; extra == 'docs'
|
34
|
+
Requires-Dist: mkdocs-material>=9.1.3; extra == 'docs'
|
35
|
+
Requires-Dist: mkdocs-mermaid2-plugin; extra == 'docs'
|
36
|
+
Requires-Dist: mkdocs-pdf-export-plugin; extra == 'docs'
|
37
|
+
Requires-Dist: mkdocstrings; extra == 'docs'
|
38
|
+
Requires-Dist: mkdocstrings-crystal; extra == 'docs'
|
39
|
+
Requires-Dist: mkdocstrings-python-legacy; extra == 'docs'
|
40
|
+
Requires-Dist: nbconvert; extra == 'docs'
|
41
|
+
Requires-Dist: nbformat; extra == 'docs'
|
42
|
+
Requires-Dist: pygments; extra == 'docs'
|
43
|
+
Requires-Dist: pymdown-extensions; extra == 'docs'
|
44
|
+
Requires-Dist: sphinx; extra == 'docs'
|
45
|
+
Requires-Dist: watchdog; extra == 'docs'
|
46
|
+
Description-Content-Type: text/markdown
|
19
47
|
|
20
48
|
[](https://pypi.org/project/active-vision/)
|
21
49
|
[](https://pypi.org/project/active-vision/)
|
22
50
|
[](https://pypi.org/project/active-vision/)
|
23
51
|
[](https://github.com/dnth/active-vision/blob/main/LICENSE)
|
24
52
|
|
53
|
+
[colab_badge]: https://img.shields.io/badge/Open%20In-Colab-blue?style=for-the-badge&logo=google-colab
|
54
|
+
[kaggle_badge]: https://img.shields.io/badge/Open%20In-Kaggle-blue?style=for-the-badge&logo=kaggle
|
55
|
+
|
25
56
|
<p align="center">
|
26
57
|
<img src="https://raw.githubusercontent.com/dnth/active-vision/main/assets/logo.png" alt="active-vision">
|
58
|
+
<br />
|
59
|
+
<br />
|
60
|
+
<a href="https://dnth.github.io/active-vision" target="_blank" rel="noopener noreferrer"><strong>Explore the docs »</strong></a>
|
61
|
+
<br />
|
62
|
+
<a href="#️-quickstart" target="_blank" rel="noopener noreferrer">Quickstart</a>
|
63
|
+
·
|
64
|
+
<a href="https://github.com/dnth/active-vision/issues/new?assignees=&labels=Feature+Request&projects=&template=feature_request.md" target="_blank" rel="noopener noreferrer">Feature Request</a>
|
65
|
+
·
|
66
|
+
<a href="https://github.com/dnth/active-vision/issues/new?assignees=&labels=bug&projects=&template=bug_report.md" target="_blank" rel="noopener noreferrer">Report Bug</a>
|
67
|
+
·
|
68
|
+
<a href="https://github.com/dnth/active-vision/discussions" target="_blank" rel="noopener noreferrer">Discussions</a>
|
69
|
+
·
|
70
|
+
<a href="https://dicksonneoh.com/" target="_blank" rel="noopener noreferrer">About</a>
|
27
71
|
</p>
|
28
72
|
|
29
73
|
The goal of this project is to create a framework for the active learning loop for computer vision. The diagram below shows a general workflow of how the active learning loop works.
|
@@ -89,41 +133,52 @@ pip install -e .
|
|
89
133
|
> uv pip install active-vision
|
90
134
|
> ```
|
91
135
|
|
92
|
-
##
|
93
|
-
See the [notebook](./nbs/04_relabel_loop.ipynb) for a complete example.
|
136
|
+
## 🚀 Quickstart
|
94
137
|
|
95
|
-
|
96
|
-
|
97
|
-
- [Unlabeled samples](./nbs/unlabeled_samples.parquet): A dataframe of *unlabeled* images. We will continuously sample from this set using active learning strategies.
|
98
|
-
- [Evaluation samples](./nbs/evaluation_samples.parquet): A dataframe of *labeled* images. We will use this set to evaluate the performance of the model. This is the test set, DO NOT use it for active learning. Split this out in the beginning.
|
138
|
+
[![Open In Colab][colab_badge]](https://colab.research.google.com/github/dnth/active-vision/blob/main/nbs/imagenette/quickstart.ipynb)
|
139
|
+
[![Open In Kaggle][kaggle_badge]](https://kaggle.com/kernels/welcome?src=https://github.com/dnth/active-vision/blob/main/nbs/imagenette/quickstart.ipynb)
|
99
140
|
|
100
|
-
|
141
|
+
The following are code snippets for the active learning loop in active-vision. I recommend running the quickstart notebook in Colab or Kaggle to see the full workflow.
|
101
142
|
|
102
143
|
```python
|
103
144
|
from active_vision import ActiveLearner
|
104
|
-
import pandas as pd
|
105
145
|
|
106
|
-
# Create an active learner instance
|
107
|
-
al = ActiveLearner("
|
146
|
+
# Create an active learner instance
|
147
|
+
al = ActiveLearner(name="cycle-1")
|
148
|
+
|
149
|
+
# Load model
|
150
|
+
al.load_model(model="resnet18", pretrained=True)
|
108
151
|
|
109
152
|
# Load dataset
|
110
|
-
train_df =
|
111
|
-
al.load_dataset(df, filepath_col="filepath", label_col="label")
|
153
|
+
al.load_dataset(train_df, filepath_col="filepath", label_col="label", batch_size=8)
|
112
154
|
|
113
155
|
# Train model
|
114
|
-
al.train(epochs=
|
156
|
+
al.train(epochs=10, lr=5e-3)
|
115
157
|
|
116
158
|
# Evaluate the model on a *labeled* evaluation set
|
117
159
|
accuracy = al.evaluate(eval_df, filepath_col="filepath", label_col="label")
|
118
160
|
|
161
|
+
# Get summary of the active learning cycle
|
162
|
+
al.summary()
|
163
|
+
|
119
164
|
# Get predictions from an *unlabeled* set
|
120
165
|
pred_df = al.predict(filepaths)
|
121
166
|
|
122
|
-
# Sample
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
167
|
+
# Sample images using a combination of active learning strategies
|
168
|
+
samples = al.sample_combination(
|
169
|
+
pred_df,
|
170
|
+
num_samples=50,
|
171
|
+
combination={
|
172
|
+
"least-confidence": 0.4,
|
173
|
+
"ratio-of-confidence": 0.2,
|
174
|
+
"entropy": 0.2,
|
175
|
+
"model-based-outlier": 0.1,
|
176
|
+
"random": 0.1,
|
177
|
+
},
|
178
|
+
)
|
179
|
+
|
180
|
+
# Launch a Gradio UI to label the samples, save the labeled samples to a file
|
181
|
+
al.label(samples, output_filename="samples.parquet")
|
127
182
|
```
|
128
183
|
|
129
184
|

|
@@ -136,18 +191,11 @@ Once complete, the labeled samples will be save into a new df.
|
|
136
191
|
We can now add the newly labeled data to the training set.
|
137
192
|
|
138
193
|
```python
|
139
|
-
|
140
|
-
al.add_to_train_set(labeled_df, output_filename="active_labeled")
|
194
|
+
al.add_to_dataset(labeled_df, output_filename="active_labeled.parquet")
|
141
195
|
```
|
142
196
|
|
143
197
|
Repeat the process until the model is good enough. Use the dataset to train a larger model and deploy.
|
144
198
|
|
145
|
-
> [!TIP]
|
146
|
-
> For the toy dataset, I got to about 93% accuracy on the evaluation set with 200+ labeled images. The best performing model on the [leaderboard](https://github.com/fastai/imagenette) got 95.11% accuracy training on all 9469 labeled images.
|
147
|
-
>
|
148
|
-
> This took me about 6 iterations of relabeling. Each iteration took about 5 minutes to complete including labeling and model training (resnet18). See the [notebook](./nbs/04_relabel_loop.ipynb) for more details.
|
149
|
-
>
|
150
|
-
> But using the dataset of 200+ images, I trained a more capable model (convnext_small_in22k) and got 99.3% accuracy on the evaluation set. See the [notebook](./nbs/05_retrain_larger.ipynb) for more details.
|
151
199
|
|
152
200
|
|
153
201
|
## 📊 Benchmarks
|
@@ -1,29 +1,26 @@
|
|
1
|
-
Metadata-Version: 2.2
|
2
|
-
Name: active-vision
|
3
|
-
Version: 0.3.0
|
4
|
-
Summary: Active learning for computer vision.
|
5
|
-
Requires-Python: >=3.10
|
6
|
-
Description-Content-Type: text/markdown
|
7
|
-
License-File: LICENSE
|
8
|
-
Requires-Dist: accelerate>=1.2.1
|
9
|
-
Requires-Dist: datasets>=3.2.0
|
10
|
-
Requires-Dist: fastai>=2.7.18
|
11
|
-
Requires-Dist: gradio>=5.12.0
|
12
|
-
Requires-Dist: ipykernel>=6.29.5
|
13
|
-
Requires-Dist: ipywidgets>=8.1.5
|
14
|
-
Requires-Dist: loguru>=0.7.3
|
15
|
-
Requires-Dist: seaborn>=0.13.2
|
16
|
-
Requires-Dist: timm>=1.0.13
|
17
|
-
Requires-Dist: transformers>=4.48.0
|
18
|
-
Requires-Dist: xinfer>=0.3.2
|
19
|
-
|
20
1
|
[](https://pypi.org/project/active-vision/)
|
21
2
|
[](https://pypi.org/project/active-vision/)
|
22
3
|
[](https://pypi.org/project/active-vision/)
|
23
4
|
[](https://github.com/dnth/active-vision/blob/main/LICENSE)
|
24
5
|
|
6
|
+
[colab_badge]: https://img.shields.io/badge/Open%20In-Colab-blue?style=for-the-badge&logo=google-colab
|
7
|
+
[kaggle_badge]: https://img.shields.io/badge/Open%20In-Kaggle-blue?style=for-the-badge&logo=kaggle
|
8
|
+
|
25
9
|
<p align="center">
|
26
10
|
<img src="https://raw.githubusercontent.com/dnth/active-vision/main/assets/logo.png" alt="active-vision">
|
11
|
+
<br />
|
12
|
+
<br />
|
13
|
+
<a href="https://dnth.github.io/active-vision" target="_blank" rel="noopener noreferrer"><strong>Explore the docs »</strong></a>
|
14
|
+
<br />
|
15
|
+
<a href="#️-quickstart" target="_blank" rel="noopener noreferrer">Quickstart</a>
|
16
|
+
·
|
17
|
+
<a href="https://github.com/dnth/active-vision/issues/new?assignees=&labels=Feature+Request&projects=&template=feature_request.md" target="_blank" rel="noopener noreferrer">Feature Request</a>
|
18
|
+
·
|
19
|
+
<a href="https://github.com/dnth/active-vision/issues/new?assignees=&labels=bug&projects=&template=bug_report.md" target="_blank" rel="noopener noreferrer">Report Bug</a>
|
20
|
+
·
|
21
|
+
<a href="https://github.com/dnth/active-vision/discussions" target="_blank" rel="noopener noreferrer">Discussions</a>
|
22
|
+
·
|
23
|
+
<a href="https://dicksonneoh.com/" target="_blank" rel="noopener noreferrer">About</a>
|
27
24
|
</p>
|
28
25
|
|
29
26
|
The goal of this project is to create a framework for the active learning loop for computer vision. The diagram below shows a general workflow of how the active learning loop works.
|
@@ -89,41 +86,52 @@ pip install -e .
|
|
89
86
|
> uv pip install active-vision
|
90
87
|
> ```
|
91
88
|
|
92
|
-
##
|
93
|
-
See the [notebook](./nbs/04_relabel_loop.ipynb) for a complete example.
|
89
|
+
## 🚀 Quickstart
|
94
90
|
|
95
|
-
|
96
|
-
|
97
|
-
- [Unlabeled samples](./nbs/unlabeled_samples.parquet): A dataframe of *unlabeled* images. We will continuously sample from this set using active learning strategies.
|
98
|
-
- [Evaluation samples](./nbs/evaluation_samples.parquet): A dataframe of *labeled* images. We will use this set to evaluate the performance of the model. This is the test set, DO NOT use it for active learning. Split this out in the beginning.
|
91
|
+
[![Open In Colab][colab_badge]](https://colab.research.google.com/github/dnth/active-vision/blob/main/nbs/imagenette/quickstart.ipynb)
|
92
|
+
[![Open In Kaggle][kaggle_badge]](https://kaggle.com/kernels/welcome?src=https://github.com/dnth/active-vision/blob/main/nbs/imagenette/quickstart.ipynb)
|
99
93
|
|
100
|
-
|
94
|
+
The following are code snippets for the active learning loop in active-vision. I recommend running the quickstart notebook in Colab or Kaggle to see the full workflow.
|
101
95
|
|
102
96
|
```python
|
103
97
|
from active_vision import ActiveLearner
|
104
|
-
import pandas as pd
|
105
98
|
|
106
|
-
# Create an active learner instance
|
107
|
-
al = ActiveLearner("
|
99
|
+
# Create an active learner instance
|
100
|
+
al = ActiveLearner(name="cycle-1")
|
101
|
+
|
102
|
+
# Load model
|
103
|
+
al.load_model(model="resnet18", pretrained=True)
|
108
104
|
|
109
105
|
# Load dataset
|
110
|
-
train_df =
|
111
|
-
al.load_dataset(df, filepath_col="filepath", label_col="label")
|
106
|
+
al.load_dataset(train_df, filepath_col="filepath", label_col="label", batch_size=8)
|
112
107
|
|
113
108
|
# Train model
|
114
|
-
al.train(epochs=
|
109
|
+
al.train(epochs=10, lr=5e-3)
|
115
110
|
|
116
111
|
# Evaluate the model on a *labeled* evaluation set
|
117
112
|
accuracy = al.evaluate(eval_df, filepath_col="filepath", label_col="label")
|
118
113
|
|
114
|
+
# Get summary of the active learning cycle
|
115
|
+
al.summary()
|
116
|
+
|
119
117
|
# Get predictions from an *unlabeled* set
|
120
118
|
pred_df = al.predict(filepaths)
|
121
119
|
|
122
|
-
# Sample
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
120
|
+
# Sample images using a combination of active learning strategies
|
121
|
+
samples = al.sample_combination(
|
122
|
+
pred_df,
|
123
|
+
num_samples=50,
|
124
|
+
combination={
|
125
|
+
"least-confidence": 0.4,
|
126
|
+
"ratio-of-confidence": 0.2,
|
127
|
+
"entropy": 0.2,
|
128
|
+
"model-based-outlier": 0.1,
|
129
|
+
"random": 0.1,
|
130
|
+
},
|
131
|
+
)
|
132
|
+
|
133
|
+
# Launch a Gradio UI to label the samples, save the labeled samples to a file
|
134
|
+
al.label(samples, output_filename="samples.parquet")
|
127
135
|
```
|
128
136
|
|
129
137
|

|
@@ -136,18 +144,11 @@ Once complete, the labeled samples will be save into a new df.
|
|
136
144
|
We can now add the newly labeled data to the training set.
|
137
145
|
|
138
146
|
```python
|
139
|
-
|
140
|
-
al.add_to_train_set(labeled_df, output_filename="active_labeled")
|
147
|
+
al.add_to_dataset(labeled_df, output_filename="active_labeled.parquet")
|
141
148
|
```
|
142
149
|
|
143
150
|
Repeat the process until the model is good enough. Use the dataset to train a larger model and deploy.
|
144
151
|
|
145
|
-
> [!TIP]
|
146
|
-
> For the toy dataset, I got to about 93% accuracy on the evaluation set with 200+ labeled images. The best performing model on the [leaderboard](https://github.com/fastai/imagenette) got 95.11% accuracy training on all 9469 labeled images.
|
147
|
-
>
|
148
|
-
> This took me about 6 iterations of relabeling. Each iteration took about 5 minutes to complete including labeling and model training (resnet18). See the [notebook](./nbs/04_relabel_loop.ipynb) for more details.
|
149
|
-
>
|
150
|
-
> But using the dataset of 200+ images, I trained a more capable model (convnext_small_in22k) and got 99.3% accuracy on the evaluation set. See the [notebook](./nbs/05_retrain_larger.ipynb) for more details.
|
151
152
|
|
152
153
|
|
153
154
|
## 📊 Benchmarks
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|