Keras工具库
Keras是站在巨人肩膀上的深度学习框架,其后端可以用不同的DL框架支撑,比如google的TensorFlow,比如微软的CNTK,比如mxnet
01.Keras工具库简介
- 高层封装神经网络API
- 纯Python编写
- 利用TensorFlow、Theano及CNTK后端计算
Kares为支持快速实验而生,能够把你的idea迅速转化为结果。
选择Kares的理由: - 简易和快速的原型设计
- 支持CNN和RNN,或二者的结合
- 无缝CPU和GPU切换
02.Keras序贯模型使用方法详解
序贯模型可以理解为简单的汉堡堆叠 or 手动加菜,可以通过向Sequential模型传递一个layer的list来构造序贯模型,或者通过.add()方法一个个的将layer加入模型中。
model = Sequential()
model.add(Dense(32, input_shape=(784,)))
model.add(Activation('relu'))
模型需要知道输入数据的shape,Sequential的第一层需要接受一个关于输入数据shape的参数,后面的各个层则可以自动的推导出中间数据的shape。第一层的数据维度可以这么给进去(和Tensorflow定义placeholder有点像):
- 传递一个input_shape的关键字参数给第一层,input_shape是一个tuple类型的数据,其中也可以填入None,如果填入None则表示此位置可能是任何正整数。数据的batch大小不应包含在其中。
- 有些2D层,如Dense,支持通过指定其输入维度input_dim来隐含的指定输入数据shape。一些3D的时域层支持通过参数input_dim和input_length来指定输入shape。
- 如果你需要为输入指定一个固定大小的batch_size(常用于stateful RNN网络),可以传递batch_size参数到一个层中,例如你想指定输入张量的batch大小是32,数据shape是(6,8),则你需要传递batch_size=32和input_shape=(6,8)。
03.Keras函数式模型使用方法详解
Keras函数式模型接口是用户定义多输出模型、非循环有向模型或具有共享层的模型等复杂模型的途径。一句话,只要你的模型不是类似VGG一样一条路走到黑的模型,或者你的模型需要多于一个的输出,那么你总应该选择函数式模型。函数式模型是最广泛的一类模型,序贯模型(Sequential)只是它的一种特殊情况。
应用场景:
当模型需要多于一个的输出或结构十分复杂时,函数式模型应用较为广泛。
from keras.layers import Input, Dense
from keras.models import Model
import tensorflow as tf
from keras.backend.tensorflow_backend import set_session
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.3
set_session(tf.Session(config=config))
inputs = Input(shape=(784,))
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x)
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(data, labels)
利用函数式模型的接口,我们可以很容易的重用已经训练好的模型:你可以把模型当作一个层一样,通过提供一个tensor来调用它。注意当你调用一个模型时,你不仅仅重用了它的结构,也重用了它的权重。
序贯式:
- 针对Model类对象操作
函数式:
- 层对象接受张量为参数,返回一个张量。
- 输入时张量,输出也是张量
- 一个框架就是一个模型,通过Model定义
序贯式和函数式的训练方式是一致的。
在写深度学习的代码时注意数据的维度。
04.Keras多层感知器
手写数字识别为例:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f465yxuN-1584535290471)(_v_images/20200318201855852_6322.png)]
model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.001),
metrics=['accuracy'])
05.Keras卷积神经网络
卷积神经网络是一种在计算机视觉当中广泛应用的神经网络,其特殊的网络结构,包含卷积层、池化层等,能在共享参数的同时保证对图像特征的高效抽取。经典的卷积神经网络结构如下。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x6o4Bl8f-1584535290472)(_v_images/20200318202048753_1643.png =609x)]
以图片识别为例:
为了提高模型的泛化能力,我们使用到了一个叫做数据增强的处理,在keras中可以通过ImageDataGenerator完成,详细的可以参见Image Data Generator。这个处理会对输入的图片数据进行例如旋转、平移、截取、水平、垂直翻转等处理,并不改变图像内容,但是能扩量计算机没有看过的数据,提高模型的泛化能力。
from keras.preprocessing.image import ImageDataGenerator
generated_images = ImageDataGenerator(
featurewise_center=True, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=True, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
rotation_range=0, # randomly rotate images in the range (degrees, 0 to 180)
width_shift_range=0.2, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.2, # randomly shift images vertically (fraction of total height)
horizontal_flip=True, # randomly flip images
vertical_flip=False) # randomly flip images
generated_images.fit(X_train)
构建模型
# nb_epoch、batch_size、nb_filters、nb_pool、nb_conv为超参数
model = Sequential()
model.add(Conv2D(nb_filters, (nb_conv, nb_conv),padding='same',input_shape=X_batch.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPool2D(2,2))
model.add(Conv2D(nb_filters, (nb_conv, nb_conv)))
model.add(Activation('relu'))
model.add(MaxPool2D(2,2))
model.add(Conv2D(nb_filters, (nb_conv, nb_conv)))
model.add(Activation('relu'))
model.add(MaxPool2D(2,2))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
06.Transfer Learning and Fine-Tuning
在实践中,由于数据集不够大,很少有人从头开始训练网络。常见的做法是使用预训练的网络(例如在ImageNet上训练的分类1000类的网络)来重新fine-tuning(也叫微调)
Fine-tuning卷积网络。替换掉网络的输入层(数据),使用新的数据继续训练。Fine-tune时可以选择fine-tune全部层或部分层。通常,前面的层提取的是图像的通用特征(generic features)(例如边缘检测,色彩检测),这些特征对许多任务都有用。后面的层提取的是与特定类别有关的特征,因此fine-tune时常常只需要Fine-tuning后面的层。
model_vgg16_conv = VGG16(weights='imagenet', include_top=False) # 到如预训练好的模型
for layer in model_vgg16_conv.layers[:-4]: # 需要训练最后四层的参数,其余都不需要训练
layer.trainable = False
# 搭建模型
input = Input(shape=(IMG_WIDTH, IMG_HEIGHT, 3))
x = model_vgg16_conv(input)
x = Flatten()(x)
x = Dense(64, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(2, activation='softmax')(x)
model = Model(input=input, output=x)
07.要点总结
1.快速Keras模型构建方案
- 线性神经网络叠加方式:
- 推荐使用序贯式模型构建方案(Sequencial)
- 多输入/多输出,循环神经网络结构,复杂神经网络:
- 推荐使用函数式模型构建方案(Functional)
2.如何用深度学习更好地解决问题
- 使用成熟的框架
- 微调(Fine-tune)
- 同一个模型,平均多个测试样例
模型构建方案(Sequencial) - 多输入/多输出,循环神经网络结构,复杂神经网络:
- 推荐使用函数式模型构建方案(Functional)
2.如何用深度学习更好地解决问题
- 使用成熟的框架
- 微调(Fine-tune)
- 同一个模型,平均多个测试样例
- 交叉验证训练多个模型