Практическое глубокое обучение 3.7 краткая реализация регрессии softmax

PyTorch

Участвуйте в 10-м дне Ноябрьского испытания обновлений, узнайте подробности события:Вызов последнего обновления 2021 г.

import torch
from torch import nn
from d2l import torch as d2l
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

Обратитесь к статье, которая реализует регрессию softmax вручную:Практическое глубокое обучение 3.6 — ручная реализация регрессии softmax — самородки (juejin.cn)

Здесь будет предупреждение пользователя, вы можете просто игнорировать его, если вы действительно хотите знать, что это такоеtorchvision.transforms.ToTensor details | Предупреждение пользователя при использовании transforms.ToTensor() | Что представляет изображение HW C

net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights);
  • nn.Flatten(): PyTorch не изменяет форму входных данных неявным образом, поэтому слой сглаживания определяется перед линейным слоем для изменения формы входных данных.nn.Linear(784, 10)Укажите размерность ввода и размерность вывода и обрабатывайте по одному изображению за раз.Известное изображение имеет размер 28*28, а при преобразовании в вектор оно равно 784.
  • net.apply(init_weights)Примените эту функцию к каждому слою сетиinit_weights: эта функция
    • Определить, является ли полученный слой nn.Linear, конечноtype(m) == nn.LinearВы также можете использовать ранее упомянутыйisinstance(m,nn.Linear)
    • Если это так, инициализируйте веса слоев, чтобы установить среднее значение на 0 и дисперсию на 0,01.
loss = nn.CrossEntropyLoss()
trainer = torch.optim.SGD(net.parameters(), lr=0.1)

Потеря напрямую использует потерю перекрестной энтропии, которая идет с nn, и тренер также напрямую использует функцию SGD, которая идет с nn. для перекрестной энтропии.

num_epochs = 10
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

Эта функция обучения является функцией обучения, описанной в предыдущем разделе, поэтому она не будет перемещена сюда. ВидетьПрактическое глубокое обучение 3.6 — ручная реализация регрессии softmax — самородки (juejin.cn)

Softmax

Softmax, реализованный в предыдущем разделе, использует:

softmax(X)ij=exp(Xij)kexp(Xik).\mathrm{softmax}(\mathbf{X})_{ij} = \frac{\exp(\mathbf{X}_{ij})}{\sum_k \exp(\mathbf{X}_{ik})}.

функция softmaxy^j=exp(oj)kexp(ok)\hat y_j = \frac{\exp(o_j)}{\sum_k \exp(o_k)}y^j\hat y_jявляется прогнозируемым распределением вероятностей.ojo_jэто ненормализованный прогнозo\mathbf{o}Первыйjjэлементы. еслиoko_kНекоторые значения в очень велики, тогдаexp(ok)\exp(o_k)может быть больше, чем максимальное число, разрешенное типом данных (т.е.переполнение(переполнение)). Это заставит знаменатель или числитель статьinf(бесконечность), мы получаем 0,infилиnan(не число)y^j\hat y_j. В этих случаях мы не можем получить четко определенное возвращаемое значение кросс-энтропии.

Уловка для решения этой проблемы состоит в том, чтобы начать со всехoko_kвычестьmax(ok)\max(o_k). вы можете доказать каждомуoko_kПеремещение на константу не меняет возвращаемое значение softmax. После шагов вычитания и нормализации могут быть некоторыеojo_jимеет большое отрицательное значение. Из-за ограниченной точностиexp(oj)\exp(o_j)будут иметь значения, близкие к нулю, т.е.недолив(недолив). Эти значения могут быть округлены до нуля, что делаетy^j\hat y_jноль и сделатьlog(y^j)\log(\hat y_j)значение-inf. После нескольких шагов обратного распространения мы можем столкнуться с ужасным экраном.nanрезультат.

Хотя мы вычисляем экспоненциальные функции, в конечном итоге мы логарифмируем их при вычислении кросс-энтропийной потери. Комбинируя softmax и кросс-энтропию вместе, мы можем избежать проблем с численной стабильностью, которые могут беспокоить нас во время обратного распространения ошибки. Как показано в приведенном ниже уравнении, мы избегаем вычисленияexp(oj)\exp(o_j), но может напрямую использоватьojo_j. так какlog(exp())\log(\exp(\cdot))был смещен.

log(y^j)=log(exp(oj)kexp(ok))=log(exp(oj))log(kexp(ok))=ojlog(kexp(ok)).\begin{aligned} \log{(\hat y_j)} & = \log\left( \frac{\exp(o_j)}{\sum_k \exp(o_k)}\right) \\ & = \log{(\exp(o_j))}-\log{\left( \sum_k \exp(o_k) \right)} \\ & = o_j -\log{\left( \sum_k \exp(o_k) \right)}. \end{aligned}
l(y,y^)=j=1qyjlogy^j.l(\mathbf{y}, \hat{\mathbf{y}}) = - \sum_{j=1}^q y_j \log \hat{y}_j.