Keras之函数式(Functional)模型
函数式(Functional)模型
我们起初将Functional一词译作泛型,想要表达该类模型能够表达任意张量映射的含义,但表达的不是很精确,在Keras2里我们将这个词改移为“函数式”,函数式模型称作Functional,但它的类名是Model,因此有时候也用Model来代表函数式模型。
Keras函数式模型接口是用户定义多输出模型、非循环有向模型或具有共享层的模型等复杂模型的途径。一句话,只要你的模型不是类似VGG一样一条路走到黑的模型,或者你的模型需要多于一个的输出,那么你总应该选择函数式模型。函数式模型是最广泛的一类模型,序贯(Sequential)模型只是它的一种特殊情况。
第一个模型:全连接网络
Sequential当然是实现全连接网络的最好方式,但我们从简单的全连接网络开始,有助于我们学习这部分的内容。在开始前,有几个概念需要澄清:
- 层对象接受张量作为参数,返回一个张量。
- 输入是张量,输出也是张量的一个框架就是一个模型,通过Model定义。
- 这样的模型可以向Keras的Sequential一样被训练
from keras.layer import Input,Dense
from keras.models import Model #This returns a tensor
inputs = Input(shape=(784,)) #a Layer instance is callable on a tensor , and returns a tensor
x = Dense(64 , activation='relu')(inputs)
x = Dense(64,activation='relu')(x)
predictions = Dense(10,activation='softmax')(x) #This creates a model that includes
#the Input layer and three Dense layers
model = Model(inputs=inputs,outputs=predictions)
model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])
model.fit(data,labels) #starts training
所有的模型都是可调用的,就像层一样
利用函数式模型的接口,我们可以很容易的重用已经训练好的模型:你可以把模型当做一个层一样,通过提供一个tensor来调用它。注意当你调用一个模型时,你不仅仅重用了它的结构,也重用了它的权重。
x = Input(shape=(784,))
#This works, and returns the 10-way softmax we defined above
y = model(x)
这种方式可以允许你快速的创建能处理序列信号的模型,你可以很快将一个图像分类的模型变为一个对视屏分类的模型,只需要一行代码:
from keras.layers import TimeDistributed #Input tensor for sequences of 20 timesteps
#each containing a 784-dimensional vector input_sequences = Input(shape=(20,784)) #This applies our previous model to every timestep in the input sequences.
#the output of the previous model was a 10-way softmax
#so the output of the layer below will be a sequence of 20 vectors of size 10. processed_sequences = TimeDistributed(model)(input_sequences)
多输入和多输出模型
使用函数式模型的一个典型场景是搭建多输入、多输出的模型。
考虑这样一个模型。我们希望预测Twitter上一条新闻会被转发和点赞多少次。模型的主要输入是新闻本身,也就是一个词语的序列。但我们还可以拥有额外的输入,如新闻发布的日期等。这个模型的损失函数将有两部分组成,辅助的损失函数评估仅仅基于新闻本身做出预测的情况,主损失函数评估基于新闻的额外信息的预测的情况,即使来自主损失函数的梯度发生弥散,来自辅导损失函数的信息也能够训练Embedding和LSTM层。在模型中早点使用主要的损失函数是对于深度网络的一个良好的正则方法。总而言之,该模型的框图如下:
让我们用函数式模型来实现这个框图
主要的输入接收新闻本身,即一个整数的序列(每个整数编码了一个词)。这些整数位于1到10,000之间(即我们的字典有10,000)个词。
from keras.layer import Input , Embedding , LSTM , Dense
from keras.models import Model #Headline input: meant to receive sequences of 100 integers ,between 1 and 10000.
#Note that we can name any layer by passing it a "name" argument.
main_input = Input(shape=(100,), dtype='int32' , name='main_input') #This embedding layer will encode the input Sequence
#into a sequence of dense 512-dimensional vectors
x = Embedding(output_dim=512, input_dim=10000, input_length=100)(main_input) #A LSTM will transform the vector sequence into a single vector,
#containing information about the entire sequence
lstm_out = LSTM(32)(x)
然后,我们插入一个额外的损失,使得即使在主损失很高的情况下,LSTM和Embedding层也可以平滑的训练。
auxiliary_output = Dense(1, activation='sigmoid' name='aux_output')(lstm_out)
再然后,我们将LSTM与额外的输入数据串联起来组成输入,送入模型中:
auxiliary_input = Input(shape(5,),name='aux_input')
x = keras.layers.concatenate([lstm_out, auxiliary_input]) #We stack a deep densely-connected network on top
x = Dense(64,activation='relu')(x)
x = Dense(64,activation='relu')(x)
x = Dense(64,activation='relu')(x) #And finally we add the main logistic regression layer
main_output = Dense(1,activation='sigmoid', name='main_output')(x)
最后,我们定义整个2输入,2输出的模型:
model = Model(inputs=[main_input,auxiliary_input], outputs=[main_output, auxiliary_output])
模型的定义完毕,下一步编译模型。我们给额外的损失赋0.2的权重。我们可以通过关键字参数loss_weights或loss来为不同的输出设置不同的损失函数或权值。这两个参数均可以为python的列表或字典。这里我们给loss传递单个损失函数,这个损失函数会被应用于所有输出上。
model.compile(optimizer='rmsprop' , loss='binary_crossentropy',loss_weights=[1.,0.2])
编译完成后,我们通过传递训练数据和目标值训练该模型:
model.fit([headline_data, additional_data],[labels,labels],epochs=50,batch_size=32)
因为我们的输入和输出时被命名过的(在定义时传递了“name”参数,我们也可以用下面的方式编译和训练模型)
model.compile(optimizer='rmsprop',loss={'main_output': 'binary_crossentropy','aux_output':'binary_crossentropy'},loss_weights={'main_output':1.,'aux_output':0.2}) #And trained it via:
model.fit({'main_input': headline_data,'aux_input': addtional_data},{'main_output':labels,'aux_output':labels},epochs=50,batch_size=32)
共享层
另一个使用函数式模型的场合是使用共享层的时候。
考虑微博数据,我们希望建立模型来判别两条微博是否是来自同一个用户,这个需求同样可以用来判断一个用户的两条微博的相似性。
一种实现方式是,我们建立一个模型,它分别将两条微博的数据映射到两个特征向量上,然后将该特征向量串联并加一个logistic回归曾,输出她们来自同一个用户的概率。这种模型的训练数据是一度对的微博。
因为这个问题是对称的,所以处理第一条微博的模型当然也能冲用于处理第二条微博,所以这里我们使用一个共享LSTM层来进行映射。
首先,我们将微博的数据转为(140,256)的矩阵,即每条微博有140个字符,每个单词的特征由256维的词向量表示,向量的每个元素为1表示某个字符出现,为0表示不出现,这是一个one-hot编码。之所以是(140,256),是因为一条微博最多有140个字符,而扩展的ASCII码表编码了常见的256个字符。如果考虑中文字符,那一个单词的词向量就不止256了,此处的微博应为Twitter
import keras
from keras.layers import Input , LSTM,Dense
from keras.models import Model tweet_a = Input(shape=(140,256))
tweet_b = Input(shape=(140,256))
若要对不同的输入共享同一层,就初始化该层一次,然后多次调用它
#This Layer can take as input a matrix
#and will return a vector of size 64
shared_lstm = LSTM(64) #When we reuse the same layer instance
#multiple times, the weights of the layer
#are also being reused
#(it is effectively * the same * layer)
encode_a = shared_lstm(tweet_a)
encode_b = shared_lstm(tweet_b) #we can then concatenate the two vectors:
merget_vector = keras.layers.cocatenate([encoded_a,encodd_b], axis=-1) # And add a logistic regression on top
predictions = Dense(1, activation='sigmoid')(merged_vector) # We define a trainable model linking the
# tweet inputs to the predictions
model = Model(inputs=[tweet_a, tweet_b], outputs=predictions) model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
model.fit([data_a, data_b], labels, epochs=10)
Keras之函数式(Functional)模型的更多相关文章
- Python机器学习笔记:深入理解Keras中序贯模型和函数模型
先从sklearn说起吧,如果学习了sklearn的话,那么学习Keras相对来说比较容易.为什么这样说呢? 我们首先比较一下sklearn的机器学习大致使用流程和Keras的大致使用流程: skl ...
- keras搭建深度学习模型的一些小tips
定义模型两种方法: 1.sequential 类仅用于层的线性堆叠,这是目前最常用的网络架构 2.函数式API,用于层组成的有向无环图,让你可以构建任意形式的架构 from keras import ...
- 【Keras篇】---利用keras改写VGG16经典模型在手写数字识别体中的应用
一.前述 VGG16是由16层神经网络构成的经典模型,包括多层卷积,多层全连接层,一般我们改写的时候卷积层基本不动,全连接层从后面几层依次向前改写,因为先改参数较小的. 二.具体 1.因为本文中代码需 ...
- Keras处理已保存模型中的自定义层(或其他自定义对象)
如果要加载的模型包含自定义层或其他自定义类或函数,则可以通过 custom_objects 参数将它们传递给加载机制: from keras.models import load_model # 假设 ...
- 揭秘Keras推荐系统如何建立模型、获取用户爱好
你是否有过这样的经历?当你在亚马逊商城浏览一些书籍,或者购买过一些书籍后,你的偏好就会被系统学到,系统会基于一些假设为你推荐相关书目.为什么系统会知道,在这背后又藏着哪些秘密呢? 荐系统可以从百万甚至 ...
- 【Keras学习】Sequential模型
序贯(Sequential)模型 序贯模型是多个网络层的线性堆叠,也就是“一条路走到黑”. 可以通过向Sequential模型传递一个layer的list来构造该模型: from keras.mode ...
- keras: 在构建LSTM模型时,使用变长序列的方法
众所周知,LSTM的一大优势就是其能够处理变长序列.而在使用keras搭建模型时,如果直接使用LSTM层作为网络输入的第一层,需要指定输入的大小.如果需要使用变长序列,那么,只需要在LSTM层前加一个 ...
- 使用Keras基于RCNN类模型的卫星/遥感地图图像语义分割
遥感数据集 1. UC Merced Land-Use Data Set 图像像素大小为256*256,总包含21类场景图像,每一类有100张,共2100张. http://weegee.vision ...
- Keras深度神经网络算法模型构建【输入层、卷积层、池化层】
一.输入层 1.用途 构建深度神经网络输入层,确定输入数据的类型和样式. 2.应用代码 input_data = Input(name='the_input', shape=(1600, 200, 1 ...
随机推荐
- SMP
SMP(Symmetrical Multi-Processing):对称多处理技术,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构. 在smp系统中,所有的CP ...
- django中使用POST方法报错 URL via POST, but the URL doesn't end in a slash
该方式是因为URL路径没有使用slash(斜线"/")结尾造成的. 因此在使用POST的JavaScript函数的路径参数中,路径URL必须使用/结尾.
- FirstLetterUtil
package cn.edu.hbcf.common.utils; public class FirstLetterUtil { private static int BEGIN = 45217; p ...
- 转载:JMeter压力测试入门教程[图文]
JMeter压力测试入门教程[图文] Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域. 它可 ...
- EMMC与nand flash的区别
1.NAND Flash 是一种存储介质,要在上面读写数据,外部要加主控和电路设计. 2.eMMC是NAND flash+主控IC ,对外的接口协议与SD.TF卡类似:对厂家而言简化了电路设计,降低了 ...
- java 获取用户真实ip
/** * 获取用户真实ip * @param request * @return */ public static String getIpAddr(HttpServletRequest reque ...
- Linux下vi命令小结
进入vi的命令 vi filename :打开或新建文件,并将光标置于第一行首 vi n filename :打开文件,并将光标置于第n行首 vi filename :打 ...
- 磁盘 & 文件系统
1. dumpe2fs –h /dev/sda1 查询整个磁盘情况( 其中后边的设备名可以换 ) 2. df –h , du –h 查询磁盘容量情况 3. 实体链接和符号链接 实体链接: ln mk. ...
- C++ 函数模板二(函数模板重载)
//函数模板重载 #include<iostream> using namespace std; /* 函数模板会进行严格的类型匹配,模板类型不提供隐式类型转化 普通函数能够进行自动类型转 ...
- 第0步:OracleRAC软件准备
表1 软件准备列表 安装包属性 文件信息 Oracle 11.2.0.4 p13390677_112040_Linux-x86-64_1of7.zip p13390677_112040_Lin ...