предисловие
После использования отличных систем компиляции и оптимизации машинного обучения, таких как TVM и TensorRT, а также сред глубокого обучения, таких как Pytorch и Keras, я всегда чувствую, что необходимотеоретическиНекоторый анализ этих систем, хотя и говорится, что обучение на практике является самым быстрым и прямым (ссылаясь на то, где бороться, где не проверять), но все же очень полезно дополнить некоторые знания о конструкции системы, правильно следует быть Консолидация некоторых основ.
Поэтому необходимо научиться понимать устройство и мышление систем машинного обучения. Если вы мало что знаете о проектировании систем машинного обучения, вы можете прочитать ответ на этот вопрос на Zhihu:По сравнению с исследованиями алгоритмов ИИ уменьшились ли исследования компьютерных систем?
Вот источник примечаний к этой серии статей:
Обратите внимание, что эта серия статей не является традиционным объяснением глубокого обучения или машинного обучения.Для объяснения этой части вы можете посмотреть вводный курс CS231n или Wu Enda.Эта серия статей подходит для детей с опытом и пониманием глубокого обучения .
прикреплен одинCSE 599WОбъяснение в начале этого курса (во главе с идолом Ткченом):
Основное внимание в этом курсе уделяется не теоретическим алгоритмам глубокого обучения, а системам глубокого обучения и машинного обучения.
Что такое глубокое обучение
Коротко о глубоком обучении.
Как видно из рисунка выше, основное содержание глубокого обучения состоит из следующих четырех частей:
- Дизайн модели (в основе своей модели, предназначенные для разных задач, разные, и конкретные используемые алгоритмы тоже разные)
- Целевая функция, стратегия обучения (целевая функция, используемая для обучения весовых параметров модели, то есть функция потерь, и некоторые методы обучения)
- Регуляризация и инициализация (связаны с информацией о весе модели в процессе обучения, ускоряют сходимость обучения и относятся к обучающей части)
- Достаточно данных (машинное обучение или глубокое обучение управляется данными, без данных это ничто)
В процессе изучения глубокого обучения у нас неизбежно будет некоторая практика, поэтому мы используем следующие отличные библиотеки глубокого обучения для реализации модели, которую мы разработали сами, и разрабатываем функцию потерь, некоторые стратегии регуляризации и, наконец, используем эти библиотеки для чтения. данные нам нужно заново подключить, а потом запустить и ждать.
Мы все должны быть знакомы с этими превосходными библиотеками глубокого обучения (caffe, Mxnet, TF, Pytorch), так какова общая структура этих библиотек глубокого обучения?
Большинство библиотек глубокого обучения состоят из следующих трех частей.
- Пользовательский API
- Системные компоненты
- базовая архитектура
Большинству из нас на самом деле не нужно касаться двух других частей, кроме пользовательского API, который также является частью верхнего уровня библиотеки глубокого обучения.
Logistic Regression
Рассмотрим пример, чтобы кратко рассказать об API пользователя. Прежде всего, у нас есть задача логистической регрессии. Возьмем для демонстрации самый знакомый набор данных MNIST. Мы вводим векторизованные данные каждого числа, а затем вычисляем их через полносвязный layer.vector и используйте функцию softmax для прогнозирования. Вся сетевая модель очень проста и имеет полносвязный слой.
Далее мы рассмотрим использование numpy иtinyflow(Это мини-библиотека системы глубокого обучения, хотя воробей маленький и полноценный, его стоит изучить) Для обучения простой нейронной сети распознавать пример базы данных рукописного ввода MNIST:
в приведенном выше кодесамое важноеТо есть есть три части (перечислены в правой части рисунка выше):
- Прямое вычисление: поскольку существует только один полносвязный слой, наши вычисления также просты.,вдля входных данных,это вес,является результатом скалярного произведения вектора весов и вектора данных. После вычисления результата мы используем функцию softmax для классификации и вычисления вектора вероятности, соответствующего десяти числам (конечный выходной вектор содержит 10 элементов, которые являются вероятностью каждого числа)
- Обратный вывод: Находим производную веса W по максимальному вероятностному проигрышу, здесь выписываем ее вручную, во второй части правого рисунка
- Обновление градиента: мы просто обновляем вес W, а значение обновления представляет собой градиент скорости обучения, умноженный на W, то есть, то есть SGD, который мы часто используем
Наиболее важными частями всей библиотеки глубокого обучения являются указанные выше три части.Большинство библиотек глубокого обучения уже реализовали для нас приведенный выше код.Нам не нужно повторять колесо и использовать его напрямую.
Попробуйте использовать TensorFlow как API
Далее мы используем API, аналогичный TensorFlow, для рефакторинга кода, описанного выше, и используем формат API TensorFlow для реализации процесса обучения, реализованного приведенным выше кодом.
Так зачем использовать для демонстраций API типа TensorFlow вместо Pytorch? На самом деле типы графиков, построенных TensorFlow и Pytorch, сильно отличаются, хотя TensorFlow появился совсем недавно.eager mode
, но классический TensorFlow использует статический граф для построения всего процесса обучения.
То есть статические графики строятся в TF, а динамические — в Pytorch:
На самом деле, было много дискуссий на эту тему о статических графиках и динамических графиках.Динамические графики гибкие и изменяемые, в то время как статические графики не такие гибкие, как динамические графики, а потому что входные параметры, методы расчета и другие процессы определяется заранее, система может планировать расчет по этим характеристикам, поэтому производительность в процессе расчета выше, чем у динамического графа.
Во-первых, мы определяем форвардные данные, которые должны быть выполнены, и оператор операции:
- Вход x является вектором типа float32, а None в [None,784] указывает, что размер пакета текущего ввода неизвестен.
- W - информация о весе, размерность [784,10]
- y — функция прямого вычисления, и весь процесс вычисления определяется вложением операторных функций.
Далее задается функция потерь, как видите
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y), reduction_indices=[1]))
В этом предложении объявляется функция потерь, которая использует наиболее часто используемые кросс-энтропийные потери в задачах классификации.Обратите внимание, чтоy_
Представляет метку классификации, в которой хранятся данные. Метка классификации каждых данных представляет собой вектор из 10 элементов, который используется для сравнения с прогнозируемым значением. Конкретная формула находится в правой части рисунка ниже.
Далее задается процесс автоматического вывода.На этом шаге нам требуется градиент вектора веса к значению потери (то есть значение, рассчитанное после потери перекрестной энтропии).Здесь мы просто объявляем функцию, но Расчет Процесс относительно сложный (то есть процесс автоматического вывода, о котором мы часто говорим), который будет объяснен позже Автоматический вывод - это то, что мы должны освоить, и необходимы прямые ручные манипуляции.
После настройки функции потерь мы будем использовать рассчитанное значение градиента для обновления информации о весе сети. В этом примере мы используем метод стохастического градиентного спуска SGD для обновления веса. Нам нужно только установить скорость обучения. Параметры могут быть.
Потому что в TF все декларативные выражения просто объявляют процесс вычисляемым, а вычисления нет (здесь можно назвать метод ленивого вычисления), то есть так называемый метод статического графа определяет всю сеть и шаги обучения, просто не начинай работать.
после бегаsess.run
После одного предложения вся сеть начала формально реализовываться.
Содержимое этих ppts описывает рабочий процесс типичной библиотеки нейронной сети (тип TF, немного другой, если это Pytorch), благодаря которому мы можем узнать основную роль среды глубокого обучения. Следующее, о чем следует поговорить, — это самый важный процесс автоматического деривации в описанном выше процессе.
Расчетный график
Вычислительный граф является основой для автоматического вывода, а также частью каждой среды глубокого обучения, которая должна быть реализована.Далее давайте кратко поговорим о том, что такое вычислительный граф?
Говоря о вычислительных графах, давайте кратко упомянем декларативное программирование. Как показано на рисунке ниже, вычислительные графы по сути являются декларативным языком. Как бы это сказать более уместно. Этот язык отличается от того, что мы обычно называем python и C++, это DSL (доменный язык) или мини-язык, который глубоко встроен в Python и C++, то есть мы используем Python для работы и C++ для реализации.
Вместо того, чтобы просто выполнять наши инструкции одну за другой, декларативное программирование создает вычислительный граф из всех инструкций, которые мы даем. Этот граф внутренне оптимизирован и скомпилирован в исполняемый код C++. Таким образом, мы можем использовать лучшее из обоих миров: скорость разработки, которую обеспечивает Python, и скорость выполнения, которую обеспечивает C++.
Конечная форма заключается в том, что мы заранее задаем логику расчета, а все остальное оставляем системе, нам не нужно беспокоиться о том, как ее оптимизировать.
Следующий рисунок является простым примером, мы определяем логику расчетаa*b+3
Эта логика, где узлы представляют содержимое вычислений, а стрелки представляют зависимости.
На рисунке ниже мы используем TF-подобный API для реализации простогоДанные (x, W) и операторы (matmult, softmax), необходимые для этого процесса, были определены заранее.
Далее следует вычислительная часть настройки функции потерь:
Затем настройте часть градиентного спуска, связанную с автоматическим выводом:
Далее показано, как установить обновление градиента:
После настройки и воспроизведения всей логики расчета здесь официально начинается процесс расчета, и только после завершения выполненияsess.run
После этого предложения весь график вычислений начинает фактически вычисляться.
Конкретный процесс автоматического вывода выше не показан. Этот процесс будет объяснен в следующем разделе, но конкретный процесс автоматического вывода также можно увидеть в курсе CS231n, в частности, вBackpropagation and Neutal Networksв этой секции.
Сравнение numpy и TF-программы
Раньше мы использовали numpy и TF-подобный API для моделирования простого процесса логистической регрессии, то есть для реализации процесса использования простой полностью подключенной сети для распознавания рукописного набора цифр MNIST, В этом процессе мы использовали два разных способа построить, в терминах вычислительного графа, этоДинамический график (numpy) и статический график (TF), а с точки зрения типа языка этоИмперативное программирование (numpy) и декларативное программирование (TF).
На самом деле приведенный выше пример с numpy также можно продемонстрировать с помощью Pytorch, потому что Pytorch — это numpy-подобная библиотека глубокого обучения, и операторная логика ее работы почти такая же, как у numpy, Можно сказать, что это домен язык с динамической структурой графа.
То есть сравнение между numpy и TF-программой может быть эквивалентно сравнению динамических графиков и статических графиков, Оба имеют свои преимущества и недостатки, но если вы преследуете производительность и эффективность разработки, статические графики лучше, но если Вы стремитесь к гибкости. Тогда преимущества динамических графиков раскрываются.
Продолжение следует
В конце этого класса предлагается некоторое последующее содержание, и первым из них является оптимизация вычислительных графов.
Оптимизация вычислительного графа занимает большое место в этом компиляторе глубокого обучения в TVM.Как упоминалось ниже, мы строим вычислительный граф, поскольку этот вычислительный граф является статическим, мы можем максимально оптимизировать его на нижнем уровне., чтобы ускорить наладить работу нейросети, так как же ее оптимизировать? Это большой вопрос, короче говоря, у нас есть много возможностей для оптимизации, а конкретные детали оптимизации будут описаны позже.
Другое дело, что параллелизм данных также является одной из ключевых проблем, требующих решения.Ведь данных становится все больше и больше.Хотя вычислительная мощность видеокарт с каждым годом улучшается, улучшение памяти (конкретно видеопамяти) ограниченное. Итак, как эффективнее и быстрее обучать большой объем данных, прямой путь — параллельное распределенное обучение, и как бороться с проблемами, возникающими при параллелизме, — тоже ключевое направление.
Связанные ссылки
dlsys.cs.washington.edu/schedule UC Brise.GitHub.IO/294 в это время очень нравится… blog.CSDN.net/Алекс/Аретти…
дразни меня
- Если вы единомышленники со мной, Лао Пан очень хочет общаться с вами;
- Если вам нравится контент Лао Пана, подпишитесь и поддержите его.
- Если вам понравилась моя статья, надеюсь, она вам понравится? Избранное ? Комментарии ? Три в ряд~
Я хочу знать, как Лао Пан научился наступать на яму, и я хочу обменяться со мной вопросами ~ Пожалуйста, обратите внимание на публичный аккаунт "старый блог". Лао Пан также организует некоторые из своих частных коллекций, надеясь помочь всем, нажмитеТаинственный порталПолучать.