如何使用Keras函数式API进行深度学习?
haoteby 2025-04-01 18:14 38 浏览
图:pixabay
原文来源:
https://machinelearningmastery.com
作者:Jason Brownlee
「雷克世界」编译:嗯~阿童木呀、多啦A亮
可以这样说,Keras Python库使得创建深度学习模型变得快速且简单。
序列API使得你能够为大多数问题逐层创建模型。当然它也是有局限性的,那就是它并不能让你创建拥有共享层或具有多个输入或输出的模型。
Keras中的的函数式API是创建模型的另一种方式,它具有更多的灵活性,包括创建更为复杂的模型。
在本教程中,你将了解如何用Keras中更具灵活性的函数式API来定义深度学习模型。
完成本教程后,你将明白:
o序列API和函数式API之间的区别。
o如何使用函数式API定义简单的多层感知器、卷积神经网络以及循环神经网络模型。
o如何定义具有共享层和多个输入和输出的更为复杂的模型。
教程概述
本教程涵盖六部分内容,分别是:
1.Keras序列模型
2.Keras函数式模型
3.标准网络模型
4.共享层模型
5.多个输入和输出模型
6.最佳实践
1. Keras序列模型
Keras提供了一个序列模型API。
这是一种创建深度学习模型的方法,其中创建了一个序列类的实例,还创建了模型层并将其添加到其中。
例如,可以将层定义为数组的形式并传递给序列:
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提供了定义模型的一种更为灵活的方式。
尤其是,它使得你能够定义具有多个输入或输出以及共享层的模型。不仅如此,它还使得你能够定义特定的非循环网络图。
模型是通过创建层的实例并将它们直接地成对相互连接来定义的,然后定义一个Model,指定层作为模型的输入和输出。
接下来了解一下Keras函数式API的三个独特方面:
o定义输入
与序列模型不同的是,你必须创建并定义一个独立的输入层来指定输入数据的形状。
输入层接受一个形状参数,即一个元组,它表示的是输入数据的维数。。
如果输入数据是一维的,例如多层感知器,那么这个形状必须能够明确地为在训练网络过程中进行分割数据时使用的小批量大小的形状留下空间。因此,这个形状数组总是用最后一个维度(2)定义,例如:
from keras.layers import Input
visible = Input(shape=(2,))
o连接层
模型中的层是成对连接的。
这是通过在定义每个新层时指定输入的出处完成的。这里使用括号表示法,以便在创建层之后,就指定了来自当前层输入出处的层。
让我们用一个简短的例子来说明这一点。我们可以如上所述那样创建输入层,然后创建一个隐藏层作为密集层,只接受来自输入层的输入。
from keras.layers import Input
from keras.layers import Dense
visible = Input(shape=(2,))
hidden = Dense(2)(visible)
注意可见性,在创建密集层之后,将输入层的输出作为输入与密集的隐藏层进行连接。
就是这种方式能够将各个层逐次连接起来,从而使得函数式API具有灵活性。例如,你可以看到开始定义层的临时图表是多么容易。
o创建模型
在创建了所有模型层并将它们连接在一起之后,你就必须定义模型了。
与序列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时,最好先去了解一些标准的神经网络模型是如何进行定义的。
在本节中,我们将定义一个简单的多层感知器、卷积神经网络和循环神经网络。
这些例子将为理解接下来更为详细的示例奠定基础。
o多层感知器
在本节中,我们定义了一个用于二元分类(binary classification)的多层感知器模型。
该模型有10个输入、3个分别具有10、20和10个神经元的隐藏层、以及一个只有一个输出的输出层。在每个隐层中都使用了纠正线性激活函数(Rectified linear activation functions),而在输出层中使用了一个sigmoid激活函数,以用于二元分类。
# 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')
运行该示例,展示出该网络的结构:
该模型图的一个简图也被创建并保存到文件中。
多层感知器网络图
o卷积神经网络
在本节中,我们将定义一个用于图像分类的卷积神经网络。
该模型接收一个规格为64×64的黑白图像作为输入,然后有一个卷积层和池化层的序列作为特征提取器,随后是一个用以解释特征的完全连接层,以及一个用于两个类预测的sigmoid激活函数。
# 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')
运行该示例,总结模型层:
该模型图的简图也被创建并保存到文件。
卷积神经网络图
o循环神经网络
在本节中,我们将定义一个用于序列分类的长短型记忆循环神经网络。
该模型期望以一个特征的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')
运行该示例,总结模型层。
该模型图的简图也被创建并保存到文件。
循环神经网络图
4.共享层模型
多个层可以共享来自一个层的输出。
例如,可能有多个不同的特征提取层是来自于同一个输入的,或者有多个层是用于解释来自一个特征提取层的输出的。
我们来看看这两个例子。
o共享输入层
在本节中,我们定义了具有不同大小内核的多个卷积层来解释图像输入。
该模型采用大小为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')
运行该示例,总结模型层。
该模型图的简图也被创建并保存到文件。
具有共享输入的神经网络图
o共享特征提取层
在本节中,我们将用两个并行子模型来解释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')
运行该示例,总结模型层。
该模型图的简图也被创建并保存到文件。
共享特征提取层的神经网络图
5.多个输入和输出模型
函数式API也可用于开发具有多个输入的更复杂的模型,可能具有不同的形式。它也可以用于开发产生多个输出的模型。
我们将在本节中查看每个示例。
o多输入模型
我们将开发一个图像分类模型,它将两个版本的图像作为输入,每个版本的大小不同。具体是黑白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')
运行该示例,总结模型层。
该模型图的简图被创建并保存到文件。
具有多个输入的神经网络图
o多输出模型
在本节中,我们将开发出一种可以进行两种不同类型预测的模型。给定一个特征的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')
运行该示例,总结模型层。
该模型图的简图被创建并保存到文件。
具有多个输出的神经网络图
6.最佳实践
在本节中,我会给你一些建议,以便在定义自己的模型时充分利用函数式API。
o一致的变量名:对输入(可见)、输出层(输出),甚至是隐藏层(hidden1,hidden2)使用相同的变量名称。它将有助于正确地将它们联系起来。
o回顾层总结:坚持归纳模型总结并回顾层输出,以确保模型按预期那样连接在一起。
o回顾图表简图:坚持创建模型图的简图,并对其进行回顾,以确保所有的东西都按照你的意愿放在一起。
o命名层:你可以为在回顾模型图的总结和简图时使用的层分配名称。例如:Dense(1,命名 ='hidden1')。
o单独的子模型:考虑分离子模型的开发,并在最后将子模型组合在一起。
更多内容
如果你想深入了解更多信息,以下将提供有关该主题的更多资源。
o序列模型API:
https://keras.io/models/model/
o使用Keras 序列模型开始:
https://keras.io/models/model/
o使用Keras函数型API开始:
https://keras.io/models/model/
o模型类函数式API:
https://keras.io/models/model/
相关推荐
- Python爬虫进阶教程(二):线程、协程
-
简介线程线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行过程中的最小单元,由线程ID、程序计数器、寄存器集合和堆栈共同组成。线程的引入减小了程序并发执行时的开销,提高了操作系统的并发性能...
- A320-V2500发动机系统FADEC介绍(2)
-
目的全权数字发动机控制(FADEC)系统在所有飞行和运行阶段提供全范围发动机控制。...
- 三国志战棋版:玩家“二叔”用这套群DOT在比武中拿下31胜5负
-
声明:本文首发于今日头条,而后发布于“鼎叔闯三棋”的微信公众号、抖音、哔哩哔哩和小红书平台,如果在其他平台就是抄袭。...
- 真正的独一无二:Dot One 推出 DNA 定制系列 139英镑起
-
相信很多人在挑选衣物时有着这样的困扰,综合了性价比、面料等因素后好不容易找到了心仪的款式,还要担心是否会撞衫,不管是擦肩而过的陌生人还是身边的熟人,都令人尴尬。小部分人为此热衷于购买少量的古着或者限量...
- 崩铁:周年庆福利再升级,老角色加强时间确定,3.xdot体系反转
-
#埃安UT大一圈高级很多#...
- Dotgo推出RBMHub,扩大了CPaaS提供商的覆盖范围和功能
-
据telecompaper网7月15日报道,用于商业消息传递的RichCommunicationServices(RCS)解决方案的领先提供商Dotgo宣布推出RBMHub。RBMHub的推出扩大了C...
- 深度解析:快照取消Dot职业的将何去何从
-
写在前面曾几何时,术士的出现便被冠以dot大师的名头,从远古时期的献祭腐蚀虹吸不如暗牧一个痛,到TBC上满dot=荣誉击杀+1,到wlk接近全暴击的冰晶腐蚀,再到CTM就算了吧MOP的各种变态吸x放...
- 星穹铁道:抽卡芙卡之前,你必须了解什么是dot!
-
卡妈终于上线了,可还是有很多人不明白什么是dot伤害,抽了卡妈直接玩起了直伤流,把一个持续伤害的引爆器玩成了打手,卡妈打dot伤害是远高于直伤的,有了卡妈的玩家一直了解dot,不然这卡妈就真被玩成四不...
- 游戏界的闪耀星辰陨落:悼念知名游戏博主″dotα牛娃″
-
无尽哀思!在数字时代浪潮中,游戏不仅是消遣娱乐的代名词,更是连接心灵的桥梁,构筑了无数人的青春回忆。在这片浩瀚无垠的游戏宇宙中,有这样一位博主,他以独特的风采、深邃的洞察力和无尽的热情,成为了玩家心中...
- 直击2017新加坡同性恋聚会Pink Dot,自由爱!
-
今年的“粉红点”又来啦~这个支持LGBT群体(男女同志、双性恋、跨性别等)群体的活动,从2009年起,已经在新加坡举办8年了!”这个非营利的同性恋权益活动,主要是希望大家了解到,不管一个人的性倾向或...
- python-dotenv,一款超级实用处理环境变量python库
-
python-dotenv,一款超级实用处理环境变量python库python-dotenv概述:...
- 亚马逊语音助手毫无征兆发笑 诡异至极吓坏用户
-
来源:新华网美国电商亚马逊7日承诺,将更改名下“亚历克萨”语音系统设置,令它不会莫名发笑,免得吓坏用户。“亚历克萨”是亚马逊开发的语音助手软件,可服从用户语音指令完成对话、播放音乐等任务。依照原来设计...
- 2022最火英文网名男女生
-
精选好听英文昵称带翻译1.moveon(离开)2.Monster(怪物)3.Solo吉他手4.Finish.(散场)...
- 智能家具 RecycleDot 的出现给传统家具厂商带来新的挑战
-
从可穿戴手环、手表到智能衣服,智能硬件逐步渗透到每一个领域。最近有一对父子MikeSandru和JohnSandru在自家的车库中设计了一款智能家具RecycleDot,给日渐萧条的家具行...
- 欧洲通信卫星公司 OneWeb 敦促印度DoT尽早批准提供卫星宽带服务
-
据telecomtalk2月17日报道,欧洲通信卫星公司EutelsatOneWeb近日敦促印度电信部(DoT)尽快批准其在印度部署双地球站网关的计划,以便连接其近地轨道(LEO)全球卫星星座,并...