Введение в Tensorflow для начинающих

TensorFlow

Примечание. Это переведенная статья, оригинальный адрес:к data science.com/ah-beginner-…

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

Основная цель этой статьи — ознакомить новичков с TensorFlow. Я предполагаю, что вы уже знакомы с Python. Основными компонентами TensorFlow являются вычислительные графы и тензоры, которые проходят через все узлы через ребра. Давайте кратко представим их один за другим.

Тензор (тензор)

image

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

image

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

Расчетный график (поток, поток)

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

image

На приведенном выше рисунке показан простой расчетный график, и соответствующее выражение:

e = (a+b)x(b+1)

Вычислительные графы обладают следующими свойствами:

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

  • Вычислительные графы всегда выражают сложные операции в иерархическом порядке. Приведенное выше выражение можно организовать иерархически, обозначив a + b как c и b + 1 как d. Следовательно, мы можем написать е как:

e = (c)x(d) 这里 c = a+b 且 d = b+1.
  • Пройдите по графу в обратном порядке, чтобы сформировать подвыражения, которые объединяются в окончательное выражение.

  • Когда мы продвигаемся вперед, встречающиеся вершины всегда становятся зависимостями следующей вершины, например, c нельзя получить без a и b, и аналогично e нельзя получить без решения c и d.

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

Параллелизм в вычислительных графах

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

распределенное исполнение

Tensorflow позволяет пользователям выполнять операции быстрее, используя параллельные вычислительные устройства. Вычислительные узлы или операции автоматически планируются для параллельных вычислений. Все это происходит внутри, например, на диаграмме выше операция c может быть запланирована на CPU, а операция d на GPU. На следующем рисунке показан процесс двух распределенных исполнений:

image

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

Вычислительный подграф

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

image

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

image

На приведенной выше диаграмме объясняется параллельное выполнение подграфов. Здесь есть 2 умножения матриц, потому что они оба находятся на одном уровне и независимы друг от друга, что соответствует последнему свойству. Узлы расположены на разных устройствах gpu_0 и gpu_1 из-за независимости.

обмен данными между работниками

Теперь мы знаем, что Tensorflow распределяет все свои операции по разным устройствам, управляемым воркерами. Чаще всего данные в виде тензоров обмениваются между рабочими, например, в графе e = (c) * (d), после вычисления c его необходимо передать в e, поэтому Tensor находится перед узлами. течь. Поток показан на рисунке:

image

Здесь тензоры передаются от устройства A к устройству B. Это вызывает некоторые задержки производительности в распределенных системах. Задержка зависит от одного важного свойства: размера тензора. Устройство B находится в режиме ожидания, пока не получит ввод от устройства A.

Необходимость сжатия

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

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

сжатие с потерями

Сжатие с потерями включает в себя размер сжатых данных и не заботится о его значении, что означает, что его значение может быть повреждено или неточным в процессе сжатия. Однако если у нас есть 32-битное число с плавающей запятой, такое как 1.01010e-12, оно менее важно для младших значащих цифр. Изменение или удаление этих значений не будет иметь большого значения в наших расчетах. Поэтому Tensorflow автоматически преобразует 32-битное представление с плавающей запятой в 16-битное представление, игнорируя все незначительные числа. Если он 64-битный, его размер уменьшится почти вдвое. Если вы сожмете 64-битное до 16-битного, оно будет почти на 75% меньше. Поэтому пространство, занимаемое тензорами, можно максимально сократить.

Как только тензор достигает узла, 16-битное представление можно вернуть к исходной форме, добавив 0. Таким образом, 32- или 64-битное представление будет восстановлено после достижения узла для обработки.


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