热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LeNet网络模型代码实现与示例

一、LeNet-5网络结构Lenet是一个7层的神经网络,包含3个卷积层,2个池化层,1个全连接层。其中所有卷积层的所有卷积核都为5x5

一、LeNet-5网络结构在这里插入图片描述

Lenet是一个 7 层的神经网络,包含 3 个卷积层,2 个池化层,1 个全连接层。其中所有卷积层的所有卷积核都为 5x5,步长 stride=1,池化方法都为全局 pooling,激活函数为 Sigmoid。
整个 LeNet-5 网络总共包括7层(不含输入层),分别是:C1、S2、C3、S4、C5、F6、OUTPUT。

二、Lenet的keras实现

如今各大深度学习框架中所使用的LeNet都是简化改进过的LeNet-5,和原始的LeNet有些许不同,把激活函数改为了现在很常用的ReLu。

import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D, Flatten
from keras.layers import Densedef LeNet():# model = tf.keras.models.Sequential()model = Sequential()model.add(Conv2D(32, (5,5), strides=(1,1), input_shape=(28,28,1), padding='valid',activation='relu', kernel_initializer='uniform'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Conv2D(64, (5,5), strides=(1,1), padding='valid',activation='relu', kernel_initializer='uniform'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Flatten())model.add(Dense(100, activation='relu'))model.add(Dense(10, activation='softmax'))return modelmodel = LeNet()
model.summary()

三、Lenet的pytorch实现

import torch
import torch.nn as nn
import torch.nn.functional as Fclass LeNet5(nn.Module):def __init__(self, num_classes, grayscale=False):''':param num_classes: 分类的数量:param grayscale: 是否为灰度图'''super(LeNet5, self).__init__()self.grayscale = grayscaleself.num_classes = num_classesif self.grayscale: # 可以适用单通道和三通道的图像in_channels = 1else:in_channels = 3# 卷积神经网络self.features = nn.Sequential(nn.Conv2d(in_channels, 6, kernel_size=5),nn.MaxPool2d(kernel_size=2),nn.Conv2d(6, 16, kernel_size=5),nn.MaxPool2d(kernel_size=2))# 分类器self.classifier = nn.Sequential(nn.Linear(16*5*5, 120), # 这里把第三个卷积当作是全连接层nn.Linear(120, 84),nn.Linear(84, num_classes))def forward(self, x):x = self.features(x) # 输出16*5*5特征图x = torch.flatten(x, 1) # 展平(1,16*5*5)logits = self.classifier(x) # 输出10probas = F.softmax(logits, dim=1)return logits, probasnum_classes = 10 # 分类数目
grayscale = True # 是否为灰度图
data = torch.rand((1, 1, 32, 32))
print('input data:\n', data, '\n')
model = LeNet5(num_classes, grayscale)
logits, probas = model(data)
print('logits:\n', logits)
print('probas:\n', probas)

四、手写数字识别(keras)

4.1 手写数字识别代码1

import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
# from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense# 1.导入数据
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()# 2.归一化
# 将像素的值标准化至0到1的区间内
train_images, test_images = train_images/255.0, test_images/255.0
train_images.shape, test_images.shape, train_labels.shape, test_labels.shape
# 输出:((60000, 28, 28), (10000, 28, 28), (60000,), (10000,))# 3.可视化图片
plt.figure(figsize=(20,20))
for i in range(20):plt.subplot(5, 10, i+1)plt.xticks([])plt.yticks([])plt.grid(False)plt.imshow(train_images[i], cmap='gray')# plt.imshow(train_images[i], cmap=plt.cm.binary)plt.xlabel(train_labels[i])
plt.show()# 4.调整图片格式
train_images = train_images.reshape((60000, 28, 28, 1))
test_images = test_images.reshape((10000, 28, 28, 1))train_images, test_images = train_images/255.0, test_images/255.0
train_images.shape, test_images.shape, train_labels.shape, test_labels.shape
# 输出:((60000, 28, 28, 1), (10000, 28, 28, 1), (60000,), (10000,))# 5. 模型构建
# 构建LeNet-5网络模型
model = models.Sequential([layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),layers.MaxPooling2D((2, 2)),layers.Conv2D(64, (3, 3), activation='relu'),layers.MaxPooling2D((2, 2)),layers.Flatten(),layers.Dense(64, activation='relu'),layers.Dense(10)
])# 6. 打印网络结构
model.summary()# 7. 模型编译
model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['accuracy'])# 8. 模型训练
history = model.fit(train_images, train_labels, epochs=2,validation_data=(test_images, test_labels))# 显示第一张图片
plt.imshow(test_images[1], cmap='gray')
# 输出预测结果
pre = model.predict(test_images)
# 输出测试集中第一张图片的预测结果
pre[1]

可视化图片
在这里插入图片描述
模型结构及参数
在这里插入图片描述
显示第一张图片
在这里插入图片描述
输出测试集中第一张图片的预测结果
在这里插入图片描述
4.2 手写数字识别代码2

# Mnist手写数字识别
# 使用TensorFlow搭建LeNet-5网络模型,实现MNIST手写数字识别import tensorflow as tf
from tensorflow import keras
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten
from keras.layers.core import Dense, Activation, Dropout
from keras.utils.vis_utils import plot_model
import matplotlib.pyplot as plt(X_train,Y_train), (X_test,Y_test) = mnist.load_data()
X_test1 = X_test
Y_test1 = Y_testX_train = X_train.reshape(-1,28,28,1).astype('float32')/255.0
X_test = X_test.reshape(-1,28,28,1).astype('float32')/255.0
'''
x = tf.reshape(x, shape=[-1, 28, 28, 1])
x_image = tf.reshape(x, [-1, 28, 28, 1])
Mnist中数据,输入n个样本,每个样本是28*28=784个列构成的向量。所以输入的是n*784的矩阵。
但是输入到CNN中需要卷积,需要每个样本都是矩阵。
这里是将一组图像矩阵x重建为新的矩阵,该新矩阵的维数为(a,28,28,1),其中-1表示a由实际情况来定。
例如,x是一组图像的矩阵(假设是50张,大小为56×56),则执行则执行x_image = tf.reshape(x, [-1, 28, 28, 1])
可以计算a=50×56×56/28/28/1=200。即x_image的维数为(200,28,28,1)
'''
"""
astype:实现变量类型转换。使用 .astype() 方法在不同的数值类型之间相互转换。
a.astype(int) # 将a的数值类型转换为 int。Python中与数据类型相关函数及属性有如下三个:type/dtype/astype
type() 返回参数的数据类型
dtype 返回数组中元素的数据类型
astype() 对数据类型进行转换 """
# 标签预处理
nb_classes = 10
Y_train = np_utils.to_categorical(Y_train, nb_classes)
Y_test = np_utils.to_categorical(Y_test, nb_classes)
"""
np_utils.to_categorical()函数
to_categorical()用于分类,将标签转为one-hot编码。。
"""
# 模型搭建
model = Sequential()
model.add(Conv2D(filters=6, # 卷积核个数kernel_size=(5,5), # 卷积核大小5*5strides=1, # 步长padding='same', # 像素填充方式activation='tanh', # 激活函数input_shape=(28,28,1) # 输入数据28*28))
model.add(MaxPooling2D(pool_size=(2,2), # 池化窗口大小2*2strides=2, # 池化步长为2padding='same' # 像素填充方式为same))
model.add(Conv2D(filters=16, kernel_size=(5,5), padding='same', activation='tanh'))
model.add(MaxPooling2D(pool_size=(2,2), strides=1, padding='same'))
model.add(Flatten())
# 全连接层
model.add(Dense(120))
model.add(Activation('tanh'))
model.add(Dropout(0.2))# 设置为0.2,改层会随机忽略20%的神经元
model.add(Dense(84))
model.add(Activation('tanh'))
# 输出层
model.add(Dense(nb_classes))
model.add(Activation('softmax'))# 显示模型摘要
model.summary()
plot_model(model=model, to_file='model_cnn.png', show_shapes=True)# 模型编译
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])# 模型训练
nb_epoch = 10
batchsize = 512
# training = model.fit(x=X_train, y=Y_train, batch_size=batchsize, epochs=nb_epoch,
# verbose=2, validation_split=0.2)
training = model.fit(x=X_train, y=Y_train, batch_size=batchsize, epochs=2,verbose=2, validation_split=0.2)# 画出训练过程随着迭代(epoch)准确率的变化图
def show_accuracy1(train_history, train, validation):plt.plot(training.history[train], linestyle='-', color='b')plt.plot(training.history[validation], linestyle='--', color='r')plt.title('Training_accuray')plt.xlabel('epoch')plt.ylabel('train')plt.legend(['train', 'validation'], loc='lower right')plt.show()
show_accuracy1(training, 'accuracy', 'val_accuracy')# 画出训练过程中随着迭代次数(epoch)误差的变化图
def show_accuracy2(train_history, train, validation):plt.plot(training.history[train], linestyle='-', color='b')plt.plot(training.history[validation], linestyle='--', color='r')plt.title('Training_loss')plt.xlabel('epoch')plt.ylabel('train')plt.legend(['train', 'validation'], loc='upper right')plt.show()
show_accuracy2(training, 'loss', 'val_loss')# 模型评估
test = model.evaluate(X_test, Y_test, verbose=1)
print('误差:', test[0])
print('准确率:', test[1])
# 误差: 0.07175197452306747
# 准确率: 0.9775000214576721
"""
model.evaluate()函数
评估模型,不输出预测结果。
输入数据和标签,输出损失和精确度.
loss, accuracy = model.evaluate(X_test, Y_test)
"""
"""
model.predict()函数
模型预测,输入测试数据,输出预测结果。
y_pred = model.predict(X_test, batch_size=1)
"""

"""
两者差异
(1)输入输出不同
model.evaluate:输入数据(data)和真实标签(label),然后将预测结果与真实标签相比较,得到两者误差并输出
model.predict:输入数据(data),输出预测结果
(2)是否需要真实标签
model.evaluate:需要,因为需要比较预测结果与真实标签的误差
model.predict:不需要,只是单纯的预测结果,不需要真实标签的参与
"""
# 模型预测
prediction = model.predict(X_test)def plot_image(image):fig = plt.gcf() # 获取当前的图像fig.set_size_inches(2,2) # 设置图像大小plt.imshow(image, cmap='binary')plt.show()def pre_result(i):plot_image(X_test1[i])print('真实值:', Y_test1[i])print('预测值:', prediction[i])pre_result(4)

随着迭代模型准确率的变化,由于笔记本性能有限,仅仅迭代2次
在这里插入图片描述
损失函数随模型迭代的变化
在这里插入图片描述
最后显示图片
在这里插入图片描述
在这里插入图片描述
参考链接:
https://blog.csdn.net/qq_42570457/article/details/81460807
https://zhuanlan.zhihu.com/p/116181964
https://zhuanlan.zhihu.com/p/379577547
https://blog.csdn.net/hgnuxc_1993/article/details/115566799


推荐阅读
  • 本文提供了PyTorch框架中常用的预训练模型的下载链接及详细使用指南,涵盖ResNet、Inception、DenseNet、AlexNet、VGGNet等六大分类模型。每种模型的预训练参数均经过精心调优,适用于多种计算机视觉任务。文章不仅介绍了模型的下载方式,还详细说明了如何在实际项目中高效地加载和使用这些模型,为开发者提供全面的技术支持。 ... [详细]
  • 在 Vue 应用开发中,页面状态管理和跨页面数据传递是常见需求。本文将详细介绍 Vue Router 提供的两种有效方式,帮助开发者高效地实现页面间的数据交互与状态同步,同时分享一些最佳实践和注意事项。 ... [详细]
  • 在Django中提交表单时遇到值错误问题如何解决?
    在Django项目中,当用户提交包含多个选择目标的表单时,可能会遇到值错误问题。本文将探讨如何通过优化表单处理逻辑和验证机制来有效解决这一问题,确保表单数据的准确性和完整性。 ... [详细]
  • 技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告
    技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告 ... [详细]
  • 【图像分类实战】利用DenseNet在PyTorch中实现秃头识别
    本文详细介绍了如何使用DenseNet模型在PyTorch框架下实现秃头识别。首先,文章概述了项目所需的库和全局参数设置。接着,对图像进行预处理并读取数据集。随后,构建并配置DenseNet模型,设置训练和验证流程。最后,通过测试阶段验证模型性能,并提供了完整的代码实现。本文不仅涵盖了技术细节,还提供了实用的操作指南,适合初学者和有经验的研究人员参考。 ... [详细]
  • 通过使用CIFAR-10数据集,本文详细介绍了如何快速掌握Mixup数据增强技术,并展示了该方法在图像分类任务中的显著效果。实验结果表明,Mixup能够有效提高模型的泛化能力和分类精度,为图像识别领域的研究提供了有价值的参考。 ... [详细]
  • 本文将深入探讨生成对抗网络(GAN)在计算机视觉领域的应用。作为该领域的经典模型,GAN通过生成器和判别器的对抗训练,能够高效地生成高质量的图像。本文不仅回顾了GAN的基本原理,还将介绍一些最新的进展和技术优化方法,帮助读者全面掌握这一重要工具。 ... [详细]
  • 在单个图表中实现饼图与条形图的精准对齐 ... [详细]
  • 本文深入探讨了 C# 中 `SqlCommand` 和 `SqlDataAdapter` 的核心差异及其应用场景。`SqlCommand` 主要用于执行单一的 SQL 命令,并通过 `DataReader` 获取结果,具有较高的执行效率,但灵活性较低。相比之下,`SqlDataAdapter` 则适用于复杂的数据操作,通过 `DataSet` 提供了更多的数据处理功能,如数据填充、更新和批量操作,更适合需要频繁数据交互的场景。 ... [详细]
  • 在Matlab中,我尝试构建了一个神经网络模型,用于预测函数 y = x^2。为此,我设计并实现了一个拟合神经网络,并对其进行了详细的仿真和验证。通过调整网络结构和参数,成功实现了对目标函数的准确估计。此外,还对模型的性能进行了全面评估,确保其在不同输入条件下的稳定性和可靠性。 ... [详细]
  • 如何在datetimebox中进行赋值与取值操作
    在 datetimebox 中进行赋值和取值操作时,可以通过以下方法实现:使用 `$('#j_dateStart').datebox('setValue', '指定日期')` 进行赋值,而通过 `$('#j_dateStart').datebox('getValue')` 获取当前选中的日期值。若需要清空日期值,可以使用 `$('#j_dateStart').datebox('clear')` 方法。这些操作能够确保日期控件的准确性和灵活性,适用于各种前端应用场景。 ... [详细]
  • 数据科学笔记26:深入解析随机森林分类算法及其在Python和R中的应用
    ### 摘要随机森林是一种在集成学习领域备受推崇的算法,被誉为“集成学习技术的典范”。该方法因其简洁性、易实现性和较低的计算成本而被广泛应用。本文将深入探讨随机森林的工作原理,特别是其在Python和R中的具体应用。随机森林通过结合多个决策树和Bagging技术,有效提高了模型的准确性和鲁棒性。我们将详细解析其核心机制,并通过实际案例展示如何在不同编程环境中高效实现这一强大的分类算法。 ... [详细]
  • [TensorFlow系列3]:初学者是选择Tensorflow2.x还是1.x? 2.x与1.x的主要区别?
    作者主页(文火冰糖的硅基工坊):https:blog.csdn.netHiWangWenBing本文网址:https:blog.csdn.netHiW ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 2018 HDU 多校联合第五场 G题:Glad You Game(线段树优化解法)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356在《Glad You Game》中,Steve 面临一个复杂的区间操作问题。该题可以通过线段树进行高效优化。具体来说,线段树能够快速处理区间更新和查询操作,从而大大提高了算法的效率。本文详细介绍了线段树的构建和维护方法,并给出了具体的代码实现,帮助读者更好地理解和应用这一数据结构。 ... [详细]
author-avatar
houjiajun
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有