很多人说深度学习是玄学,有很多说不清道不明的东西在里面,实际上,还是有一些规律可言的,虽然不是什么放之四海而皆准的真理,但也是长期总结的一些经验教训,可以试一试,看是不是有用。
卷积神经网络(CNN)等深度学习模型具有大量的参数,我们把这些叫做超参数,因为它们并没有在模型中进行优化。你可以为这些超参数搜索最优值,但是你需要大量的硬件和时间。那么,一个真正的数据科学家会满足于瞎猜这些基本参数吗?
改进模型的最佳方法之一是基于在那些对你的领域进行了深入研究的专家做的设计和结构的基础上构建你的模型。 这些专家通常能调用非常多的硬件资源。含蓄一点说,他们经常对生成的建模体系结构和基本原理进行开源。
这里有一些方法,可以使用预训练模型来减少你的拟合时间和提高你的准确性:
2.使用较小的学习率:因为预训练的权重通常比随机初始化的权重要好!你在这里的选择取决于学习环境和预训练的进展情况,在不同的epochs上检测误差,了解你离收敛有多近。
下面是如何在Minist数据集上用Keras来调整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'))
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,会给你提供高级的抽象,但是不允许你深入到模型的各个部分进行更深入的分析。幸运的是,下面的代码让我们可以直接用Python可视化我们的模型:
# From: https://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)
绘制模型图保存成png文件:
This will plot a graph of the model and save it as a png file:
from keras.utils import plot_model
plot_model(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'))
希望这些可以对你的深度学习项目有所帮助。如果你有其他关于深度学习的模型调试小技巧,也欢迎留言回复与大家交流~
作者:Jonathan Balaban