以下是我与同事和学生就如何优化深度模型进行的对话、消息和辩论的摘要。如果你发现了有影响力的技巧,请分享。
首先,为什么要改进模型?
像卷积神经网络(CNN)这样的深度学习模型具有大量的参数;实际上,我们可以调用这些超参数,因为它们原本在模型中并没有被优化。你可以网格搜索这些超参数的最优值,但需要大量硬件计算和时间。那么,一个真正的数据科学家能满足于猜测这些基本参数吗?
改进模型的最佳方法之一是基于在你的领域进行过深入研究的专家的设计和体系结构,他们通常拥有强大的硬件可供使用。而且,他们经常慷慨地开源建模架构和原理。
深度学习技术
以下是一些通过预训练模型来改善拟合时间和准确性的方法:
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 最佳实践
下面是 Keras 中的最终层修改示例,其中包含 14 个 MNIST 类:
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
TensorFlow
Torch
Caffe
在 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(""%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 = """
""".format(data=repr(str(strip_def)), id='graph'+str(np.random.rand()))
iframe = """
""".format(code.replace('"', '"'))
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 采用两个可选参数:
也可以直接获得 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'))