Советы по повышению производительности глубокого обучения
содержание
1. Улучшить производительность данных
2. Алгоритмически улучшить производительность
3. Улучшить производительность за счет настройки алгоритма
8) Метод оптимизации и функция потерь
4. Используйте метод слияния для усиления эффекта
1. Улучшить производительность данных
Корректировка обучающих данных или абстрактное определение проблемы могут привести к огромным улучшениям. Даже самое резкое улучшение.
Вот обзор:
- собрать больше данных
- генерировать больше данных
- масштабировать данные
- преобразовать данные
- Выбор функций
- переопределить проблему
1) Соберите больше данных
Можете ли вы собрать больше обучающих данных?
Качество вашей модели часто зависит от качества ваших обучающих данных. Вы должны убедиться, что используемые данные являются наиболее эффективными данными для решения проблемы.
Вы также хотите получить как можно больше данных.
Глубокое обучение и другие современные нелинейные модели машинного обученияБольшие данныеЭффект на наборе лучше, особенно для глубокого обучения. Это одна из главных причин, почему методы глубокого обучения так интересны.
Пожалуйста, посмотрите на картинку ниже:
Что такое глубокое обучение?
Слайд-шоу Эндрю Нг
Не всегда данные читаются лучше, в большинстве случаев. Если бы у меня был выбор, я бы предпочел иметь больше данных.
Связанное чтение:
2) Генерировать больше данных
Алгоритмы глубокого обучения, как правило, хорошо работают, когда объем данных велик.
Мы уже упоминали об этом в предыдущем разделе.
Если по какой-то причине вы не получаете больше данных, вы также можете внести некоторые данные.
- Если ваши данные являются числовым вектором, то случайным образом сгенерируйте деформированный вектор существующего вектора.
- Если ваши данные являются изображениями, используйте существующие изображения для случайного создания похожих изображений.
- Если ваши данные текстовые, вы знаете, как...
Этот тип практики часто называют расширением данных или генерацией данных.
Вы можете использовать генеративные модели или использовать некоторые простые приемы.
Например, если данные изображения, простой случайный выбор и перевод существующих изображений смогут получить значительно улучшенные. Он может усиливать обобщение способности модели, если новые данные включены в этот тип трансформации, может получить хорошую сделку.
Иногда добавление шума к данным эквивалентно обычному подходу, позволяющему избежать переобучения обучающих данных.
Связанное чтение:
- Увеличение данных изображения в глубоком обучении
- обучение на зашумленных данных
3) масштабировать данные
Этот метод прост и эффективен.
Эмпирическое волшебное оружие для использования моделей нейронных сетей:
Масштабируйте данные в пороговый диапазон функции активации.
Если вы используете сигмовидную функцию активации, масштабируйте данные между 0 и 1. Если используется функция активации тангенса, диапазон значений регулируется от -1 до 1.
И входные, и выходные данные подвергаются одинаковому преобразованию. Например, если в выходном слое есть сигмовидная функция, которая преобразует выходное значение в двоичные данные, нормализуйте вывод y к двоичному. Если используется функция softmax, нормализация y все еще действительна.
Я также рекомендую вам расширить данные обучения, чтобы создать несколько разных версий:
- нормализовано до 0 ~ 1
- нормализовано до -1 ~ 1
- стандартизация
Затем в каждом наборе данныхконтрольная работаПроизводительность модели, выбор лучшего набора сгенерированных данных.
Если вы меняете функцию активации, лучше всего повторить этот небольшой эксперимент.
Не подходит для расчета больших чисел в модели. Кроме того, существует много других способов сжатия данных в модели, таких как нормализация весов и активаций, и я расскажу об этих методах позже.
Связанное чтение:
- Нужно ли нормализовать входные данные (вектор-столбец)?
- Как подготовить входные данные для машинного обучения с помощью Scikit-Learn
4) Преобразование данных
Связан с методом в предыдущем разделе, но требует дополнительной работы.
Вы должны действительно понимать используемые данные. Визуализируйте данные, затем выберите выбросы.
Сначала угадайте распределение каждого столбца данных
- Является ли этот столбец данных искаженным распределением Гаусса, если да, попробуйте исправить перекос с помощью метода Бокса-Кокса.
- Является ли этот столбец данных экспоненциально распределенным, если да, то логарифмически преобразованным
- Есть ли у этого столбца данных определенные характеристики, но это сложно понять интуитивно, попробуйте возвести данные в квадрат или укоренить
- Можно ли дискретизировать признаки, чтобы лучше подчеркнуть некоторые признаки?
Используя свою интуицию, попробуйте несколько методов
- Можно ли предварительно обработать данные с помощью проекционных методов, таких как PCA?
- Можно ли объединить несколько свойств в одно значение?
- Можно ли обнаружить новое свойство, представленное логическим значением?
- Есть ли что-то новое, что можно открыть в масштабах времени или других измерениях?
Нейронные сети обладают возможностями обучения функциям, и они могут делать эти вещи.
Но если вы сможете лучше представить структуру проблемы, сетевая модель будет обучаться быстрее.
Быстро попробуйте различные преобразования на тренировочном наборе, чтобы увидеть, что работает, а что нет.
Связанное чтение:
- Как определить проблему машинного обучения
- Инжиниринг признаков, как построить признаки и как улучшить
- Как подготовить входные данные для машинного обучения с помощью Scikit-Learn
5) Выбор функции
Нейронные сети очень мало страдают от некоррелированных данных.
Они присваивают этому вес, близкий к 0, почти игнорируя вклад этой функции в прогнозируемое значение.
Можете ли вы удалить определенные атрибуты обучающих данных?
У нас есть много методов выбора функций и методов важности функций, чтобы определить, какие функции оставить, а какие удалить.
Пробуйте, пробуйте все способы.
Если у вас есть время, я все же рекомендую попробовать несколько методов на одной и той же модели нейронной сети, чтобы увидеть, насколько хорошо они работают.
- Возможно, то же самое или даже лучше можно получить с меньшим количеством функций.
- Возможно, все методы выбора признаков предпочитают отбрасывать одну и ту же часть атрибутов признаков. Тогда вам стоит хорошенько присмотреться к этим бесполезным функциям.
- Возможно, эта выбранная часть функций вдохновила вас на создание новых функций.
Связанное чтение:
6) Рефакторинг проблемы
Вернемся к определению вашего вопроса.
Являются ли эти наблюдения, которые вы собрали, единственным способом описать проблему?
Может есть другие способы. Возможно, другие подходы более четко раскрывают структуру проблемы.
Я сам очень люблю это упражнение, потому что оно заставляет нас расширить кругозор. Трудно сделать хорошо. Особенно, когда вы вложили много времени, энергии и денег в существующие методы.
Даже если вы перечислите от 3 до 5 различных способов, по крайней мере, у вас будет достаточно уверенности в том, какой путь вы выберете в итоге.
- Может быть, вы можете включить элемент времени в окно
- Может быть, ваша проблема может быть классифицирована в регрессии, а наоборот
- Может быть, можно преобразовать вывод двоичного типа в вывод softmax
- Может быть, вы можете смоделировать подзадачи
Это хорошая привычка глубоко задуматься о проблеме, и лучше всего выполнить вышеперечисленные шаги, прежде чем выбирать инструмент для начала, чтобы уменьшить неэффективные затраты энергии.
В любом случае, если вы в растерянности, эта простая полоса заставит вас задуматься.
Кроме того, вам не нужно выбрасывать много работы на ранней стадии, о чем можно узнать в следующих главах.
Связанное чтение:
2. Алгоритмически улучшить производительность
Машинное обучение всегда связано с алгоритмами.
Вся теория и математика описывают различные способы изучения процессов принятия решений на основе данных (если мы говорим здесь только о моделях прогнозирования).
Вы выбираете глубокое обучение для решения, является ли это наиболее подходящей технологией?
В этом разделе мы кратко поговорим о выборе алгоритма, а в последующем контенте будет конкретно рассказано, как улучшить эффект глубокого обучения.
Вот обзор:
- Алгоритм скрининга
- учиться на литературе
- метод передискретизации
Раскладываем по одному.
1) Алгоритм скрининга
Невозможно заранее знать, какой алгоритм лучше всего подойдет для вашей задачи.
Если вы уже знаете, вам, вероятно, тоже не нужно машинное обучение.
Какие у вас есть доказательства того, что подход, который вы выбрали сейчас, является лучшим вариантом?
Давайте подумаем над этой загадкой.
При оценке производительности на всех возможных проблемах ни один алгоритм не работает лучше, чем другие. Все алгоритмы равны. ЭтоТеории бесплатного обеда не существуетглавное.
Возможно, выбранный вами алгоритм не подходит для решения вашей задачи.
Сейчас мы не рассчитываем решить все проблемы, но современные популярные алгоритмы могут не подойти для вашего набора данных.
Мой совет — сначала собрать доказательства, предполагая, что для решения вашей проблемы существуют другие подходящие алгоритмы.
Просмотрите некоторые часто используемые алгоритмы и выберите несколько применимых.
- Попробуйте некоторые линейные алгоритмы, такие как логистическая регрессия и линейный дискриминантный анализ.
- Попробуйте некоторые модели деревьев, такие как CART, Random Forest и Gradient Boosting.
- Попробуйте такие алгоритмы, как SVM и kNN.
- Попробуйте другие модели нейронных сетей, такие как LVQ, MLP, CNN, LSTM и т. д.
Возьмите несколько методов, которые хорошо работают, а затем точно настройте параметры и данные, чтобы еще больше улучшить эффект.
将你所选用的深度学习方法与上述这些方法比较,看看是否能击败他们?
也许你可以放弃深度学习模型转而选择更简单模型,训练的速度也会更快,而且模型易于理解。
Связанное чтение:
- Подход к машинному обучению, основанный на данных
- Зачем нужны алгоритмы скрининга проблем машинного обучения?
- Проверка алгоритмов классификации машинного обучения с помощью scikit-learn
2) Изучение литературы
«Кража» идей из литературы — это самый короткий путь.
Кто-нибудь еще делал ту же проблему, что и вы, и какой метод они использовали.
Читайте статьи, книги, сайты вопросов и ответов, учебные пособия и все, что может предложить вам Google.
Примите к сведению все идеи и продолжайте исследовать в этих направлениях.
Речь идет не о повторении исследований, а о том, чтобы помочь вам обнаружить новые идеи.
Приоритет опубликованных статей
Много-много умных людей написали много интересного. Воспользуйтесь этим ценным ресурсом.
Связанное чтение:
3) Метод передискретизации
Вы должны понимать, как работает ваша модель.
Надежна ли ваша предполагаемая производительность модели?
Модели глубокого обучения медленно обучаются.
Это означает, что мы не можем использовать стандартные золотые правила для оценки производительности модели, такие как k-кратная перекрестная проверка.
- Возможно, вы просто разделили данные на обучающие и тестовые наборы. Если это так, необходимо убедиться, что распределение данных после сегментации остается неизменным. Хорошими методами являются одномерная статистика и визуализация данных.
- Может быть, вы можете расширить оборудование, чтобы улучшить эффект. Например, если у вас есть кластер или учетная запись AWS, мы можем параллельно обучать n моделей и использовать их среднее значение и дисперсию для получения более стабильных результатов.
- Может быть, вы можете выбрать часть данных для перекрестной проверки (очень эффективно для ранней остановки).
- Может быть, вы можете сохранить часть данных для проверки модели совершенно независимо.
С другой стороны, также можно уменьшить набор данных и использовать более сильные методы повторной выборки.
- Возможно, вы увидите сильную корреляцию между производительностью модели, обученной на выборочном наборе данных, и эффектом обучения на полном наборе данных. Затем вы можете выбрать модель с небольшим набором данных, а затем применить окончательный выбранный метод к полному набору данных.
- Возможно, вы можете произвольно ограничить размер набора данных, выбрать часть данных и использовать их для всех задач обучения.
Вы должны быть достаточно уверены в прогнозах производительности модели.
Связанное чтение:
- Оценка производительности моделей глубокого обучения с помощью Keras
- Использование передискретизации для оценки эффективности алгоритмов машинного обучения
3. Улучшить производительность за счет настройки алгоритма
Вы всегда можете найти один или два алгоритма, которые хорошо работают, просеивая алгоритмы. Но на то, чтобы освоить лучшие из этих алгоритмов, могут уйти дни, недели или даже месяцы.
Вот несколько идей, которые могут помочь улучшить производительность алгоритма при настройке параметров.
- Диагностируемость модели
- инициализация веса
- скорость обучения
- функция активации
- сетевая структура
- партия и эпоха
- обычный срок
- оптимизировать цель
- закончить тренировку досрочно
Вам может потребоваться указать параметры для обучения модели несколько раз (от 3 до 10 и более раз), чтобы получить набор параметров, который, как ожидается, будет работать лучше всего. Продолжайте пробовать каждый параметр.
Существует отличный блог по оптимизации гиперпараметров:
1) Диагностика
Наилучших результатов можно добиться, только зная, почему производительность модели больше не улучшается.
Это потому, что модель переоснащает или недообучает?
Имейте в виду этот вопрос. Десять миллионов.
Модели всегда находятся между этими двумя состояниями, просто в разной степени.
Быстрый способ увидеть производительность вашей модели — рассчитать производительность модели на обучающих и проверочных наборах на каждом этапе и представить результаты в виде графика.
Проверьте точность модели на обучающих и проверочных наборах.
- Если эффект обучающего набора лучше, чем у проверочного набора, это означает, что может быть переобучение, попробуйте добавить обычный член
- Если точность обучающего набора и проверочного набора очень низкая, может быть недообучение.Вы можете продолжать улучшать возможности модели и расширять этапы обучения.
- Если кривые обучения и проверки имеют фокусную точку, вам может потребоваться использовать методы ранней остановки.
Подобные графики часто строятся для детализации и сравнения различных подходов к повышению производительности модели.
Эти диаграммы, возможно, являются вашим самым ценным диагностическим инструментом.
Еще один полезный метод диагностики — изучение выборок, которые модель предсказала правильно или неправильно.
В некоторых случаях этот метод может дать вам некоторые идеи.
- Возможно, вам нужно больше непредсказуемых выборочных данных
- Может быть, вы можете удалить простые в освоении примеры из обучающего набора
- Может быть, вы можете целенаправленно обучать разные модели на разных типах входных данных.
Связанное чтение:
- Используйте Keras, чтобы показать процесс обучения модели глубокого обучения
- Переоснащение и недообучение алгоритмов машинного обучения
2) Инициализация весов
Существует эмпирическое правило: инициализируйте веса небольшими случайными числами.
На самом деле этого может быть достаточно. Но лучший ли это выбор для вашей сетевой модели?
Различные функции активации также могут иметь разные стратегии совладания, но я не припоминаю каких-либо существенных различий на практике.
保持你的模型结构不变,试一试不同的初始化策略。
Помните, значения веса — это параметры, на которых необходимо обучать вашу модель. Несколько наборов разных значений веса могут дать хорошие результаты, но вы хотите получить лучшие результаты.
- Попробуйте все методы инициализации, чтобы найти лучший набор значений инициализации.
- Попробуйте предварительное обучение с помощью неконтролируемых методов, таких как автоэнкодеры.
- Попробуйте использовать существующий набор параметров веса модели, а затем переобучите входной и выходной слои (перенос обучения).
Помните, что изменение значения инициализации веса эквивалентно изменению функции активации или целевой функции.
Связанное чтение:
3) Скорость обучения
Регулировка скорости обучения также может привести к улучшениям.
Вот несколько идей для изучения:
- Попробуйте очень большие, очень маленькие скорости обучения
- Поиск с сеткой вокруг обычных значений по ссылке
- Попробуйте использовать прогрессивно меньшие скорости обучения
- Попробуйте скорость обучения, которая затухает на каждом фиксированном шаге обучения
- Попробуйте увеличить значение вектора, а затем выполнить поиск по сетке.
Более крупные сетевые модели требуют больше шагов обучения и наоборот. Если вы добавите больше нейронных узлов и слоев сети, увеличьте скорость обучения.
Скорость обучения связана с этапами обучения, размером партии и методом оптимизации.
Связанное чтение:
- Настройка скорости обучения для моделей глубокого обучения с помощью Keras
- Какую скорость обучения следует использовать для алгоритма обратного распространения?
4) Функция активации
Возможно, вам следует использовать функцию активации ReLU.
Просто потому, что они работают лучше.
sigmoid и tanh были популярны до ReLU, потом softmax, linear и sigmoid функции выходного слоя. Кроме этого, я не рекомендую пробовать другие варианты.
Попробуйте все три функции и не забудьте нормализовать входные данные в соответствии с их диапазоном.
Очевидно, вам нужно выбрать передаточную функцию, исходя из формы вывода.
Например, измените сигмовидную функцию бинарной классификации на линейную функцию задачи регрессии, а затем повторно обработайте выходное значение. В то же время может потребоваться корректировка подходящей функции потерь. Найдите больше идей в главе «Преобразование данных».
Связанное чтение:
- Зачем использовать функции активации?
5) Топология сети
Также может помочь настройка топологии сети.
Сколько узлов вам нужно спроектировать и сколько уровней сети вам нужно?
Хватит спрашивать, черт его знает сколько.
Вы должны найти разумный набор параметров самостоятельно.
- Попробуйте добавить скрытый слой с большим количеством узлов (расширение)
- Попробуйте глубокую нейронную сеть с меньшим количеством узлов на слой (глубину).
- Попробуйте комбинацию из двух вышеперечисленных
- Попытка имитировать недавно опубликованные статьи с похожими проблемами
- Попробуйте топологические паттерны и классические приемы из книги (см. ссылки ниже)
Это сложная проблема. Чем крупнее сетевая модель, тем сильнее выразительная сила, возможно, вам нужна именно такая.
Больше утренних структур дает возможность более структурированных комбинаций абстрактных признаков, и, возможно, вам тоже нужна такая сеть.
Более поздние сетевые модели требуют большего количества процессов обучения, а размер шага обучения и скорость обучения необходимо постоянно корректировать.
Связанное чтение:
Следующие ссылки могут дать вам некоторые идеи:
- Сколько слоев должна быть моя сетевая модель?
- Сколько узлов я должен спроектировать в своей сетевой модели?
6) партия и эпоха
Размер пакета определяет значение градиента и частоту обновления весов. Эпоха означает, что все образцы в обучающем наборе участвуют в одном раунде обучения в пакетном порядке.
Вы пробовали разные размеры пакетов и количество эпох?
В предыдущем разделе мы обсудили взаимосвязь между скоростью обучения, размером сети и номером эпохи.
В моделях глубокого обучения часто используются небольшие партии, большие эпохи и повторное обучение.
Это может помочь с вашим вопросом.
- Попробуйте установить размер пакета равным размеру всего обучающего набора (пакетное обучение).
- Попробуйте установить размер пакета равным 1 (онлайн-обучение)
- Попробуйте мини-пакеты разных размеров (8, 16, 32, ...) с поиском по сетке
- Попробуйте тренироваться еще несколько эпох, а затем продолжайте тренироваться еще много эпох.
Попробуйте установить примерно бесконечное количество эпох, а затем сделайте снимок некоторых промежуточных результатов, чтобы найти модель, которая работает лучше всего.
Некоторые структуры моделей чувствительны к размеру партии. Я думаю, что многослойные персептроны очень нечувствительны к размеру пакета, в то время как LSTM и CNN очень чувствительны, но это вопрос личного мнения.
Связанное чтение:
- Что такое пакетное обучение, добавочное обучение и онлайн-обучение?
- Интуитивно понятно, как размер мини-пакета влияет на производительность (стохастического) градиентного спуска?
7) Обычный срок
Регуляризация — отличный способ преодолеть переоснащение обучающих данных.
В последнее время популярным методом регуляризации является отсев. Вы пробовали его?
Методы исключения случайным образом пропускают некоторые нейронные узлы во время обучения, заставляя другие узлы в том же слое вступить во владение. Простой, но эффективный метод.
- Снижение веса для штрафа за большие значения веса
- предел активации для штрафа за большие значения функции активации
Попробуйте поэкспериментировать с различными штрафами и терминами штрафов, такими как L1, L2 и их сумма.
Связанное чтение:
- Регуляризация отсева моделей глубокого обучения с использованием Keras
- Что такое потеря веса?
8) Метод оптимизации и функция потерь
Раньше основным методом решения был стохастический градиентный спуск, но сейчас существует множество оптимизаторов.
Пробовали ли вы разные стратегии оптимизации?
Стохастический градиентный спуск является методом по умолчанию. Сначала используйте его, чтобы получить результат, а затем настройте различные скорости обучения и значения импульса для оптимизации.
Многие более продвинутые методы оптимизации используют больше параметров, имеют более сложную структуру и быстрее сходятся. Это зависит от вашей проблемы, у каждого есть свои плюсы и минусы.
Чтобы максимально использовать потенциал существующих методов, вам действительно нужно углубиться в каждый параметр, а затем использовать поиск по сетке для проверки различных значений. Процесс трудоемкий и трудоемкий, но попробовать стоит.
Я обнаружил, что более новые/более популярные методы сходятся быстрее и дают быстрое представление о потенциале определенной топологии сети, например:
- ADAM
- RMSprop
Вы также можете изучить другие алгоритмы оптимизации, такие как более традиционные алгоритмы (Левенберга-Марквардта) и более новые алгоритмы (генетические алгоритмы). Другие методы могут дать хороший старт SGD и облегчить последующую настройку.
Функция потерь, которую необходимо оптимизировать, более актуальна для проблемы, которую необходимо решить.
Однако есть некоторые общие приемы (такие как MSE и MAE для задач регрессии), и изменение функции потерь иногда может принести неожиданные выгоды. Опять же, это также может быть связано с масштабом ваших входных данных и используемой функцией активации.
Связанное чтение:
- Обзор алгоритмов оптимизации градиентного спуска
- Что такое сопряженные градиенты и Левенберг-Марквардт?
- Методы оптимизации для глубокого обучения, 2011 г.
9) Ранняя остановка
Вы можете остановить обучение, когда производительность модели начнет ухудшаться.
Это экономит нам много времени, возможно, позволяя нам использовать более точные методы передискретизации для оценки модели.
Ранняя остановка также является методом регуляризации для предотвращения переобучения данных, требуя от вас наблюдения за производительностью модели на обучающих и проверочных наборах после каждого раунда обучения.
Как только производительность модели на проверочном наборе снизилась, обучение можно остановить.
Вы также можете установить контрольные точки, сохранить состояние на тот момент, и модель сможет продолжить обучение.
Связанное чтение:
- Как установить контрольные точки для моделей глубокого обучения в Keras
- Что такое ранняя остановка?
4. Используйте метод слияния для усиления эффекта
Вы можете объединить прогнозы из нескольких моделей.
После настройки модели это еще одна большая область улучшений.
Фактически, результаты прогнозирования нескольких моделей с хорошей производительностью часто объединяются, и эффект лучше, чем у нескольких точно настроенных моделей.
Рассмотрим три основных направления слияния моделей:
- слияние моделей
- Перспективное слияние
- stacking
1) Слияние моделей
Вместо того, чтобы выбирать модель, интегрируйте их.
Если вы обучаете несколько моделей глубокого обучения, и каждая из них работает хорошо, усредните их прогнозы.
Чем больше разница в моделях, тем лучше эффект. Например, вы можете использовать очень разные сетевые топологии и методы.
Если каждая модель независима и достоверна, результат после ансамбля более стабилен.
И наоборот, вы можете провести эксперимент в обратном порядке.
Каждый раз, когда сетевая модель обучается, она инициализируется по-разному, и конечные веса также сходятся к разным значениям. Повторите этот процесс несколько раз, чтобы сгенерировать несколько сетевых моделей, а затем интегрируйте предсказания этих моделей.
Их прогнозы будут сильно коррелированы, но, возможно, немного лучше для более сложных для прогнозирования выборок.
Связанное чтение:
- Интеграция алгоритмов машинного обучения с scikit-learn
- Как повысить производительность машинного обучения
2) Перспективное слияние
Как упоминалось в предыдущем разделе, обучайте модель с другой точки зрения или заново охарактеризуйте проблему.
Наша цель по-прежнему состоит в том, чтобы получить полезные модели, но другим способом (например, некоррелированные предсказания).
Вы можете применять совершенно разные методы масштабирования и преобразования к обучающим данным на основе методов, упомянутых выше.
Чем больше разница между выбранным методом изменения и углом характеристики проблемы, тем больше возможность улучшения эффекта.
Просто взять среднее значение прогнозов — хорошая идея.
3) укладка
Вы также можете научиться объединять прогнозы отдельных моделей.
Это называется обобщением с накоплением или просто суммированием.
Как правило, веса прогнозов отдельных моделей можно узнать с помощью простой линейной регрессии.
Метод усреднения результатов прогнозирования каждой модели используется в качестве базовой линии, а взвешенное слияние используется в качестве экспериментальной группы.
Суммировать
Нет
дополнительные материалы
Есть также очень хороший материал, но не такой исчерпывающий, как эта статья.
Я перечислил некоторые материалы и связанные статьи ниже, вы можете прочитать подробно, если вам интересно.