Blitz - это простая и расширяемая библиотека для создания слоев байесовской нейронной сети (на основе того, что предлагается в неопределенности веса в бумаге нейронных сетей) на Pytorch. Используя Blitz Layers and UTILS, вы можете добавить несертичность и собрать стоимость сложности вашей модели простым способом, который не влияет на взаимодействие между вашими слоями, как если бы вы использовали стандартный Pytorch.
Используя наши классы сэмплера веса основного веса, вы можете расширить и улучшить эту библиотеку, чтобы добавить несертичность к большему объему слоев, как вы будете хорошо интегрированы в Pytorch Way. Также приветствуются запросы на тягу.
Для установки Blitz вы можете использовать команду PIP:
pip install blitz-bayesian-pytorch
Или через Conda:
conda install -c conda-forge blitz-bayesian-pytorch
Вы также можете забрать его и провести его на местном уровне:
conda create -n blitz python=3.9
conda activate blitz
git clone https://github.com/piEsposito/blitz-bayesian-deep-learning.git
cd blitz-bayesian-deep-learning
pip install .
Документация для наших слоев, веса (и предшествующего распределения) и утилит:
(Вы можете увидеть это для себя, запустив этот пример на своей машине).
Теперь мы увидим, как байесовское глубокое обучение может использоваться для регрессии, чтобы собрать доверительный интервал над нашей датой, а не понтой непрерывной прогнозирование ценности. Сбор доверительного интервала для вашего прогноза может быть даже более полезной информацией, чем оценка с низкой ошибкой.
Я поддерживаю свою аргументацию в отношении того факта, что с хорошим/высоким содержанием доверительного интервала вы можете принять более надежное решение, чем с очень проксимальной оценкой в некоторых контекстах: если вы пытаетесь получить прибыль от торговой операции, например, наличие хорошего доверительного интервала может привести к тому, что, по крайней мере, если, по крайней мере, значение, в которой операция Wil Proces будет ниже (или выше), чем некоторые решительные x.
Знание того, будет ли значение, несомненно, (или с хорошей вероятностью) в интервале определения может помочь людям принять разумное решение больше, чем очень проксимальная оценка, которая, если они ниже, или выше, чем какое -то предельное значение, может привести к потере при транзакции. Дело в том, что иногда знание того, будет ли прибыль, может быть более полезной, чем ее измерение.
Чтобы продемонстрировать это, мы создадим байесовский регрессор нейронной сети для набора игрушек в Бостон-Хаус-Дате, пытаясь создать доверительный интервал (CI) для дома, о которой мы пытаемся предсказать. Мы выполним некоторое масштабирование, а CI будет около 75%. Будет интересно видеть, что около 90% прогнозируемых CIS ниже, чем высокий предел или (включительно) выше, чем нижний.
Несмотря на из известных модулей, мы возьмем из декоратора Blitz Athe variational_estimator , который помогает нам справиться с байесанолинеарными слоями на модуле, сохраняя его полностью интегрированным с остальной частью факела, и, конечно же, BayesianLinear , который является нашим слоем, который обладает несертичностью веса.
import torch
import torch . nn as nn
import torch . nn . functional as F
import torch . optim as optim
import numpy as np
from blitz . modules import BayesianLinear
from blitz . utils import variational_estimator
from sklearn . datasets import load_boston
from sklearn . preprocessing import StandardScaler
from sklearn . model_selection import train_test_split Ничего нового под солнцем здесь, мы импортируем и стандартируем данные, чтобы помочь с обучением.
X , y = load_boston ( return_X_y = True )
X = StandardScaler (). fit_transform ( X )
y = StandardScaler (). fit_transform ( np . expand_dims ( y , - 1 ))
X_train , X_test , y_train , y_test = train_test_split ( X ,
y ,
test_size = .25 ,
random_state = 42 )
X_train , y_train = torch . tensor ( X_train ). float (), torch . tensor ( y_train ). float ()
X_test , y_test = torch . tensor ( X_test ). float (), torch . tensor ( y_test ). float ()Мы можем создать наш класс с помощью Inhreiting из NN.Module, как и с любой сетью факела. Наш декоратор представляет методы для обработки байесовских функций, как расчет стоимости сложности байесовских слоев и выполнение множества направлений (выборки различных весов на каждом), чтобы попробовать нашу потерю.
@ variational_estimator
class BayesianRegressor ( nn . Module ):
def __init__ ( self , input_dim , output_dim ):
super (). __init__ ()
#self.linear = nn.Linear(input_dim, output_dim)
self . blinear1 = BayesianLinear ( input_dim , 512 )
self . blinear2 = BayesianLinear ( 512 , output_dim )
def forward ( self , x ):
x_ = self . blinear1 ( x )
x_ = F . relu ( x_ )
return self . blinear2 ( x_ )Эта функция создает доверительный интервал для каждого прогноза на партии, на которой мы пытаемся попробовать значение метки. Затем мы можем измерить точность наших предсказаний, требуя того, сколько распределений Prediciton действительно включало правильную метку для данных.
def evaluate_regression ( regressor ,
X ,
y ,
samples = 100 ,
std_multiplier = 2 ):
preds = [ regressor ( X ) for i in range ( samples )]
preds = torch . stack ( preds )
means = preds . mean ( axis = 0 )
stds = preds . std ( axis = 0 )
ci_upper = means + ( std_multiplier * stds )
ci_lower = means - ( std_multiplier * stds )
ic_acc = ( ci_lower <= y ) * ( ci_upper >= y )
ic_acc = ic_acc . float (). mean ()
return ic_acc , ( ci_upper >= y ). float (). mean (), ( ci_lower <= y ). float (). mean () Обратите внимание на то, что мы создаем нашу BayesianRegressor , как и с другими нейронными сетями.
regressor = BayesianRegressor ( 13 , 1 )
optimizer = optim . Adam ( regressor . parameters (), lr = 0.01 )
criterion = torch . nn . MSELoss ()
ds_train = torch . utils . data . TensorDataset ( X_train , y_train )
dataloader_train = torch . utils . data . DataLoader ( ds_train , batch_size = 16 , shuffle = True )
ds_test = torch . utils . data . TensorDataset ( X_test , y_test )
dataloader_test = torch . utils . data . DataLoader ( ds_test , batch_size = 16 , shuffle = True )Мы делаем учебный цикл, который отличается только от общего обучения факела, путем выбора его потери с помощью метода Sample_elbo. Все остальные вещи можно делать обычно, так как наша цель с Blitz состоит в том, чтобы без проблем облегчить вашу жизнь на ваши данные с различными байесовскими NNS.
Вот наша очень простая тренировочная петля:
iteration = 0
for epoch in range ( 100 ):
for i , ( datapoints , labels ) in enumerate ( dataloader_train ):
optimizer . zero_grad ()
loss = regressor . sample_elbo ( inputs = datapoints ,
labels = labels ,
criterion = criterion ,
sample_nbr = 3 )
loss . backward ()
optimizer . step ()
iteration += 1
if iteration % 100 == 0 :
ic_acc , under_ci_upper , over_ci_lower = evaluate_regression ( regressor ,
X_test ,
y_test ,
samples = 25 ,
std_multiplier = 3 )
print ( "CI acc: {:.2f}, CI upper acc: {:.2f}, CI lower acc: {:.2f}" . format ( ic_acc , under_ci_upper , over_ci_lower ))
print ( "Loss: {:.4f}" . format ( loss ))Очень быстрое объяснение того, как неопределенность вводится в байесовских нейронных сетях и как мы моделируем ее потерю, чтобы объективно повысить уверенность в его прогнозировании и уменьшить дисперсию без выпадения.
Как мы знаем, на детерминированных (не байесовских) слоях нейронной сети подготовленные параметры непосредственно соответствуют весам, используемым при его линейном преобразовании предыдущего (или входного, если это так). Это соответствует следующему уравнению:
(Z соответствует активированному-выводу слоя I)
Байесовские слои стремятся ввести неопределенность в своих весах, отбирая их из распределения, параметризованного обучаемыми переменными при каждой операции при прямой установке.
Это позволяет нам не только оптимизировать показатели производительности модели, но и собирать неопределенность предсказаний сети по определенной дата (отборность ее много раз и измерение дисперсии) и целостно уменьшать как можно больше, чтобы мы не могли моделировать его в функции, что можно узнать, насколько у нас все еще есть по сравнению с этикеткой, если мы попытаемся моделировать его в функции.
Для этого, при каждой операции при прямой установке мы выбираем параметры линейного преобразования со следующими уравнениями (где ρ параметризует стандартное отклонение и μ параметризует среднее значение для параметров линейного преобразования образцов):
Для весов:
Где выборка W соответствует весам, используемым на линейном преобразовании для слоя ITH на NTH образец.
Для предвзятости:
Где выборка B соответствует смещениям, используемым на линейном преобразовании для слоя ITH на NTH образец.
Даже жестко у нас есть случайный мультипликатор для наших весов и смещений, можно оптимизировать их, учитывая некоторую дифференцируемую функцию весов, отобранных и обучаемых параметров (в нашем случае потери), суммируя производную функции по сравнению с обоими из них:
Поэтому:
и
Известно, что потери кроссентропии (и MSE) дифференцируют. Поэтому, если мы докажем, что существует функция сложности затрат, которая дифференцируется, мы можем оставить ее в нашу структуру принять производные и вычислить градиенты на этапе оптимизации.
Стоимость сложности рассчитывается на операции при питании, по каждому из байесовских слоев (с предварительно определенным распределением априориоров слоев и его эмпирическим распределением). Сумма стоимости сложности каждого слоя суммируется до потери.
Как предложено в неопределенности веса в бумаге нейронных сетей, мы можем собрать сложность стоимости распределения, переведя из нее дивергенцию Kullback-Leibler до гораздо более простого распределения, и, сделав некоторое приближение, мы сможем дифференцировать эту функцию относительно ее переменных (распределения):: Мы можем дифференцировать эту функцию по сравнению с его переменными (распределения):
Позвольте быть низкопробранным распределением PDF, установленным вручную, который будет предположить в качестве распределения «априори» для весов
Пусть будет апостериорным эмпирическим распределением PDF для наших выборочных весов, учитывая его параметры.
Следовательно, для каждого скаляр на матрице W, выбранной W,:
Предполагая очень большой N, мы могли бы приблизиться:
и поэтому:
Поскольку ожидаемый (средний) распределение Q заканчивается просто масштабировав значения, мы можем вывести его из уравнения (поскольку не будет никакого трассы). Иметь сложность стоимости n -й выборки как:
Который дифференцируется по сравнению со всеми его параметрами.
Поэтому вся функция стоимости на n -й выборке веса будет:
Мы можем оценить истинную функцию полной стоимости с помощью Monte Carlo, отбирая ее (приспосабливаясь к Netwok x раз и принимая среднее значение в течение полных потерь), а затем обратно, используя наше предполагаемое значение. Он работает для низкого количества экспериментов на запасную процедуру и даже для унитарных экспериментов.
Мы подошли к концу байесовского глубокого обучения в двух словах. Зная, что здесь делается, вы можете реализовать свою модель BNN по своему желанию.
Возможно, вы можете оптимизировать, выполнив один оптимизирующий шаг на выборку или используя этот метод Monte-Carlo-ish, чтобы собрать потери, принять его среднее значение, а затем оптимизатор. Ваш ход.
К вашему сведению: наши байесовские слои и использование помогают вычислять стоимость сложности вдоль слоев на каждой операции при прямой установке, поэтому не обращайте внимания на это много.
Если вы используете BLiTZ в своем исследовании, вы можете привести его следующим образом:
@misc { esposito2020blitzbdl ,
author = { Piero Esposito } ,
title = { BLiTZ - Bayesian Layers in Torch Zoo (a Bayesian Deep Learing library for Torch) } ,
year = { 2020 } ,
publisher = { GitHub } ,
journal = { GitHub repository } ,
howpublished = { url{https://github.com/piEsposito/blitz-bayesian-deep-learning/} } ,
}