深度学习技巧和窍门
首先,为什么调整模型?
像卷积神经网络(CNN)这样的深度学习模型具有大量的参数; 我们实际上可以调用这些超参数,因为它们在模型中没有内在地优化。您可以使用gridsearch搜索这些超参数的最佳值,但您需要大量的硬件和时间。那么,一个真正的数据科学家是否愿意猜测这些基本参数呢?
改进模型的最佳方法之一是在专家的设计和架构基础上进行深入研究,这些专家经常使用强大的硬件进行处理。有意思的是,他们经常开源所产生的建模架构和原理。
深度学习技巧
改进模型的最佳方法之一是在专家的设计和架构基础上进行深入研究,这些专家经常使用强大的硬件进行处理。有意思的是,他们经常开源所产生的建模架构和原理。
您可以通过以下几种方法来提高训练前模型的贴合时间和准确性:
研究理想的预训练的架构:学习迁移学习的好处,或浏览一些强大的CNN架构。考虑可能看起来不太明显的领域,但共享潜在的特征。
使用较小的学习率:由于预先训练的权重通常优于随机初始化的权重,因此可以更精细地修改!您的选择取决于学习环境和预训练的进展情况,但请检查各个时期的错误,以了解您融合的程度。
Play with dropout:与回归模型的Ridge和LASSO正则化一样,所有模型都没有优化的 alpha或 dropout。这是一个超参数,取决于您的具体问题,并且必须经过测试。从更大的变化开始 - 跨越数量级的更广泛的网格搜索跨度,就像np.logspace()可以提供的一样,然后像上面的学习率那样下降。
限制权重大小:我们可以限制某些图层权重的最大范数(绝对值),以推广我们的模型
不要触及第一层:神经网络的第一个隐藏层倾向于捕捉通用和可解释的特征,如形状,曲线或跨领域经常相关的交互。我们经常应该放弃这些,并且专注于进一步优化meta²潜在水平。这可能意味着添加隐藏层,所以我们不要急于这个过程!
修改输出图层:将模型默认值替换为适合您的域的新激活函数和输出大小。但是,不要将自己限制为最明显的解决方案。虽然MNIST可能看起来像是需要10个输出类别,但一些数字有共同的变化,并且允许12-16个类别可以更好地解决这些变体并提高模型性能!与上面的提示一样,深度学习模型应该随着我们接近输出而被越来越多地修改和定制。
Techniques in 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 5
model = Sequential()
model.add(Dropout(0.2, input_shape=(784,))) # dropout on the inputs
# this helps mimic noise or missing data
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%建议用于输入。太低,你的效果可以忽略不计;太高了,你underfit。
在输入层和隐藏层上使用dropout。这已被证明可以提高深度学习表现。
使用衰减大的学习速率和大的momentum。
限制你的权重!大的学习率可能导致梯度爆炸。已经显示,对网络权重施加约束 - 例如大小为5的最大范数正则化 - 可以改善结果。
使用更大的网络。在较大的网络中使用dropout时,您可能会获得更好的性能,从而使模型更有机会学习independent representations。
下面是Keras中最后一层修改的例子,其中MNIST有14个类:
from keras.layers.core import Activation, Dense
model.layers.pop() # defaults to last
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 List
Keras Application
OpenCV Example
TensorFlow
VGG16
Inception V3
ResNet
Torch
LoadCaffe
Caffe
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 visualization
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('"', '&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 plot
plot(model, to_file='model.png')
plot 需要两个可选参数:
show_shapes (默认为False)控制图形中是否显示输出形状。
show_layer_names (默认为True)控制图层中是否显示图层名称。
您也可以直接获取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'))