优秀的编程知识分享平台

网站首页 > 技术文章 正文

Keras中最常用的函数式API(非常好)

nanyue 2024-11-23 20:17:26 技术文章 1 ℃

众所周知,利用Keras-Python库可以快速、轻松地创建属于自己的深度学习的模型,今天我们就来介绍一些我们常用的API函数。

序贯模型(Sequential)API允许你为大多数问题逐层的创建模型。它的局限性在于它不允许你创建共享层或者是具有多个输入或输出的模型。

Keras中的API函数是创建更多灵活性模型的替代方法,其中也包括创建更复杂的模型。

在本篇博客中,你将发现如何在Keras中使用灵活的API函数来定义深度学习模型。

阅读完成后,你将知道:

1.连续的API和API函数之间的区别。

2.如何使用API函数定义简单的多层感知器,卷积神经网络和循环神经网络模型。

3.如何使用共享层和多个输入和输出定义更复杂的模型。

OK,让我们开始吧。

教程概述

本教程分为6部分:

1.Keras序贯模型。

2.Keras功能函数模型。

3.标准网络模型。

4.共享层模型。

5.多个输入和输出模型。

6.最佳练习。

1.Keras序贯模型

Keras提供了一个Sequential模型的API。

这是创建深度学习模型的一种方法,其中创建了Sequential类的实例,并创建了模型图层并将其添加其中。

例如,可以将层定义并传递给Sequential作为数组:


from keras.models import Sequential
from keras.layers import Dense
model = Sequential([Dense(2, input_dim=1), Dense(1)])


层也可以分段添加:


from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(2, input_dim=1))
model.add(Dense(1))


序贯模型的API在大多数情况下非常适合开发深度学习模型,但也有一些限制。例如,它不能定义具有多个不同输入源的模型,因为那样会产生多个输出目标。

2.Keras功能函数模型

Keras功能API为定义模型提供了更灵活的方式。

它允许你定义多个输入或输出的模型以及可以共享图层的模型。除此之外,它还允许你定义临时的非循环网络图。

模型通过创建层的实例并将它们直接彼此成对连接来定义,然后定义一个模型,该模型的指定层作为模型的输入和输出。

我们来看看Keras功能API的三个独特方面:

2.1定义输入

与Sequential模型不同,你必须创建并定义一个独立的输入层,该层指定输入数据的形状。

输入层采用一个模型参数,它是一个代表输入数据维度的元组。

当输入数据为一维时,例如对于多层感知器,该模型必须明确留出在训练网络分割数据时所使用的小批量大小的形状。因此,模型元组始终以挂起的最后一维(2)定义,例如:

from keras.layers import Input

visible = Input(shape=(2,))

2.2连接层

模型中的层可以成对连接,这是通过在定义每个新图层时指定输入来自哪里。使用括号符号,使得在创建图层之后,指定从当前图层的输入到即将到达的图层。

让我们用一个简单的例子来说明这一点。我们可以创建如上所述的输入层,然后创建一个隐藏层,作为仅从输入层接收输入的密集层。


from keras.layers import Input
from keras.layers import Dense
visible = Input(shape=(2,))
hidden = Dense(2)(visible)


正是通过这种连接层的方法,使功能API更具有灵活性。你可以看到开始定义ad-hoc图层的特殊图形变得多么的容易。

2.3创建模型

创建模型所需的所有图层并将其连接在一起后,接下来必须定义模型。与Sequential API一样,该模型是你可以概述、拟合、评估和使用做出预测。

Keras提供了一个Model类,你可以使用它从创建的图层时创建模型。它要求你需要指定输入和输出层。例如:


from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
visible = Input(shape=(2,))
hidden = Dense(2)(visible)
model = Model(inputs=visible, outputs=hidden)


既然现在我们知道了Keras功能API的所有关键部分,我们通过定义一套不同的模型实践一下我们的学习成果。

以下每个示例都是可执行的,并打印结构并创建图表。我建议为你自己的模型做这个,这样可以让你清楚你的定义。

我希望这些示例可以为你在以后使用功能API定义自己的模型时提供了模板。

3.标准网络模型

当开始使用功能API时,最好先了解一些关于标准神经网络模型的定义。在本节中,我们将介绍定义一个简单的多层感知器,卷积神经网络和循环神经网络。

这些例子将为以后理解更详细的例子奠定基础。

3.1多层感知器

在本节中,我们为二进制分类定义了一个多层Perceptron模型。该模型有10个输入,3个隐藏层,10个神经元,输出层有1个输出。在每个隐藏层中使用整流线性激活函数,在输出层使用S形激活函数进行二进制分类。


# Multilayer Perceptron
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
visible = Input(shape=(10,))
hidden1 = Dense(10, activation='relu')(visible)
hidden2 = Dense(20, activation='relu')(hidden1)
hidden3 = Dense(10, activation='relu')(hidden2)
output = Dense(1, activation='sigmoid')(hidden3)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='multilayer_perceptron_graph.png')


运行示例打印网络的结构:


_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input_1 (InputLayer)         (None, 10)                0
_________________________________________________________________
dense_1 (Dense)              (None, 10)                110
_________________________________________________________________
dense_2 (Dense)              (None, 20)                220
_________________________________________________________________
dense_3 (Dense)              (None, 10)                210
_________________________________________________________________
dense_4 (Dense)              (None, 1)                 11
=================================================================
Total params: 551
Trainable params: 551
Non-trainable params: 0
_________________________________________________________________


模型图的创建并保存到文件:

3.2卷积神经网络

在本节中,我们将定义一个用于图像分类的卷积神经网络。

该模型接收黑白64×64图像作为输入,然后两个卷积层和汇集层的序列作为特征提取器,随后是完全连接的层来解释特征,并且输出层是具有S形激活函数。


# Convolutional Neural Network
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
visible = Input(shape=(64,64,1))
conv1 = Conv2D(32, kernel_size=4, activation='relu')(visible)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
conv2 = Conv2D(16, kernel_size=4, activation='relu')(pool1)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
hidden1 = Dense(10, activation='relu')(pool2)
output = Dense(1, activation='sigmoid')(hidden1)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='convolutional_neural_network.png')


运行示例:


_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input_1 (InputLayer)         (None, 64, 64, 1)         0
??????
Total params: 8,933
Trainable params: 8,933
Non-trainable params: 0
________________________________________________________________


模型图的图创建并保存到文件:

3.3循环神经网络

在本节中,我们将定义一个LSTM循环神经网络用于序列分类。

该模型是100个时间步长作为输入,该模型具有单个LSTM隐藏层,用于从序列中提取特征,然后是完全连接的层以解释LSTM输出,随后是用于进行二进制预测的输出层。


# Recurrent Neural Network
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.recurrent import LSTM
visible = Input(shape=(100,1))
hidden1 = LSTM(10)(visible)
hidden2 = Dense(10, activation='relu')(hidden1)
output = Dense(1, activation='sigmoid')(hidden2)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='recurrent_neural_network.png')


运行示例总结模型层。


_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
???????
=================================================================
Total params: 601
Trainable params: 601
Non-trainable params: 0
_________________________________________________________________


模型图的创建并保存到文件:

4.共享层模型

多层可以共享一层的输出。

例如,可能存在来自输入的多个不同的特征提取层,或者用于解释特征提取层输出的多个层。

我们来看看这两个例子。

4.1共享输入层

在本节中,我们使用不同大小的内核定义多个卷积层来解释图像输入。

该模型输入采用大小为64×64像素的黑白图像。有两个CNN特征提取子模型共享该输入:第一个内核大小为4,第二个内核大小为8。这些特征提取子模型的输出被平坦化为向量,并连接成一个长向量,并传递到完全连接的层,以便在最终输出层之前进行二进制分类。


# Shared Input Layer
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
# input layer
visible = Input(shape=(64,64,1))
# first feature extractor
conv1 = Conv2D(32, kernel_size=4, activation='relu')(visible)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
flat1 = Flatten()(pool1)
# second feature extractor
conv2 = Conv2D(16, kernel_size=8, activation='relu')(visible)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
flat2 = Flatten()(pool2)
# merge feature extractors
merge = concatenate([flat1, flat2])
# interpretation layer
hidden1 = Dense(10, activation='relu')(merge)
# prediction output
output = Dense(1, activation='sigmoid')(hidden1)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='shared_input_layer.png')

运行示例总结模型层。

___________________________________________________________________
Layer (type)           Output Shape        Param #     Connected to
===================================================================
???????????????????????
Total params: 415,045
Trainable params: 415,045
Non-trainable params: 0
___________________________________________________________________

模型图的被创建并保存到文件:

4.2共享特征提取层

在本节中,我们使用两个并行子模型解释LSTM特征提取器的输出以进行序列分类。

模型的输入是一个特征为100的时间步长,具有10个存储单元的LSTM层解释该序列。第一种解释模式是浅层的单层完全连接层,第二种是深层的3层模型。两个解释模型的输出都被连接成一个长向量,传递给用于进行二进制预测的输出层。

# Shared Feature Extraction Layer
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.recurrent import LSTM
from keras.layers.merge import concatenate
# define input
visible = Input(shape=(100,1))
# feature extraction
extract1 = LSTM(10)(visible)
# first interpretation model
interp1 = Dense(10, activation='relu')(extract1)
# second interpretation model
interp11 = Dense(10, activation='relu')(extract1)
interp12 = Dense(20, activation='relu')(interp11)
interp13 = Dense(10, activation='relu')(interp12)
# merge interpretation
merge = concatenate([interp1, interp13])
# output
output = Dense(1, activation='sigmoid')(merge)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='shared_feature_extractor.png')

运行示例总结模型层。

___________________________________________________________________
Layer (type)    Output Shape          Param #     Connected to
???????
Total params: 1,151
Trainable params: 1,151
Non-trainable params: 0
___________________________________________________________________

模型图被创建并保存到文件。

5.多个输入和输出模型

功能API也可用于开发具有多个输入的更复杂的模型,可能具有不同的模态。它也可以用于开发产生多个输出的模型。

我们将在本节中查看每个示例。

5.1多输入模型

我们将开发一个图像分类模型,它将两个版本的图像作为输入,每个版本的大小不同。具体是黑白64×64版,彩色32×32版。单独的特征提取CNN模型在每个模型上运行,然后将两个模型的结果连接起来进行解释和最终预测。

请注意,在创建Model()实例时,我们将两个输入图层定义为数组。

model = Model(inputs=[visible1, visible2], outputs=output)

完整的示例如下所示。

# Multiple Inputs
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
# first input model
visible1 = Input(shape=(64,64,1))
conv11 = Conv2D(32, kernel_size=4, activation='relu')(visible1)
pool11 = MaxPooling2D(pool_size=(2, 2))(conv11)
conv12 = Conv2D(16, kernel_size=4, activation='relu')(pool11)
pool12 = MaxPooling2D(pool_size=(2, 2))(conv12)
flat1 = Flatten()(pool12)
# second input model
visible2 = Input(shape=(32,32,3))
conv21 = Conv2D(32, kernel_size=4, activation='relu')(visible2)
pool21 = MaxPooling2D(pool_size=(2, 2))(conv21)
conv22 = Conv2D(16, kernel_size=4, activation='relu')(pool21)
pool22 = MaxPooling2D(pool_size=(2, 2))(conv22)
flat2 = Flatten()(pool22)
# merge input models
merge = concatenate([flat1, flat2])
# interpretation model
hidden1 = Dense(10, activation='relu')(merge)
hidden2 = Dense(10, activation='relu')(hidden1)
output = Dense(1, activation='sigmoid')(hidden2)
model = Model(inputs=[visible1, visible2], outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='multiple_inputs.png')

运行示例:

___________________________________________________________________
Layer (type)              Output Shape      Param #     Connected to
?????????
input_1 (InputLayer)             (None, 64, 64, 1)     0
Total params: 49,699
Trainable params: 49,699
Non-trainable params: 0
___________________________________________________________________

模型图被创建并保存到文件。

5.2多输出模型

在本节中,我们将开发出一种可以进行两种不同类型预测的模型。给定一个特征的100个时间步长的输入序列,该模型将对序列进行分类并输出具有相同长度的新序列。

LSTM层解释输入序列,并返回每个时间步长的隐藏状态。第一个输出模型创建一个堆栈的LSTM,解释特征,并进行二进制预测。第二个输出模型使用相同的输出层对每个输入时间步长进行实值预测。


# Multiple Outputs
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.recurrent import LSTM
from keras.layers.wrappers import TimeDistributed
# input layer
visible = Input(shape=(100,1))
# feature extraction
extract = LSTM(10, return_sequences=True)(visible)
# classification output
class11 = LSTM(10)(extract)
class12 = Dense(10, activation='relu')(class11)
output1 = Dense(1, activation='sigmoid')(class12)
# sequence output
output2 = TimeDistributed(Dense(1, activation='linear'))(extract)
# output
model = Model(inputs=visible, outputs=[output1, output2])
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='multiple_outputs.png')

运行示例。


___________________________________________________________________
Layer (type)           Output Shape          Param #     Connected to
===================================================================
input_1 (InputLayer)     (None, 100, 1)        0
___________________________________________________________________
········
Total params: 1,452
Trainable params: 1,452
Non-trainable params: 0
___________________________________________________________________


模型图的创建并保存到文件:

6.最佳做法

在本节中,我给你一些提示,以便在定义自己的模型时充分利用功能性API。

1.一致的变量名。对输入(可见)和输出层(输出)使用相同的变量名称,甚至可以使用隐藏层(hidden1,hidden2)。它将有助于正确地将事物联系起来。

2.查看图层图。始终打印模型摘要并查看图层输出,以确保模型按预期连接在一起。

3.查看图表。创建一个模型图的情节,并检查它,以确保所有的东西都按照你的意图放在一起。

4.命名图层。你可以为查看模型图的名称和绘图时使用的图层分配名称。例如:Dense(1,name ='hidden1')。

5.单独的子模型。考虑分开子模型的发展,并将子模型结合在一起。

Tags:

最近发表
标签列表