keras有着很多已经与训练好的模型供调用,因此我们可以基于这些已经训练好的模型来做特征提取或者微调,来满足我们自己的需求。
比如我们要调用VGG16在imagenet下训练的模型:
代码语言:javascript复制from keras.applications import VGG16
conv_base = VGG16(include_top=False, weights='imagenet')
features_batch = conv_base.predict(inputs_batch)
这里是利用预训练的模型来做特征提取,因此我们不需要顶层的分类器网络部分的权重,只需要使用到训练好的卷积基。这也就是VGG16参数中include_top=False的含义,weights='imagenet'的意思就直接是基于imagenet训练的网络权重了。
但是在服务器上运行的时候遇到一个问题,因为这个模型第一次使用时需要去下载,而服务器连接下载的url超时。。。那就只能手动离线下载然后放到路径里去供调用了。
首先keras提供的模型下载地址是:https://github.com/fchollet/deep-learning-models/releases
其中我们找到vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5下载即可。
从这个命名也可以看出很多信息了,比如从tf看出这是基于tensorflow的(th是基于Theano ),notop也就是我们上面说的不要顶层的分类器部分,h5后缀表示keras使用HDF5格式存储的,等等。
下好后放在哪呢?我们只能看看keras的代码是怎么写的,从报错信息中可以得到你的机器中vgg16.py的文件路径,比如:
代码语言:javascript复制Traceback (most recent call last):
File "main.py", line 9, in <module>
train.train()
File "/cloudox/cifar10_test/train.py", line 52, in train
conv_base = VGG16(include_top=False, weights='imagenet')
File "/……/keras/applications/__init__.py", line 28, in wrapper
return base_fun(*args, **kwargs)
File "/……/keras/applications/vgg16.py", line 11, in VGG16
return vgg16.VGG16(*args, **kwargs)
File "/……/keras_applications/vgg16.py", line 209, in VGG16
file_hash='6d6bbae143d832006294945121d1f1fc')
File "/……/keras/utils/data_utils.py", line 226, in get_file
raise Exception(error_msg.format(origin, e.errno, e.reason))
Exception: URL fetch failure on https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5: None -- [Errno 110] Connection timed out
从报错信息中,第一我们可以知道是下载“https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5”这个文件超时,这也是我们上面文件下载路径的由来。第二我们可以知道下载的源头在哪里,大致检查一下,就会发现是在"/……/keras_applications/vgg16.py"这个文件中(“/usr/local/app/anaconda2/envs/tensorflow/lib/python2.7/site-packages/keras_applications/vgg16.py”),他的代码其实就在这:https://github.com/fchollet/deep-learning-models/blob/master/vgg16.py
好我们看看vgg16.py的代码,首先在顶部定义了两个下载路径:
代码语言:javascript复制WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'
然后往下翻会看到获取模型权重文件的代码:
代码语言:javascript复制 # load weights
if weights == 'imagenet':
if include_top:
weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels.h5',
WEIGHTS_PATH,
cache_subdir='models')
else:
weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5',
WEIGHTS_PATH_NO_TOP,
cache_subdir='models')
model.load_weights(weights_path)
还记得我们调用的时候传的参数吧,VGG16(include_top=False, weights='imagenet'),所以就是这里。这里调用了get_file这个函数来从路径中获取权重文件,那我们看看这个函数在哪,代码中说了在:
代码语言:javascript复制from keras.utils.data_utils import get_file
那就去找嘛,既可以在你的文件夹里找,也可以在github找,因为vgg16这个文件属于一个单独的工程,因此我们从作者的所有仓库中找到keras工程,然后顺着keras.utils.data_utils找到代码,在这:https://github.com/keras-team/keras/blob/master/keras/utils/data_utils.py
这时候离我们要的东西就不远了,这时候都不用详细看代码,我们看下注释:
注释说,这个函数会先检查cache中是否有文件,如果没有就从url下载,而这个cache的路径在~/.keras
,默认存储文件是datasets,说明默认是下载数据集的,还记得vgg16那边传的参数么,cache_subdir='models',所以这个文件应该在的位置就是~/.keras/models
,这时候我们直接进入该目录,发现果然有个models文件:
$ cd ~/.keras/
~/.keras]$ ls
datasets keras.json models
那就直接把文件放进来就好啦。
这时候再去运行之前自己的代码就可以成功啦。