選自toward data science
作者:Jonathan Balaban
機器之心編譯
參與:張倩、劉曉坤
本文介紹了幾個深度學習模型的簡單優化技巧,包括遷移學習、dropout、學習率調整等,並展示了如何用 Keras 實現。
以下是我與同事和學生就如何優化深度模型進行的對話、消息和辯論的摘要。如果你發現了有影響力的技巧,請分享。
首先,為什麼要改進模型?
像卷積神經網絡(CNN)這樣的深度學習模型具有大量的參數;實際上,我們可以調用這些超參數,因為它們原本在模型中並沒有被優化。你可以網格搜索這些超參數的最優值,但需要大量硬體計算和時間。那麼,一個真正的數據科學家能滿足於猜測這些基本參數嗎?
改進模型的最佳方法之一是基於在你的領域進行過深入研究的專家的設計和體系結構,他們通常擁有強大的硬體可供使用。而且,他們經常慷慨地開源建模架構和原理。
深度學習技術
以下是一些通過預訓練模型來改善擬合時間和準確性的方法:
研究理想的預訓練體系架構:了解遷移學習的好處,或了解一些功能強大的 CNN 體系架構。考慮那些看起來不太適合但具有潛在共享特性的領域。
使用較小的學習率:由於預訓練的權重通常優於隨機初始化的權重,因此修改要更為精細!你在此處的選擇取決於學習環境和預訓練的表現,但請檢查各個時期的誤差,以了解距離收斂還要多久。
使用 dropout:與回歸模型的 Ridge 和 LASSO 正則化一樣,沒有適用於所有模型的優化 alpha 或 dropout。這是一個超參數,取決於具體問題,必須進行測試。從更大的變化開始——用更大的網格搜索跨越幾個數量級,如 np.logspace() 所能提供的那樣——然後像上面的學習率一樣下降。
限制權重大小:可以限制某些層的權重的最大範數(絕對值),以泛化我們的模型。
不要動前幾層:神經網絡的前幾個隱藏層通常用於捕獲通用和可解釋的特徵,如形狀、曲線或跨域的相互作用。我們應該經常把這些放在一邊,把重點放在進一步優化元潛在級別的特徵上。這可能意味著添加隱藏層,這樣我們就不需要匆忙處理了!
修改輸出層:使用適合你的領域的新激活函數和輸出大小替換模型默認值。不過,不要把自己局限於最明顯的解決方案。儘管 MNIST 看起來似乎需要 10 個輸出類,但有些數字有共同的變量,允許 12-16 個類可能會更好地解決這些變量,並提高模型性能!與上面提到的提示一樣,深度學習模型應該隨著我們接近輸出而不斷修改和定製。
Keras 中的技術
在 Keras 中修改 MNIST 的 dropout 和限制權重大小的方法如下:
model = Sequential()
model.add(Dropout(0.2, input_shape=(784,)))
model.add(Dense(128, input_dim=784, kernel_initializer='normal', activation='relu', kernel_constraint=maxnorm(5)))
model.add(Dropout(0.5))
model.add(Dense(128, kernel_initializer='normal', activation='tanh', kernel_constraint=maxnorm(5)))
model.add(Dropout(0.5))
model.add(Dense(1, kernel_initializer='normal', activation='sigmoid'))
dropout 最佳實踐
使用 20-50 % 的 dropout,建議輸入 20%。太低,影響可以忽略;太高,可能欠擬合。
在輸入層和隱藏層上使用 dropout。這已被證明可以提高深度學習的性能。
使用伴有衰減的較大的學習速率,以及較大的動量。
限制權重!較大的學習速率會導致梯度爆炸。通過對網絡權值施加約束(如大小為 5 的最大範數正則化)可以改善結果。
使用更大的網絡。在較大的網絡上使用 dropout 可能會獲得更好的性能,從而使模型有更多的機會學習獨立的表徵。
下面是 Keras 中的最終層修改示例,其中包含 14 個 MNIST 類:
from keras.layers.core import Activation, Dense
model.layers.pop()
model.outputs = [model.layers[-1].output]
model.layers[-1].outbound_nodes = []
model.add(Dense(14, activation='softmax'))
以及如何凍結前五層權重的示例:
for layer in model.layers[:5]:
layer.trainable = False
或者,我們可以將該層的學習速率設為零,或者使用每個參數的自適應學習算法,如 Adadelta 或 Adam。這有點複雜,在其他平臺(如 Caffe)中實現得更好。
預訓練網絡庫
Keras
Kaggle 列表:https://www.kaggle.com/gaborfodor/keras-pretrained-models
Keras 應用:https://keras.io/applications/
OpenCV 示例:https://www.learnopencv.com/keras-tutorial-fine-tuning-using-pre-trained-models/
TensorFlow
VGG16:https://www.learnopencv.com/keras-tutorial-fine-tuning-using-pre-trained-models/
Inceptiom V3:https://github.com/tensorflow/models/blob/master/inception/README.md#how-to-fine-tune-a-pre-trained-model-on-a-new-task
ResNet:https://github.com/tensorflow/models/blob/master/inception/README.md#how-to-fine-tune-a-pre-trained-model-on-a-new-task
Torch
Caffe
在 Jupyter 中查看你的 TensorBoard 圖
模型的可視化通常很重要。如果你用 Keras 編寫模型,它的抽象很好,但不允許你深入到模型的各個部分進行更細緻的分析。幸運的是,下面的代碼可以讓我們直接使用 Python 可視化模型:
from IPython.display import clear_output, Image, display, HTML
def strip_consts(graph_def, max_const_size=32):
"""Strip large constant values from graph_def."""
strip_def = tf.GraphDef()
for n0 in graph_def.node:
n = strip_def.node.add()
n.MergeFrom(n0)
if n.op == 'Const':
tensor = n.attr['value'].tensor
size = len(tensor.tensor_content)
if size > max_const_size:
tensor.tensor_content = bytes("<stripped %d bytes>"%size, 'utf-8')
return strip_def
def rename_nodes(graph_def, rename_func):
res_def = tf.GraphDef()
for n0 in graph_def.node:
n = res_def.node.add()
n.MergeFrom(n0)
n.name = rename_func(n.name)
for i, s in enumerate(n.input):
n.input[i] = rename_func(s) if s[0]!='^' else '^'+rename_func(s[1:])
return res_def
def show_graph(graph_def, max_const_size=32):
"""Visualize TensorFlow graph."""
if hasattr(graph_def, 'as_graph_def'):
graph_def = graph_def.as_graph_def()
strip_def = strip_consts(graph_def, max_const_size=max_const_size)
code = """
<script>
function load() {{
document.getElementById("{id}").pbtxt = {data};
}}
</script>
<link rel="import" href="https://tensorboard.appspot.com/tf-graph-basic.build.html" onload=load()>
<div style="height:600px">
<tf-graph-basic id="{id}"></tf-graph-basic>
</div>
""".format(data=repr(str(strip_def)), id='graph'+str(np.random.rand()))
iframe = """
<iframe seamless style="width:800px;height:620px;border:0" srcdoc="{}"></iframe>
""".format(code.replace('"', '"'))
display(HTML(iframe))
graph_def = tf.get_default_graph().as_graph_def()
tmp_def = rename_nodes(graph_def, lambda s:"/".join(s.split('_',1)))
show_graph(tmp_def)
使用 Keras 可視化你的模型
這一步將繪製模型的圖並將其保存為 png 文件:
from keras.utils.visualize_util import plot
plot(model, to_file='model.png')
plot 採用兩個可選參數:
也可以直接獲得 pydot.Graph 對象並自己對其進行渲染,如在 iPython notebook 中顯示它:
from IPython.display import SVG
from keras.utils.visualize_util import model_to_dot
SVG(model_to_dot(model).create(prog='dot', format='svg'))
原文連結:https://towardsdatascience.com/deep-learning-tips-and-tricks-1ef708ec5f53
本文為機器之心編譯,轉載請聯繫本公眾號獲得授權。
✄---
加入機器之心(全職記者/實習生):hr@jiqizhixin.com
投稿或尋求報導:content@jiqizhixin.com
廣告&商務合作:bd@jiqizhixin.com