跳轉到主要內容
工程的博客

你的模型有多錯了?

量化不確定性與Tensorflow概率
分享這篇文章

在這個博客中,我們看的主題不確定性量化為機器學習和深入學習。絕不是一個新的主題,但是等工具的介紹Tensorflow概率煙花使它容易執行概率建模簡化計算的不確定性。考慮場景,在該場景中,我們預測資產比如房子的價值,基於大量的特性,來驅動購買決定。豈不是很有益的知道某些我們這些預測的價格嗎?Tensorflow概率允許您使用熟悉的Tensorflow語法和方法但是分布增加了工作能力。在這篇介紹性的文章,我們離開先驗貝葉斯治療後,選擇一個更簡單的概率解釋的基本原則。我們使用的可能性原理來說明一個不確定性測量可以獲得與預測值采用深度學習回歸問題。

不確定性量化

不確定性可以分為兩種類型:

  1. 認知不確定性
  2. 偶然的不確定性

認知模型的不確定性是由於沒有信息,但這些信息可以從提供的新數據模型或模型的表示能力增加增加其複雜性。這種類型的不確定性可以解決和減少。偶然的不確定性,另一方麵,源於固有的特性轉化數據生成過程。在隨機過程中,有很多參數和隻有一個子集的這些參數是可觀測的。因此,從理論上講,如果有一種方法來衡量這些參數,我們將能夠準確地再現事件。然而,在大多數現實場景中,這並非如此。在這項工作中,我們試圖量化認知不確定性,這源於缺乏知識在我們的網絡或模型參數。

問題定義

這裏的目標是量化預測的不確定性。換句話說,隨著得到預測值,一定程度的確定性和信心也會計算為每個預測價值。我們將說明這種不確定性分析使用一個回歸的問題。在這裏我們模型自變量和因變量之間的關係用神經網絡。不是單一的神經網絡輸出預測值y_pred,網絡現在預測的參數分布。這個概率分布選擇基於目標的類型或因變量。分類,MaxLike [https://www.nbi.dk/彼得森/教學/ Stat2015 / Week3 / AS2015_1201_Likelihood.pdf)原理告訴我們,網絡權值更新的可能性或概率最大化看到真正的數據類模型(網絡+重量)。正態分布是一個基線;然而,它可能不是適合所有的情況。例如,如果目標變量代表了統計數據,我們會選擇一個泊鬆分布。正態分布,神經網絡輸出兩個值,參數分布y_mean y_std,對於每一個輸入數據點。我們假設參數分布在輸出或目標變量,這可能是也可能不是有效的。對於更複雜的建模,您可能想考慮一個混合高斯模型的或混合密度網絡代替。

通常,預測值的誤差計算使用的損失函數如MSE、叉,等。因為我們有概率輸出,MSE不是一個合適的方法來測量誤差。相反,我們選擇概率函數,或者說負對數似(NLL)作為基線損失函數。事實上,除了差異解釋的確定性和概率的性質,它可以顯示叉和劃分是等價的(參考)。為了說明這一點,下麵的兩個正態分布繪製在圖1虛線表示可能性的概率密度在兩個不同的數據點。窄分布顯示為紅色,而更廣泛的分布是用藍色繪製。的可能性的數據點x = 68高的窄分布,而由x = 85的可能性更高的更廣泛的分布。

樣本不確定性分析,不同方差的正態分布概率密度記者兩個點。
圖1在兩個不同的可能性

使用MaxLike原則[引用]和獨立的假設下的數據點,這裏的目標是最大化每個數據點的可能性。由於獨立假設,可能是因此個人可能的產物。數值穩定,我們使用對數似與可能性。每個點的附近是總結獲得每個迭代的全損。

我們想要捕獲之間的非線性關係可能存在的獨立和依賴的變量,因此我們使用多個隱藏層的激活函數為參數y_mean和y_std。這允許non-monotonic參數的變化。我們可以簡化這在兩個方麵:

  1. 固定方差:y_mean估計隻有一個參數
  2. 線性方差:y_std還估計,但現在這是一個函數的一個隱藏層和沒有激活函數

下麵的例子顯示非線性方差的標準差。第一個示例演示了如何符合線性模型(y_mean線性變異),其次是非線性變化y_mean捕捉到更複雜的現象。

Tensorflow概率(TFP)是什麼?

Tensorflow概率是一個框架,構建在Tensorflow但可以處理和執行操作的分布數據。您可以定義分布和樣本,如以下部分所示。

可用的發行版是什麼?

常見的如伯努利分布、二項正常,γ等。可以在這裏找到更多的信息關於這些分布(https://www.tensorflow.org/probability/api_docs/python/tfp/distributions]

使用Tensorflow概率合成數據預測的不確定性

為了說明如何使用TFP量化預測的不確定性,我們開始合成一維的數據集。合成數據使我們能夠執行控製實驗和單一維度很容易想象與每個數據點關聯和預測的不確定性。

合成數據生成

這裏的目標是生成一些合成數據和不恒定方差。這個屬性的數據被稱為異方差性。這個數據生成部分,然後連接在一起,如下所示。

適合不恒定標準偏差的線性模型

一些噪音被添加到上麵的數據,我們生成目標變量y自變量“x”和噪音。它們之間的關係是:

y = 2.7 * x +噪音


這些數據然後分成訓練集和驗證集來評估性能。依賴和獨立變量之間的關係可以可視化圖2為訓練集和驗證集。

np.random.seed (4710年)噪音= np.random.normal (0,x,len(x))np.random.seed (99年)first_part =len(x1)x11 = np.random.uniform (-1,1first_part)np.random.seed (97年)x12 = np.random.uniform (1,6,len(噪音)-first_part)x = np.concatenate ([x11, x12])x = np.sort (x)y =2.7* x +噪聲
樣本可視化描述的依賴和獨立變量之間的關係。
圖2 -生成的數據

定義模型

我們建立的模型,是一個相當簡單的一個有三個致密層應用於數據和兩個輸出,對應y_mean均值和標準差y_std。這些參數是連接和傳遞到分布函數“my_dist”。

在函數my_dist,正態分布均值和參數化的規模(標準差)。意思是第一個指數在二維變量的參數,定義和標準偏差通過softplus操作,因為我們計算標準差的日誌或日誌y_std。這是因為標準差總是一個積極的價值和神經網絡的輸出層可以是積極的還是消極的。因此,轉換有助於限製輸出隻是積極的價值觀。

功能“附近”計算的負對數似(NLL)輸入數據的網絡參數,顧名思義,回報他們。這將是損失函數。

三個模型生成:

  1. 模型——輸出y_mean和y_std為輸出分布
  2. Model_mean——輸出分布的均值從“my_dist”回來
  3. Model_std——輸出分布的標準偏差從“my_dist”回來
def附近(y,分配):返回-distr.log_prob (y)defmy_dist(參數個數):返回tfd.Normal (loc = params [:,0:1),規模=1 e - 3+ tf.math.softplus (0.05* params [:,1:2)))#參數都是可學的輸入=輸入(形狀= (1,))hiddena =密度(30.)(輸入)hidden1 =密度(20.激活=“relu”)(hiddena)hidden2 =密度(20.激活=“relu”)(hidden1)著幹活=密度(1)(hiddena)#一個out2 =密度(1)(hidden2)# Bparams =連接()([著幹活,out2])# Cdist = tfp.layers.DistributionLambda (my_dist) (params)model_flex_sd =模型(輸入,輸出輸入= = dist)model_flex_sd。編譯(亞當(learning_rate =0.01),損失= NLL)

評估結果

一旦模型訓練和收斂圖檢查,我們也可以觀察附近的測試數據的總和。我們將在下一節詳細看看這個。這可以用於優化模型和評估健康,但應該小心不要執行比較在不同的數據集。附近的總和計算如下所示。

model_flex_sd。評估(x_test y_test verbose = 0)4.0097329248257765

模型擬合訓練和驗證數據如下所示。線性模型是適合的培訓,和獲得的黑線y_mean捕捉到了這一趨勢。方差由虛線紅線表示,這符合方差被納入生成的數據。最後,這是評估的測試數據集。

預測的平均值和標準偏差的測試數據
圖3預測平均值和標準偏差的測試數據

適合非線性模型與不恒定標準差

在這裏,依賴和獨立變量之間的關係以非線性的方式變化由於平方項,如下所示。

2.7 x + y = x ^ 2 +噪音

為了獲得這種非線性行為,我們添加一個激活函數(非線性)y_mean的輸出。類似於之前做了什麼,我們符合預測模型和情節在每個數據點的平均值和標準偏差訓練、驗證和測試數據點如下所示。

輸入=輸入(形狀= (1,))hiddena =密度(30.激活=“relu”)(輸入)hidden1 =密度(20.激活=“relu”)(hiddena)hidden2 =密度(20.激活=“relu”)(hidden1)著幹活=密度(1)(hiddena)#一個out2 =密度(1)(hidden2)# Bparams =連接()([著幹活,out2])# Cdist = tfp.layers.DistributionLambda (my_dist) (params)
樣本可視化繪製預測的平均值和標準偏差在每個數據點的訓練,驗證和測試數據。您會注意到,現在的預測意味著不再是線性和試圖捕獲原始數據中的非線性。
圖4非線性生成數據,訓練和驗證
可視化預測樣本平均值和標準偏差的培訓和驗證數據。
圖5預測平均值和標準偏差的培訓和驗證數據
可視化預測樣本平均值和標準偏差的測試數據。量化不確定性高維真實數據
圖6預測平均值和標準偏差的測試數據

與之前的數據生成,現實往往沒有可取的屬性如單位標準差;因此,預處理的數據通常是一個好主意。技術來說,這是特別重要的,假設的正常數據分布的技術是有效的。這裏使用的數據集是糖尿病數據集[引用]。這是一個回歸的問題與數值特性和目標。

數據預處理

這裏有兩個轉換應用到數據。

  1. 標準化
  2. 電力轉換或分位數轉換

數據標準化和兩種變換應用於數據。電源轉換可以包括Box-Cox變換[g.e.p。框和考克斯,“轉換”的分析,英國皇家統計學會學報,26歲,211 - 252 (1964)。),假設所有價值觀是積極的,或者是[[I.K. Yeo-Johnson變換楊和R.A.約翰遜”,一個新家庭的權力轉換改善正常或對稱。“生物統計學,87 (4),pp.954 - 959 (2000)。],which makes no such assumption about the nature of the data. In the Quantile transformer. Both of these transform the data to more Gaussian-like distribution.每個特性的分位數信息用於地圖所需的分布,這是正態分布

defpreprocess_pipeline_power(df, target_column):定標器= StandardScaler ()power_transform = = PowerTransformer(方法“yeo-johnson”)pipeline_power =管道(((“年代”定標器),(“p”,power_transform)))res_power = pipeline_power.fit_transform (df)x_train、x_test y_train y_test = train_test_split (res_power [:,0:-1],res_power [:,1),test_size =0.2random_state =123年)返回(x_test x_train y_train y_test)
defpreprocess_pipeline_quantile(df, target_column):定標器= StandardScaler ()quantile_transform = QuantileTransformer (n_quantiles =One hundred.output_distribution =“正常”)pipeline_quantile =管道(((“年代”定標器),(“問”,quantile_transform)))res_quantile = pipeline_quantile.fit_transform (df)x_train、x_test y_train y_test = train_test_split (res_quantile [:,0:-1],res_quantile [:,1),test_size =0.2random_state =123年)返回(x_test x_train y_train y_test)

模型,評估

def附近(y,分配):返回-distr.log_prob (y)defmy_dist(參數個數):返回tfd.Normal (loc = params [:,0:1),規模=1 e - 3+ tf.math.softplus (0.05* params [:,1:2)))#參數都是可學的defget_model(X):如果(isinstance(X, pd.DataFrame)):Xlen =len(X.columns)其他的:Xlen = np.shape (X) [1]輸入input1 =(形狀= (Xlen))# 13波士頓住房和8加州房市數據hidden1 =密度(32激活=“relu”、名稱=“dense_1”)(input1)# 32或8hidden2 =密度(8激活=“relu”、名稱=“dense_2”)(input1)著幹活=密度(1激活=“relu”、名稱=“out_1”)(hidden2)#著幹活的意思out2 =密度(1激活=“relu”、名稱=“out_2”)(hidden1)# out2是性病params =連接()([著幹活,out2])# Cdist = tfp.layers.DistributionLambda (my_dist) (params)模型=模型(輸入= input1輸出=距離)模型。編譯(亞當(learning_rate =0.001),損失= NLL)model_mean =模型(輸入= input1輸出= dist.mean ())model_std =模型(輸入= input1輸出= dist.stddev ())model.summary ()返回(模型、model_mean model_std)deffit_model(模型、X_data_train y_data_train batch_size =128年時代=1000年validation_split =0.1):曆史=模型。fit (X_data_train、y_data_train batch_size = batch_size時代=時代,validation_split = validation_split)返回(模型)defevaluate_model(模型、model_mean model_std、X_data_test y_data_test):y_out_mean = model_mean.predict (X_data_test)y_out_std = model_std.predict (X_data_test)y_out_mean_vals = y_out_mean.squeeze(軸=1)如果(isinstance(y_data_test pd.DataFrame)):y_test_true_vals = y_data_test.values.squeeze(軸=1)其他的:y_test_true_vals = y_data_testy_out_std_vals = y_out_std.squeeze(軸=1)neg_log_prob_array = []初步的郵政編碼(y_test_true_vals y_out_mean_vals y_out_std_vals):預測= elem [0]predicted_var = elem [2]true_val = elem [1]neg_log_prob = -1.0* tfd。正常(預測,predicted_var) .log_prob (true_val) .numpy ()neg_log_prob_array.append (neg_log_prob)返回(neg_log_prob_array)

評估結果

如前所述,除了收斂的情節,你可以根據性能評估模型不確定性測試集上使用附近的總和。這個指標為我們提供了一種方法來比較不同模型。我們也可以看看附近的分布測試數據集上得到理解模型推廣到新的數據點。離群值可能會導致一個大發脾氣的,從檢查分布將是顯而易見的。

模型、model_mean model_std = get_model (X_trans)= fit_model模型(模型、X_data_train y_data_train時代= 1000)neg_log_array = evaluate_model(模型、model_mean model_std、X_data_test y_data_test)

這裏,每個點的附近是數組中積累neg_log_array和柱狀圖繪製。我們比較兩個場景:一個分位數轉換應用於目標和效力把應用於其他版本。我們最想要的密度直方圖接近0,表明大部分的數據點附近很低,即模型適合這些點。圖7展示了這兩個轉換技術,分位數轉換似乎略微更好的性能,如果你的目標是最小化的離群值的不確定性模型預測。這也可以用於執行hyperparameter調優的模型並選擇最優的模型。

附近的柱狀圖,最好是我們想要更多的密度對0
圖7的柱狀圖附近,最好是我們想要更多的密度對0

結論

這篇文章展示了如何在預測建模不確定性量化可以是有益的。此外,我們走過使用Tensorflow概率來量化不確定性從概率的角度深度學習的問題。這種方法避免了一個完整的貝葉斯治療和更平易近人介紹不確定性估計。

嚐試在磚上的ML運行時顯示的例子!

免費試著磚

相關的帖子

看到所有工程的博客的帖子
Baidu
map