keras提供了Sequential线性的模型,但是有些网络需要多个输入,有些网络有多个输出,更甚之层与层之间有内部分支,这使得网络看起来像是层构成的图,而不是线性的堆叠。有些场景需要多模态的输入,这些的输入来源于不同的数据,例如下面的例子

而有些场景是多个输出,例如给定一部小说,希望将其自动分类(比如爱情、惊悚),同时还希望预测其写作的日期。当然可以训练两个独立的模型,但由于这些属性并非是统计无关的,你可以构造一个更好的模型,进行联合训练输出想要的结果。

那么如何该用keras实现这类模型呢?

函数式API可是用于构建具有多个输入输出的模型,通常情况下,这种模型会在某一时刻用一个可以组合多个张量层将不同的输入分支合并、相加和连接等。

多输入模型

假设一个问答模型有两个输入:一个自然语言描述的问题和一个文本片段,后者提供用于回答问题的信息。然后模型要生成一个回答,在最简单的情况下,这个回答只包含一个词,可以通过对某个预定义的词表做softmax得到。

import numpy as np
from keras import layers
from keras.models import Model
from keras import Input
from keras.utils import plot_model
import keras text_vocabulary_size = 10000
question_vocabulary_size = 10000
answer_vocabulary_size = 500
# 文本输入是一个长度可变的整数序列,注意name为可选
text_input = Input(shape=(None,), dtype='int32', name='text')
# 将输入映射为一个64的向量
embedded_text = layers.Embedding(text_vocabulary_size, 64)(text_input)
#利用lstm将向量编码为单个向量
encoded_text = layers.LSTM(32)(embedded_text)
question_input = Input(shape=(None,),dtype='int32',name='question')
embedded_question = layers.Embedding(question_vocabulary_size, 32)(question_input)
encoded_question = layers.LSTM(16)(embedded_question)
concatenated = layers.concatenate([encoded_text, encoded_question],axis=-1)
# 拼接
answer = layers.Dense(answer_vocabulary_size,activation='softmax')(concatenated)
#在模型实例化时,指定两个输入和输出
model = Model([text_input, question_input], answer)
model.compile(optimizer='rmsprop',loss='categorical_crossentropy', metrics=['acc'])

看一下模型的架构

可以通过plot_model(model,show_shapes=True,to_file='model.png')内置方法将模型的结构输出出来

接下来怎么训练这个双输入模型呢?有两个可用的API:1、向模型中输入一个由numpy组成的列表 2、输入一个将输入名称映射为numpy数组的字典

num_samples = 1000
max_length = 100
text = np.random.randint(1, text_vocabulary_size, size=(num_samples, max_length))
question = np.random.randint(1, question_vocabulary_size, size=(num_samples, max_length))
answers = np.random.randint(answer_vocabulary_size, size=(num_samples))
answers = keras.utils.to_categorical(answers, answer_vocabulary_size)
#model.fit([text, question], answers, epochs=10, batch_size=128)
model.fit({'text': text, 'question': question}, answers,epochs=10, batch_size=128)

多输出模型

一个简单的例子:输入某人的一些列社交发帖,预测这个人的年龄、性别和收入水平

代码如下:

vocabulary_size = 50000
num_income_groups = 10
posts_input = Input(shape=(None,), dtype='int32', name='posts')
embedded_posts = layers.Embedding(256, vocabulary_size)(posts_input)
x = layers.Conv1D(128, 5, activation='relu')(embedded_posts)
x = layers.MaxPooling1D(5)(x) x = layers.Conv1D(256, 5, activation='relu')(x)
x = layers.Conv1D(256, 5, activation='relu')(x)
x = layers.MaxPooling1D(5)(x)
x = layers.Conv1D(256, 5, activation='relu')(x)
x = layers.Conv1D(256, 5, activation='relu')(x)
x = layers.GlobalMaxPooling1D()(x)
x = layers.Dense(128, activation='relu')(x) age_prediction = layers.Dense(1, name='age')(x)
income_prediction = layers.Dense(num_income_groups,activation='softmax',name='income')(x)
gender_prediction = layers.Dense(1, activation='sigmoid', name='gender')(x)
model = Model(posts_input, [age_prediction, income_prediction, gender_prediction])
model.summary()
plot_model(model,show_shapes=True,to_file='model.png')
#model.compile(optimizer='rmsprop',\
# loss=['mse', 'categorical_crossentropy', 'binary_crossentropy'])
model.compile(optimizer='rmsprop',\
loss=['mse', 'categorical_crossentropy', 'binary_crossentropy'],\
loss_weights=[0.25, 1., 10.])

对于这些多数出(多头)的模型该怎么训练呢?预测年龄是一个回归问题,性别是一个分类问题。为了能够进行训练我们必须将这些损失合并为单个标量。在合并不同的损失函数的时候,最简单的方法就是对所有的函数加权求和。在 Keras 中,你可以在编译时使用损失组成的列表或 字典来为不同输出指定不同损失,然后将得到的损失值相加得到一个全局损失,并在训练过程 中将这个损失最小化。注意,在严重不平衡的损失会导致模型单独针对单个损失最大的任务进行优化,而忽略了其他的任务。为了解决这一问题可以对每个损失指定一个权重。

有向无环图

利用函数是API不仅能够方便的构建多输入或多输出模型,而且可以实现内部更为复杂的拓扑结构。Keras中的神经网络可以是层组成的任意有向五环图(directed acyclic graph,DAG)

代码如下:

input_x = Input(shape=(250,250,1), dtype='float32', name='X')
branch_a = layers.Conv2D(128, 1,activation='relu', strides=2,padding='same')(input_x)
branch_b = layers.Conv2D(128, 1, activation='relu',padding='same')(input_x)
branch_b = layers.Conv2D(128, 3, activation='relu',strides=2,padding='same')(branch_b) branch_c = layers.AveragePooling2D(3, strides=2,padding='same')(input_x)
branch_c = layers.Conv2D(128, 3, activation='relu',padding='same')(branch_c) branch_d = layers.Conv2D(128, 1, activation='relu',padding='same')(input_x)
branch_d = layers.Conv2D(128, 3, activation='relu',padding='same')(branch_d)
branch_d = layers.Conv2D(128, 3, activation='relu', strides=2,padding='same')(branch_d) output = layers.concatenate([branch_a, branch_b, branch_c, branch_d], axis=-1) model = Model(input_x, output)
plot_model(model,show_shapes=True,to_file='model.png')

模型的效果图如下

权重共享

函数是API有一个重要的特性,那就是能够多次使用一层实例。如果对一个实例的层调用两次,而不是每次都实例化一个新层,那么每次调用都重复使用这个权重,这样就可以构建共享分支的模型了。据一个例子求A、B句子的相似度。A对于B等于B对于A的相似度。

lstm = layers.LSTM(32)
left_input = Input(shape=(None, 128))
left_output = lstm(left_input)
right_input = Input(shape=(None, 128))
right_output = lstm(right_input)
merged = layers.concatenate([left_output, right_output], axis=-1)
predictions = layers.Dense(1, activation='sigmoid')(merged)
model = Model([left_input, right_input], predictions)
plot_model(model,show_shapes=True,to_file='model.png')

模型如下:

keras实现不同形态的模型的更多相关文章

  1. keras系列︱Sequential与Model模型、keras基本结构功能(一)

    引自:http://blog.csdn.net/sinat_26917383/article/details/72857454 中文文档:http://keras-cn.readthedocs.io/ ...

  2. 使用 keras 和 tfjs 构建血细胞分类模型

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识!

  3. 【Keras篇】---Keras初始,两种模型构造方法,利用keras实现手写数字体识别

    一.前述 Keras 适合快速体验 ,keras的设计是把大量内部运算都隐藏了,用户始终可以用theano或tensorflow的语句来写扩展功能并和keras结合使用. 二.安装 Pip insta ...

  4. Keras入门(二)模型的保存、读取及加载

    本文将会介绍如何利用Keras来实现模型的保存.读取以及加载.   本文使用的模型为解决IRIS数据集的多分类问题而设计的深度神经网络(DNN)模型,模型的结构示意图如下: 具体的模型参数可以参考文章 ...

  5. keras框架 反复调用model 模型 出错

    Cannot interpret feed_dict key as Tensor: Tensor Tensor("Placeholder_8:0", shape=(3, 3, 12 ...

  6. 1.keras实现-->自己训练卷积模型实现猫狗二分类(CNN)

    原数据集:包含 25000张猫狗图像,两个类别各有12500 新数据集:猫.狗 (照片大小不一样) 训练集:各1000个样本 验证集:各500个样本 测试集:各500个样本 1= 狗,0= 猫 # 将 ...

  7. 人脸检测及识别python实现系列(5)——利用keras库训练人脸识别模型

    人脸检测及识别python实现系列(5)——利用keras库训练人脸识别模型 经过前面稍显罗嗦的准备工作,现在,我们终于可以尝试训练我们自己的卷积神经网络模型了.CNN擅长图像处理,keras库的te ...

  8. Keras之序贯(Sequential)模型

    序贯模型(Sequential) 序贯模型是多个网络层的线性堆叠. 可以通过向Sequential模型传递一个layer的list来构造该模型: from Keras.models import Se ...

  9. keras 保存训练的最佳模型

    转自:https://anifacc.github.io/deeplearning/machinelearning/python/2017/08/30/dlwp-ch14-keep-best-mode ...

随机推荐

  1. Tcp/ip实验准备:一个简单的定时器——boost实现

    tcp/ip实验须要在指定的时间查看结果,为了实验方便,做了一个定时器.用法是: 在命令行输入:timer 输入数字之后,计时对应秒数 输入m数字之后.计时对应分钟数(支持小数分钟数) 输入q退出. ...

  2. Swift - UITableView的用法

    因为倾向于纯代码编码,所以不太喜欢可视化编程,不过也略有研究,所以项目里面的所有界面效果,全部都是纯代码编写! 终于到了重中之重的tableview的学习了,自我学习ios编程以来,工作中用得最多的就 ...

  3. MongoDB启动报错

    启动mongodb的时候报错: [root@localhost bin]# ./mongod --dbpath /usr/java/mongoNode/data/db --logpath /usr/j ...

  4. docker pull 详解

    docker pull 用于从镜像仓库中拉取或更新指定镜像,用法如:docker pull centos ,默认是从 Docker Hub 中拉取镜像 在拉取镜像前,我们可以先配置 docker 加速 ...

  5. 十分钟理解Java中的动态代理

    十分钟理解 Java 中的动态代理   一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道 ...

  6. java Log4j封装,程序任何位置调用

    一般写log4j,每个类都会定义一个logger 明显这样太麻烦了, 然后封装了一下,明显好用多了. package tools; import java.io.IOException; import ...

  7. LeetCode——Search Insert Position

    Description: Given a sorted array and a target value, return the index if the target is found. If no ...

  8. latest报错

    报错: 解决办法: 安装 babel-preset-latest

  9. 【BZOJ4559】[JLoi2016]成绩比较 动态规划+容斥+组合数学

    [BZOJ4559][JLoi2016]成绩比较 Description G系共有n位同学,M门必修课.这N位同学的编号为0到N-1的整数,其中B神的编号为0号.这M门必修课编号为0到M-1的整数.一 ...

  10. java的Result类

    import org.apache.commons.lang.StringUtils; import java.io.Serializable;import java.util.HashMap;imp ...