Вы находитесь на странице: 1из 48

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ

ФЕДЕРАЦИИ

УТВЕРЖДАЮ
Научный руководитель ИЦ СИИП
Университета ИТМО

_____________ А. В. Бухановский
___ ___________ 2022 г.

ФРЕЙМВОРК АВТОМАТИЧЕСКОГО МАШИННОГО ОБУЧЕНИЯ


ДЛЯ ПРОМЫШЛЕННЫХ ЗАДАЧ (FEDOT.Industrial)

РУКОВОДСТВО ПРОГРАММИСТА.ОПИСАНИЕ ПРИМЕНЕНИЯ

ЛИСТ УТВЕРЖДЕНИЯ
По
дп
RU.СНАБ.00843-01 33 01-ЛУ

да
т
а
Представители
Организации-разработчика
Ин
в. Руководитель разработки

ду
бл
. ___________ А. В. Калюжная
Вз ____ ____________ 2022 г.
ам

нв Нормоконтролер
.
№ ___________ А. В. Киреева
По ____ ____________ 2022 г.
дп

да
т
а

Ин
в.

по
дл
. 2022
G
МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ
ФЕДЕРАЦИИ

УТВЕРЖДЕН
RU.СНАБ.00843-01 33 01-ЛУ

ФРЕЙМВОРК АВТОМАТИЧЕСКОГО МАШИННОГО ОБУЧЕНИЯ


ДЛЯ ПРОМЫШЛЕННЫХ ЗАДАЧ (FEDOT.Industrial)

РУКОВОДСТВО ПРОГРАММИСТА.ОПИСАНИЕ ПРИМЕНЕНИЯ

RU.СНАБ.00843-01 33 01
По
дп ЛИСТОВ 47

да
т
а

Ин
в.

ду
бл
.
Вз
ам

нв
.

По
дп

да
т
а

Ин
в.

по
дл 2022
.
G
2
RU.СНАБ.00843-01 33 01
АННОТАЦИЯ
Документ содержит руководство программиста для использования фреймворка
автоматического машинного обучения FEDOT.Industrial, предназначенного для решения
промышленных задач.
В число задач, решаемых фреймворком, входят классификация, поиск аномалий и
предсказательное моделирование на данных пространственно-временных полей.
FEDOT.Industrial разработан в рамках выполнения пункта 3.2 плана деятельности ИЦ
СИИП по Соглашению с АНО «Аналитический центр при Правительстве Российской
Федерации» № 70–2021–00141 (ИГК 000000D730321P5Q0002).
3
RU.СНАБ.00843-01 33 01
СОДЕРЖАНИЕ
1 НАЗНАЧЕНИЕ И УСЛОВИЯ ПРИМЕНЕНИЯ ПРОГРАММЫ..........................................4
2 ОПИСАНИЕ ПРИКЛАДНЫХ ЗАДАЧ...................................................................................5
2.1 Классы решаемых задач................................................................................................5
2.2 Примеры решения задач...............................................................................................5
2.2.1 Классификация временных рядов............................................................................5
2.2.2 Детектирование аномалий........................................................................................8
2.2.3 Автоматическое предсказательное моделирование на данных
пространственно-временных полей...................................................................................10
3 ХАРАКТЕРИСТИКА ПРОГРАММЫ..................................................................................15
3.1 Классификация временных рядов..............................................................................15
3.2 Поиск аномалий во временных рядах.......................................................................17
3.3 Автоматическое предсказательное моделирование на данных пространственно-
временных полей.....................................................................................................................21
4 ОБРАЩЕНИЕ К ПРОГРАММЕ............................................................................................25
4.1.1 Классификация временных рядов..........................................................................25
4.1.2 Детектирование аномалий......................................................................................26
4.1.3 Автоматическое предсказательное моделирование на данных
пространственно-временных полей...................................................................................27
4.2 Базовые функции.........................................................................................................28
4.2.1 Классификация временных рядов..........................................................................28
4.2.2 Детектирование аномалий..........................................................................................29
4.2.3 Автоматическое предсказательное моделирование на данных
пространственно-временных полей...................................................................................29
5 ПРОВЕРКА ПРОГРАММЫ..................................................................................................31
5.1 Классификация временных рядов..............................................................................31
5.2 Поиск аномалий во временных рядах.......................................................................35
5.3 Автоматическое предсказательное моделирование на данных пространственно-
временных полей.....................................................................................................................37
6 ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ................................................................................43
7 СООБЩЕНИЯ.........................................................................................................................44
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ..................................................................45
ЛИСТ РЕГИСТРАЦИИ ИЗМЕНЕНИЙ.....................................................................................46
4
RU.СНАБ.00843-01 33 01
1 НАЗНАЧЕНИЕ И УСЛОВИЯ ПРИМЕНЕНИЯ ПРОГРАММЫ

FEDOT.Industrial (далее – фреймворк) – фреймворк автоматического машинного


обучения для промышленных задач RU.СНАБ.00843-01 разработан в рамках выполнения
пункта 3.2 плана деятельности ИЦ СИИП по Соглашению с АНО «Аналитический центр
при Правительстве Российской Федерации» № 70–2021–00141 (ИГК
000000D730321P5Q0002). Фреймворк предназначен для автоматизации решения задач
предсказательного моделирования промышленных процессов.
Разработанный фреймворк является кроссплатформенным программным
обеспечением, поэтому системные программные средства, используемые фреймворком
могут быть представлены локализованной версией любой операционной системы для ПК
(Windows, Unix). Основным инструментом работы с фреймворком служит среда
разработки (PyCharm). Для чтения выходных данных, как результатов работы фреймворка
может применяться любой табличный редактор, имеющий возможность работать с
файлами с расширением csv (например, Microsoft Excel).
Компонент разработан на языке Python 3.8 с использованием библиотек numpy,
scikit-learn, pandas, Fedot, torch, scipiy, giotto-tda, и размещен в зеркалированных
репозиториях https://github.com/ITMO-NSS-team/Fedot.Industrial и
https://gitlab.actcognitive.org/itmo-nss-team/FEDOT-Industrial.
5
RU.СНАБ.00843-01 33 01
2 ОПИСАНИЕ ПРИКЛАДНЫХ ЗАДАЧ
2.1 Классы решаемых задач
Предметной областью применения разработанного фреймворка являются все
отрасли промышленности, требующие анализа данных, представленных в виде временных
рядов, для последующего принятия технологических решений. Практические примеры
применения с соответствующими постановками задачи в терминах машинного обучения
приведены в таблице Таблица 1.
Таблица 1 – Примеры задач, решаемых фреймворком

Постановка задачи в терминах МО Практическая реализация задачи


Детектирования аномалий во временном Поиск участков с превышением напряженно-
ряду деформированного состояния трубопровода
Предсказательное моделирование на
Детектирование объектов на изображениях
данных пространственно-временных полей
Обработка данных сейсмограмм для
Классификация временных рядов определения наличия землетрясений в данных
исторических наблюдений

2.2 Примеры решения задач

Прежде чем решать один из классов задач, описанных ниже, необходимо


выполнить установку фреймворка из последней версии, расположенной на сервисе Github,
с помощью следующего скрипта:
Листинг 1 – Скрипт установки фреймворка из Github
git clone https://github.com/ITMO-NSS-team/Fedot.Industrial.git
cd FEDOT.Industrial
pip install -r requirements.txt

2.2.1 Классификация временных рядов

Задача классификации одномерных и многомерных временных рядов возникает во


многих областях науки и техники. В качестве примера можно привести распознавание
речи и анализ сейсмологических данных, метеорологических исследования, определение
заболеваний по медицинских данным, а также целый спектр промышленных задач.
В качестве примера решаемой задачи обратимся к проблеме определения
землетрясений на основе данных сейсмограмм. Исходными данными для задачи является
набор временных рядов Earthquakes, полученный из архива UCR [1]. Архив временных
рядов UCR, созданный в 2002 году, стал важным ресурсом в сообществе специалистов по
6
RU.СНАБ.00843-01 33 01
поиску данных временных рядов: не менее тысячи опубликованных работ используют
хотя бы один набор данных из архива.
Задача в данном примере заключается в том, чтобы предсказать, произойдет ли в
ближайшее время крупное землетрясение, на основе последних показаний в окрестностях.
Данные взяты из Центра данных о землетрясениях Северной Калифорнии, и каждый
временной ряд представляет собой усредненные показания за один час, причём сбор
данных осуществлялся в течение около 40 лет. В таблице Таблица 2 приведена более
подробная информация, касающаяся набора исходных данных.
Таблица 2 – Информация о датасете

Размер обучающей Размер тестовой


Длина временного ряда Количество классов
выборки выборки
322 139 512 2

Для запуска эксперимента необходимо задать его конфигурацию с помощью


словаря (листинг Листинг 1). Затем создать экземпляр основного класса фреймворка –
Industrial, после чего вызвать его метод run_experiment, аргументом которого служит
созданных словарь Ключами словаря конфигурации являются следующие значения:
 feature_generators – список генераторов признаков для использования в
эксперименте.
 use_cache – булев флаг, указывающий, использовать ли кэширование
признакового пространства или нет.
 datasets_list – список названий датасетов, участвующих в эксперименте.
 launches – количество повторных запусков одного и того же эксперимента.
 error_correction булев флаг, указывающий, применять ли модель коррекции
ошибок.
 timeout – количество времени, отведённое на композирование пайплайна
средствами алгоритмического ядра FEDOT.
Наборы данных для классификации должны храниться в каталоге data и быть
разделены на обучающий и тестовый наборы с расширением .tsv. Поэтому имя папки в
каталоге data должно быть равно имени набора данных, который предполагается
использовать в эксперименте. В случае отсутствия данных в локальной папке,
реализованный класс DataLoader попытается загрузить данные из архива UCR.
Для данного примера был выбран квантильный метод извлечения признаков,
принцип работы которого показан на рисунке Рисунок 1. Данный метод генерации
признаков может использоваться как самостоятельно, так и в составе другого метода.
7
RU.СНАБ.00843-01 33 01
Идея в следующем: для каждого временного ряда формируется свой вектор признаков, в
который входят значения статистических признаков, рассчитанные по длине всего ряда.
Затем набор извлечённых признаков и вектор классов используются для обучения
классификационной модели средствами алгоритмического ядра Fedot.

Рисунок 1 – Принцип работы квантильного генератора признакового пространства


Листинг 2 – Код запуска эксперимента по классификации временных рядов
from fedot_ind.core.api.tsc_API import Industrial

if __name__ == '__main__':
config = {'feature_generator': ['quantile'],
'datasets_list': ['Earthquakes'],
'use_cache': False,
'error_correction': False,
'launches': 3,
'timeout': 15}

ExperimentHelper = Industrial()
ExperimentHelper.run_experiment(config)

Для уменьшения временных затрат для повторяющихся экспериментов во


фреймворке реализован механизм кэширования признаков. Чтобы включить эту функцию,
необходимо установить параметр use_cache в значение True в конфигурационном словаре.
Результаты эксперимента будут доступны в папке results_of_experiment. Для
каждого генератора признаков будет папка, содержащая папки для каждого набора
данных.
8
RU.СНАБ.00843-01 33 01
Анализ полученных результатов может быть выполнен вручную или с помощью
класса ResultsParser, как это показано в листинге Листинг 3.
Листинг 3 – Код для анализа результатов эксперимента
from fedot_ind.core.operations.utils.results_parser import ResultsParser
parser = ResultsParser()
results = parser.run()
results.to_csv(‘results_of_experiment.csv’, index=False)

Итогом запуска кода для анализа результатов станет файл с расширение csv,
содержащий данные о выполненных расчётах в виде таблицы Таблица 3.
Таблица 3 – Пример результатов эксперимента

dataset f1 roc_auc Generator n_classes


Earthquakes 0.279 0.740 quantile 2
Earthquakes 0.310 0.741 quantile 2
Earthquakes 0.250 0.739 quantile 2

Поскольку в данном примере решается задача бинарной классификации, ключевым


показателем качества предсказаний является метрика roc-auc, на которую нужно
опираться при интерпретации результатов.

2.2.2 Детектирование аномалий

Детектирование аномалий – одна из самых актуальных задач в части анализа


временных рядов, которая находит широкое применение в различных отраслях медицины,
промышленности, метеорологии и т.д.
В листинге Листинг 4 приведён пример запуска эксперимента по детектированию
аномалий с помощью ThresholdZonesDetector, который разбивает один временной ряд на
аномалии. В качестве аргумента данный детектор принимает процентное значение,
обозначающее желаемую процентную продолжительность зон, обрезанных по значению.
Листинг 4 – Код запуска эксперимента по детектированию аномалий (ThresholdZones)
from fedot_ind.core.models.anomaly_detection import FileObject,
ThresholdZonesDetector

file_object = FileObject(time_series, ‘Name’)

detector = ThresholdZonesDetector(0.5)
detector.load_data(file_object)
detector.run_operation()
file_object = detector.return_new_data()
9
RU.СНАБ.00843-01 33 01
На рисунке Рисунок 2 приведён результат работы данного детектора. Детектор
разбивает временной ряд на отдельные зоны путем обрезания значений ряда по границе,
значение которой определяется адаптивно, согласно заданному процентному значению.

Рисунок 2 – Результат работы детектора: верхний ряд – исходный, нижний –


преобразованный, зелёным цветом выделены аномальные зоны
В листинге Листинг 5 приведён пример кода работы алгоритма на основе
AngleBasedDetector, который работает с несколькими временными рядами. Детектор
принимает в себя один параметр – длину окна для анализа. Следом за ним можно указать
шаг окна. По умолчанию шаг равен длине окна поделенной на 4. Результат работы
содержится в поле test_vector_ts и представляет собой отдельный временной ряд, который
пригоден для дальнейшей обработки.
Листинг 5 – Код запуска эксперимента по детектированию аномалий (AngleBasedDetector)
from fedot_ind.core.models.anomaly_detection.FileObject, AngleBasedDetector

data_dict = {‘time_series_1’: time_series_1,


‘time_series_2’: time_series_2}

file_object = FileObject()
file_object.time_series_data = data_dict
detector = AngleBasedDetector(300)
detector.load_data(file_object)
detector.run_operation()
file_object = detector.return_new_data()
Детектор преобразует несколько временных рядов в один при помощи окна,
которое двигается по временному ряду. Внутри каждого окна совокупность рядов
разбивается на массив векторов, длина которого равна длине окна. Каждый вектор
состоит из соответствующих значений каждого временного ряда в данной точке.
После этого находится максимальное векторное расстояние между последним
вектором в окне и остальными векторами. Результат работы детектора приведён на
рисунке Рисунок 3.
10
RU.СНАБ.00843-01 33 01

Рисунок 3 – Результат работы детектора. Верхние ряды исходные, нижний


преобразованный
2.2.3 Автоматическое предсказательное моделирование на данных
пространственно-временных полей
Примером решения задачи данного класса служит задача детектирования объектов
на изображениях. В этом примере проводится эксперимент с двумя методами
оптимизации структуры:
 разложением по сингулярным значениям (SVD);
 мягкой обрезкой фильтра (SFP).
Идея метода SVD показана на рисунке Рисунок 4: веса каждого слоя разлагаются
на три матрицы, затем происходит обучение с дополнительными ограничениями на
сохранение ортогональности матриц и разреженности сингулярных значений. После
обучения происходит обрезка наименее значимых сингулярных чисел и соответствующих
строк и столбцов в ортогональных матрицах. Таким образом, удается добиться
значительного сокращения числа параметров. Во время прямого прохода вычисляется
произведение этих матриц, которое соответствует весовой матрице исходной
размерности.

Рисунок 4 – Идея применения метода сингулярного разложения


После каждой эпохи обучения оценивается значимость каждого фильтра в
конволюционном слое, затем наименее значимые фильтры устанавливаются в ноль
11
RU.СНАБ.00843-01 33 01
(рисунок Рисунок 5). Эта процедура повторяется после каждой эпохи обучения. В конце
ненужные фильтры полностью удаляются из модели.

Рисунок 5 – Обучение одной эпохи

На первом этапе эксперимента необходимо подготовить данные в формате датасета


pytorch, как это показано в листинге Листинг 6.
Листинг 6 – Код подготовки данных к предсказательному моделированию
import sys
sys.path.append('../..')

from torchvision.transforms import Compose, ToTensor, Resize


from torchvision.datasets import ImageFolder

dataset_path = 'your_path'

transform = Compose([ToTensor(), Resize((256, 256))])


train_dataset = ImageFolder(root=dataset_path + 'train',
transform=transform)
val_dataset = ImageFolder(root=dataset_path + 'validation',
transform=transform)

Затем необходимо задать параметры экспериментов (листинг Листинг 7), которые


будут проводиться:
 эксперимент без оптимизации структуры;
 эксперимент с разложением по сингулярному значению конволюционных
слоев;
 эксперименты с мягкой обрезкой фильтров.
Листинг 7 – Задание параметров эксперимента
import torch
12
RU.СНАБ.00843-01 33 01

energy_thresholds = [
0.1, 0.3, 0.5, 0.7, 0.9,
0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99,
0.992, 0.994, 0.996, 0.998, 0.999,
0.9999, 1
]

exp_params = {
'dataset_name': 'Land-Use_Scene_Classification',
'train_dataset': train_dataset,
'val_dataset': val_dataset,
'num_classes': 21,
'dataloader_params': {'batch_size': 32, 'num_workers': 4},
'model': 'ResNet18',
'model_params': {},
'models_saving_path': 'models',
'optimizer': torch.optim.Adam,
'optimizer_params': {},
'target_loss': torch.nn.CrossEntropyLoss,
'loss_params': {},
'metric': 'f1',
'summary_path': 'runs',
'summary_per_class': True,
'gpu': True
}

optimizations = {
'none': [{}],
'SVD': [
{
'decomposing_mode': 'spatial',
'orthogonal_loss_factor': 10,
'hoer_loss_factor': 0.001,
'energy_thresholds': energy_thresholds,
'finetuning_epochs': 1
},
{
'decomposing_mode': 'channel',
'orthogonal_loss_factor': 10,
'hoer_loss_factor': 0.001,
'energy_thresholds': energy_thresholds,
'finetuning_epochs': 1
},
{
'decomposing_mode': 'spatial',
'orthogonal_loss_factor': 100,
'hoer_loss_factor': 0.001,
'energy_thresholds': energy_thresholds,
'finetuning_epochs': 1
},
{
'decomposing_mode': 'channel',
'orthogonal_loss_factor': 100,
'hoer_loss_factor': 0.001,
13
RU.СНАБ.00843-01 33 01
'energy_thresholds': energy_thresholds,
'finetuning_epochs': 1
},
],
'SFP': [
{
'pruning_ratio': 0.5,
'finetuning_epochs': 1
},
{
'pruning_ratio': 0.7,
'finetuning_epochs': 1
},
{
'pruning_ratio': 0.8,
'finetuning_epochs': 1
},
{
'pruning_ratio': 0.9,
'finetuning_epochs': 1
},
]
}

После этого с использованием базового класса ClassificationExperimenter можно


провести эксперименты для 100 эпох, как это показано в листинге Листинг 8.
Листинг 8 – Код запуска эксперимента
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='3'
import warnings
warnings.filterwarnings("ignore")
from fedot_ind.core.architecture.experiment.CVModule import
ClassificationExperimenter

for optimization, params_list in optimizations.items():


for params in params_list:
experimenter = ClassificationExperimenter(
structure_optimization=optimization,
structure_optimization_params=params,
**exp_params
)
experimenter.fit(100)

Для запуска оптимизации предобученной модели используется код, приведённый в


листинге Листинг 9.
Листинг 9 – Код оптимизации предобученной модели
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='3'
import warnings
14
RU.СНАБ.00843-01 33 01
warnings.filterwarnings("ignore")
from fedot_ind.core.architecture.experiment.CVModule import
ClassificationExperimenter

experimenter = ClassificationExperimenter(
structure_optimization='SFP',
structure_optimization_params={
'pruning_ratio': 0.5,
'finetuning_epochs': 10
},

weights='models/Land-Use_Scene_Classification/ResNet18/trained_model.sd.pt',
prefix='without_training_',
**exp_params
)
experimenter.structure_optimization.optimize_during_training()
experimenter.structure_optimization.final_optimize()

experimenter = ClassificationExperimenter(
structure_optimization='SVD',
structure_optimization_params={
'decomposing_mode': 'channel',
'orthogonal_loss_factor': 10,
'hoer_loss_factor': 0,
'energy_thresholds': energy_thresholds,
'finetuning_epochs': 3
},

weights='models/Land-Use_Scene_Classification/ResNet18/trained_model.sd.pt',
prefix='without_training_',
**exp_params
)
experimenter.structure_optimization.final_optimize()
Собранные в одну таблицу результаты моделирования представлены в
таблице Таблица 4.
Таблица 4 – Результаты эксперимента

Model F1 Validation accuracy Train accuracy


Baseline 0.937292 0.938095 1.000000
SFP 50% 0.932722 0.933333 0.999728
SVD spatial 100 0.923959 0.924286 0.996060
SVD channel 100 0.903336 0.904286 0.993750
SFP 70% 0.901154 0.901429 0.996060
SVD channel 10 0.899932 0.900476 0.985734
SVD spatial 10 0.897342 0.898095 0.988043
SFP 80% 0.874307 0.874286 0.987031
SFP 90% 0.359079 0.390476 0.793021
15
RU.СНАБ.00843-01 33 01
3 ХАРАКТЕРИСТИКА ПРОГРАММЫ
3.1 Режимы работы ключевых алгоритмов
3.1.1. Классификация временных рядов

В рамках решения задачи классификации временных рядов фреймворк может


работать в двух режимах:
 Использования генераторов признакового пространства по отдельности.
 Ансамблирования моделей.
Для использования алгоритма ансамблирования предсказаний разных моделей в
конфигурационном файле (словаре) предусмотрен параметр ensemble_algorithm. Данный
параметр принимает два типа значений (листинг Листинг 10):
 False – при отсутствии необходимости ансамблирования предсказаний
разных моделей.
 AGG_voting – для применения ансамблирования методом аггрегирования.
Листинг 10 – Варианты использования параметра ensemble_algorithm
# Без ансамблирования
ensemble_algorithm: False

# Ансамблирование аггрегированием
ensemble_algorithm: ‘AGG_voting’

Зависимость значений метрик от количества моделей в ансамбле представлена на


рисунке Рисунок 6.

Рисунок 6 – Влияние количества моделей в ансамбле на ключевые метрики


классификации
Конфигурационный словарь (файл) также позволяет изменять свойства генераторов
признакового пространства с целью более тонкой настройки параметров проводимого
эксперимента. Например, для генераторов spectral, window_quantile и window_spectral
предусмотрена возможность предопределить один или несколько вариантов длины окна
для каждого исследуемого датасета, как это показано в листинге Листинг 11.
16
RU.СНАБ.00843-01 33 01
Листинг 11 – Варианты использования параметра feature_generator_params
feature_generator_params: {
'spectral':
{
'window_sizes': {
'ItalyPowerDemand': [3, 6, 9],
'Earthquakes': [48],
' Lightning7': [100]
},
},

'window_spectral':
{
'window_sizes': {
'ItalyPowerDemand': [3, 6, 9],
'Earthquakes': [48],
' Lightning7': [100]
},
},
}

Влияние длины окна для специфических генераторов при работе фреймворка


показано в таблице Таблица 5.
Таблица 5 – Изменение метрики качества классификации при разной длине окна

Имя датасета
Параметр
Earthquakes ItalyPowerDemand Lightning7
Бинарная Бинарная Многоклассовая
Тип задачи
классификация классификация класификация
Метрика roc-auc roc-auc f1
Значение метрики
при длине окна 0,543 0,916 0,580
10% от длины ряда
Значение метрики
при длине окна 0,544 0,976 0,521
20% от длины ряда
Значение метрики
при длине окна 0,455 0,535 0,580
30% от длины ряда

Поскольку работа фреймворка базируется в том числе на алгоритмическом ядре


фреймворка автоматического машинного обучения Fedot, в конфигурационном файле
предусмотрена возможность заданий его гиперпараметров, как это показано в
листинге Листинг 12. Данное поле является словарём со следующими ключевыми и
изменяемыми значениями:
 timeout – время, отведённое на композирование модели.
17
RU.СНАБ.00843-01 33 01
 n_jobs – параметр может быть использован для распределения и
использования всех процессоров, имеющихся в локальном компьютере.
Листинг 12 – Варианты использования параметра fedot_params
fedot_params:
{
'problem': 'classification',
'seed': 42,
'timeout': 15,
'max_depth': 10,
'max_arity': 4,
'cv_folds': 3,
'metric':'f1',
'logging_level': 20,
'n_jobs': 4
}

Вариация времени, отведённого на композирование модели приводит к получению


различного по количеству узлов пайплайна в результате работы фреймворка, как это
показано на рисунке Рисунок 7.

А Б

в
Рисунок 7 – Влияние времени композирования модели на сложность конечного
пайплайна: (а) 15 минут, (б) 5 минут, (в) 1 минута
3.1.2. Поиск аномалий во временных рядах

В части работы фреймворка при решении задачи поиска аномалий во временных


рядах следует отметить, что изменение режимов работы детектора производится через
перестройку пайплайна обработки (листинг Листинг 13), где каждый элемент – это
экземпляр классов действий с рядами.
Листинг 13 – Пайплайн обработки
pipe.detector_pipeline = [transformer,
visualizer_of_ts,
simple_zones_detector,
18
RU.СНАБ.00843-01 33 01
anomalies_splitter,
Metric_extractor,
Clusterizator_detector,
Metrics,
visualizer_of_results]
Объектом transformer является класс DataTransformer, аргументом конструктора
которого является количество циклов сглаживания рядов (листинг Листинг 14). Это класс,
который производит предобработку и агрегацию всех данных.
Листинг 14 – Вызов класса DataTransformer
transformer = DataTransformer(4)

Для управления визуализаторами данных используются объекты list_1,


visualizer_of_ts, list_2, visualizer_of_results. Они принимают в качестве аргумента список
типов полей, которые надо отобразить (листинг Листинг 15).
Листинг 15 – Применение визуализаторов
list_1 = ["test",
"all_ts"]

visualizer_of_ts = DataVisualizatorNew(list_1)

list_2 = ["all_ts",
"additional_transformed_average_absolute_deviation",
"predictions"]

visualizer_of_results = DataVisualizatorNew(list_2)

Объект simple_zones_detector является детектором зон, который разбивает один ряд


на заданные зоны (листинг Листинг 16). Принимает в качестве аргумента желаемый
процент длины ряда, который должен быть обрезан по граничному значению.
Листинг 16 – Применение детектора SimpleZoneDetector
simple_zones_detector = SimpleDetector(0.3)

Объект anomalies_splitter может быть использован для разбиения аномалий на


части:
Листинг 17 – Применение разделителя аномалий
anomalies_splitter = AnomaliesSplitter()

Metric_extractor – класс, который извлекает векторы признаков из аномалий.


Принимает в качестве аргументов список названий признаков (листинг Листинг 18). В
данном случае расшифровка требуется следующим названиям:
19
RU.СНАБ.00843-01 33 01
 mean_median_dist – дистанция между средним и медианным значением
целевого ряда в пределах аномалии.
 zip_10_points – результаты сжатия ряда до десяти точек
 distance_sum_40_points – сумма дистанций по оси Y ряда, сжатого до 40
точек.
Листинг 18 – Применение MetricsExtractor
Metric_extractor = MetricsExtractor(["max",
"sum",
"mean",
"median",
"mean_median_dist",
"zip_10_points",
"distance_sum_40_points"])

Детектирование аномалий во временных рядах с помощью кластеризации и на


основе имеющейся базы данных осуществляется посредством объекта
Clusterization_detector (листинг Листинг 19).
Листинг 19 – Вызов ClusterizationDetector
Clusterizator_detector = Clusterization()

Метод ClusterizationMetrics принимает желаемый тип метрики. Возможные


метрики F1 и Custom. Custom метрика считает отношение только удачно детектированных
аномалий к всем размеченным аномалиям ряда.
Листинг 20 – Класс метрик детекции
Metrics = ClusterizationMetrics("F1")

Компонент, предназначенный для поиска аномалий во временных рядах,


поддерживает два режима работы: с временными рядами и с аномалиями.
В режиме работы с временными рядами предусмотрены два типа экспериментов:
1) Работа с одним временным рядом. В этом режиме опускается этап
агрегирования признаков из множества временных рядов. Анализ начинается сразу же с
подбора граничного значения и обрезания ряда по нему с последующим разбиением на
аномалии.
2) Работа с несколькими рядами. В этом режиме первым этапом является
агрегирование признаков нескольких рядов в один, пригодный для последующего
анализа.
20
RU.СНАБ.00843-01 33 01
В режиме работы с аномалиями предусмотрен следующий тип экспериментов:
деление аномалий. Режим деления аномалий позволяет разбивать большие аномалии на
малые, вычленяя значимые пики (рисунок Рисунок 8). Этот режим позволяет уточнить
распознавание аномалий, особенно коротких.

Рисунок 8 – Пример разбиения аномалий


Для определения класса и тяжести аномалий система может применяться в
нескольких режимах работы, основывающихся на векторах признаков аномалий:
1) Анализ по базе данных. При наличии базы данных аномалий система
сравнит вектор аномалии с векторами аномалий в базе данных и, таким образом, найдет
класс и тяжесть исследуемой аномалии.
2) Кластеризационный анализ. При наличии обученного редусера и
размеченных областей, система проведет анализ, основанный на этих областях, и
присвоит аномалии соответствующий класс и тяжесть (рисунок Рисунок 9).

Рисунок 9 – Пример размеченных областей


3) Ансамблирование. Если были применены оба метода, то получение
итогового предсказания возможно только с помощью ансамблирования результатов
работы методов. Одному из методов будет выставлено приоритетное значение, а второй
будет дополнять его предсказания.

3.1.3. Автоматическое предсказательное моделирование на данных


пространственно-временных полей
21
RU.СНАБ.00843-01 33 01
Для управления работой фреймворка по оптимизации структуры в части
предсказательного моделирования необходимо инициализировать класс, передав в него
ряд параметров в формате словаря (листинг Листинг 21).
Листинг 21 – Словарь параметров для инициализации модуля предсказательного
моделирования
exp_params = {
'dataset_name': 'Land-Use_Scene_Classification',
'train_dataset': train_dataset,
'val_dataset': val_dataset,
'num_classes': 21,
'dataloader_params': {'batch_size': 32, 'num_workers': 4},
'model': 'ResNet18',
'model_params': {},
'models_saving_path': 'models',
'optimizer': torch.optim.Adam,
'optimizer_params': {},
'target_loss': torch.nn.CrossEntropyLoss,
'loss_params': {},
'structure_optimization': 'none',
'structure_optimization_params': {},
'metric': 'f1',
'summary_path': 'runs',
'summary_per_class': True,
'weights': None
'prefix': ''
'gpu': True}

Параметры train_dataset и val_dataset управляют наборами данных для обучения и


валидации соответственно. Они должны быть объектами класса-наследника от
torch.utils.data.Dataset.
Параметры dataloader_params, model_params, optimizer_params, loss_params и
structure_optimization_params являются словарями и используются для настройки
параметров соответствующих объектов.
Параметры dataset_name, model, models_saving_path, summary_path и prefix
участвуют в именовании путей сохранения файлов следующим образом: все полученные в
ходе эксперимента модели и словари состояний сохраняются в директорию
"{models_saving_path}/{dataset_name}/{prefix}{model}{гиперпараметры оптимизации}", а
история метрик при обучении сохраняются в директорию
"{summary_path}/{dataset_name}/{prefix}{model}{гиперпараметры оптимизации}".
Параметр prefix используется для разделения разных экспериментов с одинаковыми
параметрами, а параметр summary_per_class включает или отключает трекинг метрик для
каждого класса.
22
RU.СНАБ.00843-01 33 01
Строка model – имя одной из поддерживаемых моделей, отвечает за выбор базовой
архитектуры нейронной сети. Чтобы использовать предобученные веса необходимо также
передать в параметр weights путь до словаря состояния.
Параметр structure_optimization является ключевым для проведения эксперимента
по оптимизации структуры и может принимать одно из трёх значений:
 none – оптимизация структуры не производится.
 SFP – применяется мягкая обрезка фильтров к матрицам весов свёрточных
слоев.
 SVD – применяется сингулярное разложение к матрицам весов свёрточных
слоев.
Для режима мягкой обрезки фильтров необходимо настроить два параметра:
pruning_ratio и finetuning_epochs. Результаты экспериментов по определению влияния
обрезки фильтров представлены на рисунке Рисунок 10.
На рисунке Рисунок 12 показано, как изменяются значения метрики моделей SFP и
SVD после обрезки и тонкой настройки.

Рисунок 10 – Результаты экспериментов после тонкой настройки обрезанных моделей

3.2. Порядок оценки качества алгоритмов


3.2.1. Классификация временных рядов
Для оценки качества работы алгоритма в части решения задач классификации
временных рядов используются следующие стандартные метрики качества:
 F1-метрика, которая представляет собой гармоническое среднее между точностью
и полнотой.
 Roc-Auc – площадь под ROC-кривой.
Значения данных метрик при различных типах задач классификации представлены
в таблицах Таблица 6 и Таблица 7. В этом случае сравнение работы алгоритмов
23
RU.СНАБ.00843-01 33 01
проводится с лучшими на текущий момент алгоритмами (SOTA – state of the art) и базовой
моделью фреймворка.
Таблица 6 – Работа алгоритма при бинарной классификации (метрика roc-auc)

Результат
SOTA SOTA Базовая Генератор
Датасет FEDOT
результат алгоритм модель признаков
Industrial
Chinatown 0,993 ROCKET 0,896 0,995 Spectral
Earthquakes 0,693 ProximityForest 0,509 0,740 Quantile
HIVE-COTE Window
Ham 0,686 0,600 0,724
v1.0 Quantile

Таблица 7 – Работа алгоритма при многоклассовой классификации (метрика f1)

Результат
SOTA SOTA Базовая Генератор
Датасет FEDOT
результат алгоритм модель признаков
Industrial
HIVE-COTE Window
ACSF1 0,846 0,733 0,849
v1.0 Quantile

Beef 0,756 ROCKET 0,572 0,828 Quantile

Window
DistalPhalanxTW 0,530 ResNet 0,590 0,660
Quantile

3.2.2. Поиск аномалий во временных рядах

3.2.3. Предсказательное моделирование на данных пространственно-


временных полей
Для оценки качества работы алгоритмов в части предсказательного моделирования
выбраны точность обучения, точность валидации и f1-метрика. На рисунке Рисунок 11
приведены графики, отражающие влияние типа структурной оптимизации на примере
изменения метрик в течение обучения. Модели, обученные с помощью оптимизации
обрезки мягкого фильтра, могут быть сжаты единственным способом, в то время ка
модели, обученные с помощью оптимизации разложения по сингулярным значениям,
могут быть сжаты различными способами. Таким образом можно найти приемлемый
компромисс между потерей качества распознавания объектов и размером модели.
24
RU.СНАБ.00843-01 33 01

(а) (б)

(в)
Рисунок 11 – Визуализация результатов эксперимента:
(а) точность обучения, (б) точность валидации, (а) F1 метрика

На рисунке Рисунок 12 показано, как изменяются значения метрики моделей SFP и


SVD после обрезки и тонкой настройки.

а б
Рисунок 12 – Метрики моделей SFP и SVD: синее – базовая модель, синее – результат
обрезки, оранжевое – результат тонкой настройки
4. ОБРАЩЕНИЕ К ПРОГРАММЕ
4.1. Точки входа в программу
25
RU.СНАБ.00843-01 33 01
4.1.1. Классификация временных рядов

Основными классами, предназначенными для работы фреймворка в части решения


задачи классификации временных рядов являются Industrial и ExperimentRunner. Первый
отвечает за связь процессов и потоков данных между собой в единый порядок действий,
второй – является абстрактным классом для всех видов генераторов признаков.
В таблице Таблица 8 описаны основные методы классов Industrial и
ExperimentRunner и их аргументы.
Таблица 8 - Основные классы фреймворка в части задач классификации

Класс Метод Переменные


model_name – имя модели;
task_type – тип задачи;
train_features – обучающие
fit()
признаки;
train_target – целевая переменная
Метод для извлечения признаков
для обучения;
и обучения классификационной
model_params – параметры
модели
модели,
dataset_name – имя набора
данных.
predict()
Industrial
features – набор признаков.
Метод для получения
Класс для
предсказаний модели
проведения
get_metrics() target – целевая переменная:
экспериментов
prediction_label – предсказанные
Метод для получения метрик, метки классов:
определяющих качество prediction_proba – матрица
предсказаний вероятностей.
config – словарь конфигурации
или путь к файлу конфигурации;
run_experiment() direct_path – булево значение.
Используется для указания на
Метод для запуска эксперимента факт использования абсолютного
(прямого) пути к файлу
конфигурации.

Продолжение таблицы 7
save_results() dataset_name – наименование
набора данных;
Метод для сохранения modelling_results – словарь с
26
RU.СНАБ.00843-01 33 01
результатов моделирования результатами экспериментов.
ts_data – набор временных рядов.
ExperimentRunner В зависимости от типа генератора
дополнительными аргументами
get_features()
Абстракный класс могут быть:
Метод, отвечающий за
описывающий
извлечение признаков из массива
интерфейс каждого dataset_name – имя набора
данных временного ряда
из генераторов данных;
признаков: window_length – длина окна;
target – целевая переменная.
 RecurrenceRunner extract_features()
 SignalRunner features – набор временных
 SSARunner Метод-обертка для метода рядов;
 StatsRunner извлечения признаков dataset_name – имя набора
 TopologicalRunner get_features() с кэшированием данных.
результатов в pickle-файл

4.1.2. Детектирование аномалий

Основными классами, предназначенными для работы фреймворка в части решения


задачи поиска аномалий во временных рядах, являются FileObject, AnomalyZone и
AbstractDataOperation, являющийся родительским классом для ряда детекторов.
В таблице Таблица 9 описаны данные классы и их основные методы.
Таблица 9 – Основные классы фреймворка в части детектирования аномалий

Класс Метод Переменные


main_data_dict –
словарь с исходными
FileObject
данными;
get_labels_for_metrics()
Содержит в себе
filename –
информацию об
наименование
объекте анализа:
исходных данных.
исходные временные
type_numbers –
ряды, преобразования
get_all_predicts_list_by_type() число,
этих рядов и список
определяющее тип
аномалий
возвращаемого
предикта
Продолжение таблицы 8
AnomalyZone get_start()

Содержит в себе всю Метод возращающий начало аномалии
информацию о get_end() –
найденной аномальной
27
RU.СНАБ.00843-01 33 01
Метод, возвращающий конец аномалии
get_features_for_heaviness_clusterization()
get_features_for_type_clusterization() features_names –
зоне в составе данных список имён
класса FileObject: части get_features_for_dataset_comparison() признаков
исходных и
преобразованных

4.1.3. Автоматическое предсказательное моделирование на данных


пространственно-временных полей

Основными классами, предназначенными для работы фреймворка в части решения


задачи предсказательного моделирования являются _GeneralizedExperementer,
являющийся родительским классом ряда других классов, предназначенных для
проведения специфических экспериментов. В таблице Таблица 10 описаны данные классы
и их основные методы.
Таблица 10 – Основные классы фреймворка в части предсказательного моделирования

Класс Метод Переменные


train_loop()
model – обучаемая модель;
train_dataset – обучающая выборка.
Метод для val_dataset – валидационная выборка.
обучения num_classes – количество классов в наборе
модели данных.
_GeneralizedExperimenter
dataloader_params – словарь с параметрами
для загрузчика данных;
Абстрактный класс для
models_path – путь сохранения моделей;
работы с моделями, о
metric – целевая метрика;
которого наследуются
summary_path – путь сохранения
классы
результатов эксперимента;
val_loop()
weights – путь к весам модели;
 ClassificationExperimenter
gpu – флаг использования графической
 FasterRCNNExperimenter Метод валидации
карты при расчётах.
модели
В зависимости от класса дополнительными
аргументами могут быть:

Продолжение таблицы 9
model_params – словарь с параметрами
модели;
optimizer тип оптимизатора модели;
optimizer_params – параметры
28
RU.СНАБ.00843-01 33 01
оптимизатора;
target_loss – функция потерь;
loss_params – параметры функции потерь;
structure_optimization – структурный
оптимизатор;
structure_optimization_params – параметры
структурного оптимизатора;
prefix – префикс к имени эксперимента;
4.2. Базовые функции
4.2.1. Классификация временных рядов

Ключевым классом фреймворка при решении задачи классификации временных


рядов является Industrial (листинг Листинг 22), а его метод run_experiment, принимающий
в качестве аргумента конфигурационный словарь или путь к файлу, используется для
запуска процесса расчёта.
Листинг 22 – Скрипт запуска эксперимента по классификации временных рядов
from fedot_ind.core.api.API import Industrial

if __name__ == '__main__':
config = dict(feature_generator=['topological', 'wavelet'],
datasets_list=['UMD', 'Lightning7'],
use_cache=True,
error_correction=False,
launches=3,
timeout=10)
ExperimentHelper = Industrial()
ExperimentHelper.run_experiment(config_name)

Базовым классом для сбора результатов проведённого эксперимента является


ResultsParser, способ обращения к которому показан в листинге Листинг 23. Данный класс
с помощью метода run() позволяет на выходе получить полную таблицу с перечислением
наборов данных, использованных генераторов признаков и метрик, по которым
оценивается качество полученных результатов.

Листинг 23 – Использование модуля сбора данных результатов эксперимента


from fedot_ind.core.operation.utils.results_parser import ResultsParser

if __name__ == '__main__':
parser = ResultsParser()
results_table = parser.run()
results_table.to_csv(‘experiment_results.csv’, index=False)
29
RU.СНАБ.00843-01 33 01
4.2.2. Детектирование аномалий

В листинге Листинг 24 приведён базовый пример использования алгоритма поиска


аномалий во временном ряду. Класс FileObject содержит в себе информацию об объекте
анализа – исходные временные ряды, преобразования этих рядов и список аномалий.
Приведённый в примере ThresholdZonesDetector разбивает один временной ряд на
аномалии. Детектор принимает в себя один параметр – процентное значение,
обозначающее желаемую процентную продолжительность зон, обрезанных по значению.
Результат работы метода содержится в поле anomalies_list обновленного объекта класса
FileObject. Результат представляет собой список объектов класса AnomalyZone.
Класс AnomalyZone, в свою очередь, содержит в себе всю информацию о
найденной аномальной зоне в составе данных класса FileObject: части исходных и
преобразованных рядов, тяжесть аномалии и её тип.
Листинг 24 – Использование компонента для поиска аномалий
from fedot_ind.core.models.anomaly_detection.FileObject,
ThresholdZonesDetector

file_object = FileObject(time_series, ‘Name’)

detector = ThresholdZonesDetector(0.5)
detector.load_data(file_object)
detector.run_operation()
file_object = detector.return_new_data()

4.2.3. Автоматическое предсказательное моделирование на данных


пространственно-временных полей

В листинге Листинг 25 приведён пример применения фреймворка для


предсказательного моделирования на данных пространственно-временных полей.
В точки зрения решения задачи обозначенного класса в рамках фреймворка
существует ряд ключевых классов и их методов.
ClassificationExperimenter – класс реализующий основную логику проведения
эксперимента для моделей классификации изображений: запуск эксперимента по
оптимизации структуры, обучение модели, валидация, трекинг метрик, сохранение и
загрузка моделей, предсказание на произвольных изображениях. FasterRCNNExperimenter
– аналогичный класс для модели Faster R-CNN (детектирование объектов на
изображениях).
30
RU.СНАБ.00843-01 33 01
Для запуска эксперимента нужно инициализировать класс и вызывать метод fit,
аргументом которого является число эпох. Чтобы получить предсказания для директории
с изображениями необходимо вызвать метод predict, аргументом которого является путь к
директории.
Для оптимизации существуют два основных класса: SVDOptimization и
SFPOptimization, они создаются и вызываются внутри класса эксперимента (параметры
оптимизации передаются в конструктор эксперимента).
Листинг 25 – Пример запуска эксперимента на данных пространственно-временных полей
from fedot_ind.core.architecture.experiment.CVModule import
ClassificationExperimenter

experimenter = ClassificationExperimenter(
structure_optimization='SFP',
structure_optimization_params={
'pruning_ratio': 0.5,
'finetuning_epochs': 10
},

weights='models/Land-Use_Scene_Classification/ResNet18/trained_model.sd.pt',
prefix='without_training_',
**exp_params
)
experimenter.fit(100)
experementer.predict(path_to_folder)
31
RU.СНАБ.00843-01 33 01
5. ПРОВЕРКА ПРОГРАММЫ

Запуск модульных и интеграционных тестов может быть выполнен различными


способами:

1) Локально развернуть конфигурации фреймворка, установить зависимости из


файла requirements.txt (pip install requirements.txt). Перейти в каталог test, запустить
команду pytest –s.
2) На платформе github выполнить обновление основной ветки кода - это
приведет к автоматическому запуску модульных текстов. Интеграционные тесты могут
быть автоматически запущены с помощью действия Manual build.

Все тесты располагаются в репозитории по адресу: https://github.com/ITMO-NSS-


team/Fedot.Industrial/tree/main/tests.

5.1. Классификация временных рядов


 Тестирование базового класса Industrial приведено в листинге Листинг 26.
Входные данные: конфигурационный файл Config_Classification.yaml, содержащий
параметры эксперимента.
Проверка: соответствие типов данных.
Ожидаемый результат: тип объекта config_dict – словарь, тип объекта train_data[0]
– pandas.DataFrame, тип объекта train_data[1] – массив numpy, тип объекта n_classes –
целочисленное значение. При этом объект IndustrialModel, обученная модель, набор
признаков не должен принимать значение None, не должны принимать значение None.
Листинг 26 – Код тестирования основного класса для задачи классификации временных
рядов
import numpy as np
import pandas as pd
import pytest
from core.api.API import Industrial

@pytest.fixture()
def basic_config_API():
config_path = 'tests/data/config/Config_Classification.yaml'
return config_path

@pytest.fixture()
def basic_API_class():
ExperimentHelper = Industrial()
return ExperimentHelper

def load_data(dataset_name):
train_data, test_data, n_classes =
32
RU.СНАБ.00843-01 33 01
Industrial().reader.read(dataset_name=dataset_name)
return train_data, test_data, n_classes

def test_YAMl_reader(basic_API_class, basic_config_API):


config_dict =
basic_API_class.YAML.read_yaml_config(config_path=basic_config_API,
return_dict=True)
assert type(config_dict) is dict

def test_API_data_reader(basic_API_class, basic_config_API):


exclude = ['topological', 'spectral', 'window_spectral']
config_dict =
basic_API_class.YAML.read_yaml_config(config_path=basic_config_API,
return_dict=True)
train_data, test_data, n_classes = load_data('Worms')
filtred_dict = basic_API_class.exclude_generators(config_dict,
train_data=train_data[0])
assert type(train_data[0]) is pd.DataFrame
assert type(train_data[1]) is np.ndarray
assert type(n_classes) is int
assert any(exclude) not in filtred_dict['feature_generator']

def test_API_code_scenario(basic_API_class):
train_data, test_data, n_classes = load_data('Lightning7')

IndustrialModel, train_feats =
basic_API_class.fit(model_name='quantile',
task_type='ts_classification',
model_params={'problem': 'classification',
'seed': 42,
'timeout': 1,
'max_depth': 3,
'max_arity': 1,
'cv_folds': 2,
'logging_level': 20,
'n_jobs': 2},
feature_generator_params={'window_mode': False},
train_features=train_data[0],
train_target=train_data[1])

labels, test_feats = basic_API_class.predict(features=test_data[0])


probs, test_feats = basic_API_class.predict_proba(features=test_data[0])

metrics = basic_API_class.get_metrics(target=test_data[1],
prediction_label=labels,
prediction_proba=probs)
assert IndustrialModel is not None
assert basic_API_class.fitted_model is not None
assert basic_API_class.train_features is not None
assert type(train_feats) is np.ndarray
assert type(test_feats) is np.ndarray
assert type(probs) is np.ndarray
assert type(labels) is np.ndarray
assert type(metrics) is dict
33
RU.СНАБ.00843-01 33 01
def test_API_config_scenario(basic_API_class, basic_config_API):
basic_API_class.run_experiment(basic_config_API)
_ = 1
assert basic_API_class is not None

 Тестирование модуля имплементированных метрик (листинг Листинг 27).


Входные данные: тестовый набор предсказаний и тестовых переменных.
Проверка: корректность работы модулей вычисления метрик.
Ожидаемый результат: метрика pareto_front не принимает значения None, размеры
массивов вычисленных метрик больше единицы.
Листинг 27 – Тестирование имплементированных метрик
from core.metrics.metrics_implementation import *
import pytest

@pytest.fixture()
def basic_metric_data_clf():
target_label = np.array([1, 2, 3, 4])
test_label = np.array([1, 1, 2, 4])
test_proba = np.array([[0.8, 0.1, 0.05, 0.05],
[0.8, 0.1, 0.05, 0.05],
[0.1, 0.8, 0.05, 0.05],
[0.05, 0.1, 0.05, 0.8]])

return test_proba, test_label, target_label

@pytest.fixture()
def basic_metric_data_reg():
test_label = np.array([1.1, 2.2, 3.3, 4.4])
target_label = np.array([10, 0.1, 2.3, 4.1])

return test_label, target_label

def test_pareto_metric():
basic_multiopt_metric = np.array([[1.0, 0.7],
[0.9, 0.8],
[0.1, 0.3]])
pareto_front =
ParetoMetrics().pareto_metric_list(costs=basic_multiopt_metric)
assert pareto_front is not None

def test_basic_clf_metric(basic_metric_data_clf):
clf_metric_dict = {'roc_auc': ROCAUC,
'f1': F1,
'precision': Precision,
'accuracy': Accuracy,
'logloss': Logloss}
34
RU.СНАБ.00843-01 33 01

result_metric = []
for metric_name in clf_metric_dict.keys():
chosen_metric = clf_metric_dict[metric_name]
score = chosen_metric(target=basic_metric_data_clf[2],
predicted_labels=basic_metric_data_clf[1],

predicted_probs=basic_metric_data_clf[0]).metric()
score = round(score, 3)
assert score is not None
result_metric.append(score)
assert len(result_metric) > 1

def test_basic_regression_metric(basic_metric_data_reg):
reg_metric_dict = dict(rmse=RMSE,
r2=R2, mae=MAE, mse=MSE, mape=MAPE)
result_metric = []
for metric_name in reg_metric_dict.keys():
chosen_metric = reg_metric_dict[metric_name]
score = chosen_metric(target=basic_metric_data_reg[1],

predicted_labels=basic_metric_data_reg[0]).metric()
score = round(score, 3)
assert score is not None
result_metric.append(score)
assert len(result_metric) > 1

def test_SVD_loss():
reg_metric_dict = dict(rmse=RMSE,
r2=R2, mae=MAE, mse=MSE, mape=MAPE)
result_metric = []
for metric_name in reg_metric_dict.keys():
chosen_metric = reg_metric_dict[metric_name]
score = chosen_metric(target=basic_metric_data_reg[1],

predicted_labels=basic_metric_data_reg[0]).metric()
score = round(score, 3)
assert score is not None
result_metric.append(score)
assert len(result_metric) > 1

 Тестирование генераторов признаков (листинг Листинг 28).


Входные данные: два набора временных рядов из архива UCR – Lightning7 и
Earthquakes.
Проверка: корректность работы признаковых генераторов.
Ожидаемый результат: извлечённые обучающие и тестовые признаки не
принимают значения None.
35
RU.СНАБ.00843-01 33 01
Листинг 28 – Тестирование генераторов признаков
from core.architecture.utils.Testing import ModelTestingModule
from core.models.statistical.QuantileRunner import *
from core.models.spectral.SSARunner import *
from core.models.signal.SignalRunner import *
from core.models.signal.RecurrenceRunner import *
from core.models.topological.TopologicalRunner import *
import pytest

@pytest.fixture()
def feature_generators_list():
return [StatsRunner, SSARunner, SignalRunner, RecurrenceRunner,
TopologicalRunner]

@pytest.fixture()
def window_feature_generators_list():
return [StatsRunner, SSARunner]

def test_get_features(feature_generators_list):
for feature_generator in feature_generators_list:
model = feature_generator()
TestModule = ModelTestingModule(model=model)
train_feats_earthquakes, test_feats_earthquakes =
TestModule.extract_from_binary(dataset_name='Earthquakes')
train_feats_lightning7, test_feats_lightning7 =
TestModule.extract_from_multi_class(dataset_name='Lightning7')
assert train_feats_lightning7 is not None
assert test_feats_lightning7 is not None

assert train_feats_earthquakes is not None


assert test_feats_earthquakes is not None

def test_get_features_window_mode(window_feature_generators_list):
for feature_generator in window_feature_generators_list:
model = feature_generator(window_mode=True)
TestModule = ModelTestingModule(model=model)
train_feats_earthquakes, test_feats_earthquakes =
TestModule.extract_from_binary(dataset_name='Earthquakes')
train_feats_lightning7, test_feats_lightning7 =
TestModule.extract_from_multi_class(dataset_name='Lightning7')
assert train_feats_lightning7 is not None
assert test_feats_lightning7 is not None

assert train_feats_earthquakes is not None


assert test_feats_earthquakes is not None

5.2. Поиск аномалий во временных рядах


36
RU.СНАБ.00843-01 33 01
В качестве объекта входных данных при тестировании фреймворка в части поиска
аномалий являются два временных ряда, сгенерированных случайным образом
(листинг Листинг 29).
Листинг 29 – Входные данные для тестирования компонента детектирования аномалий
def basic_periodic_data():
x0 = 1 * np.ones(1000) + np.random.rand(1000) * 1
x1 = 3 * np.ones(1000) + np.random.rand(1000) * 2
x2 = 5 * np.ones(1000) + np.random.rand(1000) * 1.5
x = np.hstack([x0, x1, x2])
x += np.random.rand(x.size)

x0 = 6 * np.ones(1000) + np.random.rand(1000) * 1
x1 = 3 * np.ones(1000) + np.random.rand(1000) * 2
x2 = 7 * np.ones(1000) + np.random.rand(1000) * 1.5
y = np.vstack([x0, x1, x2])
y += np.random.rand(x.size)
return x, y

 Тестирование детектора на основе граничного значения


Проверка: проверка осуществляется по двум основным направлениям: проверка того, что
результат работы не является пустым и проверка одного из атрибутов результата на
предмет того, что он не равен нулю.
Ожидаемый результат: список объектов типа AnomalyZone, у которых
инициализированы и присвоены значения начала и конца аномалии.
Листинг 30 – Тестирование ThresholdZonesDetector
def test_Threshold_Zones_Detector(basic_periodic_data):
ts_1, _ = basic_periodic_data
file_object = FileObject(ts_1, "test")

detector = ThresholdZonesDetector(0.5)
detector.load_data(file_object)
detector.run_operation()
new_object = detector.return_new_data()

assert len(new_object.anomalies_list) is not 0


assert new_object.anomalies_list[0].get_end() is not 0
assert new_object.anomalies_list[0].get_start() is not 0

 Тестирование детектора на основе углов (листинг Листинг 31)


Проверка: проверка осуществляется по двум основным направлениям: проверка
того, что результат работы не является пустым и проверка одного из атрибутов результата
на предмет того, что он не равен нулю.
37
RU.СНАБ.00843-01 33 01
Ожидаемый результат: временной ряд ненулевой длины в котором есть отличные
от нуля значения.
Листинг 31 – Тестирование AngleBasedDetector
def test_Angle_Based_Detector(basic_periodic_data):
ts_1, ts_2 = basic_periodic_data
data_dict = {
"Ts_1": ts_1,
"Ts_2": ts_2
}
file_object = FileObject(ts_1, "test")
file_object.time_series_data = data_dict
detector = AngleBasedDetector(300)
detector.load_data(file_object)
detector.run_operation()
new_object = detector.return_new_data()
assert len(new_object.test_vector_ts) is not 0

 Тестирование метода разделения ряда на окна (листинг)


Проверка: корректность работы модуля.
Ожидаемый результат: список ненулевой длины, каждый элемент которого это это
список, ненулевой длины, являющийся частью исходного ряда.
Листинг 32 – Тестирование класса WindowCutter
def test_WindowCutting(basic_periodic_data):
test_dict = {
"ts_1": basic_periodic_data
}
cutter = WindowCutter(window_len=100, window_step=10)
cutter.load_data(test_dict)
cutter.run()
windows_list = cutter.get_windows()
assert len(windows_list) != 0
assert list(windows_list[0].keys())[0] == "ts_1"

def test_WindowSizeSelection(basic_periodic_data):
finder = WindowSizeSelection(
time_series=basic_periodic_data)
result = finder.runner_wss()
assert type(result[0]) is int and type(result[1]) is list
assert result[0] != 0

5.3. Автоматическое предсказательное моделирование на данных


пространственно-временных полей
 Тестирование основных классов для выполнения экспериментов
(листинг Листинг 33).
Входные данные: строка, не соответствующая ни одному режиму оптимизации.
38
RU.СНАБ.00843-01 33 01
Проверка: корректность выбрасываемого исключения.
Ожидаемый результат: ValueError
Листинг 33 – Тестирование класса предсказательного моделирования
def test_wrong_structure_optimization(get_test_classification_dataset):
exp_params, tmp_path = get_test_classification_dataset
with pytest.raises(ValueError):
experimenter = ClassificationExperimenter(
**exp_params,
structure_optimization='no',
structure_optimization_params={})

 Тестирование методов основного класса ClassificationExperrimenter


(листинг Листинг 34).
Входные данные: тестовый датасет с тремя классами, запуск без оптимизации
структуры.
Проверка: корректность работы основных методов классификационного
экспериментатора.
Ожидаемый результат: сохранена обученная модель, предсказания производятся
для каждого изображения из тестовой паки, предсказания модели с помощью метода
predict соответствуют одному из трёх классов, предсказания модели с помощью метода
predict_proba содержат вектора из трёх элементов.
Листинг 34 – Тестирование основных методов класса предсказательного моделирования
def classification_predict(experimenter):
test_predict_path = DATASETS_PATH + 'Agricultural/val/banana'
preds = experimenter.predict(test_predict_path)
assert set(preds.keys()) == set(os.listdir(test_predict_path))
for k, v in preds.items():
assert v in [0, 1, 2]
proba_preds = experimenter.predict_proba(test_predict_path)
assert set(proba_preds.keys()) == set(os.listdir(test_predict_path))
for k, v in proba_preds.items():
assert len(v) == 3

def test_classification_experimenter(get_test_classification_dataset):
exp_params, tmp_path = get_test_classification_dataset
experimenter = ClassificationExperimenter(
**exp_params,
structure_optimization='none',
structure_optimization_params={}
)
experimenter.fit(1)
assert os.path.exists(tmp_path.joinpath(
'models/Agricultural/ResNet18/trained.sd.pt'))
classification_predict(experimenter)
39
RU.СНАБ.00843-01 33 01
 Тестирование основных методов базового класса и оптимизатора структуры
(листинг Листинг 35) – кейс 1.
Входные данные: тестовый датасет с тремя классами, запуск с SFP оптимизацией.
Проверка: корректность работы основных методов классификационного
экспериментатора и оптимизатора структуры.
Ожидаемый результат: сохранена обученная модель, сохранена обрезанная модель,
сохранена дообученная модель, предсказания производятся для каждого изображения из
тестовой паки, предсказания модели с помощью метода predict соответствуют одному из
трёх классов, предсказания модели с помощью метода predict_proba содержат вектора из
трёх элементов.
Листинг 35 – Тестирование основных методов и оптимизатора структуры (кейс 1)
def test_sfp_classification_experimenter(get_test_classification_dataset):
exp_params, tmp_path = get_test_classification_dataset
experimenter = ClassificationExperimenter(
**exp_params,
structure_optimization='SFP',
structure_optimization_params=SFP_PARAMS
)
experimenter.fit(1)
root = tmp_path.joinpath('models/Agricultural/ResNet18_SFP_P-0.50/')
assert os.path.exists(root.joinpath('trained.sd.pt'))
assert os.path.exists(root.joinpath('fine-tuning.sd.pt'))
assert os.path.exists(root.joinpath('pruned.model.pt'))
assert os.path.exists(root.joinpath('fine-tuned.model.pt'))
classification_predict(experimenter)

 Тестирование основных методов базового класса и оптимизатора структуры


(листинг Листинг 36) – кейс 2.
Входные данные: тестовый датасет с тремя классами, запуск с по-канальной SVD
оптимизацией.
Проверка: корректность работы основных методов классификационного
экспериментатора и оптимизатора структуры.
Ожидаемый результат: сохранена обученная модель, сохранена дообученная после
обрезки модель, предсказания производятся для каждого изображения из тестовой паки,
предсказания модели с помощью метода predict соответствуют одному из трёх классов,
предсказания модели с помощью метода predict_proba содержат вектора из трёх
элементов.
Листинг 36 – Тестирование основных методов и оптимизатора структуры (кейс 2)
def test_svd_channel_classification_exper(get_test_classification_dataset):
exp_params, tmp_path = get_test_classification_dataset
40
RU.СНАБ.00843-01 33 01
experimenter = ClassificationExperimenter(
**exp_params,
structure_optimization='SVD',
structure_optimization_params={
'decomposing_mode': 'channel',
**SVD_PARAMS
}
)
experimenter.fit(1)
root = tmp_path.joinpath('models/Agricultural/ResNet18_SVD_channel_O-
10.0_H-0.001000/')
assert os.path.exists(root.joinpath('trained.sd.pt'))
assert os.path.exists(root.joinpath('fine-tuning_e_0.9.sd.pt'))
assert os.path.exists(root.joinpath('fine-tuned_e_0.9.model.pt'))
classification_predict(experimenter)

 Тестирование основных методов базового класса и оптимизатора структуры


(листинг Листинг 37) – кейс 3.
Входные данные: тестовый датасет с тремя классами, запуск с пространственной
SVD оптимизацией.
Проверка: корректность работы основных методов классификационного
экспериментатора и оптимизатора структуры.
Ожидаемый результат: сохранена обученная модель, сохранена дообученная после
обрезки модель, предсказания производятся для каждого изображения из тестовой паки,
предсказания модели с помощью метода predict соответствуют одному из трёх классов,
предсказания модели с помощью метода predict_proba содержат вектора из трёх
элементов.
Листинг 37 – Тестирование основных методов и оптимизатора структуры (кейс 3)
def test_svd_spatial_classification_exper(get_test_classification_dataset):
exp_params, tmp_path = get_test_classification_dataset
experimenter = ClassificationExperimenter(
**exp_params,
structure_optimization='SVD',
structure_optimization_params={
'decomposing_mode': 'spatial',
**SVD_PARAMS
}
)
experimenter.fit(1)
root = tmp_path.joinpath('models/Agricultural/ResNet18_SVD_spatial_O-
10.0_H-0.001000/')
assert os.path.exists(root.joinpath('trained.sd.pt'))
assert os.path.exists(root.joinpath('fine-tuning_e_0.9.sd.pt'))
assert os.path.exists(root.joinpath('fine-tuned_e_0.9.model.pt'))
classification_predict(experimenter)
41
RU.СНАБ.00843-01 33 01
 Тестирование Faster R-CNN экспериментатора (листинг Листинг 38) без
оптимизации.
Входные данные: тестовый датасет, запуск без оптимизации структуры.
Проверка: корректность работы основных методов Faster R-CNN
экспериментатора.
Ожидаемый результат: сохранена история изменения метрик при обучении,
предсказания производятся для каждого изображения из тестовой паки, предсказания
модели с помощью метода predict содержат метки класса и ограничивающие рамки,
предсказания модели с помощью метода predict_proba содержат метки классов,
ограничивающие рамки и вероятности.
Листинг 38 – Тестирование экспериментатора Faster R-CNN
def detection_predict(experimenter):
test_predict_path = DATASETS_PATH + 'ALET10/test'
preds = experimenter.predict(test_predict_path)
assert set(preds.keys()) == set(os.listdir(test_predict_path))
for k, v in preds.items():
assert set(v.keys()) == {'labels', 'boxes'}
proba_preds = experimenter.predict_proba(test_predict_path)
assert set(proba_preds.keys()) == set(os.listdir(test_predict_path))
for k, v in proba_preds.items():
assert set(v.keys()) == {'labels', 'boxes', 'scores'}

def test_fasterrcnn_experimenter(get_test_detection_dataset):
exp_params, tmp_path = get_test_detection_dataset
experimenter = FasterRCNNExperimenter(
**exp_params,
structure_optimization='none',
structure_optimization_params={}
)
experimenter.fit(1)
assert
os.path.exists(tmp_path.joinpath('runs/ALET10/FasterR-CNN/ResNet50'))
detection_predict(experimenter)

 Тестирование Faster R-CNN экспериментатора с поканальной SVD


оптимизацией (листинг Листинг 39).
Входные данные: тестовый датасет, запуск с поканальной SVD оптимизацией.
Проверка: корректность работы основных методов Faster R-CNN экспериментатора
и оптимизатора структуры.
Ожидаемый результат: сохранена дообученная после обрезки модель, предсказания
производятся для каждого изображения из тестовой паки, предсказания модели с
помощью метода predict содержат метки класса и ограничивающие рамки, предсказания
42
RU.СНАБ.00843-01 33 01
модели с помощью метода predict_proba содержат метки классов, ограничивающие рамки
и вероятности.
Листинг 39 – Тестирование экспериментатора Faster R-CNN с SVD оптимизацией
def test_svd_channel_fasterrcnn_experimenter(get_test_detection_dataset):
exp_params, tmp_path = get_test_detection_dataset
experimenter = FasterRCNNExperimenter(
**exp_params,
structure_optimization='SVD',
structure_optimization_params={
'decomposing_mode': 'channel',
**SVD_PARAMS
}
)
experimenter.fit(1)
root =
tmp_path.joinpath('models/ALET10/FasterR-CNN/ResNet50_SVD_channel_O-10.0_H-
0.001000/')
assert os.path.exists(root.joinpath('fine-tuned_e_0.9.model.pt'))
detection_predict(experimenter)

 Тестирование Faster R-CNN экспериментатора с пространственной


оптимизацией (листинг Листинг 40).
Входные данные: тестовый датасет, запуск с пространственной SVD оптимизацией.
Проверка: корректность работы основных методов Faster R-CNN экспериментатора
и оптимизатора структуры.
Ожидаемый результат: сохранена дообученная после обрезки модель, предсказания
производятся для каждого изображения из тестовой паки, предсказания модели с
помощью метода predict содержат метки класса и ограничивающие рамки, предсказания
модели с помощью метода predict_proba содержат метки классов, ограничивающие рамки
и вероятности.
Листинг 40 – Тестирование экспериментатора Faster R-CNN с пространственной
оптимизацией
def test_svd_spatial_fasterrcnn_experimenter(get_test_detection_dataset):
exp_params, tmp_path = get_test_detection_dataset
experimenter = FasterRCNNExperimenter(
**exp_params,
structure_optimization='SVD',
structure_optimization_params={
'decomposing_mode': 'spatial',
**SVD_PARAMS
}
)
experimenter.fit(1)
root = tmp_path.joinpath(
'models/ALET10/FasterR-CNN/ResNet50_SVD_spatial_O-10.0_H-0.001000/')
43
RU.СНАБ.00843-01 33 01
assert os.path.exists(root.joinpath('fine-tuned_e_0.9.model.pt'))
detection_predict(experimenter)
44
RU.СНАБ.00843-01 33 01
6. ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ

В таблице Таблица 11 указаны типы, структура, а также способы ввода и


ограничения входных данных.
Таблица 11 – Входные данные

Наименование Способ ввода


Обозначение Структура данных Ограничения
данных данных
Набор признаков
Многомерный Не более 2-х
– временных 𝑋𝑡𝑠 CSV-файлы
массив измерений
рядов
Набор признаков Многомерный Не более 3-х
𝑋𝑓𝑙𝑑 CSV-файлы
– полей массив измерений
Целевая Многомерный Не более 3-х
𝑌 CSV-файлы
переменная массив измерений

В таблице Таблица 12 указано описание выходных данных. После выполнения


эксперимента результаты обрабатываются как табличные данные, содержащие
информацию о метриках и сгенерированные признаковые пространства. Сохранённые
модели в виде объектов типа Pipeline могут применяться в дальнейшем для решения иных
задач классификации временных рядов.
Таблица 12 – Выходные данные

Способ
Наименование Структура
Обозначение вывода Ограничения
данных данных
данных
Предсказательная Объект класса JSON-
𝑓:𝑥→[1,…,𝐾]f:x→[1,…,K] Нет
модель Pipeline файл
Результаты CSV-
𝑃P Массив Нет
моделирования файл
45
RU.СНАБ.00843-01 33 01
7. СООБЩЕНИЯ

Процесс решения любой задачи средствами фреймворка сопровождается рядом


сообщений от модуля логгирования. Примеры и расшифровки таких сообщений
приведены в таблице Таблица 13
Таблица 13 – Примеры сообщений, получаемых во время работы фреймворка

Сообщение Расшифровка
Start experiment Начало эксперимента
Start launch Х Начало запуска №Х
Start training Начало обучения модели
Start prediction Получение предсказаний
Saving results Сохранение результатов
Ensemble features extraction Начало извлечения признаков при использовании
started метода ансамблирования генераторов
Number of TS to be processed: X Количество временных рядов для обработки: Х
Time spent on feature extraction – Количество времени, затраченного на извлечение
X sec признаков – Х сек
Х features extraction started Начало извлечения признаков типа Х
Generate features for windows
Начало извлечения признаков при длине окна Х
length – Х
Window length X was chosen Решение алгоритма о выборе окна длиной Х
Сигнал о завершении процесса извлечения признаков и
Feature generation finished. TS
указатель на количество обработанных временных
processed: X
рядов
Validate model for wavelet – X Выполнение валидации модели для вейвлета типа Х
Generate features for wavelet – X Извлечение признаков для вейвлета типа Х
X wavelet was chosen Вейвлет типа Х был выбран
Started boosting Начало работы модели коррекции ошибок
Boosting process is finished Окончание работы модели коррекции ошибок
End of experiment Завершение эксперимента
Сообщение, сопровождающееся выводом полученных
Metrics at datasets
метрик
Type of ML task Сообщение о типе решаемой задачи
Fitting model Сообщение о старке обучения модели
Experiment setup Сообщение с краткой информацией о постановке задачи
Baseline model fitted Сигнал о том, что базовая модель обучена
Cannot save pipeline X Сообщение о проблеме при сохранении пайплайна
Сообщение о том, что загруженный из удалённого
Loaded data is of unknown format
источника формат данных не поддерживается
Ошибка при распаковке загруженных из удалённого
Error while unpacking data
источников данных
46
RU.СНАБ.00843-01 33 01
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1. Dau H. A. [и др.]. The UCR time series archive / H. A. Dau, A. Bagnall, K. Kamgar, C. C. M.
Yeh, Y. Zhu, S. Gharghabi, C. A. Ratanamahatana, E. Keogh, 2019. 1293–1305 c.
47
RU.СНАБ.00843-01 33 01

ЛИСТ РЕГИСТРАЦИИ ИЗМЕНЕНИЙ


Лист регистрации изменений
Из Номера листов (страниц) Всего № Входящий № Под Дат
м. Изменённ Заменённ Нов Аннулирован листов докумен сопроводитель п. а
ых ых ых ных (страни та ного докум. и
ц) в дата
докум.

Вам также может понравиться