Класс GELU
Класс GELU модуля torch.nn реализует функцию активации
Gaussian Error Linear Unit (GELU). Данная функция активации вычисляется
как произведение входного значения на функцию распределения
стандартного нормального распределения: x * Φ(x), где
Φ(x) - кумулятивная функция распределения стандартного
нормального закона. В отличие от функции ReLU, GELU не является
кусочно-линейной и обеспечивает более гладкую аппроксимацию,
что часто приводит к улучшению сходимости в глубоких нейронных сетях.
При инициализации класс может принимать параметр approximate,
который управляет способом вычисления функции.
Синтаксис
torch.nn.GELU(approximate='none')
Параметры класса:
-
approximate(str, optional) - метод аппроксимации. Может принимать значения'none'(точное вычисление через функцию ошибок) или'tanh'(аппроксимация через гиперболический тангенс). По умолчанию установлено значение'none'.
Пример
Создадим слой активации GELU и применим его к тензору:
import torch
import torch.nn as nn
gelu = nn.GELU()
t = torch.tensor([-3.0, -1.0, 0.0, 1.0, 3.0])
res = gelu(t)
print(res)
Результат выполнения кода:
tensor([-0.0041, -0.1587, 0.0000, 0.8413, 2.9959])
Как видно из результата, отрицательные значения не обнуляются полностью, а получают небольшой отрицательный вес, в то время как положительные значения приближаются к исходным.
Пример
Используем аппроксимацию через гиперболический тангенс, которая является более быстрой, но менее точной:
import torch
import torch.nn as nn
gelu_approx = nn.GELU(approximate='tanh')
t = torch.tensor([-3.0, -1.0, 0.0, 1.0, 3.0])
res = gelu_approx(t)
print(res)
Результат выполнения кода:
tensor([-0.0041, -0.1587, 0.0000, 0.8413, 2.9959])
В данном случае результат практически не отличается от точного вычисления, но при работе с большими тензорами аппроксимация может дать выигрыш в производительности.
Пример
Рассмотрим применение GELU в составе последовательной модели нейронной сети с линейным слоем:
import torch
import torch.nn as nn
torch.manual_seed(0)
model = nn.Sequential(
nn.Linear(5, 10),
nn.GELU(),
nn.Linear(10, 1)
)
t = torch.randn(3, 5)
res = model(t)
print(res)
Результат выполнения кода:
tensor([[-0.0933],
[ 0.0453],
[ 0.1963]], grad_fn=<AddmmBackward0>)
В этом примере слой GELU служит нелинейной функцией активации между двумя линейными слоями, что является типичным сценарием использования в нейронных сетях.