0
雷鋒網(wǎng) AI 科技評(píng)論按:TensorFlow Probability(TFP)是一個(gè)基于 TensorFlow 的 Python 庫,能夠更容易地結(jié)合概率模型和深度學(xué)習(xí)。數(shù)據(jù)科學(xué)家、統(tǒng)計(jì)學(xué)以及機(jī)器學(xué)習(xí)研究者或者從業(yè)者,都可以用它編碼領(lǐng)域知識(shí) (Domain Knowledge),從而理解數(shù)據(jù)并寫出自己的應(yīng)用。針對(duì)那些對(duì) TFP 還不那么熟悉的入門者,日前,谷歌 TensorFlow Probability 的產(chǎn)品經(jīng)理 Mike Shwe 及軟件工程師 Josh Dillon、谷歌的軟件工程師 Bryan Seybold 及 Matthew McAteer、Cam Davidson-Pilon 共同在 TensorFlow 官網(wǎng)上發(fā)布介紹 TensorFlow Probability 的入門級(jí)實(shí)操性教程——《Bayesian Methods for Hackers》的文章,雷鋒網(wǎng) AI 科技評(píng)論編譯如下。
之前沒有學(xué)過概率編程?對(duì) TensorFlow Probability(TFP)還不熟悉?下面我們?yōu)槟銣?zhǔn)備了入門級(jí)實(shí)操性教程——《Bayesian Methods for Hackers》(教程查看地址:https://camdavidsonpilon.github.io/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers/#tensorflow),這門教程的實(shí)例現(xiàn)在也在 TFP 中開放了。作為對(duì)所有人開放的開源資源,TFP 版本的概率編程對(duì)之前用 PyMC3 寫的那版進(jìn)行了補(bǔ)充。
《Bayesian Methods for Hackers》具備許多優(yōu)勢(shì):它不僅能讓概率初學(xué)者較容易上手,而且還展示了如何將概率編程應(yīng)用于現(xiàn)實(shí)問題。
雖然概率編程不要求貝葉斯方法(Bayesian approach),但是該方法提供了一個(gè)相對(duì)直觀的框架,來表示信念(representing beliefs),并基于新的數(shù)據(jù)來更新這些信念。《Bayesian Methods for Hackers》使用 TFP 為基礎(chǔ),以實(shí)操的方式來教授這些技術(shù)。由于這本書由 Google Colab 所寫,你可以運(yùn)行并修改其中的 Python 示例。
TensorFlow 團(tuán)隊(duì)開發(fā)的 TFP 專門面向數(shù)據(jù)科學(xué)家、統(tǒng)計(jì)學(xué)家以及以及想要編碼領(lǐng)域知識(shí) (Domain Knowledge)來了解數(shù)據(jù)并進(jìn)行數(shù)據(jù)預(yù)測(cè)的機(jī)器學(xué)習(xí)研究者和從業(yè)者。TFP 是基于 TensorFlow 的 Python 開發(fā)庫,能夠更容易地結(jié)合概率模型和先進(jìn)硬件上的深度學(xué)習(xí)。TFP 可以讓你:
互動(dòng)地探究數(shù)據(jù)
快速地評(píng)估不同的模型
自動(dòng)地利用先進(jìn)的、矢量化的硬件加速器
更輕易、更有把握地啟用。TFP 經(jīng)專業(yè)地開發(fā)和測(cè)試,可使用現(xiàn)成的 Google-Cloud,并且還有一個(gè)強(qiáng)大的開源社區(qū)的支持。
正如我們?cè)谙嚓P(guān)博文中曾討論過的,概率編程有非常多樣化的應(yīng)用,包括金融、石油和天然氣等各行各業(yè)。為什么?——因?yàn)椴淮_定性無處不在?,F(xiàn)實(shí)世界的現(xiàn)象——即便是那些我們完全了解的現(xiàn)象,都受到我們無法控制甚至無法意識(shí)到的外部因素的影響。如果忽略這些因素,這些模型所得出的結(jié)論可能往好里說是誤導(dǎo)性的或者是完全錯(cuò)誤的。我們開發(fā)出了對(duì)所有場(chǎng)景都可用的 TFP,就是為了對(duì)我們周圍所有的不確定性進(jìn)行建模。
許多貝葉斯教程都是聚焦于解決那些已有分析結(jié)果的簡(jiǎn)單問題:比如擲硬幣和擲骰子的問題。不過《Bayesian Methods for Hackers》一書是從這些簡(jiǎn)單的問題開始,之后迅速轉(zhuǎn)向更加現(xiàn)實(shí)的問題,例如從理解宇宙到檢測(cè)某個(gè)在線用戶的行為變化等。
在這篇文章接下來的部分,我們將一起探討一個(gè) 非常有名的現(xiàn)實(shí)世界的問題,這個(gè)問題在 Bayesian Hackers 一書中的第二章節(jié)(查看地址:https://github.com/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers/blob/master/Chapter2_MorePyMC/Ch2_MorePyMC_TFP.ipynb)有更詳細(xì)的描述:1986 年航天飛機(jī)挑戰(zhàn)者的災(zāi)難。
1986 年 1 月 28 日,美國挑戰(zhàn)者號(hào)航天飛機(jī)的第 25 次飛行中,由于一處 O 形圈故障,挑戰(zhàn)者號(hào)的兩個(gè)固體火箭助推器其中的一個(gè)發(fā)生了爆炸。雖然控制中心的工程師們與 O 形圈制造商就先前飛行中的損壞進(jìn)行了多次溝通,但制造商堅(jiān)持認(rèn)為風(fēng)險(xiǎn)是可以接受的。
下圖將對(duì)先前航天飛機(jī)任務(wù)中的七次 O 形圈損壞事件的觀測(cè),描述成了一個(gè)環(huán)境溫度的函數(shù)。(在 70 度時(shí),有兩次損壞事件。)
你會(huì)注意到,隨著溫度的降低,O 形圈損壞的比例會(huì)明顯增多,不過沒有明顯的溫度閾值——低于該閾值時(shí) O 形圈就一定會(huì)失效。與現(xiàn)實(shí)世界中的大多數(shù)現(xiàn)象一樣,這個(gè)問題涉及不確定性。我們希望在給定溫度 t 下,來確定 O 形圈失效的概率。
我們可以特別使用邏輯函數(shù)模擬溫度 t 下 O 形環(huán)損壞的概率 p :
其中β確定概率函數(shù)的形狀,α是偏移項(xiàng),控制函數(shù)從左向右移動(dòng)。由于這兩個(gè)參數(shù)都既是正的或負(fù)的,也沒有特定的邊界或大小的偏差,我們可以將它們建模為高斯分布隨機(jī)變量:
在 TFP 中,我們可以用 tfp.distributions.Normal 直觀地表示 α 和 β,其代碼片段如下:
temperature_ = challenger_data_[:, 0]
temperature = tf.convert_to_tensor(temperature_, dtype=tf.float32)
D_ = challenger_data_[:, 1] # defect or not?
D = tf.convert_to_tensor(D_, dtype=tf.float32)
beta = tfd.Normal(name="beta", loc=0.3, scale=1000.).sample()
alpha = tfd.Normal(name="alpha", loc=-15., scale=1000.).sample()
p_deterministic = tfd.Deterministic(name="p", loc=1.0/(1. + tf.exp(beta * temperature_ + alpha))).sample()
[
prior_alpha_,
prior_beta_,
p_deterministic_,
D_,
] = evaluate([
alpha,
beta,
p_deterministic,
D,
])
(如果要運(yùn)行這個(gè)代碼片段,請(qǐng)前往本書第二章的 Google Colab 版本,來運(yùn)行整個(gè)航天飛機(jī)示例)。
要注意的是,我們?cè)诘?8 行得到 p(t) 的實(shí)際值 0 或 1,其中我們使用此前在第 6 行和第 7 行中采樣的α和β值從概率函數(shù)(logistic function)中采樣。此外,注意 evaluate() 輔助函數(shù)可以讓我們實(shí)現(xiàn)圖表和 eager 模式之間的無縫轉(zhuǎn)換,與此同時(shí)將張量值轉(zhuǎn)換為 numpy。關(guān)于 eager 和圖表模型以及這一輔助函數(shù)的更詳細(xì)的講解,請(qǐng)查看第二章節(jié)的開頭部分。
為了將溫度 t 下的失效概率 p(t) 與我們觀測(cè)的數(shù)據(jù)聯(lián)系起來,我們可以使用帶參數(shù) p(t) 的伯努利隨機(jī)變量。要注意的是,一般而言 Ber(p) 是隨機(jī)變量,它的值為 1 的概率為 p,其它情況下都為 0。因此,生成模型的最后一部分是溫度值為 ? 的情況下觀測(cè)到的有缺陷事件的數(shù)量 D?,我們可以對(duì)其建模為:
給定這一生成模型的情況下,我們希望找到模型參數(shù)從而讓模型能夠解釋所觀察到的數(shù)據(jù)——這正是是概率推理的目標(biāo)。
TFP 通過使用非標(biāo)準(zhǔn)化的聯(lián)合對(duì)數(shù)概率函數(shù)評(píng)估模型來執(zhí)行概率推斷。此 joint_log_prob 的論點(diǎn)是數(shù)據(jù)和模型狀態(tài)。該函數(shù)返回參數(shù)化模型生成觀測(cè)數(shù)據(jù)的聯(lián)合概率的對(duì)數(shù)。如果要了解更多關(guān)于 joint_log_prob 的信息,可以查看這個(gè)短文介紹。
針對(duì)上述挑戰(zhàn)者的示例,這里我們定義 joint_log_prob 的方式如下:
def challenger_joint_log_prob(D, temperature_, alpha, beta):
"""
Joint log probability optimization function.
Args:
D: The Data from the challenger disaster representing presence or
absence of defect
temperature_: The Data from the challenger disaster, specifically the temperature on
the days of the observation of the presence or absence of a defect
alpha: one of the inputs of the HMC
beta: one of the inputs of the HMC
Returns:
Joint log probability optimization function.
"""
rv_alpha = tfd.Normal(loc=0., scale=1000.)
rv_beta = tfd.Normal(loc=0., scale=1000.)
logistic_p = 1.0/(1. + tf.exp(beta * tf.to_float(temperature_) + alpha))
rv_observed = tfd.Bernoulli(probs=logistic_p)
return (
rv_alpha.log_prob(alpha)
+ rv_beta.log_prob(beta)
+ tf.reduce_sum(rv_observed.log_prob(D))
)
注意 15-18 行怎樣簡(jiǎn)單地對(duì)生成模型、每行的隨機(jī)變量進(jìn)行編碼。同時(shí)也要注意 rv_alpha 和 rv_beta 表示此前對(duì) ? 和 β 分布的隨機(jī)變量。相比之下,rv_observed 表示給定一個(gè)參數(shù)為 ? 和 β 的概率分布情況下溫度和 O 形圈輸出的觀察可能性的條件分布。
接下來,我們使用 joint_log_prob 函數(shù),并將其發(fā)送到 tfp.mcmc 模塊。馬爾可夫鏈蒙特卡洛(MCMC)算法對(duì)未知的輸入值進(jìn)行有依據(jù)的猜測(cè),并計(jì)算 joint_log_prob 函數(shù)中參數(shù)集的可能性。通過多次重復(fù)這一過程,MCMC 構(gòu)建了可能的參數(shù)的分布,而構(gòu)建這一分布是概率推理的目標(biāo)。
因此,我們將在 challenge_joint_log_prob 函數(shù)上設(shè)置一種特定類型的稱為「哈密頓蒙特卡洛」的 MCMC:
number_of_steps = 60000
burnin = 50000
# Set the chain's start state.
initial_chain_state = [
0. * tf.ones([], dtype=tf.float32, name="init_alpha"),
0. * tf.ones([], dtype=tf.float32, name="init_beta")
]
# Since HMC operates over unconstrained space, we need to transform the
# samples so they live in real-space.
unconstraining_bijectors = [
tfp.bijectors.Identity(),
tfp.bijectors.Identity()
]
# Define a closure over our joint_log_prob.
unnormalized_posterior_log_prob = lambda *args: challenger_joint_log_prob(D, temperature_, *args)
# Initialize the step_size. (It will be automatically adapted.)
with tf.variable_scope(tf.get_variable_scope(), reuse=tf.AUTO_REUSE):
step_size = tf.get_variable(
name='step_size',
initializer=tf.constant(0.5, dtype=tf.float32),
trainable=False,
use_resource=True
)
# Defining the HMC
hmc=tfp.mcmc.TransformedTransitionKernel(
inner_kernel=tfp.mcmc.HamiltonianMonteCarlo(
target_log_prob_fn=unnormalized_posterior_log_prob,
num_leapfrog_steps=2,
step_size=step_size,
step_size_update_fn=tfp.mcmc.make_simple_step_size_update_policy(),
state_gradients_are_stopped=True),
bijector=unconstraining_bijectors)
# Sampling from the chain.
[
posterior_alpha,
posterior_beta
], kernel_results = tfp.mcmc.sample_chain(
num_results = number_of_steps,
num_burnin_steps = burnin,
current_state=initial_chain_state,
kernel=hmc)
# Initialize any created variables for preconditions
init_g = tf.global_variables_initializer()
最終,我們將真正通過 evaluate() 輔助函數(shù)進(jìn)行推理:
evaluate(init_g)
[
posterior_alpha_,
posterior_beta_,
kernel_results_
] = evaluate([
posterior_alpha,
posterior_beta,
kernel_results
])
print("acceptance rate: {}".format(
kernel_results_.inner_results.is_accepted.mean()))
print("final step size: {}".format(
kernel_results_.inner_results.extra.step_size_assign[-100:].mean()))
alpha_samples_ = posterior_alpha_[burnin::8]
beta_samples_ = posterior_beta_[burnin::8]
繪制 α 和 β 的分布圖時(shí),我們注意到這兩個(gè)參數(shù)的分布相當(dāng)寬泛,正如我們所預(yù)期的那樣,數(shù)據(jù)點(diǎn)相當(dāng)少,并且失效和非失效觀測(cè)的溫度出現(xiàn)重疊。然而,即使分布寬泛,我們也可以相當(dāng)確定溫度確實(shí)對(duì) O 形圈損壞的概率有影響,因?yàn)棣碌乃袠颖径即笥?0。同樣,我們也可以確信 α 明顯小于 0,因?yàn)樗械臉颖径寄芎芎玫剞D(zhuǎn)化為負(fù)數(shù)。
正如我們上面所提到的,我們真正想知道的是: 在給定溫度下,O 形環(huán)損壞的預(yù)期概率是多少?為了計(jì)算這一概率,我們可以對(duì)來自后驗(yàn)的所有樣本求平均值,從而得到概率 p(t?) 的可能值。
alpha_samples_1d_ = alpha_samples_[:, None] # best to make them 1d
beta_samples_1d_ = beta_samples_[:, None]
beta_mean = tf.reduce_mean(beta_samples_1d_.T[0])
alpha_mean = tf.reduce_mean(alpha_samples_1d_.T[0])
[ beta_mean_, alpha_mean_ ] = evaluate([ beta_mean, alpha_mean ])
print("beta mean:", beta_mean_)
print("alpha mean:", alpha_mean_)
def logistic(x, beta, alpha=0):
"""
Logistic function with alpha and beta.
Args:
x: independent variable
beta: beta term
alpha: alpha term
Returns:
Logistic function
"""
return 1.0 / (1.0 + tf.exp((beta * x) + alpha))
t_ = np.linspace(temperature_.min() - 5, temperature_.max() + 5, 2500)[:, None]
p_t = logistic(t_.T, beta_samples_1d_, alpha_samples_1d_)
mean_prob_t = logistic(t_.T, beta_mean_, alpha_mean_)
[
p_t_, mean_prob_t_
] = evaluate([
p_t, mean_prob_t
])
我們可以在整個(gè)溫度范圍內(nèi)計(jì)算 95%的可信區(qū)間。要注意的是,這個(gè)區(qū)間是可靠的,而不是在統(tǒng)計(jì)分析的頻率論方法中常用到的置信區(qū)間。95%可信區(qū)間告訴我們,能夠以 95%的概率確定真實(shí)值將位于此區(qū)間內(nèi)。例如,在正如下圖中的紫色區(qū)域所顯示的,在 50 度時(shí),我們可以 95%確定 O 形圈損壞的概率介于 1.0 和 0.80 之間。諷刺地是,許多人都錯(cuò)誤地將置信區(qū)間解釋為具有這一特征。
挑戰(zhàn)者號(hào)災(zāi)難發(fā)生的當(dāng)天,其溫度為 31 華氏度,這一事實(shí)證明了,O 形圈失效的后驗(yàn)分布將使我們高度確信挑戰(zhàn)者號(hào)會(huì)出現(xiàn)損壞的問題。
這種非常簡(jiǎn)單的概率分析展示了 TFP 和貝葉斯方法的強(qiáng)大:它們可以提供有價(jià)值的分析,同時(shí)可以對(duì)可能帶來嚴(yán)重后果的現(xiàn)實(shí)世界的問題進(jìn)行預(yù)測(cè)。
在《Bayesian Methods for Hackers》一書中,你可以看到大量現(xiàn)實(shí)世界示例。對(duì)短信量隨時(shí)間變化的分析,可以在制造業(yè)和生產(chǎn)系統(tǒng)中的各種故障檢測(cè)問題得到廣泛應(yīng)用。在我們首次起草本章節(jié)的 TFP 版本的幾周時(shí)間內(nèi),谷歌的軟件工程師就應(yīng)用了短信分析的方法來理解生產(chǎn)軟件的文本片狀(text flakiness)。
你可以找到某個(gè)分析來尋找宇宙中的暗物質(zhì)。此外,書中還有預(yù)測(cè)上市公司的股票收益率的方法。
我們希望大家能深入了解本書中的概念性實(shí)操演示,并將這些技術(shù)應(yīng)用到各自所在領(lǐng)域的問題中。歡迎大家在 Github 中發(fā)表評(píng)論和提出要求,來幫助我們對(duì)這本書不斷改進(jìn),從而使其實(shí)現(xiàn)最佳狀態(tài)!
本文參考:https://en.wikipedia.org/wiki/Space_Shuttle_Challenger_disaster
via:https://medium.com/tensorflow/an-introduction-to-probabilistic-programming-now-available-in-tensorflow-probability-6dcc003ca29e 雷鋒網(wǎng) AI 科技評(píng)論編譯。
雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。