Python深度学习11——Keras实现共享层模型(多输入多输出)

人工智能29

参考书目:陈允杰.TensorFlow与Keras——Python深度学习应用实战.北京:中国水利水电出版社,2021

本系列基本不讲数学原理,只从代码角度去让读者们利用最简洁的Python代码实现深度学习方法。

Keras框架虽然很简单,但是封装得太好了,自定义的自由度不够高,其搭建神经网络像搭建积木一样容易,却难以更改自己想要的积木的形状和位置。好在其神经网络层可以当成函数调用,这就保证了Keras还是具有一定的自定义能力,可以面向对象编程,下面进行一定的神经网络中间层的张量形状的获取,还有怎么实现共享模型,做到多输入和输出。

取得神经网络层的信息

定义模型后,可以显示神经网络各层的名称和输出张量。如果训练完成,还可以显示神经网络的权重。

[En]

After defining the model, we can display the name and output tensor of each layer of the neural network. If the training is finished, the weight of the neural network can also be displayed.

先导入包

from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Dropout

定义模型

# 定义模型
model = Sequential()
model.add(Conv2D(16, kernel_size=(5, 5), padding="same",input_shape=(28, 28, 1), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, kernel_size=(5, 5), padding="same",activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dropout(0.5))
model.add(Dense(10, activation="softmax"))
model.summary()   # 显示模型摘要信息

Python深度学习11——Keras实现共享层模型(多输入多输出)

查看有多少层

# 显示各神经层
print("神经层数: ", len(model.layers))
for i in range(len(model.layers)):
    print(i, model.layers[i].name)

Python深度学习11——Keras实现共享层模型(多输入多输出)

print("每一层的输入张量 ")
for i in range(len(model.layers)):
    print(i, model.layers[i].input)

Python深度学习11——Keras实现共享层模型(多输入多输出)

print("每一层的输出张量: ")
for i in range(len(model.layers)):
    print(i, model.layers[i].output)

Python深度学习11——Keras实现共享层模型(多输入多输出)

#显示各层的权重形状
for i in range(len(model.layers)):
    print(i, model.layers[i].name, ":")
    weights = model.layers[i].get_weights()
    for j in range(len(weights)):
        print("==>", j, weights[j].shape)

可以读取的模型,查看其训练的权重

model = Sequential()
model = load_model("imdb_gru.h5")
model.summary()   #  显示模型摘要信息
# 编译模型
model.compile(loss="binary_crossentropy", optimizer="rmsprop",  metrics=["accuracy"])
# 显示GRU层的权重形状
print(2, model.layers[2].name, ":")
weights = model.layers[2].get_weights()
for i in range(len(weights)):
    print("==>", i,weights[i].shape)

Python深度学习11——Keras实现共享层模型(多输入多输出)

for i in range(len(model.layers)):
    print(i, model.layers[i].name)
    print(i, model.layers[i].input)
    print(i, model.layers[i].output)
    print('\n')

Python深度学习11——Keras实现共享层模型(多输入多输出)

使用Functional API进行搭建

以前Kears搭建模型都是上面那种,类似搭积木,下面使用函数的形式去搭建。

搭建这样一个网络

Python深度学习11——Keras实现共享层模型(多输入多输出)

# 定义模型
mnist_input = Input(shape=(28, 28, 1),
                    name="input")
conv1 = Conv2D(16, kernel_size=(5, 5), padding="same",
               activation="relu", name="conv1")(mnist_input)
pool1 = MaxPooling2D(pool_size=(2, 2),
                     name="pool1")(conv1)
conv2 = Conv2D(32, kernel_size=(5, 5), padding="same",
               activation="relu", name="conv2")(pool1)
pool2 = MaxPooling2D(pool_size=(2, 2),
                     name="pool2")(conv2)
drop1 = Dropout(0.5, name="drop1")(pool2)
flat = Flatten(name="flat")(drop1)
hidden1 = Dense(128, activation="relu", name="hidden1")(flat)
drop2 = Dropout(0.5, name="drop2")(hidden1)
output = Dense(10, activation="softmax",
               name="output")(drop2)
model = Model(inputs=mnist_input, outputs=output)
model.summary()   # 显示模型摘要信息

或者搭建这样一个LSTM网络

Python深度学习11——Keras实现共享层模型(多输入多输出)

# 定义模型
imdb_input = Input(shape=(100,), dtype="int32",
                   name="imdb_input")
embed = Embedding(top_words, 32, input_length=max_words,
                    name="embed")(imdb_input)
drop1 = Dropout(0.25, name="drop1")(embed)
lstm = LSTM(32, name="lstm")(drop1)
drop2 = Dropout(0.25, name="drop2")(lstm)
output = Dense(1, activation="sigmoid",
               name="output")(drop2)
model = Model(inputs=imdb_input, outputs=output)
model.summary()   #显示模型摘要信息

共享层模型

之前的模型都是序贯模型,也就是一层一层的,但有些网络可以多层一起搭建,比如下面的模型,代码如下:

[En]

The previous models are all sequential models, that is, layer by layer, but some networks can be built together with multiple layers, such as the following model, and the code is as follows:

Python深度学习11——Keras实现共享层模型(多输入多输出)

from keras.models import Model
from keras.layers import Input, Dense, Flatten, Conv2D, MaxPooling2D
from keras.layers.merge import concatenate

#定义模型
shared_input = Input(shape=(64, 64, 1))
# 第1个共享输入层的卷积和池化层
conv1 = Conv2D(32, kernel_size=3, activation="relu")(shared_input)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
flat1 = Flatten()(pool1)
# 第2个共享输入层的卷积和池化层
conv2 = Conv2D(16, kernel_size=5, activation="relu")(shared_input)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
flat2 = Flatten()(pool2)
#合并 2 个共享输入层的卷积和池化层
merge = concatenate([flat1, flat2])
hidden1 = Dense(10, activation="relu")(merge)
output = Dense(1, activation="sigmoid")(hidden1)
model = Model(inputs=shared_input, outputs=output)
model.summary()   #  显示模型摘要信息
from keras.utils import plot_model

plot_model(model, to_file="Ch16_4_1.png", show_shapes=True)

也可以不对称,两边随便弄几层,例如这样的

Python深度学习11——Keras实现共享层模型(多输入多输出)

from keras.models import Model
from keras.layers import Input, Dense, LSTM
from keras.layers.merge import concatenate

#定义模型
model_input = Input(shape=(100, 1))
lstm = LSTM(32)(model_input)
# 第 1 个共享特征提取层的解释层
extract1 = Dense(16, activation="relu")(lstm)
# 第 2 个共享特征提取层的解释层
dense1 = Dense(16, activation="relu")(lstm)
dense2 = Dense(32, activation="relu")(dense1)
extract2 = Dense(16, activation='relu')(dense2)
# 合并 2 个共享特征提取层的解释层
merge = concatenate([extract1, extract2])
output = Dense(1, activation="sigmoid")(merge)
model = Model(inputs=model_input, outputs=output)
model.summary()   #显示模型摘要信息

Python深度学习11——Keras实现共享层模型(多输入多输出)

多输入和输出模型

较复杂的模型对输入数据影响较大,如彩色、灰色图片等,销售量受季节、温度、折扣、成本等多种因素影响。这涉及到需要多个输入和输出。让我们构建一个同时输入彩色和灰色图像的模型:

[En]

More complex models have many effects on input data, such as color and gray pictures, and sales volume is affected by many factors, such as season, temperature, discount, cost and so on. This involves the need for multiple inputs and outputs. Let's build a model that inputs both color and gray images:

多输入模型为

Python深度学习11——Keras实现共享层模型(多输入多输出)

from keras.models import Model
from keras.layers import Input, Dense, Flatten, Conv2D, MaxPooling2D
from keras.layers.merge import concatenate

# 定义模型
# 第 1 个灰度图片输入
input1 = Input(shape=(28, 28, 1))
conv11 = Conv2D(16, (3,3), activation="relu")(input1)
pool11 = MaxPooling2D(pool_size=(2,2))(conv11)
conv12 = Conv2D(32, (3,3), activation="relu")(pool11)
pool12 = MaxPooling2D(pool_size=(2,2))(conv12)
flat1 = Flatten()(pool12)
# 第 2 个彩色图片输入
input2 = Input(shape=(28, 28, 3))
conv21 = Conv2D(16, (3,3), activation="relu")(input2)
pool21 = MaxPooling2D(pool_size=(2,2))(conv21)
conv22 = Conv2D(32, (3,3), activation="relu")(pool21)
pool22 = MaxPooling2D(pool_size=(2,2))(conv22)
flat2 = Flatten()(pool22)
# 合并 2 个输入
merge = concatenate([flat1, flat2])
dense1 = Dense(512, activation="relu")(merge)
dense2 = Dense(128, activation="relu")(dense1)
dense3 = Dense(32, activation="relu")(dense2)
output = Dense(10, activation="softmax")(dense3)
# 定义多输入模型
model = Model(inputs=[input1, input2], outputs=output)
model.summary()   # 显示模型摘要信息

多输出模型为:

Python深度学习11——Keras实现共享层模型(多输入多输出)

from keras.models import Model
from keras.layers import Dense, Input

#  定义模型
model_input = Input(shape = (784,))
dense1 = Dense(512, activation="relu")(model_input)
dense2 = Dense(128, activation="relu")(dense1)
dense3 = Dense(32, activation ="relu")(dense2)
# 第 1 个分类输出
output = Dense(10, activation="softmax")(dense3)
# 第 2 个自编码器输出
up_dense1 = Dense(128, activation="relu")(dense3)
up_dense2 = Dense(512, activation="relu")(up_dense1)
decoded_outputs = Dense(784)(up_dense2)
# 定义多输出模型
model = Model(model_input, [output, decoded_outputs])
model.summary()   # 显示模型摘要信息

mnist案例

使用手写数字数据集做上面两个模型的案例。

多输入

由于手写数字集没有彩色,那就改为两个黑白输入(这个案例里面这样做对精度没啥提升作用....只是演示)

from keras.models import Model
from keras.layers import Input, Dense, Flatten, Conv2D, MaxPooling2D
from keras.layers.merge import concatenate
from keras.datasets import mnist
from tensorflow.keras.utils import to_categorical

# 定义模型
# 第 1 个灰度图片输入
input1 = Input(shape=(28, 28, 1))
conv11 = Conv2D(16, (3,3), activation="relu")(input1)
pool11 = MaxPooling2D(pool_size=(2,2))(conv11)
conv12 = Conv2D(32, (3,3), activation="relu")(pool11)
pool12 = MaxPooling2D(pool_size=(2,2))(conv12)
flat1 = Flatten()(pool12)
# 第 2 个彩色图片输入
input2 = Input(shape=(28, 28, 1))
conv21 = Conv2D(16, (3,3), activation="relu")(input2)
pool21 = MaxPooling2D(pool_size=(2,2))(conv21)
conv22 = Conv2D(32, (3,3), activation="relu")(pool21)
pool22 = MaxPooling2D(pool_size=(2,2))(conv22)
flat2 = Flatten()(pool22)
# 合并 2 个输入
merge = concatenate([flat1, flat2])
dense1 = Dense(512, activation="relu")(merge)
dense2 = Dense(128, activation="relu")(dense1)
dense3 = Dense(32, activation="relu")(dense2)
output = Dense(10, activation="softmax")(dense3)
# 定义多输入模型
model = Model(inputs=[input1, input2], outputs=output)
model.summary()   # 显示模型摘要信息

Python深度学习11——Keras实现共享层模型(多输入多输出)

import numpy as np
# 指定乱数种子
seed = 7
np.random.seed(seed)
# 载入数据集
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
# 将图片转换成 4D 张量
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype("float32")
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype("float32")
# 因为是固定范围, 所以执行正规化, 从 0-255 至 0-1
X_train = X_train / 255
X_test = X_test / 255
# One-hot编码
Y_train = to_categorical(Y_train)
Y_test = to_categorical(Y_test)

#编译模型
model.compile(loss="categorical_crossentropy", optimizer="adam",metrics=["accuracy"])

#  训练模型
history = model.fit([X_train,X_train], Y_train,validation_split=0.2,
                    epochs=10, batch_size=128, verbose=2)

model.evaluate([X_test,X_test],Y_test)

Python深度学习11——Keras实现共享层模型(多输入多输出)

多输出

from keras.models import Sequential
from keras.models import load_model
# 建立Keras的Sequential模型
model = Sequential()
model = load_model("mnist.h5")
model.summary()   # 显示模型摘要信息
# 编译模型
model.compile(loss="categorical_crossentropy", optimizer="adam",metrics=["accuracy"])

#  使用 Model 建立 前4层的 Conv2D 和 MaxPooling 层
# 此模型是 1 个输入, 和 4 个输出
layer_outputs = [layer.output for layer in model.layers[:4]]
model_test = Model(inputs=model.input, outputs=layer_outputs)

outputs = model_test.predict(X_train[1].reshape(1,28,28,1))
# 取得第1个 Conv2D 的输出
output = outputs[0]
output.shape

Python深度学习11——Keras实现共享层模型(多输入多输出)

import matplotlib.pyplot as plt
#绘出第1个 Conv2D 层的输出
plt.figure(figsize=(10,8))
for i in range(0,16):
    plt.subplot(4,4,i+1)
    plt.imshow(output[0,:,:,i], cmap="gray")
    plt.axis("off")

Python深度学习11——Keras实现共享层模型(多输入多输出)

#  取得第1个 MaxPooling 的输出
output = outputs[1]
# 绘出第1个 MaxPooling 层的输出
plt.figure(figsize=(10,8))
for i in range(0,16):
    plt.subplot(4,4,i+1)
    plt.imshow(output[0,:,:,i], cmap="gray")
    plt.axis("off")

Python深度学习11——Keras实现共享层模型(多输入多输出)

# 取得第2个 Conv2D 的输出
output = outputs[2]
# 绘出第2个 Conv2D 层的输出
plt.figure(figsize=(10,8))
for i in range(0,32):
    plt.subplot(6,6,i+1)
    plt.imshow(output[0,:,:,i], cmap="gray")
    plt.axis("off")

Python深度学习11——Keras实现共享层模型(多输入多输出)

# 取得第2个 MaxPooling 的输出
output = outputs[3]
# 绘出第2个 MaxPooling 层的输出
plt.figure(figsize=(10,8))
for i in range(0,32):
    plt.subplot(6,6,i+1)
    plt.imshow(output[0,:,:,i], cmap="gray")
    plt.axis("off")

Python深度学习11——Keras实现共享层模型(多输入多输出)

这个多输出模型输出每个步骤的中间层,您可以看到模型学到了什么。它是模型中间层的可视化。

[En]

This multi-output model outputs the middle tier of each step, and you can see what the model has learned. It is the visualization of the middle layer of the model.

Original: https://blog.csdn.net/weixin_46277779/article/details/125702342
Author: 阡之尘埃
Title: Python深度学习11——Keras实现共享层模型(多输入多输出)

相关文章
手把手教你语音识别(三) 人工智能

手把手教你语音识别(三)

朋友们,手把手语音识别第三部分来了,这部分开始讲解网络搭建部分,同样是手把手教你哦,不要错过。 1、读入数据 这部分,就不展开讲了,之前的文章讲过:数据处理,这次直接从读入数据的格式到怼入网络开始讲,...
语音识别——光剑 人工智能

语音识别——光剑

我的圣剑啊,聆听我的召唤!哈哈哈,不好意思啊,我的中二病又犯了。在前段时间,各个短视频平台,光剑变身,光圈普渡众生的视频,不知道大家有没有看到过。在那个时候我就有了一个想做一把光剑的想法。但是呢,单单...
Ubuntu系统安装图形界面 人工智能

Ubuntu系统安装图形界面

一、更新软件库 二、安装插件 三、安装插件 四、运行 运行后进入安装程序,进入GUI界面,通过控制 "↑""↓"找到Ubuntu desktop按空格键选中,再按Tab键跳到OK选项回车! 如果显示a...
k-means算法例题应用 人工智能

k-means算法例题应用

简单介绍:k-means 算法是一个聚类的算法 。属于 无监督学习算法,也是就样本没有label(标签),然后根据某种规则进行"分割", 把相同的或者相近的放在一起。 算法缺点:不能帮助我们自动分类,...
剪映+json解析将视频中的声音转换成文本 人工智能

剪映+json解析将视频中的声音转换成文本

前言 有时候我们想将一段视频中的音频转换成文本,最简单最笨的方法就是通过人耳去听,然后通过打字打出来。但这种方法无疑是十分费劲的。机智的小伙伴肯定都知道我们可以借助语音识别工具来做这件事,但是比较现实...