Skip to content

Commit 36d8d1a

Browse files
committed
Add train_model to training
1 parent 4d22634 commit 36d8d1a

6 files changed

Lines changed: 62 additions & 26 deletions

File tree

README.md

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,6 @@ pc_img = hsi.principal_components(img)
236236
hsi.plot_image(pc_img, 'Principal components')
237237
```
238238

239-
### Classification model
240-
241-
Two classification models are directly available for automatic identification on hysperspectral images. One is based on support vector machines ('svm') while the other is based on deep image classification ('hsn'). Both models are available under a simple interface like bellow:
242-
243-
```python
244-
n_bands, n_classes = 30, 17
245-
model = hsi.create_model('hsn', (25, 25, n_bands), n_classes)
246-
model.train(X, y, train_ratio=0.3, epochs=5)
247-
y_pred = model.predict(X)
248-
```
249-
250239
## License
251240

252241
This software is licensed under the MIT License. [View the license](LICENSE).

abraia/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from dotenv import load_dotenv
33
load_dotenv()
44

5-
__version__ = '0.25.3'
5+
__version__ = '0.25.4'
66

77
from . import config
88
from .client import Abraia, APIError

abraia/training/__init__.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,35 @@ def split_dataset(annotations):
154154
return train, val, test
155155

156156

157-
def create_dataset(dataset, task, classes):
158-
if not os.path.exists(dataset):
159-
annotations = load_annotations(dataset)
157+
def create_dataset(project, task, classes):
158+
if not os.path.exists(project):
159+
annotations = load_annotations(project)
160160
train, val, test = split_dataset(annotations)
161161
data_annotations = {'train': train, 'val': val, 'test': test}
162162
#TODO: Download files in one single step
163163
for x in ['train', 'val', 'test']:
164-
save_data(data_annotations[x], f"{dataset}/{x}", classes, task)
165-
save_config(dataset, classes)
164+
save_data(data_annotations[x], f"{project}/{x}", classes, task)
165+
save_config(project, classes)
166+
167+
168+
def train_model(project, task, classes, epochs, batch=32, imgsz=640):
169+
if task == 'classify':
170+
training_session = classify.Model()
171+
dataloaders, classes = training_session.create_dataset(project)
172+
model = training_session.train(project, epochs=epochs)
173+
# training.classify.visualize_data(dataloaders['train'])
174+
#training.classify.visualize_model(model, dataloaders['val'])
175+
else:
176+
training_session = detect.Model(task, imgsz=imgsz)
177+
def print_train_end(trainer):
178+
print('# End training')
179+
print('Metrics:', trainer.metrics)
180+
#training_session.model.add_callback('on_train_start', print_train_start)
181+
#training_session.model.add_callback('on_train_epoch_start', print_train_epoch)
182+
training_session.model.add_callback('on_train_end', print_train_end)
183+
metrics = training_session.train(project, epochs=epochs, batch=batch)
184+
print("Train metrics")
185+
print(training_session.test('val'))
186+
#TODO: Save metrics with model
187+
training_session.metrics = training_session.test('test')
188+
return training_session

abraia/training/detect.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,17 @@ def build_model_name(model_name, task):
2727

2828

2929
class Model:
30-
def __init__(self, task, model_type='yolov8n'):
30+
def __init__(self, task, model_type='yolov8n', imgsz=640):
3131
model_name = build_model_name(model_type, task)
3232
self.model = YOLO(f"{model_name}.pt", verbose=False)
3333
self.model_name = model_name
3434
self.metrics = {}
3535
self.task = task
36+
self.imgsz = imgsz
3637

37-
def train(self, dataset, epochs=100, batch=32, imgsz=640):
38+
def train(self, dataset, epochs=100, batch=32):
3839
data = f"{dataset}" if self.task == 'classify' else f"{dataset}/data.yaml"
39-
results = self.model.train(data=data, batch=batch, epochs=epochs, imgsz=imgsz)
40+
results = self.model.train(data=data, batch=batch, epochs=epochs, imgsz=self.imgsz)
4041
# TODO: Merge with test and add parse metrics
4142
metrics = self.model.val(data=data)
4243
# self.metrics = self.test(split='val')
@@ -46,15 +47,17 @@ def test(self, split='val'):
4647
out = io.StringIO()
4748
with contextlib.redirect_stderr(out):
4849
metrics = self.model.val(split=split)
49-
return {'mAP': metrics.box.map50, 'P': metrics.box.p, 'R': metrics.box.r,
50-
'confusionMatrix': metrics.confusion_matrix.matrix}
50+
return {'mAP': float(metrics.box.map50), 'P': metrics.box.p.tolist(), 'R': metrics.box.r.tolist(),
51+
'confusionMatrix': metrics.confusion_matrix.matrix.tolist()}
5152

52-
def save(self, dataset, classes, imgsz=640, device="cpu"):
53+
def save(self, dataset, classes, device="cpu"):
5354
# TODO: Add versioning
54-
model_src = self.model.export(format="onnx", device=device, opset=21, half=True)
55+
out = io.StringIO()
56+
with contextlib.redirect_stdout(out):
57+
model_src = self.model.export(format="onnx", device=device, opset=19, half=True)
5558
abraia.upload_file(model_src, f"{dataset}/{self.model_name}.onnx")
5659
abraia.save_json(f"{dataset}/{self.model_name}.json",
57-
{'task': self.task, 'inputShape': [1, 3, imgsz, imgsz],
60+
{'task': self.task, 'inputShape': [1, 3, self.imgsz, self.imgsz],
5861
'classes': classes, 'metrics': self.metrics})
5962

6063
def run(self, img):

scripts/abraia

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,27 @@ def annotate(project, label):
286286
dataset.save_annotations(project, annotations)
287287

288288

289+
@cli_dataset.command()
290+
@click.argument('project')
291+
def train(project):
292+
"""Train a model on the specified dataset."""
293+
from abraia import training
294+
annotations = training.load_annotations(project)
295+
classes = training.load_labels(annotations)
296+
tasks = training.load_tasks(annotations)
297+
task = tasks[-1] if len(tasks) else 'detect'
298+
epochs = 25 if task == 'classify' else 250
299+
imgsz = 224 if task == 'classify' else 640
300+
click.echo('Loading dataset...')
301+
if not os.path.exists(project):
302+
training.create_dataset(project, task, classes)
303+
click.echo('Dataset loaded.')
304+
training_session = training.train_model(project, task, classes, epochs, imgsz=imgsz)
305+
click.echo('Trained model.')
306+
training_session.save(project, classes)
307+
click.echo('Model saved.')
308+
309+
289310
if __name__ == '__main__':
290311
if not abraia.userid:
291312
configure()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
extras_require = {
1616
'multiple': ['spectral>=0.23.1', 'scipy>=1.14.1', 'tifffile>=2024.8.30'],
17-
'dev': ['opencv-python>=4.10.0.84', 'ImageHash>=4.3.2', 'tifffile>=2024.8.30', 'ultralytics>=8.3.59', 'onnx>=1.18.0', 'transformers>=4.57.1'],#, 'onnxsim>=0.4.36'],
17+
'dev': ['opencv-python>=4.10.0.84', 'ImageHash>=4.3.2', 'tifffile>=2024.8.30', 'ultralytics>=8.3.161', 'onnx>=1.18.0', 'transformers>=4.57.1'],#, 'onnxsim>=0.4.36'],
1818
}
1919

2020
setup(

0 commit comments

Comments
 (0)