Введение в нейросети

Устаревшие решения для компьютерного зрения

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

Такой подход работает, однако результаты не особо впечатляют. Прежде всего, чтобы создать признаки самостоятельно, придётся приложить немало усилий, скажу больше — это требует серьёзного уровня предметных знаний. К тому же признаки сильно отличаются от случая к случаю. К примеру, то, что создано для диагностики переломов на рентгеновских снимках, вполне может не подойти для распознавания имени на почтовой посылке.

Рисунок 1: устаревшие решения для компьютерного зрения с использованием машинного обучения

Image (Matrix) - Изображение (Матрица)Hand-crafted features - Созданные вручную признакиLabel - МеткаPredictions - Прогнозы

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

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

Image (Matrix) - Изображение (Матрица)Flattened - Уплощённое (изображение)Label - МеткаTraditional ML Model/Feed-Forward Networks - Традиционная модель МО/Нейросети прямого распространенияPredictions - Прогнозы

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

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

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

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

При перенесении этих проблем на более общие случаи (к примеру, на поиск множества объектов на изображении) сложность возрастает экспоненциально.

Рецептивные поля

Существенной особенностью архитектур сверточной нейронной сети является то, что размеры ввода становятся все меньше и меньше от начала до конца сети, а количество каналов становится больше. Это, как упоминалось ранее, часто делается с помощью strides или pooling layers. Местность определяет, какие входные данные из предыдущего уровня будут на выходе следующего. Receptive field определяет, какую область исходного входа получает выход.

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

Свертка 3*3, шаг 2

Затем мы применяем нелинейность к выходном данным, затем накладываем еще один новый слой свертки сверху. Здесь все становится интересным. Даже если бы мы применили ядро того же размера (3*3), имеющее одну и ту же локальную область, к выходу strided convolution, ядро имело бы более эффективное receptive field.

Это связано с тем, что выход strided слоя по-прежнему представляет из себя одно и то же изображение. Это не столько обрезка, сколько изменение размера, только теперь каждый отдельный пиксель на выходе является «представителем» большей площади (другие пиксели которой были отброшены) из того же местоположения исходного ввода. Поэтому, когда ядро следующего слоя применяется к выходу, оно работает с пикселями, собранными из большей области.

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

Визуалицая усложнения после добавления слоев

Такое расширение восприимчивого поля позволяет слоям свертки сочетать признаки низкого уровня (линии, ребра) с признаками более высокого уровня (кривые, текстуры), как мы видим в слое mixed3a.

Вслед за слоем pooling/striding сеть продолжает создавать детекторы для еще более высокоуровневых признаков (частей, шаблонов), как мы видим на mixed4a.

Повторное уменьшение размера изображения к 5-му блоку сверток дает размеры ввода всего 7*7, по сравнению с входами 224*224. В этот момент каждый отдельный пиксель представляет собой огромную сетку размером 32*32 пикселя.

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

Сеть в целом развивается из небольшого количества фильтров (64 в случае GoogLeNet), обнаруживая функции низкого уровня, до очень большого количества фильтров (1024 в окончательной свертке), каждый из которых ищет чрезвычайно специфические признаки высокого уровня. И далее применяется окончательный слой — pooling layer, который сворачивает каждую сетку 7*7 в один пиксель, каждый канал является детектором признаков с receptive field, эквивалентным всему изображению.

По сравнению с тем, что сделала бы стандартная feedforward сеть, вывод здесь не впечатляет. Стандартная feedforward сеть создала бы абстрактные векторы признаков из комбинации всех пикселей в изображении, требуя труднообучаемых объемов данных.

Сверточная нейронная сеть с наложенными на нее priors, начинает обучение с изучения детекторов признаков низкого уровня, и когда слой за слоем ее receptive field становится все больше, учится комбинировать эти низкоуровневые признаки в признаки более высокого уровня; не абстрактное сочетание каждого пикселя, а сильная визуальная иерархия.

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

Долой максимализм.

Помните, я говорил об отрицательном влияние денег на моё желание путешествовать с человеком? Так вот — я слукавил. Для путешествий лучше всего подходит персона, у которой денег не мало, и не много. Мне так интереснее и не буду объяснять почему.

Но тут я сталкиваюсь с проблемой:

Если я ставлю вес денег отрицательным, то чем меньше денег — тем лучше для путешествий.
Если положительным, то чем богаче — тем лучше,
Если ноль — тогда деньги “побоку”.

Не получается мне вот так, одним весом, заставить нейрон распознать ситуацию “ни много -ни мало”!

Чтобы это обойти, я сделаю два нейрона — “денег много” и “денег мало”, и подам им на вход денежный поток от нашей дамы.

Теперь у меня есть два суждения: “много” и “мало”. Если оба вывода незначительны, то буквально получится “ни много — ни мало”. То есть, добавим на выход ещё один нейрон, с отрицательными весами:

“Нимногонимало”. Красные стрелки — положительные связи, синие — отрицательные

Вообще, это значит, что нейроны подобны элементам конструктора. Подобно тому, как процессор делают из транзисторов, мы можем собрать из нейронов мозг. Например, суждение “Или богата, или умна” можно сделать так:

Или-или. Красные стрелки — положительные связи, синие – отрицательные

Или так:

можно заменить “мудрые” нейроны на “максималистов” и тогда получим логический оператор XOR. Главное — не забыть настроить пороги возбуждения.

В отличие от транзисторов и бескомпромиссной логики типичного программиста “если — то”, нейронная сеть умеет принимать взвешенные решения. Их результаты будут плавно меняться, при плавном изменение входных параметров. Вот она мудрость!

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

А что если добавить скрытых слоёв ещё? Мы способны охватить разумом ту простую сеть, но как насчёт сети, у которой есть 7 слоёв? Способны ли мы осознать глубину её суждений? А если в каждом из них, включая входной, около тысячи нейронов? Как вы думаете, на что она способна?

Представьте, что я и дальше усложнял свой пример с женитьбой и влюблённостью, и пришёл к такой сети. Где-то там в ней скрыты все наши девять нейрончиков, и это уже больше похоже на правду. При всём желании, понять все зависимости и глубину суждений такой сети — попросту невозможно. Для меня переход от сети 3х3 к 7х1000 — сравним с осознанием масштабов, если не вселенной, то галактики — относительно моего роста. Попросту говоря, у меня это не получится. Решение такой сети, загоревшийся выход одного из её нейронов — будет необъясним логикой. Это то, что в быту мы можем назвать “интуицией” (по крайней мере – “одно из..”). Непонятное желание системы или её подсказка.

Но, в отличие от нашего синтетического примера 3х3, где каждый нейрон скрытого слоя достаточно чётко формализован, в настоящей сети это не обязательно так. В хорошо настроенной сети, чей размер не избыточен для решения поставленной задачи — каждый нейрон будет детектировать какой-то признак, но это абсолютно не значит, что в нашем языке найдётся слово или предложение, которое сможет его описать. Если проецировать на человека, то это — какая-то его характеристика, которую ты чувствуешь, но словами объяснить не можешь.

«Лучше, чем человек»

У специалистов возникает вопрос, как можно работу нейросети сравнить с человеческим опытом: «Да Иван Петрович с нами с 1964 года, да он этого керна перенюхал!» Конечно, но он делал то же самое, что и сетка: брал керн, брал учебник, смотрел, как другие люди это делают, и пытался вывести из этого закономерность. Только нейросеть работает гораздо быстрее и жизненный опыт Ивана Петровича переживает 500 раз за день. Однако люди все равно еще не верят в технологию, поэтому нам приходится все задачи разбивать на небольшие этапы, чтобы эксперт мог завалидировать каждый из них и поверить в то, что нейросеть работает.

Все заявления о том, что какая-то нейросеть работает «лучше, чем человек», чаще всего ни на чем не основаны, потому что всегда найдется кто-то, кто будет «глупее» нейросети. Вы мне: «Распознай нефть». А я: «Ну, тут где-то». Вывод: «Ага, не получилось, значит, наша система работает лучше тебя». На самом деле для того, чтобы оценить эффективность работы нейросети, должно быть сравнение с целой группой экспертов, главными людьми в отрасли.

Не меньше вопросов вызывают заявления о точности. Если взять десять человек, один из которых болен раком легких, и сказать, что все они здоровы, то мы предскажем ситуацию с точностью в 90%. Мы ошиблись в одном из десяти, все честно, никто никого не обманул. Но полученный результат нас ни к чему не приводит. Любые новости о революционных разработках — неправда, если нет открытого кода или описания того, как они сделаны.

Данные должны быть качественными. Не существует ситуаций, когда вы вбрасываете в нейросеть неочищенные, неизвестно как собранные данные и получаете нечто дельное. Что значит «плохие данные»? Чтобы распознать онкологическое заболевание, нужно сделать много снимков компьютерной томографии в высоком разрешении и собрать из них 3D-куб органов. Тогда в одном из срезов врач сможет найти картину подозрения на рак — плотную массу, которой там быть не должно. Мы попросили специалистов разметить нам много таких снимков, чтобы поучить нейросеть выделять рак. Проблема в том, что один врач считает, что рак в одном месте, другой врач считает, что там два рака, третий врач думает еще как-то иначе. Сделать из этого нейросеть невозможно, потому что все это разные ткани, и если обучить нейросеть на таких данных, то она будет видеть рак вообще везде.

Python код среднеквадратической ошибки (MSE)

Ниже представлен код для подсчета потерь:

Python

import numpy as np

def mse_loss(y_true, y_pred):
# y_true и y_pred являются массивами numpy с одинаковой длиной
return ((y_true — y_pred) ** 2).mean()

y_true = np.array()
y_pred = np.array()

print(mse_loss(y_true, y_pred)) # 0.5

1
2
3
4
5
6
7
8
9
10
11
12

importnumpy asnp

defmse_loss(y_true,y_pred)

# y_true и y_pred являются массивами numpy с одинаковой длиной

return((y_true-y_pred)**2).mean()

y_true=np.array(1,,,1)

y_pred=np.array(,,,)

print(mse_loss(y_true,y_pred))# 0.5

При возникновении сложностей с пониманием работы кода стоит ознакомиться с в NumPy для операций с массивами.

История

Какова же история развития нейронных сетей в науке и технике? Она берет свое начало с появлением первых компьютеров или ЭВМ (электронно-вычислительная машина) как их называли в те времена. Так еще в конце 1940-х годов некто Дональд Хебб разработал механизм нейронной сети, чем заложил правила обучения ЭВМ, этих «протокомпьютеров».

Дальнейшая хронология событий была следующей:

  • В 1954 году происходит первое практическое использование нейронных сетей в работе ЭВМ.
  • В 1958 году Франком Розенблатом разработан алгоритм распознавания образов и математическая аннотация к нему.
  • В 1960-х годах интерес к разработке нейронных сетей несколько угас из-за слабых мощностей компьютеров того времени.
  • И снова возродился уже в 1980-х годах, именно в этот период появляется система с механизмом обратной связи, разрабатываются алгоритмы самообучения.
  • К 2000 году мощности компьютеров выросли настолько, что смогли воплотить самые смелые мечты ученых прошлого. В это время появляются программы распознавания голоса, компьютерного зрения и многое другое.

Схема работы нейронной сети

Чтобы представить принцип работы нейронной сети не требуется особых навыков. На входной слой нейронов поступает определённая информация. Она передаётся посредством синапсов следующему слою, при этом каждый синапс имеет свой коэффициент веса, а каждый следующий нейрон может иметь несколько входящих синапсов.

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

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

  • Линейная функция f(x) = x, самая простая из всех возможных, используется только для тестирования созданной нейронной сети или передачи данных в исходном виде.
  • Сигмоид считается самой распространённой функцией активации и имеет вид f(x) = 1 / 1+e–×; при этом диапазон её значений от 0 до 1. Она ещё называется логистической функцией.
  • Чтобы охватить и отрицательные значения используют гиперболический тангенс. F(x) = e²× – 1 / e²× + 1 — такой вид имеет эта функция и диапазон который она имеет от -1 до 1. Если нейронная сеть не предусматривает использование отрицательных значений, то использовать её не стоит.

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

Соответственно, чтобы проводить тренировку сети правильно нужно выполнять сеты, последовательно увеличивая показатель эпохи.

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

Разновидность ИНС

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

Первый вид — сверточные — представляют собой самый популярный вид. Их эффективность проверена на практике. Во-первых, для распознавания визуальных образов: будь то картинка, фотография или видеозапись. Во-вторых, для предсказывания каких-либо объектов, которые будут интересны пользователю в интернете (видео, музыка, книги и т.д.). В этом случае они применяют для сбора и обработки определенной информации о человеке, взятой из открытых источников в интернете, и истории запросов поисковых систем.

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

В отличие от предыдущего вида, здесь можно дать машине указания, на какие объекты или данные следует «обратить внимание», и подвергнуть более тщательной обработке. Применяются они, как правило, в распознавании текста, будь то Google-переводчик, поисковой алгоритм от компании «Яндекс» — «Палех», или встроенное приложение в смартфоны с операционной системой iOS — Siri

Глубокое обучение: принципы работы и результаты использования

К глубокому обучению относят класс ML-моделей, основанных на обучении представлениями (feature/representation learning), а не на специализированных алгоритмах под конкретные задачи. В DL многослойные нейронные сети играют роль многоуровневой системы нелинейных фильтров для извлечения признаков. Для DL-моделей характерно иерархическое сочетание нескольких алгоритмов обучения: с учителем, без учителя, с подкреплением. Архитектура нейросети и состав ее нелинейных слоёв зависит от решаемой задачи. При этом используются скрытые переменные, организованные послойно, например, узлы в глубокой сети доверия и глубокой ограниченной машине Больцмана. При этом, независимо от архитектурных особенностей и прикладного назначения, для всей DL-сетей характерно предварительное обучение на большом объеме общих данных с последующей подстройкой на датасетах, специфичных для конкретного применения .

Например, одна из наиболее известных реализаций DL-моделей, нейронная сеть BERT, о которой я рассказывал здесь, предварительно обучена на статьях из Википедии, чтобы затем использоваться в распознавании текстов. По аналогичному принципу работает нейросеть XLNet, также применяемая в задачах обработки естественного языка для анализа и генерации текстов, извлечения данных, информационного поиска, синтеза речи, машинного перевода, автоматического реферирования, аннотирования, упрощения текстовой информации и прочих NLP-проблем . Другая глубокая нейросеть, CQM (Calibrated Quantum Mesh), также показывает отличные результаты (более 95%) в понимании естественного языка, извлекающая смысл слова на основе вероятностного анализа его окружения (контекста) без использования заранее заданных ключевых слов . На рисунке 5 показано использование предварительно подготовленной модели в качестве объектов в отдельной нисходящей DL-сети при трансферном обучении в NLP-задачах .

Рис. 5. Схема трансферного обучения в DL-сетях

Среди других DL-моделей стоит упомянуть капсульные сети, которые, в отличие от сверточных сетей, обрабатывают визуальные образы с учетом пространственной иерархии между простыми и сложными объектами, что повышает точность классификации и снижает объем данных для обучения . Также отметим глубокое обучение с подкреплением (DRL, Deep Reinforcement Learning), работающее по принципу взаимодействия нейросети с окружающей средой посредством наблюдений, действий, штрафов и вознаграждений . DRL считается наиболее универсальным из всех ML-методов, поэтому его можно использовать в большинстве бизнес-приложений. В частности, именно к DRL-моделям относится нейросеть AlphaGo, которая в 2015 году впервые победила человека в соревнованиях по древней китайской игре го, а в 2017 – обыграла сильнейшего профессионального игрока в мире .

А для распознавания образов, получения фотореалистичных изображений, улучшения качества визуальной информации и обеспечения кибербезопасности активно используются GAN-подобные сети. GAN-сеть представляет собой комбинацию двух конкурирующих нейросетей, одна из которых (G, генератор) генерирует образцы,а другая (D, Дискриминатор) старается отличить правильные («подлинные») образцы от неправильных, обрабатывая все данные. Со временем каждая сеть улучшается, благодаря чему качество обработки данных существенно возрастает, т.к. в процесс обучения уже заложена функция обработки помех. Эту систему DL-обучения без учителя впервые описал Ян Гудфеллоу из компании Google в 2014 году, а сама идея состязательного обучения была выдвинута в 2013 году учеными Li, Gauci и Gross. Сегодня GAN-сети активно используются в видеоиндустрии и дизайне (для подготовки кадров фильмов или мультипликации, сцен компьютерных игр, создания фотореалистичных изображений), а также в космической промышленности и астрономии (для улучшения снимков, полученных из астрономических наблюдений) . Таким образом, GAN-сети отлично подходят для широкого спектра задач обучения без учителя, где помеченные данные не существуют или процесс их подготовки слишком дорог, например, создание 3D-образа удаленного объекта на основе его фрагментарных изображений. Благодаря состязательному подходу, этот ML-метод оказывается быстрее аналогичных DL-моделей, т.к. используются сразу две сети с противоположными локальными целями, направленными на общий глобальный результат .

Что такое нейронные сети и их типы?

Первый вопрос, который возникает у интересующихся, что же такое нейронная сеть? В классическом определении это определённая последовательность нейронов, которые объединены между собой синапсами. Нейронные сети являются упрощённой моделью биологических аналогов.

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

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

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

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

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

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

  • Однослойная нейронная сеть. Это структура взаимодействия нейронов, при которой после попадания входных данных в первый входной слой сразу передаётся в слой выхода конечного результата. При этом первый входной слой не считается, так как он не выполняет никаких действий, кроме приёма и распределения, об этом уже было сказано выше. А второй слой производит все нужные вычисления и обработки и сразу выдаёт конечный результат. Входные нейроны объединены с основным слоем синапсами, имеющими различный весовой коэффициент, обеспечивающий качество связей.
  • Многослойная нейронная сеть. Как понятно из определения, этот вид нейронных сетей помимо входного и выходного слоёв имеет ещё и промежуточные слои. Их количество зависит от степени сложности самой сети. Она в большей степени напоминает структуру биологической нейронной сети. Такие виды сетей были разработаны совсем недавно, до этого все процессы были реализованы с помощью однослойных сетей. Соответственно подобное решение имеет намного больше возможностей, чем её предок. В процессе обработки информации каждый промежуточный слой представляет собой промежуточный этап обработки и распределения информации.

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

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

Это не единственные варианты классификации сетей.

Создание небольшой нейронной сети с PyTorch

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

Этот код вы также можете найти на Github.

#Импорт требуемых библиотекimport torch as tchimport torch.nn as nnimport numpy as npfrom sklearn.metrics import confusion_matrix#Создание 500 результатов с помощью randn | Присвоен тег 0X1 = tch.randn(3000, 32)#Создание ещё 500 немного отличающихся от X1 результатов с помощью randn | Присвоен тег 0X2 = tch.randn(3000, 32) + 0.5#Комбинирование X1 и X2X = tch.cat(, dim=0)#Создание 1000 Y путём комбинирования 50% 0 и 50% 1Y1 = tch.zeros(3000, 1)Y2 = tch.ones(3000, 1)Y = tch.cat(, dim=0)# Создание индексов данных для обучения и расщепления для подтверждения:batch_size = 16validation_split = 0.2 # 20%random_seed= 2019#Перемешивание индексовdataset_size = X.shapeindices = list(range(dataset_size))split = int(np.floor(validation_split * dataset_size))np.random.seed(random_seed)np.random.shuffle(indices)#Создание индексов для обучения и подтвержденияtrain_indices, val_indices = indices, indices#Создание набора данных для обучения и подтвержденияX_train, x_test = X, XY_train, y_test = Y, Y#Отрисовка формы каждого набора данныхprint("X_train.shape:",X_train.shape)print("x_test.shape:",x_test.shape)print("Y_train.shape:",Y_train.shape)print("y_test.shape:",y_test.shape)#Создание нейронной сети с 2 скрытыми слоями и 1 выходным слоем#Скрытые слои имеют 64 и 256 нейронов#Выходные слои имеют 1 нейронclass NeuralNetwork(nn.Module):    def __init__(self):        super().__init__()        self.fc1 = nn.Linear(32, 64)        self.relu1 = nn.ReLU()        self.fc2 = nn.Linear(64, 256)        self.relu2 = nn.ReLU()        self.out = nn.Linear(256, 1)        self.final = nn.Sigmoid()    def forward(self, x):        op = self.fc1(x)        op = self.relu1(op)                op = self.fc2(op)        op = self.relu2(op)        op = self.out(op)        y = self.final(op)        return ymodel = NeuralNetwork()loss_function = nn.BCELoss()  #Бинарные потери по перекрёстной энтропииoptimizer = tch.optim.Adam(model.parameters(),lr= 0.001)num_epochs = 10batch_size=16for epoch in range(num_epochs):    train_loss= 0.0    #Начало явного обучения модели    model.train()    for i in range(0,X_train.shape,batch_size):        #Извлечение пакета обучения из X и Y        input_data = X_train,i+batch_size)]        labels = Y_train,i+batch_size)]        #Установление градиентов на 0 перед применением алгоритма  обратного распространения ошибок         optimizer.zero_grad()        #Дальнейшая передача данных        output_data  = model(input_data)        #Подсчёт потерь        loss = loss_function(output_data, labels)        #Применение алгоритма  обратного распространения ошибок        loss.backward()        #Обновление весов        optimizer.step()        train_loss += loss.item() * batch_size    print("Epoch: {} - Loss:{:.4f}".format(epoch+1,train_loss/X_train.shape ))#Прогнозированиеy_test_pred = model(x_test)a =np.where(y_test_pred>0.5,1,0)confusion_matrix(y_test,a)