Keras中的顺序模型Sequential和函数式模型Model

原文链接:https://blog.csdn.net/weixin_44177568/article/details/115873212

文章目录

使用函数式模型构建复杂网络

前面两节分别讲述了:基本分类模型和回归模型 ,但是这两种都是基于Keras中的顺序模型进行构建的,即神经网络只有一个输入和一个输出;如下图所示:

而Keras中模型的构建方式分为两种:

顺序模型(Sequential)

函数式模型(Model)

相比顺序模型,函数式模型可以构建更加深层、更加宽度的网络,其在大量数据基础上,可以有更强的拟合能力。

1、加宽网络(输入、输出不变)

在不改变数据的基础上,加宽网络的宽度!直接修改上一节中的网络结构,新的网络结构如下:

input = keras.layers.Input(shape=x_train_all.shape[1:]) # 定义输入层(指定输入数据的维度)

dense_1 = keras.layers.Dense(30, activation="relu")(input) # 全连接1

dense_2 = keras.layers.Dense(30, activation="relu")(dense_1) # 全连接2

concat_layer = keras.layers.Concatenate()([input, dense_2]) # 将输入层 和 全连接2 拼接

dense_3 = keras.layers.Dense(30, activation="relu")(concat_layer) # 全连接3

output = keras.layers.Dense(1)(dense_3) # 输出层

model = keras.Model(inputs = [input], outputs = [output]) # 创建函数式Model,指定输入层和输出层

上图为上一节中的顺序式模型。

上图为函数式模型。两种神经网络最终效果不同,网络更宽的模型效果更好!

1.1、完整代码:

# 导入相关工具库

from sklearn.datasets import fetch_california_housing

from sklearn.model_selection import train_test_split

from sklearn.preprocessing import StandardScaler

import keras

# 加载数据集

housing_data = fetch_california_housing()

# 划分训练集和测试集

x_train_all, x_test_all, y_train_all , y_test_all = train_test_split(housing_data["data"], housing_data["target"])

# 数据处理(标准化)

scaler = StandardScaler()

x_train_all = scaler.fit_transform(x_train_all)

x_test_all = scaler.transform(x_test_all)

# 构建模型

input = keras.layers.Input(shape=x_train_all.shape[1:])

dense_1 = keras.layers.Dense(30, activation="relu")(input)

dense_2 = keras.layers.Dense(30, activation="relu")(dense_1)

concat_layer = keras.layers.Concatenate()([input, dense_2])

dense_3 = keras.layers.Dense(30, activation="relu")(concat_layer)

output = keras.layers.Dense(1)(dense_3)

model = keras.Model(inputs = [input], outputs = [output])

# 打印模型结构信息

model.summary()

# 模型编译

model.compile(optimizer=keras.optimizers.SGD(), loss=keras.losses.mean_squared_error)

# 模型训练

history = model.fit(x_train_all, y_train_all, epochs= 50, validation_split=0.1)

# 在测试集上评估

loss = model.evaluate(x_test_all, y_test_all) # 返回测试集的loss

print(loss)

2、多个输入层

和上述改变网络中宽度不同,有时也想改变数据,例如,数据集中一部分特征直接输入网络深层;一部分特征数据依旧一步一步传递下去:如下图所示:

上述中,输入层1、输入层2中的特征划分需要依据数据类型以及实际场景!两个输入层的数据可以重叠也不可以不重叠!

具体网络结构如下所示:

input_1 = keras.layers.Input(shape=[5]) # 特征 0-5 # 总特征有8维,取前4维特征数据

input_2 = keras.layers.Input(shape=[6]) # 特征 2-7 # 总特征有8维,取第2-7维特征数据

dense_1 = keras.layers.Dense(30, activation="relu")(input_2) # 全连接1

dense_2 = keras.layers.Dense(30, activation="relu")(dense_1) # 全连接2

concat_layer = keras.layers.Concatenate()([input_1, dense_2]) # 输入层1 和 全连接2 拼接

dense_3 = keras.layers.Dense(30, activation="relu")(concat_layer) # 全连接3

output = keras.layers.Dense(1)(dense_3) # 输出层

model = keras.Model(inputs = [input_1, input_2], outputs = [output]) # 创建函数式Model,注意输入层有两个!

由于输入层有两个,因此,后期训练、预测时都要指定两个输入层!

2.2、完整代码

# 导入相关工具库

from sklearn.datasets import fetch_california_housing

from sklearn.model_selection import train_test_split

from sklearn.preprocessing import StandardScaler

import keras

# 加载数据集

housing_data = fetch_california_housing()

# 划分训练集和测试集

x_train_all, x_test_all, y_train_all , y_test_all = train_test_split(housing_data["data"], housing_data["target"])

# 数据处理(标准化)

scaler = StandardScaler()

x_train_all = scaler.fit_transform(x_train_all)

x_test_all = scaler.transform(x_test_all)

# 构建模型

input_1 = keras.layers.Input(shape=[5]) # 特征 0-4 # 总特征有8维,取前4维特征数据

input_2 = keras.layers.Input(shape=[6]) # 特征 2-7 # 总特征有8维,取第2-7维特征数据

dense_1 = keras.layers.Dense(30, activation="relu")(input_2)

dense_2 = keras.layers.Dense(30, activation="relu")(dense_1)

concat_layer = keras.layers.Concatenate()([input_1, dense_2])

dense_3 = keras.layers.Dense(30, activation="relu")(concat_layer)

output = keras.layers.Dense(1)(dense_3)

model = keras.Model(inputs = [input_1, input_2], outputs = [output])

# 打印模型结构信息

model.summary()

# 模型编译

model.compile(optimizer=keras.optimizers.SGD(), loss=keras.losses.mean_squared_error)

# 将训练集划分子集

x_train_1, x_train_2 = x_train_all[:, :5], x_train_all[:, 2:]

x_test_1, x_test_2 = x_test_all[:, :5], x_test_all[:, 2:]

# 模型训练

history = model.fit([x_train_1, x_train_2], y_train_all, epochs= 50, validation_split=0.1)

# 在测试集上评估

loss = model.evaluate([x_test_1, x_test_2], y_test_all) # 返回测试集的loss

print(loss)

3、多个输出层

有些任务不仅仅是分类或回归,而是多任务结合的,例如目标检测任务,不仅要在图片中识别出目标(分类)还要给出目标位置、宽高等信息(回归),因此,需要模型多个输出!并且多任务模型训练,有时可以增加模型整体的鲁棒性

对上面的代码继续修改,得到多输出的神经网络模型,图下图所示:

input_1 = keras.layers.Input(shape=[5]) # 特征 0-4 # 总特征有8维,取前4维特征数据

input_2 = keras.layers.Input(shape=[6]) # 特征 2-7 # 总特征有8维,取第2-7维特征数据

dense_1 = keras.layers.Dense(30, activation="relu")(input_2)

dense_2 = keras.layers.Dense(30, activation="relu")(dense_1)

concat_layer = keras.layers.Concatenate()([input_1, dense_2])

dense_3 = keras.layers.Dense(30, activation="relu")(concat_layer)

output1 = keras.layers.Dense(1)(dense_3)

output2 = keras.layers.Dense(1)(dense_2)

model = keras.Model(inputs = [input_1, input_2], outputs = [output1, output2]) # 多输入,多输出

3.3 完整代码

# 导入相关工具库

from sklearn.datasets import fetch_california_housing

from sklearn.model_selection import train_test_split

from sklearn.preprocessing import StandardScaler

import keras

# 加载数据集

housing_data = fetch_california_housing()

# 划分训练集和测试集

x_train_all, x_test_all, y_train_all , y_test_all = train_test_split(housing_data["data"], housing_data["target"])

# 数据处理(标准化)

scaler = StandardScaler()

x_train_all = scaler.fit_transform(x_train_all)

x_test_all = scaler.transform(x_test_all)

# 构建模型

input_1 = keras.layers.Input(shape=[5]) # 特征 0-4 # 总特征有8维,取前4维特征数据

input_2 = keras.layers.Input(shape=[6]) # 特征 2-7 # 总特征有8维,取第2-7维特征数据

dense_1 = keras.layers.Dense(30, activation="relu")(input_2)

dense_2 = keras.layers.Dense(30, activation="relu")(dense_1)

concat_layer = keras.layers.Concatenate()([input_1, dense_2])

dense_3 = keras.layers.Dense(30, activation="relu")(concat_layer)

output1 = keras.layers.Dense(1)(dense_3)

output2 = keras.layers.Dense(1)(dense_2)

model = keras.Model(inputs = [input_1, input_2], outputs = [output1, output2])

# 打印模型结构信息

model.summary()

# 模型编译

model.compile(optimizer=keras.optimizers.SGD(), loss=keras.losses.mean_squared_error)

# 划分特征子集

x_train_1, x_train_2 = x_train_all[:, :5], x_train_all[:, 2:]

x_test_1, x_test_2 = x_test_all[:, :5], x_test_all[:, 2:]

# 模型训练

history = model.fit([x_train_1, x_train_2], [y_train_all, y_train_all], epochs= 50, validation_split=0.1)

# 在测试集上评估,返回总loss、每个输出的loss

sum_loss, output1_loss, output2_loss = model.evaluate([x_test_1, x_test_2], [y_test_all, y_test_all]) # 返回测试集的loss

print(sum_loss, output1_loss, output2_loss)

注意: 由于是多输出,那么每个输出的损失函数都是可以定义的,上述在模型编译时,仅仅指定了loss=keras.losses.mean_squared_error,那么两个输出的损失函数都是均方误差!也可以分开定义。如下;

指定每个输出的损失函数:loss=[“sgd”, “sgd”]

model.compile(optimizer=keras.optimizers.SGD(), loss=["sgd", "sgd"])

指定每个loss的权重,给与某分支较大的决策权:loss_weights=[0.7,0.3]

model.compile(optimizer=keras.optimizers.SGD(), loss=["sgd", "sgd"], loss_weights=[0.7,0.3])

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值