Русский
Русский
English
Статистика
Реклама

Scikit-learn

Как самому разработать систему обнаружения компьютерных атак на основе машинного обучения

25.01.2021 20:08:49 | Автор: admin

На фото Arthur Lee Samuel, пионер машинного обучения, демонстрирует возможности искусственного интеллекта и играет в шашки с собственной программой Checkers-Playing, одной из первых самообучающихся программ в мире. 1962 год.

Спустя почти 60 лет, я решил познакомиться с машинным обучением и научить свою собственную программу систему обнаружения компьютерных атак находить вредоносный трафик в сети.

Как разработчик средств защиты информации я в общих чертах представлял архитектуру такой системы. Но как ML инженер, который должен был научить ее, я мало что знал.

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

Вступление. Машинное обучение и информационная безопасность

Да, сегодня все знают про машинное обучение. Умная колонка и онлайн-кинотеатр угадывают ваше настроение и близко к идеальному предлагают в рекомендациях следующий трек/фильм. Когда вы звоните на горячую линию банка, трудно понять, кто отвечает робот или живой человек. Беспилотные автомобили уже на дорогах общего назначения.

Но как связаны машинное обучение и информационная безопасность?

Признаться, тяжело представить себе распространение технологий AI/ML в проекты и приложения информационной безопасности. Пока не пролистаешь отчет из Стэнфорда AI Index 2019 Report, 220 страниц о современном состоянии дел в области искусственного интеллекта.

Привлечение инвестиций ведущими мировыми разработчиками средств защиты информации с применением технологий искусственного интеллектаПривлечение инвестиций ведущими мировыми разработчиками средств защиты информации с применением технологий искусственного интеллекта

Выводы после прочтения отчета:

  1. Направление Сybersecurity (Network Security) это около 3% мировых частных инвестиций в стартапы, использующие технологии искусственного интеллекта. Впечатляюще.

  2. В блокноте я подсчитал объемы привлеченных инвестиций ведущими мировыми разработчиками средств защиты информации с использованием AI (таблица на рисунке выше). В топ-10 из знакомых имён только Splunk. А кто такие Sophos, Cylance, CrowdStrike, Wangsu, Opzoon? И с какими питчами они привлекают миллиарды долларов?

  3. Среди продуктов лидеров построенного рейтинга антивирусы, средства обнаружения атак, управления инцидентами, анализа защищенности, защиты от утечек, спам-фильтры, threat intelligence, почти вся номенклатура СЗИ. ML, как минимум, делает вид, что работает везде.

Итак, у меня есть желание разобраться в машинном обучении. Есть опыт в разработке средств защиты. Известны примеры успешных реализаций СЗИ c ML. Что мешает попробовать самому, с нуля разработать систему обнаружения компьютерных атак на основе машинного обучения? Вперед!

Дисклеймер. Разрабатываемая система обнаружения атак призвана не заменить, а лишь дополнить сигнатурный анализатор с целью повышения общей эффективности системы, особенно в отношении ранее неизвестных атак.

Последовательность шагов

Уже после прохождения первых курсов обучения и первых набросков, пытаясь упорядочить последовательность шагов при построении модели ML, я обнаружил типовую схему и на ее основе разработал план действий:

  1. Выбор набора данных для обучения системы обнаружения компьютерных атак.

  2. Предварительная обработка данных.

  3. Сэмплирование против дисбаланса классов.

  4. Оценка значимости и отбор признаков.

  5. Сокращение признакового пространства.

  6. Выбор модели.

  7. Настройка и обучение модели.

  8. Тестирование и апробация.

Далее по шагам.

Оригинальная схема обучения с учителем от Sebastian Raschka
Типовая схема обучения с учителемТиповая схема обучения с учителем

Шаг 1. Выбор набора данных для обучения

Для обучения системы обнаружения атак среди доступных публичных наборов данных (DARPA1998, KDD1999, ISCX2012, ADFA2013 и других) я выбрал один из наиболее актуальных (на момент начала исследования) Intrusion Detection Evaluation Dataset CICIDS2017. Разработчик Canadian Institute for Cybersecurity. Набор данных CICIDS2017 подготовлен по результатам анализа сетевого трафика в изолированной среде, в которой моделировались действия 25 легальных пользователей, а также вредоносные действия нарушителей.

Набор объединяет более 50 Гб сырых данных в формате PCAP и включает 8 предобработанных файлов в формате CSV, содержащих размеченные сессии с выделенными признаками в разные дни наблюдения. Краткое описание файлов и количественный состав набора данных представлены в таблицах ниже.

Описание файлов набора данных CICIDS2017Описание файлов набора данных CICIDS2017Количественный состав набора данных CICIDS2017Количественный состав набора данных CICIDS2017Пример одной записи из набора данных CICIDS2017

Каждая запись соответствует сетевой сессии и характеризуется 85 признаками.

Flow ID, Source IP, Source Port, Destination IP, Destination Port, Protocol, Timestamp, Flow Duration, Total Fwd Packets, Total Backward Packets,Total Length of Fwd Packets, Total Length of Bwd Packets, Fwd Packet Length Max, Fwd Packet Length Min, Fwd Packet Length Mean, Fwd Packet Length Std,Bwd Packet Length Max, Bwd Packet Length Min, Bwd Packet Length Mean, Bwd Packet Length Std,Flow Bytes/s, Flow Packets/s, Flow IAT Mean, Flow IAT Std, Flow IAT Max, Flow IAT Min,Fwd IAT Total, Fwd IAT Mean, Fwd IAT Std, Fwd IAT Max, Fwd IAT Min,Bwd IAT Total, Bwd IAT Mean, Bwd IAT Std, Bwd IAT Max, Bwd IAT Min,Fwd PSH Flags, Bwd PSH Flags, Fwd URG Flags, Bwd URG Flags, Fwd Header Length, Bwd Header Length,Fwd Packets/s, Bwd Packets/s, Min Packet Length, Max Packet Length, Packet Length Mean, Packet Length Std, Packet Length Variance,FIN Flag Count, SYN Flag Count, RST Flag Count, PSH Flag Count, ACK Flag Count, URG Flag Count, CWE Flag Count, ECE Flag Count, Down/Up Ratio, Average Packet Size, Avg Fwd Segment Size, Avg Bwd Segment Size, Fwd Header Length,Fwd Avg Bytes/Bulk, Fwd Avg Packets/Bulk, Fwd Avg Bulk Rate, Bwd Avg Bytes/Bulk, Bwd Avg Packets/Bulk,Bwd Avg Bulk Rate,Subflow Fwd Packets, Subflow Fwd Bytes, Subflow Bwd Packets, Subflow Bwd Bytes, InitWinbytesforward, InitWinbytesbackward, actdatapktfwd, minsegsizeforward, Active Mean, Active Std, Active Max, Active Min, Idle Mean, Idle Std, Idle Max, Idle Min, Label

192.168.10.14-65.55.44.109-59135-443-6, 65.55.44.109, 443, 192.168.10.14, 59135, 6, 6/7/2017 9:00, 48, 1, 1, 6, 6, 6, 6, 6, 0, 6, 6, 6, 0, 250000, 41666.66667, 48, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20833.33333, 20833.33333, 6, 6, 6, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 9, 6, 6, 20, 0, 0, 0, 0, 0, 0, 1, 6, 1, 6, 513, 253, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, BENIGN

Хорошие данные обязательное условие для построения хорошего классификатора.

В обзорах набора данных CICIDS2017 (Intrusion2017, Panigrahi2018, Sharafaldin2018) отмечались проблемы дисбаланса классов, сложной файловой структуры, пропуска значений. Эти замечания я принял как некритичные.

Сегодня у меня есть вопросы по аккуратности разметки набора данных CICIDS2017 (связаться с авторами набора данных и задать вопросы не удалось ни по личным адресам электронной почты, ни через Canadian Institute for Cybersecurity), но именно по этой причине мне пришлось самому разработать весь pipeline начиная от сниффера и предобработки сетевых сессий, заканчивая моделью машинного обучения и тестированием в реальной сети.

Получается, больше приобрел, чем потерял.

Шаг 2. Предварительная обработка данных

Отправной точкой для проведения собственных экспериментов с датасетом CICIDS2017 послужило исследование Kahraman Kostas Anomaly Detection in Networks Using Machine Learning. При попытке воспроизведения этого исследования были обнаружены расхождения в результатах, а потом и ошибки в коде автора. Я связался в апреле 2020 года с Kahraman Kostas, мы обсудили варианты исправления ошибки, однако по состоянию на январь 2021 года код в репозитории по-прежнему некорректно оценивает значимость признаков.

Для сокращения времени вычислений в обучающей выборке был оставлен единственный класс атак веб-атаки (Brute Force, XSS, SQL Injection). Для этого я подготовил подвыборку WebAttacks на основе обработки файла Thursday-WorkingHours-Morning-WebAttacks.pcap_ISCX.csv из набора данных CICIDS2017. Набор WebAttacks включает 458968 записей, из которых 2180 относятся к веб-атакам, остальные к нормальному трафику.

Такое решение упрощает задачу и снижает качество итоговых выводов: многоклассовая классификация свелась к бинарной классификации, значительно уменьшился размер обучающей выборки.

Этапы предварительной обработки набора данных CICIDS2017 и подготовки подвыборки WebAttacks
  1. Исключение признака Fwd Header Length.1 (признаки Fwd Header Length и Fwd Header Length.1 являются идентичными).

  2. Удаление записей с null значениями идентификатора сессии Flow ID (из 458968 записей после удаления осталось 170366 записей).

  3. Замена нечисловых значений признаков Flow Bytes/s, Flow Packets/s значениями -1.

  4. Замена неопределенных значений (NaN) и бесконечных значений значениями -1.

  5. Приведение строковых значений признаков Flow ID, Source IP, Destination IP, Timestamp к числовым значениям методом label encoding.

  6. Кодирование ответов в обучающей выборке в соответствии с правилом: 0 нет атаки, 1 есть атака.

После прочтения обсуждения Should I normalize/standardize/rescale the data? понимаю, что вопросы нормирования данных это отдельное исследование.

Я храню Jupyter блокноты на Github в репозитории ml-cybersecurity, а ссылки даю на Google Colabоratory тогда код готов к запуску прямо в браузере.

Исходный код в Google Colabоratory

Матч с канадцами. Поиск и исправление ошибок в датасете

На этапе предварительной обработки данных я обнаружил погрешности в признаковом пространстве (как минимум, подозрительным показалось наличие двух разных признаков с попарно одинаковыми значениями). И решил выполнить проверку: взять сырой трафик CICIDS2017, самому выделить в нём сетевые сессии и сформировать свой датасет. Мой датасет должен был совпасть с датасетом CICIDS2017.

Обрабатываю pcap файл с записанным траффиком своим сниффером, выделяю сессии и признаки, сравниваю с датасетом Thursday-WorkingHours-Morning-WebAttacks.pcap_ISCX.csv, пытаюсь понять и исправить расхождения. Да, расхождения есть.

Подробности поиска ошибок
Выбранная сессия для анализаВыбранная сессия для анализа

Анализирую сессию Flow ID = 192.168.10.14-65.55.44.109-59135-443-6, Source IP = 65.55.44.109. У канадских исследователей два последних пакета выделены в отдельную сессию? Внимательно просматриваю исходники их сниффера и нахожу подтверждение в методе addPacket.

Что нужно учесть в моем сниффере:

  1. При появлении пакета с флагом FIN в направлении forward для воспроизведения эксперимента нужно завершить текущую сессию и создать новую. Чтобы два последних пакета FIN ACK и ACK попали во вторую сессию вместе, условие прерывания сессии нужно дополнить: количество пакетов в сессии должно быть больше 1.

  2. Завершение сессии по таймеру, 120 секунд (хотя в readme сказано про 600 секунд).

Иду дальше. Для той же сессии в прямом направлении зафиксирован один пакет (Total Fwd Packets = 1), при этом общая длина переданных пакетов в прямом направлении Total Length of Fwd Packets = 6. По данным Wireshark, длина пакета = 0. Откуда разница в 6 байт? Спускаюсь от TCP до Ethernet и обнаруживаю неучтенные 6 байт в виде дополнения (padding) фрейма Ethernet. Спорная ситуация, нужно ли включать эти 6 байт в длину TCP пакета.

Проверка длины пакета в WiresharkПроверка длины пакета в Wireshark

Проверяю остальные признаки для этой сессии, совпадают все значения, кроме Average Packet Size = 9. Как при двух пакетах по 6 байт получить значение 9, не ясно. При этом Packet Length Mean = 6, совпадает.

Начинаю проверять другие сессии, и оказывается, что часто встречаются небольшие расхождения в признаках: Packet Length Mean, Packet Length Std, Packet Length Variance , Average Packet Size, Average Fwd Segment Size, Average Bwd Segment Size. Вскрытие (восстановление исходных слагаемых по значениям средних) показывает, что при срабатывании таймаута сессии длина отбрасываемого пакета ошибочно учитывается в статистике.

Как могу, обновляю свой код, добиваться полного соответствия датасетов ( = вносить ошибки) не имеет смысла.

После устранения большинства расхождений в моем датасете и датасете CICIDS2017 можно двигаться дальше: теперь понятно, как вычисляются значения признаков по записанному трафику.

Шаг 3. Сэмплирование против дисбаланса классов

Подготовленная подвыборка WebAttacks является насбалансированной: при общем количестве записей 170366 класс нет атаки объединяет 168186 экземпляров, класс есть атака 2180 экземпляров. Для устранения дисбаланса классов подойдет метод случайного сэмплирования (субдискретизация, undersampling), заключающийся в удалении случайно выбранных экземпляров класса нет атаки. Целевое соотношение количества экземпляров классов нет атаки и есть атака я выбрал 70% / 30%.

Шаг 4. Оценка значимости и отбор признаков

Предварительно из признакового пространства были исключены признаки Flow ID, Source IP, Source Port, Destination IP, Destination Port, Protocol, Timestamp в предположении, что признаки формы (соответствующие статистикам сетевого трафика) являются более значимыми для общего случая. Кроме того, исключаемые признаки адресации могут быть относительно легко подделаны злоумышленником и не должны учитываться при обучении.

Анализ значимости признаков я выполнил с помощью встроенного механизма метода sklearn.ensemble.RandomForestClassifier (атрибут feature_importances_).

Первые результаты оценки значимости показали сильную взаимосвязь признаков Init_Win_bytes_backward, Init_Win_bytes_forward с меткой класса в обучающей выборке, что может свидетельствовать о допущенных погрешностях при формировании набора данных. Дополнительные эксперименты показали, что можно построить достаточно точный классификатор, опираясь на один единственный признак или Init_Win_bytes_backward, или Init_Win_bytes_forward. Указанные признаки были исключены из признакового пространства.

Итоговые результаты анализа значимости представлены на рисунке ниже, список ограничен первыми двадцатью признаками.

Результаты оценки значимости признаковРезультаты оценки значимости признаков

Шаг 5. Сокращение признакового пространства

На следующем рисунке представлена корреляционная матрица с линейными коэффициентами корреляции (коэффициентами корреляции Пирсона), рассчитанными для всех пар двадцати наиболее значимых признаков. Насыщенность цвета заливки пропорциональна значению коэффициента корреляции.

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

Корреляционный анализ показал сильную зависимость между парами признаков:

  1. Average Packet Size и Packet Length Mean.

  2. Subflow Fwd Bytes и Total Length of Fwd Packets.

  3. Fwd Packet Length Mean и Avg Fwd Segment Size.

  4. Flow Duration и Fwd IAT Total.

  5. Flow Packets/s и Fwd Packets/s.

  6. Flow IAT Max и Fwd IAT Max.

По результатам корреляционного анализа из признакового пространства были исключены следующие признаки: Packet Length Mean, Subflow Fwd Bytes, Avg Fwd Segment Size, Fwd IAT Total, Fwd Packets/s, Fwd IAT Max.

После исключения признаков с наименьшей значимостью признаковое пространство было сокращено до объединения 10 признаков:

  1. Average Packet Size, средняя длина поля данных пакета TCP/IP (далее длина пакета).

  2. Flow Bytes/s, скорость потока данных.

  3. Max Packet Length, максимальная длина пакета.

  4. Fwd Packet Length Mean, средняя длина переданных в прямом направлении пакетов.

  5. Fwd IAT Min, минимальное значение межпакетного интервала (IAT, inter-arrival time) в прямом направлении.

  6. Total Length of Fwd Packets, суммарная длина переданных в прямом направлении пакетов.

  7. Fwd IAT Std, среднеквадратическое отклонение значения межпакетного интервала в прямом направлении пакетов.

  8. Flow IAT Mean, среднее значение межпакетного интервала.

  9. Fwd Packet Length Max, максимальная длина переданного в прямом направлении пакета.

  10. Fwd Header Length, суммарная длина заголовков переданных в прямом направлении пакетов.

Шаг 6. Выбор модели

На этапе выбора модели я взял 10 наиболее распространенных моделей машинного обучения и оценил их качество на подвыборке WebAttacks.

Список из 10 моделей

Для сравнения были выбраны следующие модели (алгоритмы) машинного обучения (в скобках указывается сокращенное обозначение и соответствующая реализация модели из состава пакета scikit-learn):

  1. Метод k ближайших соседей (KNN, sklearn.neighbors.KNeighborsClassifier).

  2. Метод опорных векторов (SVM, sklearn.svm.SVC).

  3. Дерево решений (CART, алгоритм обучения CART, sklearn.tree.DecisionTreeClassifier).

  4. Случайный лес (RF, sklearn.ensemble.RandomForestClassifier).

  5. Модель адаптивного бустинга над решающим деревом (AdaBoost, sklearn.ensemble.AdaBoostClassifier).

  6. Логистическая регрессия (LR, sklearn.linear_model.LogisticRegression).

  7. Байесовский классификатор (NB, sklearn.naive_bayes.GaussianNB).

  8. Линейный дискриминантный анализ (LDA, sklearn.discriminant_analysis.LinearDiscriminantAnalysis).

  9. Квадратичный дискриминантный анализ (QDA, sklearn.discriminant_analysis.QuadraticDiscriminantAnalysis).

  10. Многослойный персептрон (MLP, sklearn.neural_network.MLPClassifier).

Качество ответов классификаторов (моделей) сравнивалось с использованием следующих метрик:

  • доля правильных ответов (accuracy);

  • точность (precision, насколько можно доверять классификатору);

  • полнота (recall, как много объектов класса есть атака определяет классификатор);

  • F1-мера (F1-measure, гармоническое среднее между точностью и полнотой).

Оценка качества классификаторов производилась на сбалансированной и предобработанной подвыборке веб-атак WebAttacks набора данных CICIDS2017 (соотношение нормального и аномального трафика 70% / 30%, 20 наиболее значимых признаков). В таблице ниже приведены полученные значения метрик качества, усредненные по результатам 5 итераций кросс-валидации.

Результаты оценки качества десяти классификаторовРезультаты оценки качества десяти классификаторов

Наилучшие результаты ожидаемо продемонстрировали модели (алгоритмы) KNN, CART, RF, AdaBoost, LR. Принимая во внимание минимальное время выполнения, применение модели случайный лес (RF) для решения поставленной задачи является обоснованным выбором.

Исходный код в Google Colaboratory

Шаг 7. Настройка и обучение модели

Итак, за основу я взял модель типа случайный лес, реализация в scikit-learn RandomForestClassifier.

Среди настраиваемых гиперпараметров модели были выбраны следующие: количество деревьев в лесу (n_estimators), минимальное число объектов в одном листе дерева (min_samples_leaf), максимальная глубина дерева (max_depth), максимальное количество признаков для одного дерева (max_features).

Степень квазиоптимальности параметров модели оценивалась значением F1-меры.

Проведенный экспертный анализ я дополнил результатами встроенного метода оптимизации параметров GridSearchCV библиотеки scikit-learn, итоговые значения параметров модели случайный лес получились следующие:

RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',max_depth=17, max_features=10, max_leaf_nodes=None,min_impurity_decrease=0.0, min_impurity_split=None,min_samples_leaf=3, min_samples_split=2,min_weight_fraction_leaf=0.0, n_estimators=50,n_jobs=None, oob_score=False, random_state=1, verbose=0,warm_start=False)
Пример настройки

Пример результатов подбора одного гиперпараметра (max_depth) при фиксированных значениях других гиперпараметров (n_estimators, min_samples_leaf, max_features) представлен на рисунке ниже в виде зависимости метрики качества (F1-меры) от значения настраиваемого параметра (max_depth).

Зависимость F1-меры модели от параметра max_depthЗависимость F1-меры модели от параметра max_depth

Шаг 8. Тестирование и апробация

Настроенная и обученная модель RandomForestClassifier на тестовой выборке позволила получить оценку полноты (recall) 0.961 и F1-меры 0.971 (запуск 1 в протоколе эксперимента, см. таблицу ниже). Достигнутый результат свидетельствует о возможности повышения точности модели за счет квазиоптимального подбора гиперпараметров (результаты исследования Kahraman Kostas recall 0.94 и F1-мера 0.94, результаты авторов CICIDS2017 recall 0.97 и F1-мера 0.97).

Для апробации модели на реальной сетевой инфраструктуре я разработал свой сетевой анализатор сниффер (C#). Анализатор позволяет перехватить передаваемый сетевой трафик и с использованием алгоритмов реконструкции TCP сессий свободно распространяемых программных продуктов Wireshark и TCP Session Reconstruction Tool выделить отдельные сессии. Для каждой сохраненной сессии сниффер на основе алгоритма CICFlowMeter выделяет признаки и таким образом формирует набор данных.

В качестве атакуемого веб-приложения использовалась разработанная консоль администратора безопасности (PHP) с единственным включенным модулем авторизации, функционирующая под управлением веб-сервера Apache.

Нормальный трафик соответствовал запросам легальных пользователей на подключение к консоли администратора и авторизацию. Вредоносный (аномальный) трафик моделировался программным средством OWASP ZAP и включал три типа атак: Brute Force, XSS, SQL Injection. Соотношение нормального и аномального трафика в реальном тестовом наборе данных составило 70% / 30%.

Схема стенда тестированияСхема стенда тестированияПодробно про запуск ZAP

Пример защищаемого приложения (заимствован из поста: Как за один день разработать SIEM).

Пример URL, соответствующего попытке входа в защищаемое приложение: http://192.168.121.129/buggy/admin.php?password=12345&username=admin

ZAP запускается в режиме фаззинга, при котором будут перебираться различные значения параметра password. Важно: параметр username сразу устанавливается равным admin. Будем считать, что злоумышленник знает имя администратора наверняка. В противном случае, можно для фаззера указать оба параметра, но и количество попыток возрастёт до N*N для двух параметров вместо N для одного (N количество строк в словаре).

Нагрузки (payloads, словари) для проведения атак Brute Force, XSS и SQL Injection я взял из репозитория github.com/danielmiessler/SecLists.

Как узнать, подобрал ли фаззер пароль при реализации атаки Brute Force? Я знаю, что в защищаемом веб-приложении страница авторизованного пользователя отличается от приветственной. Поэтому достаточно отсортировать результаты работы фаззера по размеру ответа столбец Size Resp. Body. И в строке с размером ответа, отличающимся от всех остальных, обнаружить пароль admin.

Успешный запуск фаззераУспешный запуск фаззера

Проведенные эксперименты на сформированном наборе данных (запуски 2, 3 в протоколе эксперимента) показали невозможность применения модели, обученной на наборе данных CICIDS2017, по следующим причинам:

  1. Анализ обучающей выборки показывает, что характер моделируемых компьютерных атак в исследовании авторов набора данных CICIDS2017 отличается от реального. Так, атаки типа Brute Force присутствуют в сессиях с максимальными скоростями до 10 Кбит/c, что не соответствует случаям применения автоматизированных средств перебора паролей.

  2. Среди десяти признаков с наибольшей значимостью четыре признака Flow Bytes/s (скорость потока данных), Fwd IAT Min (минимальное значение межпакетного интервала в прямом направлении), Flow IAT Std (среднеквадратическое отклонение значения межпакетного интервала), Flow IAT Mean (среднее значение межпакетного интервала) непосредственно зависят от физической структуры сети, в которой производится сбор сетевого трафика, а также настроек сетевого оборудования. В обучающем наборе данных сессии с признаками веб-атак записаны с низкими значениями скорости потока и высокими значениями межпакетных интервалов, что не соответствует характеристикам реальной сетевой инфраструктуры (сеть Ethernet 100 Мбит/c).

Как подготовить свой датасет

Хороший датасет должен удовлетворять определенным требованиям. У авторов CICIDS2017 есть работа, в которой перечислено 11 таких требований. Главное из этого: обеспечить разнообразие сетевого оборудования, компьютеров и операционных систем в тестовой инфраструктуре, разнообразие потоков сетевого трафика по разным направлениям, разнообразие протоколов и типов атак, разметить данные для атак и для чистого трафика.

Я сильно упрощаю задачу уточнить возможность построения эвристического анализатора и грубо оценить его точность. Не претендуя на сбор сверхкачественного датасета, поскольку это задача целых институтов.

План сбора датасета:

1 этап. Запись pcap файлов, очистка. При сборе грязного трафика изменяем параметры фаззера и ставим паузы во время фаззинга, чтобы разорвать сессии и увеличить их количество в датасете. При сборе чистого трафика моделируем разные действия пользователя.

2 этап. Подача pcap файлов на вход сниффера и выделение признаков. Объединение всех размеченных записей в один датасет.

Протокол экспериментаПротокол эксперимента

Важно. Запуск 2. Модель была обучена на подвыборке WebAttacks набора данных CICIDS2017 (трафик собирался в одной сети). После этого я протестировал модель на реальном трафике в другой сети, отличающейся скоростью и другими характеристиками от первой. И получил неудовлетворительное качество значение F1-меры 0.064.

Оценка вычислительной сложности производилась косвенным способом: разработанный в среде Jupyter Notebook макет системы обнаружения веб-атак запускался на персональном компьютере (процессор Intel Core i5-2300 CPU @ 2300 ГГц, ОЗУ 8 Гб) в режиме обнаружения. Тестовый набор данных содержал около 70000 записанных сессий, время обнаружения составило 0,74669 с. Таким образом, скорость обнаружения веб-атак оценивается величиной порядка 100000 сессий в секунду.

Подведение итогов

Итак, завершен эксперимент с разработкой модели случайный лес для решения задачи обнаружения компьютерных атак. Модель обучена на публичном наборе данных CICIDS2017 и протестирована в реальных условиях.

Настройка параметров выбранного классификатора RandomForestClassifier пакета scikit-learn позволила на тестовой выборке получить оценку полноты (recall) 0.961 и F1-меры 0.971 для набора данных CICIDS2017 и 0.966 и 0.882 соответственно для сформированного в исследовании набора данных.

Главный вывод эксперимента: методы машинного обучения на практике применимы для обнаружения компьютерных атак.

Из отрицательных результатов. Даже с учетом погрешности в оценках качества у меня не получилось применить предобученную модель обнаружения атак в реальной компьютерной сети. Основные причины:

  1. Характер моделируемых компьютерных атак при сборе обучающего набора данных отличался от реального.

  2. Часть значимых признаков непосредственно зависят от физической структуры сети, в которой производился сбор сетевого трафика, а также настроек сетевого оборудования.

Что исправить, чтобы получилось? Идеально обучать модель на наборе данных, размеченном на основе анализа сетевого трафика в защищаемой сети. При использовании предобученной в другой сети модели (проблема transfer learning) обязательным является соответствие физической структуры защищаемой сети и сети, в которой обучалась модель, а также настроек сетевого оборудования.

Личные выводы. В начале освоения пути исследователя данных применение машинного обучения представлялось в виде 10 строчек кода из примера на scikit-learn.org. Сегодня, глядя на >500 строк кода в итоговом блокноте, я понимаю, сколько еще улучшений можно сделать и как развить решение.

Этот эксперимент занял больше двух лет, без спешки, в перерывах между чтением книг, статей, прохождением курсов, участием в соревнованиях по ML и выступлениями на конференциях. Я был нубом на старте, но смог разобраться и пройти этот увлекательный трек. Впереди новые знания и эксперименты. Но уже сегодня я уверен: современный инженер должен знать, как работает машинное обучение. Чтобы быть ближе к будущему!

Полезные ссылки

Исходный код эксперимента (блокноты, сниффер, разное): github.com/fisher85/ml-cybersecurity

Книги, которые помогли в исследовании:

  • Talabis M. Information Security Analytics.

  • Sumeet D. Data Mining and Machine Learning in Cybersecurity.

  • Lee K.-F. AI Superpowers: China, Silicon Valley, and the New World Order.

  • McAfee A. Machine, Platform, Crowd. Harnessing Our Digital Future.

  • Chio С. Machine Learning and Security: Protecting Systems with Data and Algorithms.

История прохождения курсов обучения, все бесплатные:

Цвет титульной фотографии восстановлен здесь

Подробнее..

Перевод Как писать аккуратные конвейеры для машинного обучения

17.08.2020 18:04:48 | Автор: admin
Здравствуйте, Хабр.

Тема конвейеризации и распараллеливания машинного обучения давно фигурирует у нас в проработке. В частности, интересно, достаточно ли для этого специализированной книги с акцентом на Python, либо нужна более обзорная и, возможно, сложная литература. Мы решили перевести вводную статью об устройстве конвейеров для машинного обучения, содержащую как архитектурные, так и более прикладные соображения. Давайте обсудим, актуальны ли поиски в этом направлении.


Вы когда-нибудь писали конвейер машинного обучения, на прогон которого требовалось много времени? Или хуже того: доходили ли до этапа, когда требуется сохранить на диске промежуточные части конвейера, чтобы можно было изучить этапы конвейера по одному, опираясь на контрольные точки? Или еще хуже: вы когда-нибудь пытались рефакторить такой отвратительный код для машинного обучения перед пуском этого кода в продакшен и обнаруживали, что на это нужны месяцы? Да, с подобным приходилось сталкиваться каждому, кто достаточно долго работал над конвейерами машинного обучения. Так почему бы не построить хороший конвейер, который обеспечит нам достаточную гибкость и возможность легко рефакторить код для последующей отправки в продакшен?

Сначала давайте дадим определение конвейерам машинного обучения и обсудим идею использования контрольных точек между этапами конвейера. Затем посмотрим, как можно реализовать такие контрольные точки, чтобы не выстрелить себе в ногу при переводе конвейера в продакшен. Мы также обсудим потоковую передачу данных и компромиссы, связанные с инкапсуляцией в духе объектно-ориентированного программирования (ООП), на которые приходится идти в конвейерах при указании гиперпараметров.

ЧТО ТАКОЕ КОНВЕЙЕР?

Конвейер это последовательность шагов при преобразовании данных. Он создается в соответствии со старинным паттерном проектирования канал и фильтр (вспомните, например, команды unix bash с каналами | или операторами редиректа >). Однако конвейеры это объекты в коде. Следовательно, у вас может быть класс для каждого фильтра (то есть, для каждого этапа конвейера), а также еще один класс для комбинации всех этих этапов в готовый конвейер. Некоторые конвейеры могут объединять другие конвейеры последовательно или параллельно, иметь много входов или выходов и т.д. Конвейеры машинного обучения удобно рассматривать как:

  • Канал и фильтры. На этапах конвейера обрабатываются данные, причем, этапы управляют своим внутренним состоянием, которое можно узнать из данных.
  • Компоновка. Конвейеры можно вкладывать друг в друга; например, целый конвейер можно трактовать как один этап в рамках другого конвейера. Эта конвейера не обязательно является конвейером, но конвейер как таковой по определению не менее чем этап конвейера.
  • Ориентированные ациклические графы (DAG). Вывод этапа конвейера может направляться множеству других этапов, после чего результирующие выводы могут рекомбинироваться и так далее. Отметим: несмотря на то, что конвейеры ацикличны, они могут обрабатывать множество элементов один за другим, и, если их состояние меняется (например, при использовании метода fit_transform на каждом этапе), то их можно считать рекуррентно разворачивающимися во времени, сохраняющими при этом свои состояния (по образцу RNN).Это интересный ракурс, позволяющий рассматривать конвейеры как средство для онлайнового машинного обучения, после чего конвейеры можно переводить в продакшен и обучать на более обширных данных.


Методы конвейера

Конвейеры (или этапы конвейера) обязательно должны обладать следующими двумя методами:

  • fit для обучения на данных и приобретения состояния (напр., таким состоянием являются веса нейронной сети)
  • transform (или predict) для фактической обработки данных и генерации прогноза.
  • Примечание: если этапу конвейера не требуется один из этих методов, то этап может унаследовать от NonFittableMixin или NonTransformableMixin, где будет по умолчанию предоставляться такая реализация одного из этих методов, чтобы он ничего не дела.


На этапах конвейера также могут опционально определяться следующие методы:

  • fit_transform для подгонки и последующего преобразования данных, но в один проход, что допускает потенциальную оптимизацию кода в случаях, когда два метода должны выполняться непосредственно один после другого.
  • setup который будет вызывать метод setup на каждом из таких этапов конвейера. Например, если на этапе конвейера содержится нейронная сеть TensorFlow, PyTorch или Keras, то на этих этапах могли бы создаваться собственные нейронные графы и регистрироваться для работы с GPU в методе setup до подгонки. Не рекомендуется создавать графы прямо в конструкторах этапов до подгонки; на то есть несколько причин. Например, до запуска этапы могут многократно копироваться с разными гиперпапарметрами в рамках работы алгоритма Automatic Machine Learning, который подыскивает для вас наилучшие гиперпараметры.
  • teardown, этот метод функционально противоположен setup: он сносит ресурсы.


Следующие методы предоставляются по умолчанию, обеспечивая управление гиперпараметрами:

  • get_hyperparams возвращает словарь гиперпараметров. Если конвейер содержит другие (вложенные) конвейеры, то ключи гиперпараметров сцепляются при помощи двойных нижних подчеркиваний __.
  • set_hyperparams позволяет задавать новые гиперпараметры в том же формате, в каком вы их получаете.
  • get_hyperparams_space позволяет вам получить пространство гиперпараметра, которое будет непустым, если вы определили гиперпараметр. Поэтому, все отличие от get_hyperparams в данном случае таково, что вы получаете в качестве значений статистические распределения, а не точное значение. Например, один гиперпараметр, для количества слоев, может быть RandInt(1, 3) то есть, предусматривать от 1 до 3 слоев. Можно вызвать call .rvs() с этим словарем, чтобы случайным образом выбрать значение и отправить его к set_hyperparams, попытавшись таким образом организовать обучение.
  • set_hyperparams_space может использоваться для задания нового пространства при помощи тех же классов для распределения гиперпараметров, что и в случае с get_hyperparams_space.


Переподгонка конвейера, мини-батчинг и онлайновое обучение

Для алгоритмов, использующих мини-батчинг, например, при обучении глубоких нейронных сетей (DNN) или для алгоритмов, обучающихся онлайн, например, при обучении с подкреплением (RL), для конвейеров или их этапов идеально подходит сцепление нескольких вызовов так, чтобы они следовали точно друг за другом, и на лету происходила их подгонка под размеры мини-батчей. Такая возможность поддерживается в некоторых конвейерах и на некоторых этапах конвейеров, но на определенном этапе достигнутая подгонка может сброситься из-за того, что метод fit будет вызван заново. Все зависит от того, как вы запрограммировали ваш этап конвейера. В идеале этап конвейера должен сбрасываться только после вызова метода teardown, а затем повторного вызова метода setup до следующей подгонки, и данные не сбрасывались ни между подгонками, ни в процессе преобразования.

ИСПОЛЬЗОВАНИЕ КОНТРОЛЬНХ ТОЧЕК В КОНВЕЙЕРАХ

Целесообразно использовать в конвейерах контрольные точки до тех пор, пока этот код не понадобится использовать для других целей и изменить данные. Если вы не применяете в коде нужных абстракций, то, возможно, стреляете себе в ногу.

За и против использования контрольных точек в конвейерах:

  • Расстановка контрольных точек может ускорить процесс работы, если этапы программирования и отладки расположены в середине или в конце конвейера. Так отпадает необходимость каждый раз заново вычислять первые этапы конвейера.
  • При выполнении оптимизации гиперпараметров (либо путем настройки вручную, либо с использованием метаобучения), вы будете только рады обойтись без пересчета первых этапов конвейера, пока занимаетесь настройкой следующих. Например, если начало вашего конвейера не содержит гиперпараметров, то оно всякий раз может быть одинаковым или почти одинаковым если гиперпараметров всего несколько. Следовательно, при работе с контрольными точками целесообразно возобновлять работу именно с тех мест, где они расставлены, если гиперпараметры и исходный код этапа, предшествующего контрольной точке, не изменились с момента последнего выполнения.
  • Возможно, вы располагаете ограниченными вычислительными ресурсами, и единственный приемлемый вариант для вас прогонять по одному этапу за раз на имеющемся аппаратном обеспечении. Можно использовать контрольную точку, затем добавить после нее еще несколько этапов, а потом данные будут использоваться с того места, на котором вы остановились, если вы захотите повторно выполнить всю структуру.


Недостатки использования контрольных точек в конвейерах:

  • При этом используются диски, поэтому, если действовать неправильно, то выполнение вашего кода может замедляться. Чтобы ускорить работу, можно, как минимум, воспользоваться RAM Disk или монтировать папку кэша к вашей RAM.
  • Для этого может потребоваться много дискового пространства. Либо много пространства RAM, при использовании каталога, монтированного к RAM.
  • Состоянием, сохраненным на диске, управлять тяжелее: для вашей программы возникает дополнительная сложность, нужная, чтобы код работал быстрее. Обратите внимание, что, с точки зрения функционального программирования, ваши функции и код больше не будут чистыми, поскольку необходимо управлять побочными эффектами, связанными с использованием дисков. Побочные эффекты, связанные с управлением состоянием диска (вашим кэшем) могут становиться почвой для возникновения всевозможных страннейших багов
.

Известно, что одни из самых сложных багов в программировании возникают из-за проблем, связанных с инвалидацией кэша.

В Computer Science есть всего две по-настоящему сложные вещи: инвалидация кэша и именование сущностей. Фил Карлтон


Совет о том, как правильно управлять состоянием и кэшем в конвейерах.

Известно, что фреймворки для программирования и паттерны проектирования могут выступать ограничивающим фактором по той простой причине, что регламентируют определенные правила. Остается надеяться, что это делается ради максимального упрощения задач по управлению кодом, чтобы вы сами избегали ошибок, а ваш код не получался грязным. Вот мои пять копеек по поводу проектирования в контексте конвейеров и управления состоянием:

ЭТАП КОНВЕЙЕРА НЕ ДОЛЖН УПРАВЛЯТЬ РАССТАНОВКОЙ КОНТРОЛЬНХ ТОЧЕК В ТЕХ ДАННХ, КОТОРЕ ВДАЮТ


Для управления этим должна применяться специальная библиотека конвейеризации, которая сможет все это сделать за вас сама.

Почему?

Почему же этапы конвейера не должны управлять расстановкой контрольных точек в тех данных, которые выдают? По тем же веским причинам, по которым вы пользуетесь при работе библиотекой или фреймворком, а не воспроизводите соответствующий функционал самостоятельно:

  • У вас будет простой выключатель, который позволит с легкостью полностью активировать или отменить расстановку контрольных точек перед развертыванием сделанного в продакшен.
  • Когда требуется переучить систему на новых данных, окажется, что управление кэшированием поставлено настолько хорошо, что система сама заметит: ваши данные изменились и, следовательно, имеющийся кэш следует игнорировать. Вашего вмешательства при этом совершенно не потребуется, что позволит не допустить возникновения серьезных багов.
  • Вам не придется самостоятельно иметь дело с дисками и писать операции ввода/вывода (I/O) на каждом этапе конвейера. Большинство программистов предпочитают пользоваться алгоритмами машинного обучения и строить конвейеры, а не заниматься созданием методов сериализации данных. Будем честны: вы же хотите просто запрограммировать готовенькие алгоритмы, а все остальное чтобы было сделано за вас. Верно?
  • Теперь вы можете придумывать названия для каждого из ваших конвейерных экспериментов или каждой итерации, так, чтобы при каждом рестарте в кэше создавался новый подкаталог строго на данный случай даже если вы собираетесь переиспользовать одни и те же этапы конвейера. Причем, именовать этапы экспериментов даже не требуется, поскольку с изменением данных меняется и кэширование.
  • Внутренний код классов, описывающих этапы вашего конвейера, хэшируется, после чего хэши сравниваются, чтобы посмотреть, нужно ли заново выполнить кэширование для того класса, в котором вы только что изменили код. Именно так избегаются баги, связанные с инвалидацией кэша. Ура.
  • Теперь вы можете хэшировать промежуточные результаты обработки данных и пропускать этап вычисления конвейера на этих данных, если гиперпраметры не изменились, а ваш конвейер уже преобразовал (и, следовательно, хэшировал) данные ранее. Это может упростить тонкую настройку гиперпараметров в случаях, когда некоторые этапы конвейера (в том числе, промежуточные) могут меняться. Например, первые этапы конвейера могут оставаться кэшированными, поскольку изменения их не затрагивают, а, если у вас появятся дополнительные гиперпараметры, которые потребуется настроить на дальнейших этапах конвейера, то вы всегда сможете добавить нужное количество контрольных точек после этих этапов. Тогда полученные в результате многократного кэширования этапы сохраняются с уникальным именем, вычисленным на основе хэша. Можете считать такую систему блокчейном, так как это и есть блокчейн.


Это круто. Грамотно подбирая абстракции, вы теперь можете запрограммировать конвейеры для машинного обучения так, чтобы этап настройки гиперпараметров радикально ускорился; для этого нужно кэшировать промежуточный результат каждого испытания, пропуская этапы конвейера раз за разом, когда гиперпараметры промежуточных этапов конвейера остаются без изменений. Более того, когда вы будете готовы вывести код в продакшен, вы сможете сразу целиком отключить кэширование, а не рефакторить для этого код на протяжении целого месяца.

Не врезайтесь в эту стену.

ПОТОКОВАЯ ПЕРЕДАЧА ДАННХ В КОНВЕЙЕРАХ ДЛЯ МАШИННОГО ОБУЧЕНИЯ

Теория параллельной обработки гласит, что конвейеры это инструмент потоковой передачи данных, позволяющий распараллеливать этапы конвейера. Пример с прачечной хорошо иллюстрирует как эту проблему, так и ее решение. Например, на втором этапе конвейера может приступить к обработке частичной информации, полученной с первого этапа конвейера, в то время как первый этап продолжает вычислять новые данные. Причем, для работы второго этапа конвейера не требуется, чтобы первый этап полностью завершил свой этап обработки всех данных. Давайте назовем такие особые конвейеры потоковыми (см. здесь и здесь).

Не поймите меня неправильно, работать с конвейерами scikit-learn очень приятно. Но они не рассчитаны на потоковую передачу. Не только scikit-learn, но и большинство существующих конвейерных библиотек не используют возможностей потоковой передачи данных, тогда как могли бы. В масштабах всей экосистемы Python есть проблемы с многопоточностью. В большинстве конвейерных библиотек каждый этап является полностью блокирующим и требует преобразования всех данных сразу. Найдутся лишь считанные библиотеки, обеспечивающие потоковую обработку.

Активировать потоковую обработку может быть совсем просто: использовать класс StreamingPipeline вместо Pipeline для сцепления этапов одного за другим. При этом указывается размер мини-батча и размер очереди (во избежание чрезмерного потребления RAM, так обеспечивается более стабильная работа в продакшене). В идеале такая структура также потребовала бы многопоточных очередей с семафорами, как это описано в задаче поставщика и потребителя: чтобы организовать передачу информации от одного этапа конвейера к другому.

В нашей компании Neuraxle уже удается делать одну вещь лучше, чем она реализована в scikit-learn: речь идет о последовательных конвейерах, которыми можно пользоваться при помощи класса MiniBatchSequentialPipeline. Пока эта штука не многопоточная (но это в планах). Как минимум, она уже передает данные в конвейер в виде мини-батчей в процессе подгонки или преобразования, до сбора результатов, что позволяет работать с большими конвейерами точно как в scikit-learn, но на этот раз с применением мини-батчинга, а также с многочисленными другими возможностями, среди которых: пространства гиперпараметров, установочные методы, автоматическое машинное обучение и так далее.

Наше решение параллельной потоковой обработки данных на Python

  • Метод подгонки и/или преобразования можно вызывать много раз подряд, чтобы улучшить подгонку при помощи новых мини-батчей.
  • Многопоточные очереди внутри конвейера используются так, как в проблеме поставщика-потребителя. Между любыми двумя этапами конвейера, передаваемыми по потоковому принципу, нужна одна очередь.
  • Можно обеспечить параллельную репликацию этапов конвейера, чтобы на каждом этапе параллельно преобразовывать множество элементов. Это можно делать до того, как по всему конвейеру будут вызваны методы setup. В противном случае конвейер необходимо сериализовать, клонировать и перезагрузить с использованием механизмов, сохраняющих этапы. Код, использующий TensorFlow, и иной импортированный код, написанный на других языках, например, на C++, сложно распределить на потоки в Python, особенно если он использует память GPU. Даже joblib не так легко справляется с некоторыми из таких проблем. Поэтому благоразумно избегать подобных проблем при помощи грамотной сериализации.
  • Параметр конвейера может быть важен, а может быть и не важен для поддержания данных в правильном порядке перед отправкой их на следующий этап. По умолчанию он важен, а если нет то конвейер может продолжать обработку данных в произвольном порядке, по мере поступления, причем, так и бывает, если на разные этапы требуется разное количество времени.
  • Будет можно использовать барьерные объекты между этапами конвейера. Они будут представлять собой не настоящие этапы, а указания конвейеру, как обращаться с данными между этапами; например, должны или нет данные сохранять определенный порядок в заданных ключевых местах. Например, можно использовать барьеры, предусматривающие соблюдение порядка, не предусматривающие соблюдения порядка, либо дожидающиеся всех данных блокирующие барьеры (мы назвали такой барьер Joiner). Эти барьеры добавляют информацию о том, как обрабатывать данные между этапами или группами этапов. Например, на конкретном этапе я могу задавать или переопределять длину очереди и указывать, сколько раз нужно параллельно прогнать этап конвейера, как распараллелить этот этап.


Более того, мы хотим обеспечить возможность разделения между потоками любого объекта в Python: так он будет поддаваться сериализации и перезагрузке. В таком случае код можно будет динамически отправлять на обработку на любом воркере (это может быть другой компьютер или процесс), даже если сам нужный код на этом воркере отсутствует. Это делается при помощи цепочки сериализаторов, специфичных для каждого класса, воплощающего этап конвейера. По умолчанию на каждом из этих этапов есть сериализатор, позволяющий обрабатывать обычный код на Python, а для более заковыристого кода применять GPU и импортировать код на других языках. Модели просто сериализуются при помощи своих сейверов, а затем заново загружаются в воркер. Если воркер локальный, то объекты могут быть сериализованы на диск, расположенный в RAM, или в каталог, монтированный в RAM.

КОМПРОМИСС ПРИ ИНКАПСУЛЯЦИИ

Остается еще одна досадная вещь, присущая большинству библиотек для конвейерного машинного обучения. Речь о том, как обрабатываются гиперпараметры. Возьмем для примера scikit-learn. Пространства гиперпараметров (они же статистические распределения значений гиперпараметров) часто должны указываться вне конвейера с нижними подчеркиваниями в качестве разделительных знаков между этапами конвейера (конвейеров). Тогда как Случайный Поиск и Поиск по сетке позволяют исследовать сетки гиперпараметров или пространства вероятностей гиперпараметров, как это определяется в дистрибутивах scipy, сама scikit-learn не предоставляет пространства гиперпараметров по умолчанию для каждого классификатора и преобразователя. Ответственность за выполнение этих функций можно возложить на каждый из объектов конвейера. Таким образом, объект будет самодостаточен и будет содержать собственные гиперпараметры. Так не нарушается принцип единственной ответственности, принцип открытости/закрытоcти и принципы SOLID объектно-ориентированного программирования.

СОВМЕСТИМОСТЬ И ИНТЕГРАЦИЯ

Программируя конвейеры для машинного обучения, полезно держать в уме, что они должны сохранять совместимость со множеством других инструментов, в частности, scikit-learn, TensorFlow, Keras, PyTorch и многими другими библиотеками машинного и глубокого обучения.
Например, мы написали метод .tosklearn() позволяющий превращать этапы конвейера или целый конвейер в BaseEstimator базовый объект библиотеки scikit-learn. Что касается других библиотек машинного обучения, задача сводится к написанию нового класса, который наследует от нашего BaseStep и к переопределению в конкретном коде операций подгонки и преобразования, а также, возможно, установки и сноса. Также нужно определить сейвер, который будет сохранять и загружать вашу модель. Вот документация по классу BaseStep и примеры к ней.

ЗАКЛЮЧЕНИЕ

Резюмируя, отметим, что код конвейеров машинного обучения, готовый к выходу в продакшен, должен соответствовать множеству критериев качества, которые вполне достижимы, если придерживаться нужных паттернов проектирования и хорошо структурировать код. Отметим следующее:

  • В коде для машинного обучения целесообразно использовать конвейеры, и каждый этап конвейера определять как экземпляр класса.
  • Затем вся такая структура может быть оптимизирована при помощи контрольных точек, помогающих найти наилучшие гиперпараметры и многократно выполнять код над одними и теми же данными (но, возможно, с разными гиперпараметрами или с измененным исходным кодом).
  • Также целесообразно выполнять подгонку и преобразование данных последовательно, чтобы не раздувать RAM. Затем всю такую структуру можно распараллелить, когда переключаешься с последовательного конвейера на потоковый.
  • Наконец, можно программировать собственные этапы конвейеров для этого достаточно наследовать от класса BaseStep, показанного в этой статье, и реализовать нужные вам методы.
Подробнее..

Из песочницы Расширение возможностей алгоритмов Машинного Обучения с помощью библиотеки daal4py

26.10.2020 14:14:03 | Автор: admin

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


Данная статья продемонстрирует, как на примере алгоритмов, взятых из библиотеки Scikit-Learn, можно расширить возможности обучения нейронных сетей, путём использования ускоренных вычислений библиотеки daal4py.


Введение


Scikit-Learn предоставляет серьёзный набор инструментов для решения Machine Learning задач. Классификация, Регрессия, Кластеризация sklearn обладает алгоритмами для всего этого. С некоторыми из этих алгоритмов мы и поработаем.


В 2019 году на базе Intel Data Analytics Acceleration Library (DAAL) формируется библиотека daal4py. Intel презентовало решение, напрямую относящееся к predictive data analysis, имеющее существенное преимущество среди аналогов за счёт производительности и простоты использования.


Технология daal4py позволяет увеличить производительность
классических методов sklearn за счёт ускоренных вычислений(в частности матричных преобразований), базирующихся на Intel DAAL.


Реализация


Рассмотрим методы daal4py.sklearn на тестовой задаче.


Датасет, опубликованный на kaggle: Cardiovascular Disease dataset
Задачей поставлено создание модели, способной сделать предсказание относительно наличия или отсутствия сердечно-сосудистых заболеваний у человека.


Данная задача задача классификации, поэтому было решено использовать ensamble из моделей LogisticRegression, RandonForestClassifier и KNeighborsClassifier, пропущенные через инструмент подгона параметров GridSearchCV, реализации Scikit-Learn.


Для начала обучим обе реализации алгоритмов на одинаковых параметрах и сравним их:


Функции обучения и вывода лучших классификаторов:


from sklearn.model_selection import GridSearchCV# Best Logistic Regressiondef get_best_clf_lr(name, clf, params):    start = timer()    grid_clf = GridSearchCV(estimator=clf, param_grid=params, n_jobs=-1)    grid_clf.fit(X_train, y_train)    end = timer()    learning_time = end - start    print(learning_time)    return name, learning_time, grid_clf.best_estimator_# Best Random Forest Classifierdef get_best_clf_rf(name, clf, params):    start = timer()    grid_clf = GridSearchCV(estimator=clf, param_grid=params, n_jobs=-1, cv=5)    grid_clf.fit(X_train, y_train)    end = timer()    learning_time = end - start    print(learning_time)    return name, learning_time, grid_clf.best_estimator_# Best K Neighbors Classifierdef get_best_clf_knn(name, clf, params):    start = timer()    grid_clf = GridSearchCV(estimator=clf, param_grid=params, n_jobs=-1)    grid_clf.fit(X_train, y_train)    end = timer()    learning_time = end - start    print(learning_time)    return name, learning_time, grid_clf.best_estimator_

Данные функции принимают на вход название, классификатор и перебираемые параметры обучения, а на выходе возвращают название, время обучения модели и лучшую обученную модель. Относительно каждой модели распишем передаваемые параметры и запустим обучение для sklearn и daal4py версий алгоритмов. Представлю данный процесс на примере RandomForestClassifier алгоритма:


from sklearn.ensemble import RandomForestClassifier as RandomForestClassifier_sklfrom daal4py.sklearn import ensemble# Random Forest Classifierparams_RF = {    'n_estimators': [1, 3, 5, 7, 10],    'max_depth': [3, 5, 7, 9, 11, 13, 15],    'min_samples_leaf': [2, 4, 6, 8],    'min_samples_split': [2, 4, 6, 8, 10]}name, lrn_time, model = get_best_clf_lr("RF_sklearn", RandomForestClassifier_skl(random_state = 42), params_RF)learn_data_skl.append([name, model, lrn_time])name, lrn_time, model = get_best_clf_lr("RF_daal4py", ensemble.RandomForestClassifier(random_state = 42), params_RF)learn_data_daal.append([name, model, lrn_time])

Очевидным является прирост скорости обучения моделей. Особенно ярко он выражен на модели KNeigborsClassifier, где скорость обучения модели увеличилась в 45раз. Это невероятный показатель, позволяющий нагружать алгоритм, увеличением количества итераций, перебираемых гиперпараметров или ещё чем-нибудь другим. На остальных алгоритмах ускорение составило 1.5 2 раза.


Полученный выигрыш во времени, был использован для увеличением количества перебираемых параметров RandomForestClassifier модели, а также увеличением выборки на 34% без временных потерь.


Последующее объединение моделей в ensamble и определяло финальный вид модели.
В качестве метрики качества использовали ROC_AUC score.


Учитывая тот факт, что обучение происходило без разного рода feature engineering, корреляции между данными практически не наблюдалось, то получившийся показатель roc_auc_score в 0.74 на результирующей модели можно считать закономерным.


Заключение


Посредством библиотеки daal4py, использующей быстрые матричные преобразования, удалось ускорить модели машинного обучения и расширить возможности обучения без потери времени. На данной, тестовой задаче удалось увеличить количество перебираемых параметров, а также увеличить обучающую выборку на 34%, без изменения времени выполнения.


GitHub
Dataset
Daal4py

Подробнее..

Перевод Как магия машинного обученияменяет нашу жизнь

05.04.2021 16:10:13 | Автор: admin

Много лет назад я загорелась идеей научиться программированию, создав собственный сайт. Тогда я ничего не понимала в компьютерах и тем более в серверах. И только одна мысль о том, сколько же мне предстоит узнать нового, будила во мне необыкновенный интерес. Перед сном я обдумывала сотни вариантов своего сайта от параллакс-эффекта при прокручивании до шрифтов из Google Fonts и мечтала о будущих проектах.

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

Один из веселых способов познакомиться с машинным обучением это создать что-то для себя. В этой статье я расскажу, как это сделать.

Работая в сфере технологий, вы посвящаете свою жизнь учебе. Глазом не успеешь моргнуть, как самое совершенное ПО моментально заменяется чем-то более продвинутым (хотя я все никак не могу отвыкнуть от старого доброго Vim).

Одно из интереснейших направлений в ИТ машинное обучение. Большинству из нас не рассказывали о нем в вузах (а у некоторых вообще не было уроков информатики), но скоро машинное обучение станет повсеместным, и оно изменит процесс разработки ПО во всех областях. Неудивительно, что меня часто спрашивают, с чего лучше начать изучение машинного обучения.

Обычно я советую обратиться к таким ресурсам, как курс компании Google под названиемMachine Learning Crash Course, а также книгаПрикладное машинное обучение с помощью Scikit-Learn, Keras и TensorFlowи курс на сайте CourseraМашинное обучение(автор: Andrew Ng), который нацелен не только на теоретические основы, но и на практику.

Но если вы, как и я, предпочитаете сразу переходить к делу, попробуйте познакомиться с машинным обучением, создав для себя программу. Собственные проекты это не только приятный и полезный способ знакомства с новыми технологиями. В отличие от идеальных условий, которые предлагаются в домашних заданиях, на практике вы столкнетесь с реальными трудностями при внедрении машинного обучения в ПО.

В начале пандемии я вдруг поняла, что у меня много свободного времени. И я поставила перед собой задачу узнать больше о машинном обучении, решая с его помощью повседневные задачи. С тех пор машинное обучение помогает мне искать семейные видео, улучшать подачу во время игры в теннис, переводить видео, создавать новые рецепты выпечки и многое другое.

Ниже вы найдете список и обзор всех этих проектов, а такжеисходный код, обучающиевидео на YouTubeи пошаговые инструкции вмоем блоге. Я расскажу обо всем процессе от работы с новыми технологиями и инструментами до создания приложения с их помощью. Надеюсь, эти проекты окажутся для вас не только веселыми, но и полезными. А если они вдохновят вас на собственные проекты с машинным обучением, я буду только рада. Не забудьтерассказать мнео своих свершениях в твиттере. Удачной работы!

Внедрение машинного обучения в свои проекты

Умный архив семейных видео

  • Вы создадите: архив, который сможет предоставлять видео по фразе или объекту из записи (например, "день рождения", "велосипед" или "видеоигры").

  • Вы узнаете:

    • как применять машинное обучение в сортировке и поиске сложных типов данных;

    • как использовать Video Intelligence API;

    • как проектировать приложение, в основе которого лежит машинное обучение (в этом помогут инструментыFlutter для создания клиентской части,Firebase для написания кода без использования серверов, и поиск как сервис, предоставленныйAlgolia).

Бот-модератор в Discord

  • Вы создадите: бот для чат-платформыDiscord,который помогает находить оскорбительные и нецензурные сообщения, а также спам.

  • Вы узнаете:

    • как использоватьPerspective APIдля анализа текста;

    • как применять машинное обучение в приложениях для чата;

    • как выбирать, нужно ли машинное обучение в сложных и неоднозначных ситуациях.

  • Вы создадите: блокнот Jupyter, который отслеживает подачу и траекторию теннисного мяча (может также пригодиться в гольфе и баскетболе), а также анализирует данные, чтобы дать полезные советы. Для этого перейдите вQwiklabs.

  • Вы узнаете:

    • как выполнять сложное машинное обучение с помощью небольших наборов данных;

    • как комбинировать простые математические вычисления с распознаванием поз для понимания движений человека;

    • как использовать Video Intelligence API;

    • как работать c AutoML Vision.

Умный игровой мир с технологией обработки естественного языка

илиСоздание приложений на основе языка с помощью семантического машинного обучения

  • Вы создадите:

    • простую систему на основе языка, с помощью которой можно взаимодействовать с игровым миром через ввод текста.

  • Вы узнаете:

    • как использовать одну из самых полезных методик обработки естественного языка встраивание предложений;

    • как реализовывать семантический поиск текста;

    • как разделять текст на кластеры;

    • как добавлять простые чат-боты;

    • как выполнять эти действия в Google Таблице.

Преобразование PDF-документа в аудиокнигу

  • Вы создадите: код, который преобразует PDF-файлы в аудиокниги формата MP3.

  • Вы узнаете:

    • как извлекать текст из PDF-файлов при помощи Vision API;

    • как озвучивать текст при помощи Text-to-Speech API;

    • как использовать математические вычисления для разделения макетов документа.

Перевод и озвучивание видео с помощью машинного обучения

  • Вы создадите: код, который автоматически преобразовывает речь из видео в текст, а затем переводит и озвучивает его.

  • Вы узнаете:

    • как совмещать технологии распознавания, перевода и синтеза речи;

    • как улучшать качество перевода и преобразования речи в текст;

    • как работать с видео и аудио на языке Python.

Создание рецептов выпечки с помощью ИИ

  • Вы создадите: модель машинного обучения без единой строки кода, которая может классифицировать рецепты и генерировать новые.

  • Вы узнаете:

    • как создавать модели машинного обучения в AutoML Tables с помощью табличных данных без написания кода;

    • как определять причину решений модели с помощью функций.

Создание модели машинного обучения в браузере без написания кода

  • Вы создадите: быструю модель машинного обучения, которая распознает позы, объекты и звуки.

  • Вы узнаете:

    • что нужно, чтобы создать простую модель машинного обучения без написания кода;

    • как с помощью инструмента "Обучаемая машина" создать быструю модель, которую можно запустить в браузере.

Создание образов с помощью ИИ

  • Вы создадите: приложение, которое будет рекомендовать образы на основе фотографий вашего гардероба и публикаций медийных персон в соцсетях.

  • Вы узнаете:

    • как использовать Product Search и Vision API;

    • как проектировать приложения на основе машинного обучения с помощью React и Firebase.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru