Python深度学习之Keras函数式API

Deep Learning with Python

这篇文章是我学习《Deep Learning with Python》(第二版,François Chollet 著) 时写的系列笔记之一。文章的内容是从 Jupyter notebooks 转成 Markdown 的,你可以去 GitHubGitee 找到原始的 .ipynb 笔记本。

你可以去这个网站在线阅读这本书的正版原文(英文)。这本书的作者也给出了配套的 Jupyter notebooks

本文为 第7章 高级的深度学习最佳实践 (Chapter 7. Advanced deep-learning best practices) 的笔记之一。

7.1 Going beyond the Sequential model: the Keras functional API

不用 Sequential 模型的解决方案:Keras 函数式 API

我们之前用的 Sequential 模型是最基础、但常用的一种模型,它只有一个输入和一个输出,整个网络由层线性堆叠而成。

Sequential 模型:层的线性堆叠

但是,有时我们的网络需要多个输入。比如预测衣服价格,输入商品信息、文本描述、图片,这三类信息应该分别用 Dense、RNN、CNN 处理,提取出信息后用一个合并模块把所有各种信息综合起来最终预测价格:

一个多输入模型

也有时,我们的网络需要多个输出(多个头)。比如输入一个小说,我们希望得到小说的分类,并推测写作时间。这个问题应该使用一个共用的模块去处理文本,提取信息,然后分别交给小说分类器、日期回归器去预测分类、写作时间:

一个多输出(或多头)模型

还有时,有些复杂的网络会使用非线性的网络拓扑结构。比如一种叫 Inception 的东西,输入会被多个并行的卷积分支处理,然后将这些分支的输出合并为单个张量;还有种叫 residual connection (残差连接)的方法,将前面的输出张量与后面的输出张量相加,从而将前面的表示重新注入下游数据流中,防止信息处理流程中的信息损失:

Inception 模块:层组成的子图,具有多个并行卷积分支;残差连接:通过特征图相加将前面的信息重新注入下游数据

这些网络都是图状(graph-like)的,是个网络结构,而不是 Sequential 那样的线性堆叠。要在 Keras 中实现这种复杂的模型,就需要使用 Keras 的函数式 API。

函数式 API

Keras 的函数式 API 把层当作函数来使用,接收张量并返回张量:

from tensorflow.keras import Input, layers

input_tensor = Input(shape=(32, ))    # 输入张量
dense = layers.Dense(32, activation='relu')    # 层函数
output_tensor = dense(input_tensor)   # 输出张量 

我们来用函数式 API 构建一个简单网络,和 Sequential 做比较:

# Sequential 模型

from tensorflow.keras.models import Sequential
from tensorflow.keras import layers

seq_model = Sequential()
seq_model.add(layers.Dense(32, activation='relu', input_shape=(64, )))
seq_model.add(layers.Dense(32, activation='relu'))
seq_model.add(layers.Dense(10, activation='softmax'))

seq_model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 32)                2080      
_________________________________________________________________
dense_2 (Dense)              (None, 32)                1056      
_________________________________________________________________
dense_3 (Dense)              (None, 10)                330       
=================================================================
Total params: 3,466
Trainable params: 3,466
Non-trainable params: 0
_________________________________________________________________
# 函数式 API 模型

from tensorflow.keras.models import Model
from tensorflow.keras import Input
from tensorflow.keras import layers

input_tensor = Input(shape=(64, ))
x = layers.Dense(32, activation='relu')(input_tensor)
x = layers.Dense(32, activation='relu')(x)
output_tensor = layers.Dense(10, activation='softmax')(x)

func_model = Model(input_tensor, output_tensor)

func_model.summary()
Model: "functional_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_2 (InputLayer)         [(None, 64)]              0         
_________________________________________________________________
dense_4 (Dense)              (None, 32)                2080      
_________________________________________________________________
dense_5 (Dense)              (None, 32)                1056      
_________________________________________________________________
dense_6 (Dense)              (None, 10)                330       
=================================================================
Total params: 3,466
Trainable params: 3,466
Non-trainable params: 0
_________________________________________________________________

Model 对象实例化的时候,只需给出输入张量和输入张量变换(经过各种层)得到的输出张量。Keras 会在自动找出从 input_tensor 到 output_tensor 所包含的每一层,并将这些层组合成一个图状的数据结构——一个 Model。

注意,output_tensor 必须是由对应的 input_tensor 变换得到的。如果用不相关的输入张量和输出张量来构建 Model,会爆 Graph disconnected 的 ValueError (书上写的 keras 是 RuntimeError,tf.keras 是 ValueError):

>>> unrelated_input = Input(shape=(32,))
>>> bad_model = Model(unrelated_input, output_tensor)
... # Traceback
ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_2:0", shape=(None, 64), dtype=float32) at layer "dense_4". The following previous layers were accessed without issue: []

也就是说,无法从指定的输入连接到输出形成一张图(Graph,那种数据结构,网络的那种)啦。

对这种函数式 API 构建的网络,编译、训练或评估都和 Sequential 相同。

# 编译
func_model.compile(optimizer='rmsprop', loss='categorical_crossentropy')

# 随机训练数据
import numpy as np
x_train 
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值