深度學習模型的簡單優化技巧

 2018-06-11 12:01:50.0

以下是我與同事和學生就如何優化深度模型進行的對話、消息和辯論的摘要。如果你發現了有影響力的技巧,請分享。

首先,爲什麼要改進模型?

卷積神經網絡(CNN)這樣的深度學習模型具有大量的參數;實際上,我們可以調用這些超參數,因爲它們原本在模型中並沒有被優化。你可以網格搜索這些超參數的最優值,但需要大量硬件計算和時間。那麼,一個真正的數據科學家能滿足於猜測這些基本參數嗎?

改進模型的最佳方法之一是基於在你的領域進行過深入研究的專家的設計和體系結構,他們通常擁有強大的硬件可供使用。而且,他們經常慷慨地開源建模架構和原理。

深度學習技術

以下是一些通過預訓練模型來改善擬合時間和準確性的方法:

  1. 研究理想的預訓練體系架構:瞭解遷移學習的好處,或瞭解一些功能強大的 CNN 體系架構。考慮那些看起來不太適合但具有潛在共享特性的領域。

  2. 使用較小的學習率:由於預訓練的權重通常優於隨機初始化的權重,因此修改要更爲精細!你在此處的選擇取決於學習環境和預訓練的表現,但請檢查各個時期的誤差,以瞭解距離收斂還要多久。

  3. 使用 dropout:與迴歸模型的 Ridge 和 LASSO 正則化一樣,沒有適用於所有模型的優化 alpha 或 dropout。這是一個超參數,取決於具體問題,必須進行測試。從更大的變化開始——用更大的網格搜索跨越幾個數量級,如 np.logspace() 所能提供的那樣——然後像上面的學習率一樣下降。

  4. 限制權重大小:可以限制某些層的權重的最大範數(絕對值),以泛化我們的模型。

  5. 不要動前幾層:神經網絡的前幾個隱藏層通常用於捕獲通用和可解釋的特徵,如形狀、曲線或跨域的相互作用。我們應該經常把這些放在一邊,把重點放在進一步優化元潛在級別的特徵上。這可能意味着添加隱藏層,這樣我們就不需要匆忙處理了!

  6. 修改輸出層:使用適合你的領域的新激活函數和輸出大小替換模型默認值。不過,不要把自己侷限於最明顯的解決方案。儘管 MNIST 看起來似乎需要 10 個輸出類,但有些數字有共同的變量,允許 12-16 個類可能會更好地解決這些變量,並提高模型性能!與上面提到的提示一樣,深度學習模型應該隨着我們接近輸出而不斷修改和定製。

Keras 中的技術

在 Keras 中修改 MNIST 的 dropout 和限制權重大小的方法如下:

# dropout in input and hidden layers# weight constraint imposed on hidden layers# ensures the max norm of the weights does not exceed 5model = Sequential()model.add(Dropout(0.2, input_shape=(784,))) # dropout on the inputs# this helps mimic noise or missing datamodel.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, Densemodel.layers.pop() # defaults to lastmodel.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

  • LoadCaffe:https://github.com/szagoruyko/loadcaffe

Caffe

  • Model Zoo:https://github.com/BVLC/caffe/wiki/Model-Zoo

在 Jupyter 中查看你的 TensorBoard 圖

模型的可視化通常很重要。如果你用 Keras 編寫模型,它的抽象很好,但不允許你深入到模型的各個部分進行更細緻的分析。幸運的是,下面的代碼可以讓我們直接使用 Python 可視化模型

# From: http://nbviewer.jupyter.org/github/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/deepdream/deepdream.ipynb# Helper functions for TF Graph visualizationfrom IPython.display import clear_output, Image, display, HTMLdef 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_defdef 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_defdef 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('"', '&quot;'))    display(HTML(iframe))# Visualizing the network graph. Be sure expand the "mixed" nodes to see their # internal structure. We are going to visualize "Conv2D" nodes.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 plotplot(model, to_file='model.png')

plot 採用兩個可選參數

  • show_shapes(默認爲 False)控制輸出形狀是否顯示在圖中。

  • show_layer_names(默認爲 True)控制層命名是否顯示在圖中。

也可以直接獲得 pydot.Graph 對象並自己對其進行渲染,如在 iPython notebook 中顯示它:

from IPython.display import SVGfrom keras.utils.visualize_util import model_to_dotSVG(model_to_dot(model).create(prog='dot', format='svg'))

原文鏈接:https://towardsdatascience.com/deep-learning-tips-and-tricks-1ef708ec5f53

文章來源:機器之心