自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

你用什么方法調(diào)試深度神經(jīng)網(wǎng)絡(luò)?這里有四種簡(jiǎn)單的方式哦

開發(fā) 開發(fā)工具 深度學(xué)習(xí)
本文作者總結(jié)了四種調(diào)試深度神經(jīng)網(wǎng)絡(luò)的方法,分別是預(yù)測(cè)合成輸出、可視化激活值、梯度分析和分析模型預(yù)測(cè)。希望這些技巧可以幫助你調(diào)試模型哦!

當(dāng)你花了幾個(gè)星期構(gòu)建一個(gè)數(shù)據(jù)集、編碼一個(gè)神經(jīng)網(wǎng)絡(luò)并訓(xùn)練好了模型,然后發(fā)現(xiàn)結(jié)果并不理想,接下來你會(huì)怎么做?

深度學(xué)習(xí)通常被視為一個(gè)黑盒子,我并不反對(duì)這種觀點(diǎn)——但是你能講清楚學(xué)到的上萬參數(shù)的意義嗎?

但是黑盒子的觀點(diǎn)為機(jī)器學(xué)習(xí)從業(yè)者指出了一個(gè)明顯的問題:你如何調(diào)試模型?

在這篇文章中,我將會(huì)介紹一些我們?cè)?Cardiogram 中調(diào)試 DeepHeart 時(shí)用到的技術(shù),DeepHeart 是使用來自 Apple Watch、 Garmin、和 WearOS 的數(shù)據(jù)預(yù)測(cè)疾病的深度神經(jīng)網(wǎng)絡(luò)。

在 Cardiogram 中,我們認(rèn)為構(gòu)建 DNN 并不是煉金術(shù),而是工程學(xué)。

調(diào)試深度神經(jīng)網(wǎng)絡(luò)

你的心臟暴露了很多你的信息。DeepHeart 使用來自 Apple Watch、 Garmin、和 WearOS 的心率數(shù)據(jù)來預(yù)測(cè)你患糖尿病、高血壓以及睡眠窒息癥(sleep apnea)的風(fēng)險(xiǎn)。

一、預(yù)測(cè)合成輸出

通過預(yù)測(cè)根據(jù)輸入數(shù)據(jù)構(gòu)建的合成輸出任務(wù)來測(cè)試模型能力。

我們?cè)跇?gòu)建檢測(cè)睡眠窒息癥的模型時(shí)使用了這個(gè)技術(shù)?,F(xiàn)有關(guān)于睡眠窒息癥篩查的文獻(xiàn)使用日間和夜間心率標(biāo)準(zhǔn)差的差異作為篩查機(jī)制。因此我們?yōu)槊恐艿妮斎霐?shù)據(jù)創(chuàng)建了合成輸出任務(wù):

標(biāo)準(zhǔn)差 (日間心率)—標(biāo)準(zhǔn)差 (夜間心率)

為了學(xué)習(xí)這個(gè)函數(shù),模型要能夠:

  • 區(qū)分白天和黑夜
  • 記住過去幾天的數(shù)據(jù)

這兩個(gè)都是預(yù)測(cè)睡眠窒息癥的先決條件,所以我們使用新架構(gòu)進(jìn)行實(shí)驗(yàn)的第一步就是檢查它是否能學(xué)習(xí)這個(gè)合成任務(wù)。

你也可以通過在合成任務(wù)上預(yù)訓(xùn)練網(wǎng)絡(luò),以半監(jiān)督的形式來使用類似這樣的合成任務(wù)。當(dāng)標(biāo)記數(shù)據(jù)很稀缺,而你手頭有大量未標(biāo)記數(shù)據(jù)時(shí),這種方法很有用。

二、可視化激活值

理解一個(gè)訓(xùn)練好的模型的內(nèi)部機(jī)制是很難的。你如何理解成千上萬的矩陣乘法呢?

在這篇優(yōu)秀的 Distill 文章《Four Experiments in Handwriting with a Neural Network》中,作者通過在熱圖中繪制單元激活值,分析了手寫模型。我們發(fā)現(xiàn)這是一個(gè)「打開 DNN 引擎蓋」的好方法。

我們檢查了網(wǎng)絡(luò)中幾個(gè)層的激活值,希望能夠發(fā)現(xiàn)一些語(yǔ)義屬性,例如,當(dāng)用戶在睡覺、工作或者焦慮時(shí),激活的單元是怎樣的?

用 Keras 寫的從模型中提取激活值的代碼很簡(jiǎn)單。下面的代碼片段創(chuàng)建了一個(gè) Keras 函數(shù) last_output_fn,該函數(shù)在給定一些輸入數(shù)據(jù)的情況下,能夠獲得一層的輸出(即它的激活值)。

  1. from keras import backend as K 
  2.  
  3. def extract_layer_output(model, layer_name, input_data): 
  4.   layer_output_fn = K.function([model.layers[0].input], 
  5.                                [model.get_layer(layer_name).output]) 
  6.  
  7.   layer_output = layer_output_fn([input_data]) 
  8.  
  9.   # layer_output.shape is (num_units, num_timesteps) 
  10.   return layer_output[0] 

我們可視化了網(wǎng)絡(luò)好幾層的激活值。在檢查第二個(gè)卷積層(一個(gè)寬為 128 的時(shí)間卷積層)的激活值時(shí),我們注意到了一些奇怪的事:

卷積層的每個(gè)單元在每個(gè)時(shí)間步長(zhǎng)上的激活值。藍(lán)色的陰影代表的是激活值。

激活值竟然不是隨著時(shí)間變化的!它們不受輸入值影響,被稱為「死神經(jīng)元」。

ReLU 激活函數(shù),f(x) = max(0, x)

這個(gè)架構(gòu)使用了 ReLU 激活函數(shù),當(dāng)輸入是負(fù)數(shù)的時(shí)候它輸出的是 0。盡管它是這個(gè)神經(jīng)網(wǎng)絡(luò)中比較淺的層,但是這確實(shí)是實(shí)際發(fā)生的事情。

在訓(xùn)練的某些時(shí)候,較大的梯度會(huì)把某一層的所有偏置項(xiàng)都變成負(fù)數(shù),使得 ReLU 函數(shù)的輸入是很小的負(fù)數(shù)。因此這層的輸出就會(huì)全部為 0,因?yàn)閷?duì)小于 0 的輸入來說,ReLU 的梯度為零,這個(gè)問題無法通過梯度下降來解決。

當(dāng)一個(gè)卷積層的輸出全部為零時(shí),后續(xù)層的單元就會(huì)輸出其偏置項(xiàng)的值。這就是這個(gè)層每個(gè)單元輸出一個(gè)不同值的原因——因?yàn)樗鼈兊钠庙?xiàng)不同。

我們通過用 Leaky ReLU 替換 ReLU 解決了這個(gè)問題,前者允許梯度傳播,即使輸入為負(fù)時(shí)。

我們沒想到會(huì)在此次分析中發(fā)現(xiàn)「死神經(jīng)元」,但最難找到的錯(cuò)誤是你沒打算找的。

三、梯度分析

梯度的作用當(dāng)然不止是優(yōu)化損失函數(shù)。在梯度下降中,我們計(jì)算與Δparameter 對(duì)應(yīng)的Δloss。盡管通常意義上梯度計(jì)算的是改變一個(gè)變量對(duì)另一個(gè)變量的影響。由于梯度計(jì)算在梯度下降方法中是必需的,所以像 TensorFlow 這樣的框架都提供了計(jì)算梯度的函數(shù)。

我們使用梯度分析來確定我們的深度神經(jīng)網(wǎng)絡(luò)能否捕捉數(shù)據(jù)中的長(zhǎng)期依賴。DNN 的輸入數(shù)據(jù)特別長(zhǎng):4096 個(gè)時(shí)間步長(zhǎng)的心率或者計(jì)步數(shù)據(jù)。我們的模型架構(gòu)能否捕捉數(shù)據(jù)中的長(zhǎng)期依賴非常重要。例如,心率的恢復(fù)時(shí)間可以預(yù)測(cè)糖尿病。這就是鍛煉后恢復(fù)至休息時(shí)的心率所耗的時(shí)間。為了計(jì)算它,深度神經(jīng)網(wǎng)絡(luò)必須能夠計(jì)算出你休息時(shí)的心率,并記住你結(jié)束鍛煉的時(shí)間。

衡量模型能否追蹤長(zhǎng)期依賴的一種簡(jiǎn)單方法是去檢查輸入數(shù)據(jù)的每個(gè)時(shí)間步長(zhǎng)對(duì)輸出預(yù)測(cè)的影響。如果后面的時(shí)間步長(zhǎng)具有特別大的影響,則說明模型沒有有效地利用早期數(shù)據(jù)。

對(duì)于所有時(shí)間步長(zhǎng) t,我們想要計(jì)算的梯度是與Δinput_t 對(duì)應(yīng)的Δoutput。下面是用 Keras 和 TensorFlow 計(jì)算這個(gè)梯度的代碼示例:

  1. def gradient_output_wrt_input(model, data): 
  2.   # [:, 2048, 0] means all users in batch, midpoint timestep, 0th task (diabetes) 
  3.   output_tensor = model.model.get_layer('raw_output').output[:, 2048, 0] 
  4.   # output_tensor.shape == (num_users) 
  5.  
  6.   # Average output over all users. Result is a scalar. 
  7.   output_tensor_sum = tf.reduce_mean(output_tensor) 
  8.  
  9.   inputs = model.model.inputs # (num_users x num_timesteps x num_input_channels) 
  10.   gradient_tensors = tf.gradients(output_tensor_sum, inputs) 
  11.   # gradient_tensors.shape == (num_users x num_timesteps x num_input_channels) 
  12.  
  13.   # Average over users 
  14.   gradient_tensors = tf.reduce_mean(gradient_tensors, axis=0
  15.   # gradient_tensors.shape == (num_timesteps x num_input_channels) 
  16.   # eg gradient_tensor[10, 0] is deriv of last output wrt 10th input heart rate 
  17.  
  18.   # Convert to Keras function 
  19.   k_gradients = K.function(inputsinputs=inputs, outputs=gradient_tensors
  20.  
  21.   # Apply function to dataset 
  22.   return k_gradients([data.X]) 

在上面的代碼中,我們?cè)谄骄鼗?,在中點(diǎn)時(shí)間步長(zhǎng) 2048 處計(jì)算了輸出。我們之所以使用中點(diǎn)而不是最后的時(shí)間步長(zhǎng)的原因是,我們的 LSTM 單元是雙向的,這意味著對(duì)一半的單元來說,4095 實(shí)際上是第一個(gè)時(shí)間步長(zhǎng)。我們將得到的梯度進(jìn)行了可視化:

Δoutput_2048 / Δinput_t

請(qǐng)注意我們的 y 軸是 log 尺度的。在時(shí)間步長(zhǎng) 2048 處,與輸入對(duì)應(yīng)的輸出梯度是 0.001。但是在時(shí)間步長(zhǎng) 2500 處,對(duì)應(yīng)的梯度小了一百萬倍!通過梯度分析,我們發(fā)現(xiàn)這個(gè)架構(gòu)無法捕捉長(zhǎng)期依賴。

四、分析模型預(yù)測(cè)

你可能已經(jīng)通過觀察像 AUROC 和平均絕對(duì)誤差這樣的指標(biāo)分析了模型預(yù)測(cè)。你還可以用更多的分析來理解模型的行為。

例如,我們好奇 DNN 是否真的用心率輸入來生成預(yù)測(cè),或者說它的學(xué)習(xí)是不是嚴(yán)重依賴于所提供的元數(shù)據(jù)——我們用性別、年齡這樣的用戶元數(shù)據(jù)來初始化 LSTM 的狀態(tài)。為了理解這個(gè),我們將模型與在元數(shù)據(jù)上訓(xùn)練的 logistic 回歸模型做了對(duì)比。

DNN 模型接收了一周的用戶數(shù)據(jù),所以在下面的散點(diǎn)圖中,每個(gè)點(diǎn)代表的是一個(gè)用戶周。

這幅圖驗(yàn)證了我們的猜想,因?yàn)轭A(yù)測(cè)結(jié)果并不是高度相關(guān)的。

除了進(jìn)行匯總分析,查看最好和最壞的樣本也是很有啟發(fā)性的。對(duì)一個(gè)二分類任務(wù)而言,你需要查看最令人震驚的假陽(yáng)性和假陰性(也就是預(yù)測(cè)距離標(biāo)簽最遠(yuǎn)的情況)。嘗試鑒別損失模式,然后過濾掉在你的真陽(yáng)性和真陰性中出現(xiàn)的這種模式。

一旦你對(duì)損失模式有了假設(shè),就通過分層分析進(jìn)行測(cè)試。例如,如果最高損失全部來自第一代 Apple Watch,我們可以用第一代 Apple Watch 計(jì)算我們的調(diào)優(yōu)集中用戶集的準(zhǔn)確率指標(biāo),并將這些指標(biāo)與在剩余調(diào)優(yōu)集上計(jì)算的指標(biāo)進(jìn)行比較。

原文鏈接:https://blog.cardiogr.am/4-ways-to-debug-your-deep-neural-network-e5edb14a12d7

【本文是51CTO專欄機(jī)構(gòu)“機(jī)器之心”的原創(chuàng)譯文,微信公眾號(hào)“機(jī)器之心( id: almosthuman2014)”】 

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2022-06-14 13:55:30

模型訓(xùn)練網(wǎng)絡(luò)

2017-07-05 15:14:30

神經(jīng)網(wǎng)絡(luò)連接方式網(wǎng)絡(luò)單元

2017-06-18 16:20:57

神經(jīng)網(wǎng)絡(luò)單元

2023-10-10 18:00:49

Python編程語(yǔ)言

2022-11-01 16:02:31

架構(gòu)神經(jīng)網(wǎng)絡(luò)模型

2016-07-12 10:03:37

2021-06-11 13:30:28

神經(jīng)網(wǎng)絡(luò)機(jī)器學(xué)習(xí)

2019-03-26 19:00:02

神經(jīng)網(wǎng)絡(luò)AI人工智能

2023-08-30 23:41:16

AI框架項(xiàng)目

2020-05-11 13:44:38

神經(jīng)網(wǎng)絡(luò)人工智能深度學(xué)習(xí)

2017-04-25 08:26:39

神經(jīng)網(wǎng)絡(luò)解碼

2023-02-10 11:13:42

網(wǎng)絡(luò)功耗無線網(wǎng)絡(luò)設(shè)備

2023-11-27 17:24:43

2013-05-13 09:48:47

網(wǎng)絡(luò)接入接入方法綜合布線

2021-06-17 14:46:50

框架jQuery開發(fā)

2020-06-12 07:36:33

Redis

2017-03-22 11:59:40

深度神經(jīng)網(wǎng)絡(luò)

2024-11-04 09:39:08

Java?接口Thread?類

2010-07-28 13:54:42

Flex數(shù)據(jù)綁定

2022-03-25 14:47:24

Javascript數(shù)據(jù)類型開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)