1. Автоматическая дифференциация и версия мышления tf
написать впереди
Вы также можете видеть из недавнего блога, что я недавно узнал о контенте, связанном с интерфейсом и сервером. Будь то по причинам проекта или по личным причинам, я давно не писал на python, и я не касался содержания машинного обучения и глубокого обучения, Иногда я вижу некоторые из последних бумажных методов, продвигаемых публичной учетной записью, и нет больше волн в моем сердце. В последнее время все потихоньку устаканилось.Если вы хотите заниматься академическими науками (водная работа), вам не избежать этого, поэтому я планирую заново изучить глубокое обучение в основном из-за использования фреймворков. Соответствующие очки знаний будут дополняться в зависимости от ситуации, поэтому, если есть друзья, которые хотят начать работу с глубоким обучением и мало знают об использовании фреймворка, мы можем учиться и общаться вместе, и вы можете получить что-то из этой колонки.
Фреймворк, задействованный на этот раз, по-прежнему остается мейнстримом.tensorflow 2.X
иpytorch
, конкретное содержание представляет собой сводку различных онлайн-материалов, таких как Huashu, d2l, вводные учебные пособия, официальные документы... Порядок такой: сначала выучить tf, а затем pytorch, снова объяснитьОсновное внимание по-прежнему уделяется использованию API-интерфейса фреймворка.Что касается части, связанной с базовыми знаниями, вы можете самостоятельно перейти на Huashu или d2l.
Кроме того, рекомендуется пойти на станцию B, чтобы посмотреть видео Мушена, Каждое видео не длинное, но очень четкое.
Официально начать
Прежде всего, необходимо построение среды, поскольку версия TF 2 или более, лучше всего установить версию GPU.
Первый шаг — проверить версию и доступность графического процессора.
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='1'
print(tf.__version__)
print(tf.config.list_physical_devices('GPU'))
В чем именно разница между версиями
Впервые я столкнулся с tensorflow более двух лет назад, учитель немного рассказал о глубоком обучении, а затем разрешил нам установить среду tensorflow, которая в то время была еще 1.9. Я нашел несколько примеров на github и запустил их, наиболее запоминающимся должен быть следующий код
with tf.Session(graph = g) as sess:
sess.run(...)
Когда мне посчастливилось помочь другу найти данные, которые он хотел сегодня, я также откопал код несколько лет назад в предыдущей записной книжке.
В TF1 по умолчанию используетсястатическое изображение, первый шаг — определить график расчета, а второй шаг — открыть сеанс для расчета, но вскоре после того, как я начал TF1, был выпущен TF2.0, и использование по умолчаниюдинамическое изображение, вам не нужно определять и выполнять снова, а выполнять сразу после определения, что ближе к привычке редактирования кодировщика Python.Одной из причин, почему вам нравится Python, может быть то, что вам не нужно сначалаint a=1;
но прямоa=1
. Удобство динамических графов также означает, что эффективность работы кода снижается, но это снижение все еще допустимо для удобства наших исследований и обучения.
**Причина низкой эффективности динамических графов: **После того, как статические графы определены, все они выполняются на C++ в ядре TF, а динамические графы работают в режиме реального времени, что означает, что процесс Python может взаимодействовать с процесс TF C++ для передачи данных в любое время, что, несомненно, занимает много времени, а после того, как статический граф определен, шаги расчета могут быть оптимизированы сами по себе, а динамический граф теряет эту возможность.
Ниже приведен пример расчета на динамическом графике.
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='1'
a=tf.constant(2)
b=tf.constant(1)
#c=tf.add(a,b)
c=a+b
print(c)
Функция преобразуется в статический расчетный график
Иногда для решения проблемы эффективности динамического графа добавляют@tf.function
Преобразуйте функцию в соответствующую конструкцию статического графика для вычисления
@tf.function
def my_add(x,y):
return x**2+y**2
res=my_add(a,b)
print(res)
Принято смотреть исходный код декоратора
decorated()
Внутри оставляем нужные нам функции иtf_export
Декоратор снова украшает, чтобы стать функцией окончательного построения режима статического графа.
здесь финалpartial()
В файле .pyi, который является файлом-заглушкой, статические типы уже определены.
наконец начните различать
Причина, по которой мы используем фреймворки глубокого обучения, или основная функция этих фреймворков, заключается в решении дифференциальных задач. После того, как мы изучили градиентный спуск и обратное распространение, мы должны знать, что для обновления параметров нейронной сети мы должны вычислить градиент каждого слоя при обратном распространении, а в градиентах без функции дифференцирования не обойтись.
В ТФ мы используемtf.GradientTape
Положительная передача, затем автоматический дифференциальный градиент. Сначала зайдите и посмотрите пример
import tensorflow as tf
# 输入一个x
x=tf.Variable(int(input()),dtype=tf.float32)
# 首先设计待微分函数 y=5x^3+3x^2-8x+10
@tf.function
def f():
a=tf.constant(5.0)
b=tf.constant(3.0)
c=tf.constant(-8.0)
with tf.GradientTape() as tape:
tape.watch(x)
y=a*tf.pow(x,3)+b*tf.pow(x,2)+c*x+10
dy_dx=tape.gradient(y,x)
tf.print(dy_dx)
return y
# 打印微分结果
f()
Забудьте о декораторахtf.funtion
Роль того, что в режиме динамического графикаtf.GradientTape
Как найти градиент?
Если вы сомневаетесь, нажмите здесь, чтобы увидеть исходный код
Основная часть кодаimperative_grad.imperative_grad()
Раздел функций, продолжайте нажимать для просмотра
Ознакомьтесь с функциями в этой связанной библиотекеnm -D xxx.so
В конце концов, это должен быть интерфейс, реализующий здесь вычисление градиента.Но когда мы его используем, нам не нужно учитывать, является ли нижележащий слой символьным выводом, числовым выводом, прямым или обратным режимом., вот я как раз сегодня поковырялся кстати.
Дифференцировать, чтобы найти минимум
Конечной целью глубокого обучения является минимизация функции потерь, или же она сводится к проблеме нахождения минимального значения. В tensorflow также предоставляется ряд оптимизаторов для оптимизации параметров и минимизации функции потерь. Используя приведенный выше пример, мы находим минимальное значение этой функции.
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='1'
# 输入一个x
x=tf.Variable(int(input()),dtype=tf.float32)
# 首先设计待微分函数 y=5x^3+3x^2-8x+10
@tf.function
def f():
a=tf.constant(5.0)
b=tf.constant(3.0)
c=tf.constant(-8.0)
with tf.GradientTape() as tape:
tape.watch(x)
y=a*tf.pow(x,3)+b*tf.pow(x,2)+c*x+10
dy_dx=tape.gradient(y,x)
tf.print(dy_dx)
return y
# 打印微分结果
f()
# 寻找函数最小值
# global_step = tf.Variable(100)
# lr=tf.compat.v1.train.exponential_decay(0.01,global_step=global_step,decay_rate=0.8,decay_steps=10)
lr=0.01
optimizer=tf.keras.optimizers.SGD(learning_rate=lr)
for _ in range(100):
optimizer.minimize(f,x)
print(f().numpy(),x.numpy())
Введите 3, результат будет следующим
Вроде бы хорошо, но что если я введу относительно большое число, например 10
Мы видим, что градиент сначала немного падает, а затем продолжает увеличиваться, пока не перестанет соответствовать nan.
Раньше нас учили, что выбор скорости обучения очень важен: слишком маленькая будет затруднять сходимость, слишком большая — градиент взорвется, как показано на следующем рисунке.
Когда скорость обучения слишком велика, она непосредственно пересекает точку минимума, а затем градиент все время увеличивается, что можно рассматривать как интуитивное представление о влиянии скорости обучения на градиент.
Теперь, когда мы знаем, что скорость обучения слишком велика, давайте уменьшим скорость обучения и попробуем еще раз, установив lr=0,001.
Успешная сходимость, минимальное значение мало чем отличается от предыдущего. Если вы все еще заинтересованы, вы можете попробовать часть, которую я прокомментировал, и использовать скорость обучения с экспоненциальным затуханием, Эффект выглядит следующим образом
Вы также можете попробовать Адама и других оптимизаторов.Говорят, что Адам работает очень хорошо, но так ли это на самом деле?
При тех же параметрах производительность Адама не так хороша, как у SGD.
конец
Сегодня я снова начал изучать фреймворк, и я был очень взволнован.Я нашел много вещей, которые я не рассматривал раньше.В будущем прогресс должен быть ускорен, но не слишком дотошно.