Приступая к работе, ИНТУИТИВНАЯ СЕРИЯ УЧЕБНОГО ОБУЧЕНИЯ

Упрощенное обучение с подкреплением (часть 1): введение в основные понятия и терминологию

Краткое руководство по применению марковских процессов принятия решений на простом английском языке

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

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

Вот краткое изложение статей этой серии. Моя цель - понять не только то, как что-то работает, но и почему это работает именно так.

  1. Введение в основные концепции и терминологию - эта статья (Что такое проблема RL и как применить к ней структуру решения проблем RL, используя методы из Марковских процессов принятия решений и такие концепции, как Return, Ценность и Политика)
  2. Подходы к решению (Обзор популярных решений RL и их категоризация на основе взаимосвязи между этими решениями. Важные выводы из уравнения Беллмана, которое является основой всех алгоритмов RL.)
  3. Алгоритмы без моделей (Сходства и различия решений на основе ценностей и политик, использующих итеративный алгоритм для постепенного улучшения прогнозов. Политика использования, исследования и ε-жадности.)
  4. Q-Learning (Углубленный анализ этого алгоритма, который является основой для последующих подходов к глубокому обучению. Развивайте интуитивное понимание того, почему этот алгоритм сходится к оптимальным значениям.)
  5. Deep Q Networks (Наш первый алгоритм глубокого обучения. Пошаговое описание того, как именно он работает и почему был сделан этот архитектурный выбор.)
  6. Градиент политики (Наш первый алгоритм глубокого обучения на основе политик.)
  7. Критик-исполнитель (сложный алгоритм глубокого обучения, сочетающий в себе лучшее из сетей Deep Q и градиентов политик.)
  8. Тема-сюрприз 😄 (Следите за обновлениями!)

Обзор RL

Какое место занимает RL в мире машинного обучения?

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

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

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

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

Чем RL отличается от контролируемого (или неконтролируемого) обучения?

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

Какие проблемы решает RL?

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

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

Это полезно для множества приложений, таких как:

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

Обучение с подкреплением происходит методом проб и ошибок

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

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

Чтобы использовать RL, структурируйте вашу проблему как Марковский процесс принятия решений.

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

Чтобы применить RL, первым делом нужно структурировать проблему как нечто, называемое Марковским процессом принятия решений (MDP). Если вы раньше не работали с RL, скорее всего, единственное, что вы знаете о MDP, - это то, что это звучит пугающе 😄.

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

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

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

Состояние: представляет текущее «состояние мира» в любой момент. например. он мог фиксировать положение робота относительно его местности, положение объектов вокруг него и, возможно, направление и скорость ветра.

Может быть конечный или бесконечный набор состояний.

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

Возможных действий может быть конечный или бесконечный набор.

Вознаграждение: положительное или отрицательное подкрепление, которое агент получает из окружающей среды в результате своих действий. Это способ оценить «доброту» или «вредность» конкретного действия.

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

Что вы должны иметь в виду при определении своего MDP?

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

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

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

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

Действия. Какие действия может предпринять ваш агент?

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

Как работает MDP?

Теперь, когда мы узнали, что такое MDP, давайте разберемся, как это работает. Давайте возьмем игру в крестики-нолики (также известные как крестики-нолики) в качестве простого примера. В эту игру играют два игрока, размещая свои жетоны на сетке 3x3. Один игрок кладет нолики (в форме пончика), а другой кладет кресты. Цель состоит в том, чтобы выиграть игру, разместив три своих жетона в ряд.

Вы можете определить свой MDP следующим образом:

  • Агент играет против окружающей среды, поэтому среда действует как его противник.
  • Состояние в любой момент - это текущая позиция всех токенов, как агента, так и среды, на доске.
  • Существует 9 возможных действий, при которых агент может разместить свой жетон в каждом из 9 доступных квадратов сетки.
  • Если агент побеждает, он получает положительное вознаграждение в размере +10 баллов, а если он проигрывает, он получает отрицательное вознаграждение в размере -10 баллов. Каждый промежуточный ход дает нейтральную награду в размере 0 очков.

Теперь давайте рассмотрим работу MDP во время игры.

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

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

Теперь, начиная с первого временного шага, на каждом временном шаге выполняются следующие шаги:

  1. Текущее состояние среды передается агенту.
  2. Агент использует это текущее состояние, чтобы решить, какое действие ему следует предпринять. Ему не нужна память о полной истории состояний и действий, которые были до него. Агент решает поместить свой токен в какую-то позицию. Есть много возможных действий на выбор, так как же он решает, какое действие предпринять? Это очень важный вопрос, но мы вернемся к нему позже.
  3. Это действие передается как вход в среду.
  4. Среда использует текущее состояние и выбранное действие и выводит две вещи: она переводит мир в следующее состояние и обеспечивает некоторую награду. Например, он делает следующий ход, помещая свой жетон в какую-либо позицию, и дает нам вознаграждение. В этом случае, поскольку никто еще не выиграл игру, она дает нейтральную награду в размере 0 очков. Как среда делает это, агент не может контролировать и не может контролировать это.
  5. Затем эта награда из среды предоставляется агенту в качестве обратной связи в результате предыдущего действия.

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

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

MDP выполняет итерацию по последовательности временных шагов

Вот еще один вид работы MDP, который показывает прогрессию временных шагов.

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

Траектория описывает выполнение за несколько временных шагов

Таким образом, выполнение MDP можно описать как траекторию событий (с точки зрения состояния, действия, вознаграждения) в последовательности временных шагов, как показано ниже.

(s3,a3,r4, s4,a4,r5, s5,a5,r6, s6)

Эпизодические задачи заканчиваются конечным состоянием

Для задач RL, которые имеют четко определенное конечное или конечное состояние, полная последовательность от начального состояния до конечного состояния называется эпизодом. например. Каждый раунд игры - это эпизод.

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

Следовательно, работа системы RL повторяется в нескольких эпизодах. В каждом эпизоде ​​он повторяется через несколько временных шагов.

Постоянные задачи продолжаются вечно

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

Агент и среда контролируют переходы между состоянием и действием

Как мы только что видели, MDP работает поочередно между агентом, который что-то делает, а затем средой, что-то делает на каждом временном шаге:

  • Учитывая текущее состояние, следующее действие принимает агент. Фактически, это единственная работа агента. Например, из текущего состояния агент может выбрать, скажем, действие a₁ или a₂, чтобы разместить свой токен.
  • Учитывая текущее состояние и следующее действие, выбранное агентом, переход к следующему состоянию и вознаграждение контролируются средой. Например, если агент выбрал действие a₁, среда может перейти в состояние S₂ или S₃, выполняя разные ходы. Другой пример видеоигры может заключаться в том, что, начиная с заданного состояния (например, персонаж стоит на крыше), одно и то же действие агента (персонаж прыгает) с некоторой вероятностью может закончиться более чем в одном следующем состоянии (например, приземлиться на соседняя крыша, или падение на землю), что контролируется окружающей средой.

Как среда переходит в следующее состояние?

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

Для наиболее реалистичных проблем RL, с которыми мы будем иметь дело, ответ обычно будет такой: «Это просто так». Большинство сред имеют сложную внутреннюю динамику, которая контролирует их поведение, когда действие выполняется из определенного состояния.

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

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

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

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

Эта матрица отображает данную пару состояния и действия на:

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

Как агент выбирает действие?

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

Для этого он использует три концепции, которые мы рассмотрим далее:

  • Возвращение
  • Политика
  • Ценить

Возврат - это общая награда за все временные шаги.

Когда агент выполняет временные шаги, он накапливает вознаграждение на каждом временном шаге.

Однако нас действительно волнуют не отдельные награды, а совокупные.

Мы называем это Возвращением. Это общее вознаграждение, которое агент накапливает за время выполнения задачи.

Возврат рассчитывается с использованием дисконтированных вознаграждений.

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

Возврат = r₀ + γ r₁ + γ² r₂

и, в более общем плане:

Return = r₀ + γ r₁ + γ² r₂ +…. + γr

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

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

Конечная цель агента - получить максимальную отдачу не только за один эпизод, но и за многие-многие эпизоды.

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

Немедленное вознаграждение более ценно, чем Позднее вознаграждение

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

Награды, которые дают нам самый высокий общий доход, лучше

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

Политика - это стратегия выбора действия

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

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

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

Политика похожа на (огромную) таблицу поиска

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

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

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

Однако интуиция та же - подумайте о функции как о «огромной таблице поиска».

Детерминированные и стохастические политики

Политики могут быть детерминированными или стохастическими.

Детерминированная политика - это политика, в которой агент всегда выбирает одно и то же фиксированное действие при достижении определенного состояния.

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

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

Как агент получает полис?

Мы говорили о Политике так, как если бы агент уже имел ее, которую можно было бы использовать. Но на самом деле это не так.

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

Существует так много возможных политик, какую из них следует использовать агенту?

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

Другими словами, цель агента - следовать Политике (то есть, как он выбирает свои действия), которая максимизирует его доход.

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

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

Значение сообщает вам ожидаемый доход, следуя некоторой политике

Допустим, агент находится в определенном состоянии. Кроме того, предположим, что агенту каким-то образом была предоставлена ​​политика π. Теперь, если он запускается из этого состояния и всегда выбирает действия на основе этой политики, какой возврат он может ожидать?

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

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

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

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

Таким образом, у нас есть два типа Ценности:

  • Значение состояния - ожидаемый возврат из заданного состояния путем выполнения действий, основанных на заданной политике π, начиная с этого состояния. Другими словами, функция State Value отображает состояние в его значение.

  • Значение состояния-действия (также известное как Q-значение) - ожидаемый возврат, если после этого выполнить заданное действие из заданного состояния, а затем выполнить действия на основе заданной политики π. Другими словами, функция State-Action Value сопоставляет пару State-Action со своим значением.

Взаимосвязь между вознаграждением, отдачей и стоимостью

  • Награда - это немедленная награда, получаемая за одно действие.
  • Возврат - это сумма всех наград со скидкой, полученных до конца этого эпизода.
  • Ценность - это средний доход (он же ожидаемый доход) за многие эпизоды.

Думайте о вознаграждении как о немедленном удовольствии, а о ценности как о продолжительном счастье 😃.

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

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

Он хранит этот «опыт» как «Ценность».

Почему ценность зависит от нашей политики?

Ясно, что получаемые нами награды (и, следовательно, Возврат и, следовательно, Ценность) зависят от действия, которое мы предпринимаем в данном состоянии. А поскольку действие зависит от выбранной Политики, из этого следует, что Ценность зависит от Политики.

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

Например. Вместо этого, если бы наша политика заключалась в том, чтобы выбирать действия из распределения вероятностей, которое дает максимальное вознаграждение при выборке, значение (ожидаемое вознаграждение) состояния было бы намного выше.

Используйте функцию значения для сравнения политик

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

Имея две политики, мы можем определить соответствующие функции State-Value или State-Action Value для каждой из этих политик, следуя политике и оценивая Returns.

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

«Лучшая» политика называется оптимальной политикой.

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

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

Решите проблему RL, найдя оптимальную политику

Итак, теперь у нас есть подход к решению проблемы RL.

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

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

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

В следующей статье этой серии мы рассмотрим подход к решению, используемый этими алгоритмами RL.

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





Продолжаем учиться!