参考书目:陈允杰.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() # 显示模型摘要信息
查看有多少层
# 显示各神经层
print("神经层数: ", len(model.layers))
for i in range(len(model.layers)):
print(i, model.layers[i].name)
print("每一层的输入张量 ")
for i in range(len(model.layers)):
print(i, model.layers[i].input)
print("每一层的输出张量: ")
for i in range(len(model.layers)):
print(i, model.layers[i].output)
#显示各层的权重形状
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)
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')
使用Functional API进行搭建
以前Kears搭建模型都是上面那种,类似搭积木,下面使用函数的形式去搭建。
搭建这样一个网络
# 定义模型
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网络
# 定义模型
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:
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)
也可以不对称,两边随便弄几层,例如这样的
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() #显示模型摘要信息
多输入和输出模型
较复杂的模型对输入数据影响较大,如彩色、灰色图片等,销售量受季节、温度、折扣、成本等多种因素影响。这涉及到需要多个输入和输出。让我们构建一个同时输入彩色和灰色图像的模型:
[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:
多输入模型为
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() # 显示模型摘要信息
多输出模型为:
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() # 显示模型摘要信息
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)
多输出
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
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")
# 取得第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")
# 取得第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")
# 取得第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")
这个多输出模型输出每个步骤的中间层,您可以看到模型学到了什么。它是模型中间层的可视化。
[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实现共享层模型(多输入多输出)

利用WordPress搭建网站

Keras深度学习实战(18)——语义分割详解

深度学习–TensorFlow(4)BP神经网络(损失函数、梯度下降、常用激活函数、梯度消失&&梯度爆炸)

【机器学习】详解 BERT

【SCA-CNN 解读】空间与通道注意力:Spatial and Channel-wise Attention

ubantu18.04下基于cuda11.0的MaskRCNN环境搭建

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

语音识别—kaldi常用文件查看指令

在RTX 3090上复现点云语义分割算法RandLA-net

语音识别——光剑

网易有道 ASR 团队斩获 Interspeech 2021 算法竞赛两项冠军

Ubuntu系统安装图形界面

k-means算法例题应用

Hadoop 综合揭秘——MapReduce 基础编程(介绍 Combine、Partitioner、WritableComparable、WritableComparator 使用方式)
