Skip to content

Commit

Permalink
MORE UNIT TESTS
Browse files Browse the repository at this point in the history
  • Loading branch information
technocreep committed Nov 15, 2023
1 parent 5214d56 commit 42d7c9b
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 56 deletions.
23 changes: 18 additions & 5 deletions fedot_ind/tools/synthetic/ts_datasets_generator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from fedot_ind.tools.synthetic.ts_generator import TimeSeriesGenerator


class TimeSeriesDatasetsGenerator:
Expand All @@ -13,6 +12,7 @@ class TimeSeriesDatasetsGenerator:
max_ts_len: The maximum length of the time series.
n_classes: The number of classes.
test_size (float): The proportion of the dataset to include in the test split.
multivariate (bool): Whether to generate multivariate time series.
Example:
Easy::
Expand All @@ -23,25 +23,38 @@ class TimeSeriesDatasetsGenerator:
train_data, test_data = generator.generate_data()
"""
def __init__(self, num_samples: int = 80, max_ts_len: int = 50, n_classes: int = 3, test_size: float = 0.5):
def __init__(self, num_samples: int = 80,
max_ts_len: int = 50,
n_classes: int = 3,
test_size: float = 0.5,
multivariate: bool = False):

self.num_samples = num_samples
self.max_ts_len = max_ts_len
self.n_classes = n_classes
self.test_size = test_size
self.multivariate = multivariate
self.ts_types = None

def generate_data(self):
"""
Generates the dataset and returns it as a tuple of train and test data.
"""Generates the dataset and returns it as a tuple of train and test data.
Returns:
Tuple of train and test data, each containing tuples of features and targets.
"""

ts_frame = pd.DataFrame(np.random.rand(self.num_samples, self.max_ts_len))
ts_frame = self.create_features(n_samples=self.num_samples,
ts_length=self.max_ts_len,
multivariate=self.multivariate)
labels = np.random.randint(self.n_classes, size=self.num_samples)

X_train, X_test, y_train, y_test = train_test_split(ts_frame, labels, test_size=self.test_size, random_state=42)
return (X_train, y_train), (X_test, y_test)

def create_features(self, n_samples, ts_length, multivariate):
features = pd.DataFrame(np.random.random((n_samples, ts_length)))
# TODO: add option to select dimentions
if multivariate:
features = features.apply(lambda x: pd.Series([x, x, x]), axis=1)
return features
39 changes: 39 additions & 0 deletions tests/unit/api/utils/test_input_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import pytest

from fedot_ind.api.utils.input_data import init_input_data
import numpy as np
import pandas as pd


@pytest.fixture
def sample_univariate():
rows, cols = 100, 50
X = pd.DataFrame(np.random.random((rows, cols)))
y = np.random.randint(0, 2, rows)
return X, y


@pytest.fixture
def sample_multivariate():
rows, cols = 100, 50
X = pd.DataFrame(np.random.random((rows, cols)))
X = X.apply(lambda x: pd.Series([x, x]), axis=1)
y = np.random.randint(0, 2, rows)
return X, y


def test_init_input_data_uni(sample_univariate):
x, y = sample_univariate
input_data = init_input_data(X=x, y=y)

assert np.all(input_data.features == x.values)
assert np.all(input_data.target == y.reshape(-1, 1))


def test_init_input_data_multi(sample_multivariate):
x, y = sample_multivariate
input_data = init_input_data(X=x, y=y)

assert input_data.features.shape[0] == x.shape[0]
assert input_data.features.shape[1] == x.shape[1]
assert np.all(input_data.target == y.reshape(-1, 1))
Original file line number Diff line number Diff line change
@@ -1,73 +1,37 @@
import json
from pathlib import Path
import os

import pytest
import yaml
from torchvision import transforms

from fedot_ind.api.utils.path_lib import PROJECT_PATH
from fedot_ind.core.architecture.datasets.object_detection_datasets import COCODataset, YOLODataset

synthetic_coco_data = {
"categories": [{"id": 1, "name": "cat"}, {"id": 2, "name": "dog"}],
"images": [
{"id": 1, "file_name": "image1.jpg"},
{"id": 2, "file_name": "image2.jpg"}
],
"annotations": [
{"image_id": 1, "category_id": 1, "area": 100, "bbox": [10, 20, 30, 40], "iscrowd": 0},
{"image_id": 2, "category_id": 2, "area": 150, "bbox": [15, 25, 35, 45], "iscrowd": 1}
]
}


synthetic_yolo_data = {
"train": "train/images",
"val": "val/images",
"names": ["cat", "dog"]
}
yolo_path = os.path.join(PROJECT_PATH, 'tests', 'data', 'datasets', 'minerals', 'minerals.yaml')
coco_path = os.path.join(PROJECT_PATH, 'tests', 'data', 'datasets', 'ALET10', 'test.json')
coco_img_path = os.path.join(PROJECT_PATH, 'tests', 'data', 'datasets', 'ALET10', 'test')


@pytest.fixture
def synthetic_coco_dataset():
tmp_path = Path('.')
coco_json_path = tmp_path / "synthetic_coco.json"
coco_json_path.write_text(json.dumps(synthetic_coco_data))
images_path = tmp_path / "images"
images_path.mkdir(exist_ok=True)
(images_path / "image1.jpg").write_text("")
(images_path / "image2.jpg").write_text("")
return COCODataset(str(images_path), str(coco_json_path), transform=transforms.ToTensor())
return COCODataset(coco_img_path, coco_path, transform=transforms.ToTensor())


@pytest.fixture
def synthetic_yolo_dataset():
tmp_path = Path('.')
yolo_yaml_path = tmp_path / "synthetic_yolo.yaml"
yolo_yaml_path.write_text(yaml.dump(synthetic_yolo_data))
root_path = tmp_path / "train" / "images"
root_path.mkdir(exist_ok=True, parents=True)
(root_path / "image1.jpg").write_text("") # Create empty files for images
(root_path / "image2.jpg").write_text("")
return YOLODataset(str(yolo_yaml_path), transform=transforms.ToTensor())


def test_coco_dataset_length(synthetic_coco_dataset):
assert len(synthetic_coco_dataset) == 2
def yolo_dataset():
return YOLODataset(yolo_path, transform=transforms.ToTensor())


def test_coco_dataset_sample(synthetic_coco_dataset):
sample = synthetic_coco_dataset.samples[0]
image, label = sample['image'], sample['labels']
sample = synthetic_coco_dataset[0]
image, label = sample
assert len(synthetic_coco_dataset) == 3
assert image is not None
assert label is not None


def test_yolo_dataset_length(synthetic_yolo_dataset):
assert len(synthetic_yolo_dataset) == 2


def test_yolo_dataset_sample(synthetic_yolo_dataset):
sample = synthetic_yolo_dataset.samples[0]
def test_yolo_dataset_sample(yolo_dataset):
sample = yolo_dataset[0]
image, label = sample
assert len(yolo_dataset) == 47
assert image is not None
assert label is not None
37 changes: 37 additions & 0 deletions tests/unit/core/architecture/datasets/test_prediction_datasets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import os

import numpy as np
import pytest
from torch import Tensor
from torchvision.transforms import transforms

from fedot_ind.api.utils.path_lib import PROJECT_PATH
from fedot_ind.core.architecture.datasets.prediction_datasets import PredictionFolderDataset, PredictionNumpyDataset

IMAGE_SIZE = (50, 50)
N_SAMPLES = 5
yolo_path = os.path.join(PROJECT_PATH, 'tests', 'data', 'datasets', 'ALET10', 'test')


@pytest.fixture
def images():
return np.array([np.random.randint(low=0,
high=255,
size=IMAGE_SIZE) for _ in range(N_SAMPLES)])


def test_prediction_numpy_dataset(images):
dataset = PredictionNumpyDataset(images=images)
sample = dataset[0]
assert len(dataset) == N_SAMPLES
assert isinstance(sample, tuple)
assert isinstance(sample[0], Tensor)


def test_prediction_folder_dataset():
dataset = PredictionFolderDataset(image_folder=yolo_path,
transform=transforms.ToTensor())
tensor, filename = dataset[0]
assert len(dataset) == 3
assert isinstance(tensor, Tensor)
assert isinstance(filename, str)
33 changes: 33 additions & 0 deletions tests/unit/core/architecture/datasets/test_visualization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import os

import pytest
from matplotlib import pyplot as plt
from torchvision.transforms import transforms

from fedot_ind.api.utils.path_lib import PROJECT_PATH
from fedot_ind.core.architecture.datasets.object_detection_datasets import COCODataset
from fedot_ind.core.architecture.datasets.visualization import draw_sample_with_bboxes, draw_sample_with_masks

coco_path = os.path.join(PROJECT_PATH, 'tests', 'data', 'datasets', 'ALET10', 'test.json')
coco_img_path = os.path.join(PROJECT_PATH, 'tests', 'data', 'datasets', 'ALET10', 'test')


@pytest.fixture
def synthetic_coco_dataset():
return COCODataset(coco_img_path, coco_path, transform=transforms.ToTensor())


def test_draw_sample_with_bboxes(synthetic_coco_dataset):
sample = synthetic_coco_dataset[0]
image, label = sample
figure = draw_sample_with_bboxes(image=image, target=label)

assert isinstance(figure, plt.Figure)


def test_draw_sample_with_masks(synthetic_coco_dataset):
sample = synthetic_coco_dataset[0]
image, _ = sample
figure = draw_sample_with_masks(image=image, target=image)

assert isinstance(figure, plt.Figure)
14 changes: 13 additions & 1 deletion tests/unit/tools/test_ts_datasets_generator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from fedot_ind.tools.synthetic.ts_datasets_generator import TimeSeriesDatasetsGenerator


def test_generate_data():
def test_generate_data_uni():
generator = TimeSeriesDatasetsGenerator(num_samples=80,
max_ts_len=50,
n_classes=3,
Expand All @@ -10,3 +10,15 @@ def test_generate_data():

assert X_train.shape[0] == X_test.shape[0]
assert X_train.shape[1] == X_test.shape[1]


def test_generate_data_multi():
generator = TimeSeriesDatasetsGenerator(num_samples=80,
max_ts_len=50,
n_classes=3,
test_size=0.5,
multivariate=True)
(X_train, y_train), (X_test, y_test) = generator.generate_data()

assert X_train.shape[0] == X_test.shape[0]
assert X_train.shape[1] == X_test.shape[1]

0 comments on commit 42d7c9b

Please sign in to comment.