Blitz是一個簡單且可擴展的庫,可在Pytorch上創建貝葉斯神經網絡層(基於神經網絡論文中的重量不確定性提議的內容)。通過使用Blitz層和UTILS,您可以以簡單的方式添加不穩定性並收集模型的複雜性成本,不會影響圖層之間的相互作用,就好像您正在使用標準的Pytorch一樣。
通過使用我們的核心重量採樣器類,您可以擴展和改進該庫,以在更大的層次上添加不穩定範圍。也歡迎拉動請求。
要安裝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 .
我們的層,重量(和先前分佈)採樣器和utils的文檔:
(您可以通過在計算機上運行此示例來為自己看到它)。
現在,我們將看到如何將貝葉斯深度學習用於回歸,以便在我們的數據點上收集置信區間,而不是涉及的連續價值預測。比低錯誤估計,為您的預測收集置信區間可能甚至是更有用的信息。
我對以下事實保持了論點:憑藉良好/高的置信區間,您可以做出比在某些情況下進行非常近端的估計更可靠的決定:如果您試圖從交易行動中獲利,例如,擁有良好的置信區間,良好的置信區間可能會導致您至少知道該操作的價值是否會降低(或更高)(或更高)比某些確定的X。
知道一個值是否會在確定的間隔內肯定會(或概率),這可以幫助人們做出明智的決策,而不是一個非常近端的估計,如果較低或高於某些限制值,則可能會導致交易的損失。關鍵是,有時知道是否有利潤可能比測量它更有用。
為了證明這一點,我們將為波士頓-House-DATA玩具數據集創建貝葉斯神經網絡回歸劑,試圖為我們試圖預測的價格創建置信區間(CI)。我們將執行一些縮放,CI約為75%。有趣的是,大約90%的順式預測低於高極限或(包含)高於下限。
儘管通過已知的模塊,我們將帶來Blitz A The variational_estimator Decorator,這有助於我們處理模塊上的貝葉斯利層層,以使其與其餘的火炬完全集成在一起, 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 ()我們可以像使用任何火炬網絡一樣從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_ )此功能確實為我們試圖採樣標籤值的批次上的每個預測創建了一個置信區間。然後,我們可以通過尋求多少Predicon分佈確實包含數據標籤的正確標籤來衡量預測的準確性。
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方法對其損失進行損失而與普通火炬訓練有所不同。所有其他事情都可以正常地完成,因為我們的閃電戰的目的是在毫無麻煩的情況下使用不同的貝葉斯NN迭代數據。
這是我們非常簡單的訓練循環:
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層的激活輸出)
貝葉斯層試圖通過從每個前饋操作的可訓練變量參數的分佈中對其進行對重量的不確定性引入不確定性。
這不僅使我們不僅可以優化模型的性能指標,而且還可以通過特定數據點(通過對其進行抽樣次數並測量分散體)來收集網絡預測的不確定性,並旨在盡可能減少網絡差異而不是預測,從而使我們能夠了解我們在標籤上超過了我們嘗試對特定的ITIT ITIN -DATINIT ITINITINITINITINITINIM ITINCONTIM notiboint oblestoint oblotib oblespoint aboint aboint aboint aboint aboint aboint aboint aboint oblotib aboint oblobers obloine noberaint oblober的功能。
為此,在每個進發操作上,我們都使用以下方程式採樣線性轉換的參數(其中ρ參數為標準偏差, μ參數為樣本線性轉換參數的平均值):
重量:
其中採樣W對應於第n樣品上ITH層的線性轉換上使用的權重。
偏見:
其中採樣B對應於第n個樣本上ITH層的線性轉換上使用的偏差。
即使很艱難,我們也有一個隨機的乘數來適合自己的權重和偏見,可以通過對重量的一些可區分功能進行了優化,並且可以採樣和可訓練的參數(在我們的情況下為損失),將功能相對於兩個功能的導數求和:
所以:
和
眾所周知,Crossentropy損失(和MSE)是可區分的。因此,如果我們證明存在可區分的複雜性成本函數,則可以將其保留到我們的框架上,以衍生物為例,並在優化步驟中計算梯度。
每個貝葉斯層都計算出複雜性成本(在前饋操作上)(具有預定的較抽動器Apriori分佈及其經驗分佈)。每層的複雜性成本的總和總結為損失。
正如神經網絡論文中的重量不確定性所提出的那樣,我們可以通過將kullback-leibler差異從中獲得分佈的複雜性成本來收集分佈的複雜性成本,並通過進行一些近似值來收集分佈的分佈,並且我們可以將此功能相對於其變量(分佈)(分佈)區分(分佈):
設為手工設置的低透鏡分佈PDF,將其假定為重量的“先驗”分佈
鑑於其參數,令我們作為採樣權重的A後驗經驗分佈PDF。
因此,對於W採樣矩陣上的每個標量:
通過假設n很大,我們可以近似:
因此:
由於Q分佈的預期(平均值)僅通過縮放值而結束,因此我們可以將其從方程式中取出(因為不會有框架追踪)。將第n個樣本的複雜性成本為:
相對於其所有參數,這是可區分的。
因此,第n個權重樣本上的整個成本函數將是:
我們可以通過對蒙特卡洛進行抽樣(將Netwok X次並承擔全部損失的平均值),然後使用我們的估計值倒流來估算真正的全部成本函數。它適用於每個後退次數少的實驗,甚至用於單一實驗。
簡而言之,我們進入了貝葉斯深度學習的盡頭。通過知道這裡正在做什麼,您可以按照自己的意願實施BNN模型。
也許您可以通過每次樣本進行優化的步驟來優化,或者使用這種蒙特 - 卡洛語方法來收集損失,以均值,然後以優化器來收集損失。你的舉動。
僅供參考:我們的貝葉斯層和Utils有助於計算每個進料操作上層的複雜性成本,因此請不要介意太多。
如果您在研究中使用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/} } ,
}