Blitz هي مكتبة بسيطة ويمكن توسيعها لإنشاء طبقات شبكة عصبية بايزي (استنادًا إلى ما هو مقترح في عدم اليقين في الوزن في ورقة الشبكات العصبية) على Pytorch. من خلال استخدام طبقات ومواقع Blitz ، يمكنك إضافة untertanity وجمع تكلفة التعقيد لنموذجك بطريقة بسيطة لا تؤثر على التفاعل بين طبقاتك ، كما لو كنت تستخدم Pytorch القياسي.
باستخدام فئات أخذ العينات الأساسية الخاصة بنا ، يمكنك تمديد هذه المكتبة وتحسينها لإضافة inchertanity إلى نطاق أكبر من الطبقات كما سترتبط بشكل جيد بالتدبير إلى Pytorch. كما ترحب بطلبات السحب.
لتثبيت Blitz ، يمكنك استخدام أمر PIP:
pip install blitz-bayesian-pytorch
أو عبر كوندا:
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:
(يمكنك رؤيته لنفسك من خلال تشغيل هذا المثال على جهازك).
سنرى الآن كيف يمكن استخدام التعلم العميق بايزي للانحدار من أجل جمع فاصل الثقة على نقطة بياناتنا بدلاً من التنبؤ بالقيمة المستمرة. قد يكون جمع فاصل ثقة لتنبؤاتك معلومات أكثر فائدة من تقدير الخاطف المنخفض.
أحافظ على حججتي حول حقيقة أنه مع فاصل ثقة جيد/عالي ، يمكنك اتخاذ قرار أكثر موثوقية من التقدير القريب للغاية في بعض السياقات: إذا كنت تحاول الحصول على ربح من عملية تجارية ، على سبيل المثال ، قد تقودك وجود فاصل ثقة جيد إلى معرفة ما إذا كانت القيمة التي ترتجفها على الأقل (أو أعلى).
إن معرفة ما إذا كانت القيمة ستكون ، بالتأكيد (أو مع احتمال جيد) على الفاصل الزمني المحدد يمكن أن تساعد الأشخاص على قرار معقول أكثر من تقدير قريب جدًا ، إذا كان أقل أو أعلى من قيمة الحد ، فقد يتسبب في خسارة في المعاملة. النقطة المهمة هي أنه ، في بعض الأحيان ، معرفة ما إذا كان سيكون هناك ربح قد يكون أكثر فائدة من قياسه.
من أجل إثبات ذلك ، سننشئ تراجعًا عن شبكة Bayesian Neural Network لمجموعة بيانات Boston-House-Data Toy ، في محاولة لإنشاء فاصل ثقة (CI) للمنازل التي نحاول التنبؤ بها. سنقوم ببعض التحجيم وستكون CI حوالي 75 ٪. سيكون من المثير للاهتمام أن نرى أن حوالي 90 ٪ من رابطة الدول المستقلة المتوقعة أقل من الحد الأعلى أو (شامل) أعلى من أقل.
على الرغم من الوحدات النمطية المعروفة ، سنحضر من Decorator blitz 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 ()يمكننا إنشاء فصلنا مع inhrecting من nn.module ، كما سنفعل مع أي شبكة الشعلة. يقدم ديكورنا طرقًا للتعامل مع ميزات Bayesian ، حيث يحسب تكلفة التعقيد لطبقات Bayesian والقيام بالعديد من الأعلاف (أخذ عينات من الأوزان المختلفة على كل واحدة) من أجل أخذ عينات من خسارتنا.
@ 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 Bayesian المختلفة دون مشكلة.
ها هي حلقة التدريب البسيطة للغاية:
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 ))شرح سريع للغاية لكيفية إدخال عدم اليقين في شبكات Bayesian Neural Neural وكيفية تصميم خسارتها من أجل تحسين الثقة بموضوعية على تنبؤها وتقليل التباين دون التسرب.
كما نعلم ، على طبقات الشبكة العصبية الحتمية (غير البايزية) ، تتوافق المعلمات القابلة للتدريب مباشرة مع الأوزان المستخدمة في التحول الخطي للذات السابقة (أو المدخلات ، إذا كان الأمر كذلك). يتوافق مع المعادلة التالية:
(z تتوافق مع الإخراج المنشط للطبقة الأولى)
تسعى طبقات بايزي إلى إدخال عدم اليقين على أوزانها عن طريق أخذ عينات منها من توزيع معلي بواسطة المتغيرات القابلة للتدريب على كل عملية تغذية.
هذا لا يسمح لنا فقط بتحسين مقاييس الأداء للنموذج ، ولكن أيضًا جمع عدم اليقين في تنبؤات الشبكة على نقطة بيانات معينة (عن طريق أخذ عينات من أوقات كثيرة وقياس التشتت) وخفض قدر الإمكان من التباين في الشبكة على داتبة خاصة بنا.
للقيام بذلك ، في كل عملية تغذية ، نقوم بتجربة معلمات التحول الخطي مع المعادلات التالية (حيث ρ parameTrate الانحراف المعياري و μ parametries المعاملات لمعلمات التحول الخطي العينات):
للأوزان:
حيث يتم أخذ عينات W مع الأوزان المستخدمة في التحول الخطي لطبقة ITH على العينة التاسعة.
من أجل التحيزات:
حيث يتوافق Sampled B مع التحيزات المستخدمة في التحول الخطي لطبقة ITH على العينة التاسعة.
حتى أن لدينا مضاعفًا عشوائيًا لأوزاننا وتحيزاتنا ، من الممكن تحسينها ، بالنظر إلى بعض الوظائف التي يمكن الاختلاف في الأوزان التي تم أخذ عينات منها وقابلة للتدريب (في حالتنا ، الخسارة) ، لتلخيص مشتق الوظيفة بالنسبة لكليهما:
لذلك:
و
من المعروف أن فقدان crossentropy (و MSE) قابل للتمييز. لذلك ، إذا أثبتنا أن هناك وظيفة تكلفة التعقيد قابلة للتمييز ، فيمكننا تركها لإطار عملنا ، خذ مشتقات وحساب التدرجات على خطوة التحسين.
يتم حساب تكلفة التعقيد ، على العملية التغذية ، بواسطة كل من الطبقات البايزية ، (مع توزيع الطبقات المحددة مسبقًا وتوزيعها التجريبي). يتم تلخيص مجموع تكلفة التعقيد لكل طبقة للخسارة.
كما هو مقترح في عدم اليقين في الوزن في ورقة الشبكات العصبية ، يمكننا جمع تكلفة التعقيد للتوزيع عن طريق أخذ اختلاف Kullback-Leibler منه إلى توزيع أبسط بكثير ، وبالتقريب ، يمكننا التمييز بين هذه الوظيفة بالنسبة إلى متغيراتها (التوزيعات):
دعنا يكون التوزيع المنخفض التوزيع PDF تم تعيينه باليد ، والذي سيتم افتراضه كتوزيع "مسبق" للأوزان
دعنا يكون التوزيع التجريبي الخلفي PDF لأوزاننا التي تم أخذ عينات منها ، بالنظر إلى معلماتها.
لذلك ، لكل عدادات على المصفوفة التي تم أخذ عينات منها:
من خلال افتراض وجود n كبير جدًا ، يمكننا التقارب:
وبالتالي:
نظرًا لأن المتوقع (المتوسط) لتوزيع Q ينتهي به الأمر بمجرد تحجيم القيم ، يمكننا إخراجها من المعادلة (حيث لن يكون هناك تتبع إطار). لديك تكلفة تعقيد للعينة التاسعة على النحو التالي:
وهو أمر قابل للتمييز بالنسبة لجميع معاييره.
لذلك ستكون وظيفة التكلفة بأكملها على العينة التاسعة من الأوزان هي:
يمكننا تقدير وظيفة التكلفة الكاملة الحقيقية من خلال أخذ عينات من Monte Carlo (تغذيها في Netwok X Times واتخاذ الوسيلة على الخسارة الكاملة) ثم Backpropagate باستخدام قيمتنا المقدرة. إنه يعمل مع عدد منخفض من التجارب في كل من الخلفية وحتى للتجارب الموحدة.
لقد وصلنا إلى نهاية التعلم العميق بايزي في برنامج تعليمي باختصار. من خلال معرفة ما يجري هنا ، يمكنك تنفيذ نموذج 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/} } ,
}