Это 9-й день моего участия в ноябрьском испытании обновлений, подробности о событии:Вызов последнего обновления 2021 г.
Эта статья предназначена в основном для статей о EMNLP2021.Raise a Child in Large Language Model: Towards Effective and Generalizable Fine-tuningОбъяснять. Название статьи несколько абстрактно, но, по словам авторов, суть статьи можно свести к двум словам:Child Tuning
Хотя эта статья в основном нацелена на задачи НЛП и модели, связанные с НЛП, на самом деле, прочитав ее, я чувствую, что это общий метод, который также можно использовать в области CV. Конкретно параметры текущей предобученной модели очень велики.В нисходящих задачах мы можем использовать только ограниченный обучающий набор для тонкой настройки модели.Ощущение руки человека как автомобиля,поэтому автор предлагает новый метод тонкой настройки——Child Tuning. Если бы я мог подытожить это одним предложением, это было бы:В процессе обратного распространения нам не нужно обновлять все параметры, только некоторые параметры, и структура сети, соответствующая этим обновленным параметрам, называется дочерней сетью (подсетью)
Как показано на рисунке выше, верхняя линия — это нормальный процесс обратного распространения, где
Нижний индекс 0 не относится к определенному параметру, а относится к процессу 0-й итерации,это скорость обучения. Для следующей строкиЧасть его была удалена MASK, что привело к градиенту 0.
в,Элементы в матрице либо 0, либо 1,Это умножение соответствующих позиций элементов в матрице. Мы можем суммировать процесс дочерней настройки в два этапа:
- Откройте и подтвердите дочернюю сеть в предварительно обученной модели и сгенерируйте 0-1 MASK, соответствующую весам.
- После того, как обратное распространение вычисляет градиент, обновляются только параметры в дочерней сети.
Итак, теперь вопрос в том, как подтвердить дочернюю сеть?
How to find Child Network?
На самом деле нам не нужно искать дочернюю сеть, достаточно определить матрицуВот и все. В статье представлены два алгоритма построения матриц, которые являются независимым от задачи алгоритмом Child_Tuning_F (F для Task-Free) и алгоритм Child_Tuning_D (D для Task-Drivern)
Child_Tuning_F
Алгоритм, независимый от задачи, означает, что он не имеет ничего общего с конкретными задачами, которые вы выполняете, и вы можете использовать этот алгоритм, который является общим методом. Конкретно в это время**генерируется из распределения Бернулли**
в— это гиперпараметр, управляющий размером дочерней сети, если, дочерняя сеть — это исходная сеть, а дочерняя настройка — это точная настройка; если, никакие параметры не будут обновлены. Ниже приведен простой код моделирования, который я написал, чтобы помочь вам понять
import torch
from torch.distributions.bernoulli import Bernoulli
gradient = torch.randn((3, 4)) # 这里用一个随机生成的矩阵来代表梯度
p_F = 0.2
gradient_mask = Bernoulli(gradient.new_full(size=gradien.size(), fill_value=p_F))
gradient_mask = gradient_mask.sample() / p_F # 除以p_F是为了保证梯度的期望不变
print(gradient_mask)
gradient *= gradient_mask
print(gradient)
Bernoulli
это класс, который генерируетgradient_mask
является объектом, нам нужно вызвать этот объектsample()
метод получения матрицы. Одним из наиболее важных моментов является то, что хотя мы получили МАСКУ 0-1, нам нужно расширить все единицы в этой МАСКЕ.раз, чтобы сохранить ожидаемое значение градиента
Другие градиенты исчезли, а живой градиент должен быть размножен с помощью сильного желания других!
Child_Tuning_D
Учитывая существование различных последующих задач, автор предлагает алгоритм Child_Tuning_D для конкретной задачи, который может определять наиболее важные подсети (или параметры) для целевой задачи. В частности, авторы используютИнформационная оценка Фишерачтобы найти параметры, которые очень важны для конкретной последующей задачи. Формально параметры моделиИнформационная матрица Фишера (FIM) определяется следующим образом:
в,являются входом и выходом, соответственно, из которых мы можем получить первоеИнформация Фишера для каждого параметра выглядит следующим образом:
в,- количество всех выборок. Автор считает, что чем важнее параметры для целевой задачи, тем больше информация Фишера.Поэтому дочерняя настройка состоит из тех параметров с самой высокой информацией Фишера.В настоящее время доля дочерней сети составляет
впредставляет собой не подсеть, когдаВ то время Child Tuning выродился в Fine Tuning. На самом деле вычисление информации Фишера довольно трудоемко.Если мы вычисляем информацию Фишера всех параметров после каждого обратного распространения, а затем находим самые большие первые несколько, это очень хлопотно, поэтому автор предлагаетПрежде чем приступить к обучению, мы сначала выполняем полное (одну эпоху) прямое распространение и обратное распространение для всех образцов.В это время рассчитываются параметры с самой высокой информацией Фишера, и определенная в это время дочерняя сеть не изменится в будущее. , то, что будет выбрано на этот раз, будет иметь преимущественную силу.
Код для расчета информации Фишера приведен ниже.
def calculate_fisher():
gradient_mask, p_F = {}, 0.2
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size, shuffle=True)
N = len(train_dataloader) # N = |D|
for name, params in model.named_parameters():
if 'layer' in name:
gradient_mask[params] = params.new_zeros(params.size())
for batch in train_loader:
outpus = model(**batch)
loss = outpus['loss'] if isinstance(outpus, dict) else outputs[0]
loss.backward()
for name, params in model.named_parameters():
if 'layer' in name:
torch.nn.utils.clip_grad_norm(params, 1)
gradient_mask[params] += (params.grad ** 2) / N
model.zero_grad()
r = None
for k, v in gradient_mask.items():
v = v.view(-1).cpu().numpy() # flatten
if r is None:
r = v
else:
r = np.append(r, v)
# polar = np.percentile(a, q) # a中有q%的元素小于polar
polar = np.percentile(r, (1-p_F)*100)
for k in gradient_mask:
gradient_mask[k] = gradient_mask[k] >= polar
print('Polar => {}'.format(polar))
return gradient_mask
Proof
Если в этой статье говорится об этих вещах, есть большая вероятность, что вы не сможете выиграть EMNLP.Я лично думаю, что это связано с большим количеством доказательств в этой статье.Автор доказывает, что использование Child Tuning может помогите модели избежать локальных экстремумов Небольшое значение, затем я попытаюсь уточнить часть доказательства статьи
Сначала мы предполагаемзаданный образецпараметр времениградиент , и он следует нормальному распределению,определение, то есть
за,У нас есть
Предполагать,вдаили(в зависимости от того, какой алгоритм вы используете), то
Вывод приведенной выше формулы не является строгим, например, молекулярнаяНевозможно объяснить, откуда он взялся, молекулярныйтолько возможнорезультат, ноЭто матрица, как ожидание матрицы может стать числом? Но принуждать к объяснению нормально, потому чтосложите все единицы и разделите наВсе элементы внутри также кажутся равнымииз
Предполагатьсоответственнопервоезначение в измерении, то есть
следовательно
В итоге мы получаем
В частности, когда параметрПри тренировке до точки локального минимума,,В настоящее время, мы заметилиэто оубывающая функция ,чем большеменьше, крайний случай, в это время Детская настройка вырождается в Точную настройку, иМинимальное значение эквивалентно его небольшому изменению каждый раз, поэтому выскочить из точки локального минимума сложно;чем меньшеЧем больше значение, тем больше количество изменений каждый раз, поэтому легче выпрыгнуть из точки локального минимума.
Персональное резюме
Когда я впервые прочитал эту статью, я подумал, что она очень мощная, но после того, как я на самом деле понял ее, я почувствовал, что на самом деле это версия Dropout с обратным распространением. этот документ. Тогда в статье действительно много экспериментов.Результаты экспериментов показывают, что по сравнению с Fine Tuning его можно улучшить примерно на 1,5–8,6 балла. Наконец, я хочу поговорить о части этой статьи, посвященной доказательству формулы.Я лично думаю, что доказательство этой статьи не очень строгое, например, почему математическое ожидание становится числом. В общем, этот способ можно использовать как Уловку при игре в игры.