feat: export classifier with YOLO OpenVINO interface
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import pytest
|
||||
import torch
|
||||
from torch import nn
|
||||
|
||||
from scripts.export_classifier_openvino import YoloClassifierAdapter, class_order, preprocessing
|
||||
|
||||
|
||||
class FixedClassifier(nn.Module):
|
||||
def forward(self, x):
|
||||
return torch.tensor([1.0, 3.0, -1.0]).expand(x.shape[0], -1)
|
||||
|
||||
|
||||
def test_yolo_contract_and_class_reordering():
|
||||
adapter = YoloClassifierAdapter(FixedClassifier(), 128, 336, [2, 0, 1])
|
||||
result = adapter(torch.rand(1, 3, 128, 128))
|
||||
assert result.shape == (1, 7, 336)
|
||||
torch.testing.assert_close(result[0, :4, 0], torch.tensor([64., 64., 128., 128.]))
|
||||
expected = torch.tensor([1., 3., -1.]).softmax(0)[[2, 0, 1]]
|
||||
torch.testing.assert_close(result[0, 4:, 0], expected)
|
||||
assert result[0, 4:, 0].argmax().item() == 2
|
||||
assert torch.count_nonzero(result[:, :, 1:]) == 0
|
||||
|
||||
|
||||
def test_normalization_matches_training_for_each_image():
|
||||
adapter = YoloClassifierAdapter(FixedClassifier(), 128, 1, [0, 1, 2])
|
||||
images = torch.stack((torch.rand(3, 128, 128), torch.ones(3, 128, 128)))
|
||||
expected = torch.stack([(x - x.mean()) / (x.std() + 1e-5) for x in images])
|
||||
torch.testing.assert_close(adapter.normalize(images), expected)
|
||||
assert torch.isfinite(adapter(images)).all()
|
||||
|
||||
|
||||
def test_class_sets_must_match():
|
||||
assert class_order(["normal", "mosquito"], ["mosquito", "normal"]) == [1, 0]
|
||||
with pytest.raises(ValueError, match="Class sets differ"):
|
||||
class_order(["normal", "mosquito"], ["normal", "blackdot"])
|
||||
with pytest.raises(ValueError, match="Duplicate"):
|
||||
class_order(["normal", "normal"], ["normal"])
|
||||
|
||||
|
||||
def test_refuses_resampling_and_unknown_preprocessing():
|
||||
config = {"data": {"val_transforms": [
|
||||
{"name": "Resize", "size": [160, 160]}, {"name": "ToTensor"},
|
||||
{"name": "PerImageStandardize"}]}}
|
||||
with pytest.raises(ValueError, match="Training size differs"):
|
||||
preprocessing(config, 128)
|
||||
config["data"]["val_transforms"] = [{"name": "Normalize"}]
|
||||
with pytest.raises(ValueError, match="Unsupported"):
|
||||
preprocessing(config, 128)
|
||||
Reference in New Issue
Block a user