建设一个营销网站的费用,ios软件开发前景,自己做的网站发布详细步骤,wordpress如何修改版权1.LeNet概述 LeNet是Yann LeCun于1988年提出的用于手写体数字识别的网络结构#xff0c;它是最早发布的卷积神经网络之一#xff0c;可以说LeNet是深度CNN网络的基石。 当时#xff0c;LeNet取得了与支持向量机#xff08;support vector machines#xff09;性能相…1.LeNet概述 LeNet是Yann LeCun于1988年提出的用于手写体数字识别的网络结构它是最早发布的卷积神经网络之一可以说LeNet是深度CNN网络的基石。 当时LeNet取得了与支持向量机support vector machines性能相媲美的成果成为监督学习的主流方法。 LeNet当时被广泛用于自动取款机ATM机中帮助识别处理支票的数字。 下面是整个网络的结构图 LeNet共有8层其中包括输入层3个卷积层2个子采样层也就是现在的池化层1个全连接层和1个高斯连接层。 上图中用C代表卷积层用S代表采样层用F代表全连接层。输入size固定在1*32*32LeNet图片的输入是二值图像。网络的输出为0~9十个数字的RBF度量可以理解为输入图像属于0~9数字的可能性大小。
2.详解LeNet 下面对图中每一层做详细的介绍
LeNet使用的卷积核大小都为5*5步长为1无填充只是卷积深度不一样(卷积核个数导致生成的特征图的通道数)激活函数为Sigmoid下采样层都是使用最大池化实现池化的核都为2*2步长为2无填充 input输入层尺寸为1*32*32的二值图 C1层是一个卷积层。该层使用6个卷积核生成特征图尺寸为32-5128输出为6个大小为28*28的特征图。再经过一个Sigmoid激活函数非线性变换。 S2层是一个下采样层。生成特征图尺寸为28/214得到6个14*14的特征图。 C3层是一个卷积层该层使用16个卷积核生成特征图尺寸为14-5110输出为16个10*10的特征图。再经过一个Sigmoid激活函数非线性变换。 S4层是一个下采样层生成特征图尺寸为10/25得到16个5*5的特征图 C5层是一个卷积层卷积核数量增加至120。生成特征图尺寸为5-511。得到120个1*1的特征图。这里实际上相当于S4全连接了但仍将其标为卷积层原因是如果LeNet-5的输入图片尺寸变大其他保持不变那该层特征图的维数也会大于1*1那就不是全连接了。再经过一个Sigmoid激活函数非线性变换。 F6层是一个全连接层该层与C5层全连接输出84张特征图。再经过一个Sigmoid激活函数非线性变换。 输出层输出层由欧式径向基函数高斯单元组成每个类别0~9数字对应一个径向基函数单元每个单元有84个输入。也就是说每个输出RBF单元计算输入向量和该类别标记向量之间的欧式距离距离越远PRF输出越大同时我们也会将与标记向量欧式距离最近的类别作为数字识别的输出结果。当然现在通常使用的Softmax实现。
3.使用LeNet实现Mnist数据集分类
1.导入所需库
import torch
import torch.nn as nn
from torchsummary import summary
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
from tqdm import tqdm # 显示训练进度条
2.使用GPU
device cuda if torch.cuda.is_available() else cpu
3.读取Mnist数据集
# 定义数据转换以进行数据标准化
transform transforms.Compose([transforms.ToTensor(), # 将图像转换为 PyTorch 张量
])# 下载并加载 MNIST 训练和测试数据集
train_dataset datasets.MNIST(root./dataset, trainTrue, downloadTrue, transformtransform)
test_dataset datasets.MNIST(root./dataset, trainFalse, downloadTrue, transformtransform)# 创建数据加载器以批量加载数据
batch_size 256
train_dataloader DataLoader(train_dataset, batch_sizebatch_size, shuffleTrue)
test_dataloader DataLoader(test_dataset, batch_sizebatch_size, shuffleFalse)
4.搭建LeNet 需要注意的是torch.nn.CrossEntropyLoss自带了softmax函数所以最后一层使用全连接即可在训练时使用torch.nn.CrossEntropyLoss
class LeNet(nn.Module):def __init__(self):super(LeNet, self).__init__()self.conv1 nn.Conv2d(1, 6, kernel_size5, padding2) # Mnist尺寸为28*28这里设置填充变成32*32self.sigmoid nn.Sigmoid()self.pool nn.MaxPool2d(kernel_size2, stride2)self.conv2 nn.Conv2d(6, 16, kernel_size5)self.flatten nn.Flatten()self.fc1 nn.Linear(16 * 5 * 5, 120)self.fc2 nn.Linear(120, 84)self.fc3 nn.Linear(84, 10)def forward(self, x):x self.pool(self.sigmoid(self.conv1(x)))x self.pool(self.sigmoid(self.conv2(x)))x self.flatten(x)x self.sigmoid(self.fc1(x))x self.sigmoid(self.fc2(x))x self.fc3(x)return x
# 实例化模型
model LeNet().to(device)
summary(model, (1, 28, 28)) 5.训练函数
def train(model, lr, epochs):# 将模型放入GPUmodel model.to(device)# 使用交叉熵损失函数loss_fn nn.CrossEntropyLoss().to(device)# SGDoptimizer torch.optim.SGD(model.parameters(), lrlr)# 记录训练与验证数据train_losses []train_accuracies []# 开始迭代 for epoch in range(epochs): # 切换训练模式model.train() # 记录变量train_loss 0.0correct_train 0total_train 0# 读取训练数据并使用 tqdm 显示进度条for i, (inputs, targets) in tqdm(enumerate(train_dataloader), totallen(train_dataloader), descfEpoch {epoch1}/{epochs}, unitbatch):# 训练数据移入GPUinputs inputs.to(device)targets targets.to(device)# 模型预测outputs model(inputs)# 计算损失loss loss_fn(outputs, targets)# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 使用优化器优化参数optimizer.step()# 记录损失train_loss loss.item()# 计算训练正确个数_, predicted torch.max(outputs, 1)total_train targets.size(0)correct_train (predicted targets).sum().item()# 计算训练正确率并记录train_loss / len(train_dataloader)train_accuracy correct_train / total_traintrain_losses.append(train_loss)train_accuracies.append(train_accuracy)# 输出训练信息print(fEpoch [{epoch 1}/{epochs}] - Train Loss: {train_loss:.4f}, Train Acc: {train_accuracy:.4f})# 绘制损失和正确率曲线plt.figure(figsize(10, 5))plt.subplot(1, 2, 1)plt.plot(range(epochs), train_losses, labelTraining Loss)plt.xlabel(Epoch)plt.ylabel(Loss)plt.legend()plt.subplot(1, 2, 2)plt.plot(range(epochs), train_accuracies, labelAccuracy)plt.xlabel(Epoch)plt.ylabel(Accuracy)plt.legend()plt.tight_layout()plt.show()
6.模型训练
model LeNet()
lr 0.9 # sigmoid两端容易饱和gradient比较小学得比较慢所以学习率要大一些
epochs 20
train(model,lr,epochs) 7.模型测试
def test(model, test_dataloader, device, model_path):# 将模型设置为评估模式model.eval()# 将模型移动到指定设备上model.to(device)# 从给定路径加载模型的状态字典model.load_state_dict(torch.load(model_path))correct_test 0total_test 0# 不计算梯度with torch.no_grad():# 遍历测试数据加载器for inputs, targets in test_dataloader: # 将输入数据和标签移动到指定设备上inputs inputs.to(device)targets targets.to(device)# 模型进行推理outputs model(inputs)# 获取预测结果中的最大值_, predicted torch.max(outputs, 1)total_test targets.size(0)# 统计预测正确的数量correct_test (predicted targets).sum().item()# 计算并打印测试数据的准确率test_accuracy correct_test / total_testprint(fAccuracy on Test: {test_accuracy:.4f})return test_accuracy
model_path save_path
test(model, test_dataloader, device, save_path)