您好,登錄后才能下訂單哦!
這篇文章給大家介紹使用ML和DNN建模的技巧是什么,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
處理原始數據(Process Your Own Data)
因為消費者可能不知道開展數據處理和特征工程,所以數據分析師需要在模型內進行數據預處理。
以文本分類問題為例,使用BERT進行分類。數據分析師不能要求客戶進行標記處理和特征整理。
以回歸問題為例,時間是特征之一。在初始模型中,數據分析師只能使用星期幾(如星期四)作為特征。經過幾次迭代之后,星期幾不再是一個好的特征因素,數據分析師只想使用日期(如31號)作為特征。而客戶可能只提供了星期幾的信息,而沒有具體日期的信息,因此需要進行數據預處理。
以語音識別為例,消費者只能向數據分析師發送音頻,而不能發送諸如Mel Cepstral Coefficient(MFCC)等經典特征數據。
因此,建議在代碼中嵌入數據預處理,而不是要求客戶機進行預處理。
使用張量(Use Tensor)
張量是一個N維數組,用于多維計算。它比使用Python字典或數組要快,深度學習框架(例如PyTorch或TensorFlow)的對象數據格式是tensor。
數據擴充(Data Augmentation)
缺少標記數據是從業者通常面臨的挑戰之一。遷移學習是克服這一問題的途徑之一,計算機視覺從業者可以考慮使用ResNet,自然語言處理從業者可以考慮BERT。另一方面,可以生成合成數據以增加標記數據。albumentations和imgaug可以生成圖像數據,而nlpaug可以生成文本數據。
如果你了解你的數據,你應該量身設計數據擴充方法。請記住,數據科學的黃金法則是garbage in garbage out。
數據采樣(Sampling Same Data)
大多數情況下,我們希望隨機抽取數據,以保持樣本數據在訓練集、測試集和驗證集之間的概率分布是一致的。同時,也希望保持這種“隨機”行為,使得我們可以在不同的時刻獲得相同的訓練集、測試集和驗證集。
如果數據帶有日期屬性,則可以按日期拆分數據。
否則,可以更改隨機種子,使其具有一致的隨機行為。
import torch
import numpy as np
import random
seed = 1234
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
存儲中間狀態(Saving Intermediate Checkpoint)
只是在訓練完成后保存模型,通常具有以下幾個缺點:
由于模型的復雜性、計算資源和訓練數據的大小,整個模型訓練過程可能需要幾天或幾周的時間。如果沒有中間狀態被存儲,這將是非常危險的,因為機器可能會被意外關閉。
一般來說,較長訓練能夠獲得更好的結果(例如,損失更少)。然而,可能會發生過度擬合。在大多數情況下,最后一個模型狀態并不能提供最佳結果。我們大部分時間都需要使用中間狀態的模型來進行生產。
使用檢查-停止機制能夠節省資金。注意到一個模型在幾個周期內并沒有改進,我們可以早點停止它以節省時間和資源。
理想情況下,我們可以連續性存儲模型(例如,在每個epoch之后保存模型),但它需要大量的存儲。事實上,我們建議只保留最好的模型(或最好的三個模型)和最后一個模型。
虛擬周期(Virtual Epoch)
Epoch是模型訓練中一個非常常見的參數。如果初始化不正確,可能會影響模型性能。
例如,如果我們有100萬條記錄,我們設置了5個epoch,那么總共有500萬條的訓練數據。三周后,我們又得到了50萬條記錄。如果我們使用相同的epoch進行模型訓練,總訓練數據將達到750萬。問題是:
難以確定模型性能的改進是由于特定數據的數量增加還是總體數據的數量增加。
新的50萬條數據使訓練時間延長1小時甚至幾天。它增加了機器故障的風險。
建議用虛擬epoch代替原始靜態epoch。虛擬epoch可以根據訓練數據的大小、期望epoch、批大小來計算得到。
通常的靜態epoch如下:
#original
num_data = 1000 * 1000
batch_size = 100
num_step = 14 * 1000 * 1000
num_checkpoint = 20
steps_per_epoch = num_step//num_checkpoint
#TensorFlow/ Keras
model.fit(x, epoch=num_checkpoint, steps_per_epoch=steps_per_epoch,
batch_size=batch_size
)
而虛擬epoch如下:
num_data = 1000 * 1000
num_total_data = 14 * 1000 * 1000
batch_size = 100
num_checkpoint = 20
steps_per_epoch = num_total_data // (batch_size*num_checkpoint)
#TensorFlow/ Keras
model.fit(x, epoch=num_checkpoint, steps_per_epoch=steps_per_epoch,
batch_size=batch_size
)
簡化原則(Simple is Beauty)
從業者通常打算使用最先進的模型來構建初始模型。事實上,我們建議建立一個足夠簡單的模型作為基線模型。原因是:
我們總是需要一個基線模型來證明所提出的模型是正確的。
基線模型不需要在性能方面非常好,但它必須是可解釋的。業務用戶總是想知道預測結果的原因。
易于實施是非常重要的。客戶不能等一年才能得到一個足夠好的模型。我們需要建立一套模型,以便從投資者那里獲得動力,在初始模型的基礎上建立你的精彩模型。
以下是一些建議的不同領域的基線模型:
語音識別:可以使用經典特征,如mel frequency cepstral coefficient(MFCC)或 mel spectrogram features,而不是訓練模型來獲得向量表征(如增加嵌入層)。將這些特征傳遞給一個長短期記憶網絡(LSTM)或卷積神經網絡(CNN)和一個完全連接的層進行分類或預測。
計算機視覺:TODO。
自然語言處理:使用bag-of-words 或 classic word embeddings嵌入LSTM是一個很好的出發點,然后再轉向其它模型,如BERT或XLNet。
簡化問題(Simplifying Problem)
有時,分類問題包括100萬個數據和1000個類別。當模型性能低于理想值時,很難調試模型。糟糕的性能可能是由模型復雜性、數據質量或bug造成的。因此,建議簡化問題,這樣我們就可以保證它是無缺陷的。我們可以利用過度擬合問題來實現這一目標。
一開始,不需要對1000個類別進行分類,可以先對10個類別進行抽樣,每個類別有100個數據,并訓練模型。通過使用相同的訓練數據集(或子集)作為評估數據集,能夠過度擬合模型并獲得良好的結果(例如,80甚至90+的精確度)。在這一基礎上進行模型開發能夠減少bug的出現。
使用評估模式(Using Eval Mode for Training)
如果評估模式的精度在前幾個epoch中沒有變化,通常可能是忘記在評估后重置為“訓練”模式。
在Pytorch中,需要在訓練和評估階段轉換訓練模式以及評估模式。如果啟用訓練模式,批標準化、dropout或其他參數將受到影響。有時,數據分析師可能會在評估模式后忘記啟用訓練模式。
model = MyModel() # Default mode is training mode
for e in range(epoch):
# mode.train() # forget to enable train mode
logits = model(x_train)
loss = loss_func(logits, y_train)
model.zero_grad()
loss.backward()
optimizer.step()
mode.eval() # enable eval mode
with torch.no_grad():
eval_preds = model(x_val)
數據轉換(Data Shifting)
當訓練數據集與評估/測試數據集存在顯著差異時,需要進行數據轉換。在計算機視覺任務中,可能大部分訓練數據是白天的圖片,而測試數據是夜間的圖片。
如果發現訓練損失/準確度和測試損失/準確度之間存在很大差異,可以從兩個數據集中隨機抽取一些樣本進行檢查。為了解決這個問題,可以考慮如下方法:
確保在訓練、測試和預測數據集之間保持相似的數據分布。
如果可能,添加更多的訓練數據。
通過利用相關庫添加合成數據。考慮使用nlpaug(用于自然語言處理和聲學任務)和imgaug(用于計算機視覺任務)。
欠擬合問題(Addressing Underfitting)
欠擬合是指訓練誤差大于期望誤差。換言之,模型無法達到預期的性能。造成大誤差的因素很多。要解決這個問題,可以從一個更簡單的模型或者方法開始,看看它是否可以解決。
執行錯誤分析。通過LIME、SHAP或Anchor來解釋你的模型,這樣你就可以感覺到問題所在。
初始模型可能過于簡單。增加模型的復雜性,例如增加長短期記憶(LSTM)層、卷積神經網絡(CNN)層或完全連接(FC)層。
通過減少正則化層,稍微過擬合模型。Dropout和降低權重則可以防止過擬合。然后可以嘗試移除這些正則化層,看看是否可以解決問題。
采用最先進的模型架構。考慮在自然語言處理(NLP)中使用轉換器(如BERT或XLNet)。
引入合成數據。生成更多數據有助于提高模型性能,而無需任何人工操作。理論上,生成的數據應該共享同一個標簽。它允許模型“看到”更多不同的數據,并最終提高魯棒性。可以利用nlpaug和imgaug來執行數據擴充。
分配更好的超參數和優化器。可以考慮執行超參數調整,而不是使用默認/常規學習速率、epoch、batch size。考慮使用波束搜索、網格搜索或隨機搜索來識別更好的超參數和優化器。這種方法相對簡單,只需改變超參數,但可能需要較長的時間。
重新查看數據并引入額外的特征。
過擬合問題(Addressing Overfitting)
除了欠擬合,你還可能面臨著過擬合的問題。過度擬合意味著你的模型太適合你的訓練集,而對其他數據沒有足夠的適用性。換句話說,訓練集準確性比驗證集準確性要好。考慮以下解決方法:
執行錯誤分析。通過LIME、SHAP或Anchor來解釋你的模型,這樣你就可能發現問題所在。
增加更多的訓練數據。
引入正則化層。Dropout(正則化層)和批處理標準化(normalization layer)通過刪除一些輸入和平滑輸入來幫助減少過度擬合。
引入合成數據。生成更多數據有助于提高模型性能,而無需任何人工操作。
分配更好的超參數和優化器。
移除部分特征。
模型可能太過于復雜。可以減少模型復雜度。
元數據聯系(Meta Data Association)
在模型推出后,需要檢查一些例外數據。一種方法是生成ID并將添加到數據庫中。然而,它伴隨著幾個問題,也增加了故障排除的難度。以下是一些缺點:
影響系統的靈活性。從體系結構設計的角度來看,解耦是構建高柔性系統的途徑之一。如果我們生成ID并將帶有此ID的預測結果傳遞給客戶,那么客戶需要在其數據庫中持久使用它。如果我們更改了格式或數據類型,需要通知所有使用者更新他們的數據庫。
我們可能需要根據使用者的關鍵數據收集更多的元數據。額外的關鍵數據增加了連接的復雜性和存儲消耗。
為了克服這個問題,預測結果應該直接與使用者的關鍵數據相關聯。
轉換為推理模型(Switch to Inference Mode)
使用Pytorch時,在將模型部署到生產環境中時,需要注意幾個設置。前面提到了Pytorch中的eval,它使這些層(如Dropout、BatchNorm)在推理模式下工作,例如在推理階段內不應用任何Dropout操作。它不僅能加快你的進程,而且能把所有的信息輸入神經網絡。
mode.eval() # enable eval mode
with torch.no_grad():
eval_preds = model(x_val)
計算成本(Scalling Cost)
當嘗試擴展API以處理更大的數據量時,有時可能會考慮使用GPU。的確,GPU虛擬機比CPU貴得多。然而,GPU帶來了一些優勢,例如計算時間更少,并且需要較少的VM來維持相同的服務級別。數據分析師應該試著評估一下GPU是否能節省一些錢。
無狀態化(Stateless)
試著使你的API無狀態化,這樣你的API服務可以很容易地調整。無狀態意味著不在API服務器(內存或本地存儲)中保存任何中間結果。只需保持API服務器的簡單性,并將結果返回給客戶端,而無需在內存或本地存儲中存儲任何內容。
批處理(Batch Process)
預測一組數據通常比逐個預測更快。大多數現代機器學習或深度學習框架優化了預測性能(在速度方面)。你可能會注意到,切換到批處理模式預測對于效率有很大的改進。
使用C++
雖然Python是機器學習領域中的主流語言,但與其他編程語言(如C++)相比,Python可能太慢了。如果希望低延遲的計算推理時間,可以考慮使用TorchScript。一般的方案是,你仍然可以在Python中訓練你的模型,但是通過使用它生成C++兼容的模型。
關于使用ML和DNN建模的技巧是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。