Functional API
前面我们介绍了序列模型,可以实现简单的神经网络算法,然而很多时候我们的模型并不是严格的序列化模型。你的网络可能是network-in-network形式的,或者有多输入,多输出(图像分割)等等。 这个时候序列模型就不可行了,你需要用到keras的Functional API。Functional API接受tensors返回tensor,多个函数组合到一起就是一个框架, 也就是keras.models里面的Model类。
在函数式模型中,所有的模型都是可调用的,就像层一样,很容易利用可以训练好的模型,提供tensor进行调用。调用训练好的模型时,不仅仅是重用结构,也是重用权重。
先使用keras.Input将输出转换为tensor
from keras import Input
input_tensor = Input(shape=(64,))
使用keras.models.Model将定义好的模型转换为函数式框架,
from keras.models import Sequential, Model
from keras import layers
from keras import Input
input_tensor = Input(shape=(784,))
x = layers.Dense(128, activation='relu')(input_tensor)
x = layers.Dense(64, activation='relu')(x)
x = layers.Dense(32, activation='relu')(x)
output_tensor = layers.Dense(10, activation='softmax')(x)
model = Model(input_tensor, output_tensor)
下面我们使用函数式模型改写上次定义的Sequential Model
函数式多层感知机
from keras import layers
from keras import models
from keras.models import Model
from keras import Input
from keras.datasets import mnist
from keras.utils import to_categorical # convert int labels to one-hot vector
# define model
input_tensor = Input(shape=(784,))
x = layers.Dense(128, activation='relu')(input_tensor)
x = layers.Dense(64, activation='relu')(x)
x = layers.Dense(32, activation='relu')(x)
output_tensor = layers.Dense(10, activation='softmax')(x)
model = Model(input_tensor, output_tensor)
# print the model
model.summary
# load data
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.astype('float32')/255 # normalize to 0~1
test_images = test_images.astype('float32')/255
train_images = train_images.reshape((60000,-1))
test_images = test_images.reshape((10000,-1))
# convert to one-hot vectors
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
# define training config
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
# train the model
model.fit(train_images, train_labels, epochs=5, batch_size=64)
# evaluate the model
test_loss, test_accuracy = model.evaluate(test_images, test_labels)
print("test loss:", test_loss)
print("test accuracy:", test_accuracy)
# 输出
60000/60000 [==============================] - 2s 33us/step - loss: 0.2904 - acc: 0.9173
Epoch 2/5
60000/60000 [==============================] - 2s 30us/step - loss: 0.1186 - acc: 0.9653
Epoch 3/5
60000/60000 [==============================] - 2s 30us/step - loss: 0.0852 - acc: 0.9747
Epoch 4/5
60000/60000 [==============================] - 2s 30us/step - loss: 0.0670 - acc: 0.9798
Epoch 5/5
60000/60000 [==============================] - 2s 30us/step - loss: 0.0541 - acc: 0.9839
10000/10000 [==============================] - 0s 21us/step
test loss: 0.09876689948337153
test accuracy: 0.9746
当然函数式模型可以做的肯定不止是这么简单,下面我们看两个只有函数式模型才可以做的例子, 多输入模型, 主要参考kaggle上这篇文章, 这里我们只看模型定义部分。
# define CNN model using keras
# input 1
Input_figure = Input(shape=(75,75,3), name='input1')
# input 2
Input_angle = Input(shape=(1,), name = 'input2')
x = Conv2D(13, kernel_size=(3,3))(Input_figure)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = MaxPooling2D(pool_size=(2,2))(x)
x = Dropout(0.3)(x)
x = Conv2D(21, kernel_size=(3,3))(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = MaxPooling2D(pool_size=(2,2))(x)
x = Dropout(0.3)(x)
x = Conv2D(34, kernel_size=(3,3))(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = MaxPooling2D(pool_size=(2,2), strides=(2,2))(x)
x = Dropout(0.3)(x)
x = Conv2D(55, kernel_size=(3,3))(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = MaxPooling2D(pool_size=(2,2), strides=(2,2))(x)
x = Dropout(0.3)(x)
x = GlobalMaxPool2D()(x)
# concatenate x and input 2
x = concatenate([x, Input_angle])
x = Dense(89)(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = Dropout(0.3)(x)
x = Dense(89, activation='elu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(inputs=[Input_figure, Input_angle], outputs=out)
后面我们介绍一个实例来了解下深度学习中常见的流程。