2025年3月26日 星期三 甲辰(龙)年 月廿五 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 人工智能

保姆级教程:手把手教你使用 Keras 搭建神经网络

时间:08-05来源:作者:点击数:23

大家好,本文从0到1详细讲解两种基于Keras的建模方法:

  • 基于Sequential的建模;快速方便,易上手
  • 基于函数式API的建模;易于扩展,灵活性强

你会学到什么?

通过本文你将学到下面10个实用的知识点,快速掌握基于Kera搭建神经网络模型的流程:

  1. 如何导入keras的内置数据集
  2. keras如何实现one-hot编码
  3. 如何定义keras的Sequential模型,包含卷积层、池化层、Dropout层等
  4. 如何查看各个层基本信息,比如层的名称、权重、形状等
  5. 模型的编译、训练
  6. 如何创建回调函数并使用它
  7. 如何将模型的精度和准确率指标进行可视化
  8. 如何使用TensorFlow的Tensorboard进行可视化
  9. 如何搭建基于函数式API的keras模型
  10. 如何将神经网络结构图进行可视化

导入内置数据集

  • # 导入数据集
  • from keras.datasets import cifar10
  • (train_images, train_labels), (test_images, test_labels) = cifar10.load_data()
  • train_images.shape, test_images.shape, train_labels.shape, test_labels.shape

Out[1]:

  • ((50000, 32, 32, 3), (10000, 32, 32, 3), (50000, 1), (10000, 1))

可以看到cifar服装图片数据集存在50000个训练样本,10000个测试样本;数据集是四维的。

数据缩放和标签编码

神经网络中一般输入较小的数值,需要对数据进行缩放:

  • # 将像素的值标准化至0到1
  • train_images, test_images = train_images / 255.0, test_images / 255.0

同时对标签labels进行one-hot编码:

  • # 标签编码
  • from keras.utils.np_utils import to_categorical
  • one_hot_train_labels = to_categorical(train_labels)
  • one_hot_test_labels = to_categorical(test_labels)

搭建Sequential网络模型

搭建基于Sequential的网络模型:

  • import tensorflow as tf
  • from keras.models import Sequential
  • from keras.layers import Dense,Flatten,Conv2D,MaxPooling2D,Dropout,Activation,ZeroPadding2D
  • from tensorflow.keras import datasets, layers, models
  • # Sequential模型实例化
  • model = Sequential()
  • # 卷积层1
  • model.add(Conv2D(filters = 32, # filters个数
  • kernel_size = (3,3), # 卷积核大小
  • padding="same", # 边界填充方式
  • input_shape=(32,32,3), # 输入数据shape
  • activation="relu" # 激活函数
  • ))
  • # Dropout层1
  • model.add(Dropout(0.25)) # dropout比例
  • # 最大池化层1
  • model.add(MaxPooling2D(pool_size=(2,2)))
  • # 卷积层2
  • model.add(Conv2D(64, kernel_size=(3,3), padding="same",activation="relu"))
  • # 最大池化层2
  • model.add(MaxPooling2D(pool_size=(2,2)))
  • # Dropout层2
  • model.add(Dropout(0.2)) # dropout比例
  • # 拉直层
  • model.add(Flatten())
  • # 密集连接层
  • model.add(Dense(128,activation="relu"))
  • # Dropout层3
  • model.add(Dropout(0.25))
  • # 输出层:10表示的最终数据的分类数目
  • model.add(Dense(10, activation="softmax")) # 多分类使用softmax激活函数

在多分类问题的最后全连接层中,激活函数使用softmax函数;它输出的是每个分类的概率值,且它们的概率之和为;取最大的概率所在的类。

查看网络信息

查看所搭建的网络层的基本信息:

总层数

In [5]:

  • len(model.layers) # 总层数

Out[5]:

  • 10
每层网络名

In [6]:

  • for i in range(len(model.layers)):
  • print(f'第 {i + 1} 层网络名称:{model.layers[i].name}')
  • 1 层网络名称:conv2d
  • 2 层网络名称:dropout
  • 3 层网络名称:max_pooling2d
  • 4 层网络名称:conv2d_1
  • 5 层网络名称:max_pooling2d_1
  • 6 层网络名称:dropout_1
  • 7 层网络名称:flatten
  • 8 层网络名称:dense
  • 9 层网络名称:dropout_2
  • 10 层网络名称:dense_1
每层形状

In [7]:

  • for i in range(len(model.layers)):
  • print(f'第 {i + 1} 层网络shape:{model.layers[i].input.shape}')
  • 1 层网络shape:(None, 32, 32, 3)
  • 2 层网络shape:(None, 32, 32, 32)
  • 3 层网络shape:(None, 32, 32, 32)
  • 4 层网络shape:(None, 16, 16, 32)
  • 5 层网络shape:(None, 16, 16, 64)
  • 6 层网络shape:(None, 8, 8, 64)
  • 7 层网络shape:(None, 8, 8, 64)
  • 8 层网络shape:(None, 4096)
  • 9 层网络shape:(None, 128)
  • 10 层网络shape:(None, 128)
显示各层权重形状

In [8]:

  • for i in range(len(model.layers)):
  • print(i, model.layers[i].name, ":") # 每层的名称
  • weights = model.layers[i].get_weights() # 获取每层的权重
  • print(f'第{i}的权重层数: {len(weights)}')
  • for j in range(len(weights)): # 每个网络的每层权重数
  • print("====>",j, weights[j].shape)
  • 0 conv2d :
  • 0的权重层数: 2
  • ====> 0 (3, 3, 3, 32)
  • ====> 1 (32,)
  • 1 dropout :
  • 1的权重层数: 0
  • 2 max_pooling2d :
  • 2的权重层数: 0
  • 3 conv2d_1 :
  • 3的权重层数: 2
  • ====> 0 (3, 3, 32, 64)
  • ====> 1 (64,)
  • 4 max_pooling2d_1 :
  • 4的权重层数: 0
  • 5 dropout_1 :
  • 5的权重层数: 0
  • 6 flatten :
  • 6的权重层数: 0
  • 7 dense :
  • 7的权重层数: 2
  • ====> 0 (4096, 128)
  • ====> 1 (128,)
  • 8 dropout_2 :
  • 8的权重层数: 0
  • 9 dense_1 :
  • 9的权重层数: 2
  • ====> 0 (128, 10)
  • ====> 1 (10,)

In [9]:

  • # 同时显示网络层名称、inputoutput
  • 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")
在这里插入图片描述
显示模型信息

In [10]:

  • model.summary() # 显示模型信息
  • Model: "sequential"
  • _________________________________________________________________
  • Layer (type) Output Shape Param #
  • =================================================================
  • conv2d (Conv2D) (None, 32, 32, 32) 896
  • dropout (Dropout) (None, 32, 32, 32) 0
  • max_pooling2d (MaxPooling2D (None, 16, 16, 32) 0
  • )
  • conv2d_1 (Conv2D) (None, 16, 16, 64) 18496
  • max_pooling2d_1 (MaxPooling (None, 8, 8, 64) 0
  • 2D)
  • dropout_1 (Dropout) (None, 8, 8, 64) 0
  • flatten (Flatten) (None, 4096) 0
  • dense (Dense) (None, 128) 524416
  • dropout_2 (Dropout) (None, 128) 0
  • dense_1 (Dense) (None, 10) 1290
  • =================================================================
  • Total params: 545,098
  • Trainable params: 545,098
  • Non-trainable params: 0
  • _________________________________________________________________

编译模型

网络编译的时候通常需要指定3个参数:

  • 优化器optimizer
  • 损失函数loss
  • 评价指标metrics

In [11]:

  • model.compile(optimizer='rmsprop', # 优化器
  • loss='categorical_crossentropy', # 多分类交叉熵categorical_crossentropy
  • metrics=['accuracy'] # 评价指标
  • )

回调函数

在使用TensorBoard的时候需要

In [12]:

  • # 后面tensorborad使用需要
  • tf_callback = tf.keras.callbacks.TensorBoard(log_dir="./logs") # 指定log_dir路径

存放路径为当前路径下的logs文件夹下

训练模型

  • history = model.fit(train_images, # x
  • one_hot_train_labels, # y
  • epochs=20, # 训练轮次
  • batch_size=1024, # 每次训练使用样本小批量
  • validation_split=0.2, # 验证集比例
  • callbacks=[tf_callback], # 回调函数
  • verbose=1 # 是否显示训练详细信息,1-显示 0-不显示
  • # validation_data=[x_val,y_val] # 验证集的数据
  • )

当verbose=1的时候会显示每轮训练的具体信息:

在这里插入图片描述
在这里插入图片描述

指标可视化

主要是针对精度和损失值的可视化

In [14]:

  • history_data = history.history # 字典形式
  • for keys in history_data:
  • print(keys)
  • loss
  • accuracy
  • val_loss
  • val_accuracy

In [15]:

  • loss = history_data["loss"]
  • val_loss = history_data["val_loss"]
  • # 原文 acc = history_data["acc]
  • acc = history_data["accuracy"] # 改动:精度acc使用全称accuracy
  • val_acc = history_data["val_accuracy"]

In [16]:

  • # 1、损失loss
  • import matplotlib.pyplot as plt
  • %matplotlib inline
  • epochs = range(1, len(loss) + 1) # 作为横轴
  • plt.plot(epochs, loss, "bo", label="Training Loss")
  • plt.plot(epochs, val_loss, "b", label="Validation Loss")
  • plt.xlabel("Epochs")
  • plt.ylabel("Loss")
  • plt.legend()
  • plt.title("Training and Validation Loss")
  • plt.show()
在这里插入图片描述
  • # 2、精度acc
  • plt.plot(epochs, acc, "bo", label="Training Acc")
  • plt.plot(epochs, val_acc, "b", label="Validation Acc")
  • plt.xlabel("Epochs")
  • plt.ylabel("Acc")
  • plt.legend()
  • plt.title("Training and Validation Acc")
  • plt.show()
在这里插入图片描述

tensorboard使用

首次使用的时候需要先加载两个环境:

In [18]:

  • %load_ext tensorboard

In [19]:

  • %tensorboard --logdir logs

然后在notebook页面中会直接显示Tensorboard:

在这里插入图片描述

除此之外,你也可以通过localhost:6006到本地网页查看:

在这里插入图片描述

显示的内容就是每轮的loss和acc

构建函数式模型

上面的网络模型是基于Sequential;下面对比构建出基于函数式API的等效模型:

  • from keras.models import Model
  • from keras.layers import Input
  • 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
  • from keras.layers import Activation
  • from keras.layers import ZeroPadding1D
  • # 第一步:实例化输入层
  • cifar_input = Input(shape=(32,32,3),
  • name="input")
  • # 第二步:中间层的不断传递
  • conv1 = Conv2D(32,
  • kernel_size=(3,3),
  • padding="same",
  • activation="relu",
  • name="conv1")(cifar_input)
  • drop1 = Dropout(0.25, name="drop1")(conv1)
  • maxpool1 = MaxPooling2D(pool_size=(2,2), name="maxpool1")(drop1)
  • conv2 = Conv2D(64,
  • kernel_size=(3,3),
  • padding="same",
  • activation="relu",
  • name="conv2")(maxpool1)
  • maxpool2 = MaxPooling2D(pool_size=(2,2), name="maxpool2")(conv2)
  • drop2 = Dropout(0.25, name="drop2")(maxpool2)
  • flatten = Flatten(name="flatten")(drop2)
  • dense1 = Dense(128, activation="relu")(flatten)
  • drop3 = Dropout(0.25, name="drop3")(dense1)
  • # 第三步:输出层
  • output = Dense(10, activation="softmax")(drop3)
  • # 第四步:实例化Model类:传入输入和输出信息
  • model = Model(inputs=cifar_input, outputs=output)
  • model.summary()

打印出来的效果:

  • Model: "model"
  • _________________________________________________________________
  • Layer (type) Output Shape Param #
  • =================================================================
  • input (InputLayer) [(None, 32, 32, 3)] 0
  • conv1 (Conv2D) (None, 32, 32, 32) 896
  • drop1 (Dropout) (None, 32, 32, 32) 0
  • maxpool1 (MaxPooling2D) (None, 16, 16, 32) 0
  • conv2 (Conv2D) (None, 16, 16, 64) 18496
  • maxpool2 (MaxPooling2D) (None, 8, 8, 64) 0
  • drop2 (Dropout) (None, 8, 8, 64) 0
  • flatten (Flatten) (None, 4096) 0
  • dense_2 (Dense) (None, 128) 524416
  • drop3 (Dropout) (None, 128) 0
  • dense_3 (Dense) (None, 10) 1290
  • =================================================================
  • Total params: 545,098
  • Trainable params: 545,098
  • Non-trainable params: 0
  • _________________________________________________________________

网络可视化

通过keras自带的plot_model能够绘制出当前模型的框架。

首先需要安装两个库:pydot 和 graphviz。其中graphviz的安装可能你会遇到些困难;特别是在windows系统下,希望你有耐心解决。

  • pip install pydot
  • pip install graphviz

安装完成之后在命令行输入dot -version出现下面的界面则表示安装成功:

在这里插入图片描述

然后就可以绘图了:

  • from keras.utils.vis_utils import plot_model
  • plot_model(model, to_file="model_graph.png", show_shapes=True)
在这里插入图片描述
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐