Keras高层接口实现-基于Keras的深度学习框架-自定义网络层-模型迁移实例-手写数字识别

程序代码:

https://download.csdn.net/download/do_it_123/88923773

Keras 提供了一系列高层的神经网络相关类和函数,如经典数据集加载函数、 网络层类、 模型容器、 损失函数类、 优化器类、 经典模型类等。

常见网络层类

tf.keras.layers 命名空间中提供了大量常见网络层的类,如全连接层、 激活函数层、 池化层、 卷积层、 循环神经网络层等。 对于这些网络层类,只需要在创建时指定网络层的相关参数, 并调用__call__方法即可完成前向计算。在调用__call__方法时, Keras 会自动调用每个层的前向传播逻辑,这些逻辑一般实现在类的call 函数中。 

Softmax 层为例, 它既可以使用 tf.nn.softmax 函数在前向传播逻辑中完成 Softmax运算, 也可以通过 layers.Softmax(axis)类搭建 Softmax 网络层,其中 axis 参数指定进行softmax 运算的维度。

网络容器:

可以通过 Keras 提供的网络容器 Sequential 将多个网络层封装成一个大网络模型,只需要调用网络模型的实例一次即可完成数据从第一层到最末层的顺序传播运算; Sequential 容器也可以通过 add()方法继续追加新的网络层, 实现动态创建网络的功能  

当我们通过 Sequential 容量封装多个网络层时, 每层的参数列表将会自动并入Sequential 容器的参数列表中,不需要人为合并网络参数列表,这也是 Sequential 容器的便捷之处。 Sequential 对象的 trainable_variables variables 包含了所有层的待优化张量列表和全部张量列表 。

模型装配:

我们以 Sequential 容器封装的网络为例,首先创建 5 层的全连接网络, 用于 MNIST 手写数字图片识别; 创建网络后,正常的流程是循环迭代数据集多个 Epoch,每次按批产生训练数据、 前向计算,然后通过损失函数计算误差值,并反向传播自动计算梯度、 更新网络参数。这一部分逻辑由于非常通用,在 Keras 中提供了 compile()fit()函数方便实现上述逻辑。 首先通过compile 函数指定网络使用的优化器对象、 损失函数类型, 评价指标等设定,这一步称为装配。 

模型训练:

模型装配完成后,即可通过 fit()函数送入待训练的数据集和验证用的数据集,这一步称为模型训练; 行上述代码即可实现网络的训练与验证的功能, fit 函数会返回训练过程的数据记录history, 其中 history.history 为字典对象,包含了训练过程中的 loss、 测量指标等记录项.

模型测试

如果只是简单的测试模型的性能,可以通过 Model.evaluate(db)循环测试完 db 数据集上所有样本,并打印出性能指标, 

模型保存与加载 

张量方式

网络的状态主要体现在网络的结构以及网络层内部张量数据上,因此在拥有网络结构源文件的条件下,直接保存网络张量参数到文件系统上是最轻量级的一种方式。 我们以MNIST 手写数字图片识别模型为例,通过调用 Model.save_weights(path)方法即可将当前的网络参数保存到 path 文件上

网络方式

我们来介绍一种不需要网络源文件,仅仅需要模型参数文件即可恢复出网络模型的方法。 通过 Model.save(path)函数可以将模型的结构以及模型的参数保存到 path 文件上,在不需要网络源文件的条件下,通过 keras.models.load_model(path)即可恢复网络结构和网络参数

SavedModel方式

当需要将模型部署到其他平台时,采用 TensorFlow 提出的 SavedModel 方式更具有平台无关性,通过 tf.saved_model.save (network, path)即可将模型以 SavedModel 方式保存到 path 目录中。

自定义网络 

对于需要创建自定义逻辑的网络层,可以通过自定义类来实现。在创建自定义网络层类时,需要继承自 layers.Layer 基类; 创建自定义的网络类时,需要继承自 keras.Model 基类, 这样建立的自定义类才能够方便的利用 Layer/Model 基类提供的参数管理等功能,同时也能够与其他的标准网络层类交互使用

自定义网络层 

对于自定义的网络层, 至少需要实现初始化__init__方法和前向传播逻辑 call 方法。 我们以某个具体的自定义网络层为例, 假设需要一个没有偏置向量的全连接层,即 bias 为0, 同时固定激活函数为 ReLU 函数。完成自定义类的初始化工作后,我们来设计自定义类的前向运算逻辑,对于这个例子,只需要完成矩阵运算,并通过固定的 ReLU 激活函数即可 

自定义网络

自定义网络类可以和其他标准类一样,通过 Sequential 容器方便地封装成一个网络模型通过堆叠我们的自定义网络层类,一样可以实现 5 层的全连接层网络,每层全连接层无偏置张量,同时激活函数固定地使用 ReLU 函数。 

加载模型

ResNet50 网络模型为例,一般将 ResNet50 去除最后一层后的网络作为新任务的特征提取子网络, 即利用在 ImageNet 数据集上预训练好的网络参数初始化, 并根据自定义任务的类别追加一个对应数据类别数的全连接分类层或子网络, 从而可以在预训练网络的基础上快速、高效地学习新任务。

首先利用 Keras 模型乐园加载 ImageNet 预训练好的 ResNet50 网络经代码实现,自动从服务器下载模型结构和在 ImageNet 数据集上预训练好的网络参数。通过设置 include_top 参数为 False,可以选择去掉 ResNet50 最后一层, 此时网络的输出特征图大小为[b,7,7,2048]。对于某个具体的任务,需要设置自定义的输出节点数,以 100 类的分类任务为例,我们在 ResNet50 基础上重新构建新网络。新建一个池化层(这里的池化层暂时可以理解为高、宽维度下采样的功能),将特征从[b,7,7,2048]降维到[b,2048].最后新建一个全连接层,并设置输出节点数为 100 这样,在创建预训练的 ResNet50 特征子网络、 新建的池化层和全连接层后,我们可以重新利用Sequential 容器封装成一个新的网络

通过设置 resnet.trainable = False 可以选择冻结 ResNet 部分的网络参数,只训练新建的网络层,从而快速、高效完成网络模型的训练。 当然也可以在自定义任务上更新网络的全部参数

 

备注
简介此部分摘自互联网,仅供参考,若侵权,联系删除。

创作不易,相关程序,说明文档需求,如需,可加作者新联系方式,WX:Q3101759565,QQ:3101759565[多加几次!!!]

学业有成!工作顺利 年薪百万!  

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,我们需要导入keras和相关的库: ```python import keras from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense from keras.datasets import mnist from keras.utils import to_categorical ``` 然后我们加载mnist数据集,并对其进行预处理: ```python # 加载mnist数据集 (x_train, y_train), (x_test, y_test) = mnist.load_data() # 数据预处理 x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype('float32') / 255 x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype('float32') / 255 y_train = to_categorical(y_train, 10) y_test = to_categorical(y_test, 10) ``` 接下来,我们搭建Lenet-5网络模型: ```python # 创建lenet-5网络 model = Sequential() model.add(Conv2D(filters=6, kernel_size=(5, 5), strides=(1, 1), activation='tanh', input_shape=(28, 28, 1))) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) model.add(Conv2D(filters=16, kernel_size=(5, 5), strides=(1, 1), activation='tanh')) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) model.add(Flatten()) model.add(Dense(120, activation='tanh')) model.add(Dense(84, activation='tanh')) model.add(Dense(10, activation='softmax')) ``` 最后,我们编译并训练模型,并在测试集上进行评估: ```python # 编译模型 model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy']) # 训练模型 model.fit(x_train, y_train, batch_size=128, epochs=10, validation_data=(x_test, y_test)) # 在测试集上评估模型性能 score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) ``` 通过以上步骤,我们就成功基于keras搭建了一个Lenet-5网络,并实现了对mnist手写数字的识别。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迪哥_AI_人工智能

您的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值