當前位置:
首頁 > 新聞 > PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

機器之心報道

參與:一鳴、張倩


近日,來自荷蘭拉德堡德大學(Radboud University)團隊的開發者在 reddit 上發布了一個 PyTorch 深度概率推斷工具——Brancher,旨在使貝葉斯統計和深度學習之間的集成變得簡單而直觀。與其他概率推斷工具相比,Brancher 對新手更加友好,只具備機器學習和 Python 基礎的人也可以上手使用。

項目地址:https://brancher.org/

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

特點

Brancher 官網顯示,這一工具具有靈活(flexible)、集成(integrated)、直觀(intuitive)的特點。

  • 靈活:易於擴展建模帶有 GPU 加速的 PyTorch 後端的框架
  • 集成:易於使用帶有 Pandas 和 Seaborn 支持的當前工具
  • 直觀:易於利用數學類語法學習符號推理

與其他概率建模工具有什麼區別?

項目的主要開發者 LucaAmbrogioni 表示,與 Brancher 緊密相關的兩個模塊是 Pyro 和 PyMC3。Brancher 的目標受眾比 Pyro 更廣泛,包括那些只接受過機器學習和 Python 編程基本培訓的人。界面設計得儘可能接近數學。缺點是 Brancher 不如 Pyro 靈活。

Brancher 的前端與 PyMC3 非常相似。與 PyMC 的主要區別在於,Brancher 構建在深度學習庫 PyTorch 的頂部。每一個在 PyTorch 中實現的深度學習工具都可以用來在 Brancher 中構建深度概率模型。此外,PyMC 主要利用採樣,而 Brancher 則基於變分推理。

安裝

用戶需要首先安裝 PyTorch,然後使用 pip 命令行:

pip install *brancher*

或從 GitHub 地址克隆代碼,Github 地址:https://github.com/AI-DI/Brancher

教程

Google Colab 上有相關教程,包括

  • Brancher 入門
  • 使用 Brancher 進行時間序列分析
  • 使用 Brancher 進行貝葉斯統計分析

Brancher 入門

Brancher 是一個以用戶為中心的概率微分程序包。Brancher 希望能夠為初學者提供友好的服務,在保證計算運行效率和靈活性的前提下減少多餘的代碼。Brancher 以 PyTorch 為核心構建。

安裝 Brancher 成功後,首先需要用戶導入相關包:

import torch
import matplotlib.pyplot as plt
from brancher.variables import ProbabilisticModel
from brancher.standard_variables import NormalVariable, LogNormalVariable
from brancher import inference
import brancher.functions as BF

Brancher 是一個對象導向的工具包。因此內部的所有對象都是一個類,可以用來抽象化為概率計算程序。建立所有 Brancher 程序的基礎組件是 RandomVariable 類。通過微分方程連接隨機變數,可以建立概率模型。

例如,可以建立這樣一個模型,其中一個正則隨機變數的均值是由另一個正則隨機變數的正弦函數值決定的。Brancher 可以讓你像在學術論文里那樣使用符號定義模型。

創建變數:

nu = LogNormalVariable(loc=0., scale=1., name="nu")
mu = NormalVariable(loc=0., scale=10., name="mu")
x = NormalVariable(loc=BF.sin(mu), scale=nu, name="x")

使用定義好的變數創建一個概率模型:

model = ProbabilisticModel([x, mu, nu])

列印模型的內部組成:

model.model_summary

列印結果:

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

正如我們所預計的那樣,變數 x 是 mu 和 nu 的計算結果。但是,列表中也出現了 mu_mu 或 mu_sigma 這樣沒有提前明確定義的變數。這些確定變數(Deterministic Variables)代表的是概率分布參數的固定值。確定變數是 Brancher 中的特例,和隨機變數相似,但值是確定的。我們不需要定義他們,只需要在計算時輸入數字即可。

由於現在沒有輸入數據,因此 Observed 一欄為 False,現在我們輸入一些樣本數據,看看概率模型如何工作。

sample = model.get_sample(10)
sample

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

如果只需要單個變數的結果:

x_sample = x.get_sample(10)
x_sample

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

我們還可以做到通過輸入某些變數的值後進行採樣,如設定 mu 變數為 100 時,查看樣本結果:

in_sample = model.get_sample(10, input_values={mu: 100.})
in_sample

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

為了對某些已知的值進行上採樣,我們需要定義一些觀測值,並使用變分推斷的方法獲得分布。我們可以首先對 mu 和 nu 變數定義一些真實值,並生產一些觀測結果:

nu_real = 0.5
mu_real = -1.
data = x.get_sample(number_samples=100, input_values={mu: mu_real, nu: nu_real})

現在我們可以告訴 Brancher 變數 x 是從生成數據的值中觀察到的。

x.observe(data)
model.model_summary

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

這時可以看到變數 x 變為 observed。

如果你想採樣下游 x 的變數 mu 和 nu,你需要執行近似貝葉斯推理。在 Brancher 中,可以通過為所有想要採樣的變數定義一個變分分布來實現這一點。變分模型本身是一個概率模型,其構造方法與原概率模型完全相同。

指定此分布的最簡單方法是使用與原始模型中相同的分布:

Qnu = LogNormalVariable(0., 1., "nu", learnable=True)
Qmu = NormalVariable(0., 1., "mu", learnable=True)
model.set_posterior_model(ProbabilisticModel([Qmu, Qnu]))

現在我們需要使用一些隨機優化來學習變分近似的參數。這種技術被稱為隨機變分推理,該技術非常強大,因為它可以將貝葉斯推理很好地融入到深度學習框架中(實際上 brancher 的目的是與深度神經網路一起作為構建複雜概率模型的模塊)。

現在讓 Brancher 知道,變數分布的參數可以使用「learnable」flag 學習。接下來學習這些參數:

inference.perform_inference(model,
number_iterations=500,
number_samples=50,
optimizer="Adam",
lr=0.01)
loss_list = model.diagnostics["loss curve"]

現在把損失函數畫出來,以確保一切順利。

plt.plot(loss_list)

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

現在從後驗取一些樣本:

post_sample = model.get_posterior_sample(1000)
post_sample.describe()

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

與真值一起繪製後驗分布:

g = plt.hist(post_sample["mu"], 50)
plt.axvline(x=mu_real, color="k", lw=2)
[Image: image.png]

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

可以用 Brancher 繪製的函數可視化後驗分布。這個函數依賴於 Seaborn,Seaborn 是一個非常方便的可視化庫,與 panda 結合使用非常好。

from brancher.visualizations import plot_posterior
plot_posterior(model, variables=["mu", "nu", "x"])

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

更多教程請參考:

  • 使用 Brancher 進行時間序列分析,地址:https://colab.research.google.com/drive/1WuVUqr9pahhO4E4ema4vjDxxH-aMvMqb
  • 使用 Brancher 進行貝葉斯統計分析,地址:https://colab.research.google.com/drive/1L3kp7V48mRQYQDimn16OX1l0c0s20JFd

案例

作者提供了許多使用 Brancher 的案例,包括:

  • 自動回歸建模
  • 變分自動編碼器
  • 多元回歸

自動回歸建模完整代碼:

import matplotlib.pyplot as plt
import numpy as np
from brancher.variables import RootVariable, RandomVariable, ProbabilisticModel
from brancher.standard_variables import NormalVariable, LogNormalVariable, BetaVariable
from brancher import inference
import brancher.functions as BF
# Probabilistic model #
T = 200
nu = LogNormalVariable(0.3, 1., "nu")
x0 = NormalVariable(0., 1., "x0")
b = BetaVariable(0.5, 1.5, "b")
x = [x0]
names = ["x0"]
for t in range(1, T):
names.append("x{}".format(t))
x.append(NormalVariable(b*x[t-1], nu, names[t]))
AR_model = ProbabilisticModel(x)
# Generate data #
data = AR_model._get_sample(number_samples=1)
time_series = [float(data[xt].cpu().detach().numpy()) for xt in x]
true_b = data[b].cpu().detach().numpy()
true_nu = data[nu].cpu().detach().numpy()
print("The true coefficient is: {}".format(float(true_b)))
# Observe data #
[xt.observe(data[xt][:, 0, :]) for xt in x]
# Variational distribution #
Qnu = LogNormalVariable(0.5, 1., "nu", learnable=True)
Qb = BetaVariable(0.5, 0.5, "b", learnable=True)
variational_posterior = ProbabilisticModel([Qb, Qnu])
AR_model.set_posterior_model(variational_posterior)
# Inference #
inference.perform_inference(AR_model,
number_iterations=200,
number_samples=300,
optimizer="Adam",
lr=0.05)
loss_list = AR_model.diagnostics["loss curve"]
# Statistics
posterior_samples = AR_model._get_posterior_sample(2000)
nu_posterior_samples = posterior_samples[nu].cpu().detach().numpy().flatten()
b_posterior_samples = posterior_samples[b].cpu().detach().numpy().flatten()
b_mean = np.mean(b_posterior_samples)
b_sd = np.sqrt(np.var(b_posterior_samples))
print("The estimated coefficient is: {} +- {}".format(b_mean, b_sd))
# Two subplots, unpack the axes array immediately
f, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4)
ax1.plot(time_series)
ax1.set_title("Time series")
ax2.plot(np.array(loss_list))
ax2.set_title("Convergence")
ax2.set_xlabel("Iteration")
ax3.hist(b_posterior_samples, 25)
ax3.axvline(x=true_b, lw=2, c="r")
ax3.set_title("Posterior samples (b)")
ax3.set_xlim(0,1)
ax4.hist(nu_posterior_samples, 25)
ax4.axvline(x=true_nu, lw=2, c="r")
ax4.set_title("Posterior samples (nu)")
plt.show()

PyTorch深度概率推斷工具Brancher,掌握ML和Python基礎即可上手

從左到右依次為「Time Series」、「Convergence」、「Posterior Samples (b)」、「Posterior Samples (n)」

更多案例請參考:

  • 使用變分自動編碼器學習識別 MNIST 手寫數字:https://colab.research.google.com/drive/1EvQS1eWWYdVlhuoP-y1RXED9a2CNu3XQ
  • 多元回歸分析:https://colab.research.google.com/drive/1ZyhidyCGEH_epDRt29HzvR65V8EN0kpX

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器之心 的精彩文章:

GMIS2019全球數據智能峰會正式啟動:擁抱數智經濟,賦能產業生態
1+1>2:MIT&IBM提出結合符號主義和連接主義的高效、準確新模型

TAG:機器之心 |