网站视频嵌入代码,室内设计图片大全,圣诞节html网页代码,wordpress怎样清理数据库#x1f449;#x1f3fc;目录#x1f448;#x1f3fc;
#x1f352;1. 数据
1.1 准备数据 1.2 数据预处理
#x1f352;2. 模型构建
2.1 模型测试
2.2 测试网络运算速度
2.3 输出模型参数量
2.4 输出模型计算量
#x1f352;3. 模型训练
#x1f352;4.模…目录
1. 数据
1.1 准备数据 1.2 数据预处理
2. 模型构建
2.1 模型测试
2.2 测试网络运算速度
2.3 输出模型参数量
2.4 输出模型计算量
3. 模型训练
4.模型评价
5.模型预测
6 使用完整数据集不改变输入图像尺寸使其为1*28*28的图像输入
6.1在第一层卷积时对图像进行padding 2 填充
6.2 在第一层卷积时不对图像进行padding 2 填充 6.3 完整代码
运行结果及调参
参考链接 1. 数据
1.1 准备数据
本实验用到的数据集为MNIST数据集在实验开始之前先认识一下吧~ MNIST数据集是CV领域的经典入门数据集包含了手写数字的图像每个图像都是一个28x28像素的灰度图像并标注了图像所表示的数字0-9。MNIST 数据集被广泛用于图像分类任务尤其是在深度学习领域。如图源paddle) 训练集包含60,000个手写数字图像和它们对应的标签数字0到9。测试集包含10,000个手写数字图像和它们对应的标签。
可见数据集还是很大的为了节省时间实验选取MNIST数据集的一个子集数据集划分为 训练集train_set1,000条样本验证集dev_set200条样本测试集test_set200条样本 # 加载数据集
train_set, dev_set, test_set json.load(gzip.open(rD:\i dont want to open\深度学习-实验\实验11-卷积神经网络2-LeNet-Mnisit\mnist.json.gz, rb))# 获取前3000个训练样本200个验证样本和200个测试样本
train_images, train_labels train_set[0][:3000], train_set[1][:3000]
dev_images, dev_labels dev_set[0][:200], dev_set[1][:200]
test_images, test_labels test_set[0][:200], test_set[1][:200]
train_set, dev_set, test_set [train_images, train_labels], [dev_images, dev_labels], [test_images, test_labels]# 打印数据集长度
print(Length of train/dev/test set: {}/{}/{}.format(len(train_images), len(dev_images), len(test_images)))
运行结果
Length of train/dev/test set: 3000/200/200
可视化观察其中的一张样本以及对应的标签:
image, label train_set[0][0], train_set[1][0]
image, label np.array(image).astype(float32), int(label)
# 原始图像数据为长度784的行向量需要调整为[28,28]大小的图像
image np.reshape(image, [28, 28])
image Image.fromarray((image*255).astype(uint8), modeL)print(The number in the picture is {}.format(label))
plt.figure(figsize(5, 5))
plt.imshow(image)
plt.show()
运行结果 The number in the picture is 5 【这里是下载的老师在群里发的数据集文件已归一化的彩色图像不是官网处理好的灰度图像】 1.2 数据预处理
调整图片大小LeNet网络对输入图片大小的要求为 32×32 而MNIST数据集中的原始图片大小却是 28×28 为了符合网络的结构设计将其调整为32×32规范化 把输入图像的分布改变成均值为0标准差为1的标准正态分布使得最优解的寻优过程明显会变得平缓训练过程更容易收敛。
# 数据预处理
import torchvision.transforms as transforms
from torch.utils.data import Dataset, DataLoader
import numpy as np
from PIL import Image# 数据预处理 将图像的尺寸修改为32*32转换为tensor形式。并且将输入图像分布改为均值为0标准差为1的正态分布
transforms transforms.Compose([transforms.Resize(32), transforms.ToTensor(), transforms.Normalize(mean[0.], std[1.0])])# 数据集类的定义 定义MNIST_dataset类继承dataset类
class MNIST_dataset(Dataset):# 初始化数据集接收一个数据集dataset,转换操作transform 测试操作modetraindef __init__(self, dataset, transforms, modetrain):self.mode modeself.transforms transformsself.dataset dataset# 根据索引idx从数据集中获取样本。def __getitem__(self, idx):# 获取图像和标签image, label self.dataset[0][idx], self.dataset[1][idx]# 将图像转换为float32类型image, label np.array(image).astype(float32), int(label)image np.reshape(image, [28, 28]) # 重塑形状# 将重塑后的图像转换为Image对象应用转换操作image Image.fromarray(image.astype(uint8), modeL)image self.transforms(image)return image, label# 返回数据集中的样本数量def __len__(self):return len(self.dataset[0])# 加载 mnist 数据集 这些数据集在MNIST_dataset类中被初始化并用于训练、测试和开发模型
train_dataset MNIST_dataset(datasettrain_set, transformstransforms, modetrain)
test_dataset MNIST_dataset(datasettest_set, transformstransforms, modetest)
dev_dataset MNIST_dataset(datasetdev_set, transformstransforms, modedev)
2. 模型构建 网络共有7层包含3个卷积层、2个汇聚层以及2个全连接层的简单卷积神经网络接受输入图像大小为32×321 024输出对应10个类别的得分。 class LeNet(nn.Module):def __init__(self, in_channels, num_classes10):super(LeNet, self).__init__()# 卷积层输出通道数为6卷积核大小为5×5self.conv1 nn.Conv2d(in_channelsin_channels, out_channels6, kernel_size5)# 汇聚层汇聚窗口为2×2步长为2self.pool2 nn.MaxPool2d(2, stride2)# 卷积层输入通道数为6输出通道数为16卷积核大小为5×5步长为1self.conv3 nn.Conv2d(in_channels6, out_channels16, kernel_size5, stride1)# 汇聚层汇聚窗口为2×2步长为2self.pool4 nn.AvgPool2d(2, stride2)# 卷积层输入通道数为16输出通道数为120卷积核大小为5×5self.conv5 nn.Conv2d(in_channels16, out_channels120, kernel_size5, stride1)# 全连接层输入神经元为120输出神经元为84self.linear6 nn.Linear(120, 84)# 全连接层输入神经元为84输出神经元为类别数self.linear7 nn.Linear(84, num_classes)def forward(self, x):# C1卷积层激活函数output F.relu(self.conv1(x))# S2汇聚层output self.pool2(output)# C3卷积层激活函数output F.relu(self.conv3(output))# S4汇聚层output self.pool4(output)# C5卷积层激活函数output F.relu(self.conv5(output))# 输入层将数据拉平[B,C,H,W] - [B,CxHxW]output torch.squeeze(output, dim3)output torch.squeeze(output, dim2)# F6全连接层output F.relu(self.linear6(output))# F7全连接层output self.linear7(output)return output
2.1 模型测试 测试一下上面的LeNet-5模型构造一个形状为 [1,1,32,32]的输入数据送入网络观察每一层特征图的形状变化。
# 这里用np.random创建一个随机数组作为输入数据
inputs np.random.randn(*[1, 1, 32, 32])
inputs inputs.astype(float32)
model LeNet(in_channels1, num_classes10)
c []
for a, b in model.named_children():c.append(a)
print(c)
x torch.tensor(inputs)
for a, item in model.named_children():try:x item(x)except:x torch.reshape(x, [x.shape[0], -1])x item(x)print(a, x.shape, sep , end )for name, value in item.named_parameters():print(value.shape, end )print()
运行结果
[conv1, pool2, conv3, pool4, conv5, linear6, linear7]
conv1 torch.Size([1, 6, 28, 28]) torch.Size([6, 1, 5, 5]) torch.Size([6])
pool2 torch.Size([1, 6, 14, 14])
conv3 torch.Size([1, 16, 10, 10]) torch.Size([16, 6, 5, 5]) torch.Size([16])
pool4 torch.Size([1, 16, 5, 5])
conv5 torch.Size([1, 120, 1, 1]) torch.Size([120, 16, 5, 5]) torch.Size([120])
linear6 torch.Size([1, 84]) torch.Size([84, 120]) torch.Size([84])
linear7 torch.Size([1, 10]) torch.Size([10, 84]) torch.Size([10])
从输出结果看 对于大小为32×32的单通道图像先用6个大小为5×5的卷积核对其进行卷积运算输出为6个28×28大小的特征图6个28×28大小的特征图经过大小为2×2步长为2的汇聚层后输出特征图的大小变为14×146个14×14大小的特征图再经过16个大小为5×5的卷积核对其进行卷积运算得到16个10×10大小的输出特征图16个10×10大小的特征图经过大小2×2步长为2的汇聚层后输出特征图的大小变为5×516个5×5大小的特征图再经过120个大小为5×5的卷积核对其进行卷积运算得到120个1×1大小的输出特征图此时将特征图展平成1维则有120个像素点经过输入神经元个数为120输出神经元个数为84的全连接层后输出的长度变为84。再经过一个全连接层的计算最终得到了长度为类别数的输出结果。 2.2 测试网络运算速度
import time
x torch.tensor(inputs)
# 创建LeNet类的实例指定模型名称和分类的类别数目
model LeNet(in_channels1, num_classes10)
# 计算LeNet类的运算速度
model_time 0
for i in range(60):strat_time time.time()out model(x)end_time time.time()# 预热10次运算不计入最终速度统计if i 10:continuemodel_time (end_time - strat_time)
avg_model_time model_time / 50
print(LeNet speed:, avg_model_time, s)LeNet speed: 0.0003125572204589844 s 我直接调用 了pytroch的API没有用自定义的算子由输出结果可以看到模型运算效率很快。
2.3 输出模型参数量 对于一个卷积层假设输入通道数为 cin卷积核大小为 k×k输出通道数为 cout则卷积层的参数量为 k*k*cin 1 *cout【其中 1是偏置项】 对于一个全连接层假设输入神经元数为n输出神经元数为 m则全连接层的参数量为n*mm【m 是偏置项】 第一个卷积层的参数量为6×1×5×56156第二个卷积层的参数量为16×6×5×5162416第三个卷积层的参数量为120×16×5×512048120第一个全连接层的参数量为120×848410164第二个全连接层的参数量为84×1010850
所以LeNet-5总的参数量为61706。
# 计算参数量
from torchsummary import summary
device torch.device(cuda if torch.cuda.is_available() else cpu) # PyTorch v0.4.0
Torch_model LeNet(in_channels1, num_classes10).to(device)
summary(Torch_model, (1,32, 32))
输出结果
----------------------------------------------------------------Layer (type) Output Shape Param #
Conv2d-1 [-1, 6, 28, 28] 156MaxPool2d-2 [-1, 6, 14, 14] 0Conv2d-3 [-1, 16, 10, 10] 2,416AvgPool2d-4 [-1, 16, 5, 5] 0Conv2d-5 [-1, 120, 1, 1] 48,120Linear-6 [-1, 84] 10,164Linear-7 [-1, 10] 850Total params: 61,706
Trainable params: 61,706
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.06
Params size (MB): 0.24
Estimated Total Size (MB): 0.30
----------------------------------------------------------------
[Train] epoch: 0/6, step: 0/4692, loss: 2.29571 可以看到结果与公式推导一致。
2.4 输出模型计算量
计算量即浮点运算次数通常计算操作中的乘法和加法
第一个卷积层的计算量为28×28×5×5×6×128×28×6122304第二个卷积层的计算量为10×10×5×5×16×610×10×16241600第三个卷积层的计算量为1×1×5×5×120×161×1×12048120平均汇聚层的计算量为16×5×5400第一个全连接层的计算量为120×8410080第二个全连接层的计算量为84×10840
所以LeNet-5总的计算量为423344。
from thop import profile
# 创建一个假输入并将其移动到相同的设备GPU
dummy_input torch.randn(1, 1, 32, 32).to(device)
# 计算模型的 FLOPS 和参数量
flops, params profile(model, (dummy_input,))
运行结果
[INFO] Register count_convNd() for class torch.nn.modules.conv.Conv2d.
[INFO] Register zero_ops() for class torch.nn.modules.pooling.MaxPool2d.
[INFO] Register count_avgpool() for class torch.nn.modules.pooling.AvgPool2d.
[INFO] Register count_linear() for class torch.nn.modules.linear.Linear.
模型的计算量FLOPS416920.0
模型的参数量params61706.0 【不知道为什么和计算的不一样o(╥﹏╥)o】
3. 模型训练
和之前实验差不多用到了RunnerV3类需要导入
# 进行训练
import torch.optim as opti
from torch.utils.data import DataLoader# 学习率大小
lr 0.1
# 批次大小
batch_size 64# 创建三个数据加载器分别用于训练、开发和测试数据集 shuffleTrue表示在每个epoch开始时对数据进行随机打乱防止过拟合
train_loader DataLoader(train_dataset, batch_sizebatch_size, shuffleTrue)
dev_loader DataLoader(dev_dataset, batch_sizebatch_size)
test_loader DataLoader(test_dataset, batch_sizebatch_size)
# 定义LeNet网络
model LeNet(in_channels1, num_classes10)
# 定义优化器 优化器的学习率设置为0.2
optimizer opti.SGD(model.parameters(), 0.2)
# 定义损失函数 使用交叉熵损失函数
loss_fn F.cross_entropy
# 定义评价指标-这里使用的是准确率
metric Accuracy()
# 实例化 RunnerV3 类并传入模型、优化器、损失函数和评价指标
runner RunnerV3(model, optimizer, loss_fn, metric)
# 启动训练设置每15步记录一次日志 每15步评估一次模型性能
log_steps 15
eval_steps 15
# 训练模型6个epoch,并保存最好的模型参数
runner.train(train_loader, dev_loader, num_epochs6, log_stepslog_steps,eval_stepseval_steps, save_pathbest_model.pdparams)runner.load_model(best_model.pdparams)运行结果
[Train] epoch: 0/6, step: 780/4692, loss: 0.13901
[Evaluate] dev score: 0.97590, dev loss: 0.08247
[Evaluate] best accuracy performence has been updated: 0.97450 -- 0.97590
.....
[Train] epoch: 1/6, step: 1560/4692, loss: 0.02407
[Evaluate] dev score: 0.98080, dev loss: 0.06440
.....
[Evaluate] best accuracy performence has been updated: 0.98470 -- 0.98700
[Train] epoch: 2/6, step: 2340/4692, loss: 0.05586
[Evaluate] dev score: 0.98170, dev loss: 0.06324
.....
[Train] epoch: 3/6, step: 3120/4692, loss: 0.04725
[Evaluate] dev score: 0.98240, dev loss: 0.05973
.....
[Train] epoch: 4/6, step: 3900/4692, loss: 0.06728
[Evaluate] dev score: 0.98120, dev loss: 0.07054
.....
[Evaluate] dev score: 0.97870, dev loss: 0.07452
[Train] Training done!损失函数收敛训练集上精度达到0.98
4.模型评价
使用测试集对在训练过程中保存的最佳模型进行评价
# 加载最优模型
runner.load_model(best_model.pdparams)
# 模型评价
score, loss runner.evaluate(test_loader)
print([Test] accuracy/loss: {:.4f}/{:.4f}.format(score, loss))
[Test] accuracy/loss: 0.9861/0.0413 可见模型结果还是很不错的。
5.模型预测
使用保存好的模型对测试集中的某一个数据进行模型预测
# 获取测试集中第一条数据
X, label next(test_loader())
logits runner.predict(X)
# 多分类使用softmax计算预测概率
pred F.softmax(logits)
# 获取概率最大的类别
pred_class paddle.argmax(pred[1]).numpy()
label label[1][0].numpy()
# 输出真实类别与预测类别
print(The true category is {} and the predicted category is {}.format(label[0], pred_class[0]))
# 可视化图片
plt.figure(figsize(2, 2))
image, label test_set[0][1], test_set[1][1]
image np.array(image).astype(float32)
image np.reshape(image, [28,28])
image Image.fromarray(image.astype(uint8), modeL)
plt.imshow(image)
plt.savefig(cnn-number2.pdf)
The true category is 2 and the predicted category is 2
6 使用完整数据集不改变输入图像尺寸使其为1*28*28的图像输入
6.1在第一层卷积时对图像进行padding 2 填充
class LetNet(nn.Module):def __init__(self):super(LetNet, self).__init__()# 第一层卷积输入 (1, 28, 28) - 输出 (6, 28, 28)self.conv1 nn.Sequential(nn.Conv2d(in_channels1, # 输入通道数1灰度图out_channels6, # 输出通道数6kernel_size5, # 卷积核大小5x5stride1, # 步长1padding2, # 填充2), # 输出特征图 (6, 28, 28)nn.BatchNorm2d(6), # 批标准化nn.ReLU(), # ReLU 激活函数nn.MaxPool2d(kernel_size2), # 池化操作2x2区域- 输出 (6, 14, 14))# 第二层卷积输入 (6, 14, 14) - 输出 (16, 10, 10)self.conv2 nn.Sequential(nn.Conv2d(6, 16, 5, 1, padding0), # 卷积核大小5x5步长1 - 输出 (16, 10, 10)nn.BatchNorm2d(16),nn.ReLU(),nn.AvgPool2d(2), # 池化操作2x2区域- 输出 (16, 5, 5))# 第二层卷积输入 (16, 5, 5) - 输出 (120, 1, 1)self.conv3 nn.Sequential(nn.Conv2d(16, 120, 5, 1, padding0), # 卷积核大小5x5步长1 - 输出 (120, 1, 1)nn.BatchNorm2d(120),nn.ReLU(),)# 全连接层self.fc nn.Sequential(nn.Linear(120 , 84), # 120x1x1 展平后输入到全连接层 - 84个输出nn.Linear(84, 10) # 最后一层输出10个类别)def forward(self, x):x self.conv1(x)x self.conv2(x)x self.conv3(x)x torch.flatten(x, 1) # 展平操作保持batch_size展平特征图output self.fc(x) # 通过全连接层进行分类return output6.2 在第一层卷积时不对图像进行padding 2 填充
class LetNet(nn.Module):def __init__(self):super(LetNet, self).__init__()# 第一层卷积输入 (1, 28, 28) - 输出 (6, 12, 12)self.conv1 nn.Sequential(nn.Conv2d(in_channels1, # 输入通道数1灰度图out_channels6, # 输出通道数6kernel_size5, # 卷积核大小5x5stride1, # 步长1), # 输出特征图 (6, 24, 24)nn.BatchNorm2d(6), # 批标准化nn.ReLU(), # ReLU 激活函数nn.MaxPool2d(kernel_size2), # 池化操作2x2区域- 输出 (6, 12, 12))# 第二层卷积输入 (6, 12, 12) - 输出 (16, 4, 4)self.conv2 nn.Sequential(nn.Conv2d(6, 16, 5, 1), # 卷积核大小5x5步长1 - 输出 (16, 8, 8)nn.BatchNorm2d(16),nn.ReLU(),nn.AvgPool2d(2), # 池化操作2x2区域- 输出 (16, 4, 4))# 全连接层self.fc nn.Sequential(nn.Linear(16*4*4,120),nn.Linear(120 , 84), # 120x1x1 展平后输入到全连接层 - 84个输出nn.Linear(84, 10) # 最后一层输出10个类别)def forward(self, x):x self.conv1(x)x self.conv2(x)x torch.flatten(x, 1) # 展平操作保持batch_size展平特征图output self.fc(x) # 通过全连接层进行分类return output 这里我本来想接着用最后一层的卷积但是发现卷积核为5*5而此时图像尺寸为4*4了应该使用4*4的卷积核但是这里我把最后一个卷积写到全连接层了效果是一样的 6.3 完整代码 function: 基于LeNet识别MNIST数据集
Author: lxy
date: 2024/11/14import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
import numpy as np# 定义超参数
input_size 28 # 图像的总尺寸28*28
num_classes 10 # 标签的种类数
num_epochs 3 # 训练的总循环周期
batch_size 64 # 一个撮批次的大小64张图片# 训练集
train_dataset datasets.MNIST(root./data,trainTrue,transformtransforms.ToTensor(),downloadTrue)# 测试集
test_dataset datasets.MNIST(root./data,trainFalse,transformtransforms.ToTensor())# 构建batch数据
train_loader torch.utils.data.DataLoader(datasettrain_dataset,batch_sizebatch_size,shuffleTrue)
test_loader torch.utils.data.DataLoader(datasettest_dataset,batch_sizebatch_size,shuffleFalse)class LetNet(nn.Module):def __init__(self):super(LetNet, self).__init__()# 第一层卷积输入 (1, 28, 28) - 输出 (6, 12, 12)self.conv1 nn.Sequential(nn.Conv2d(in_channels1, # 输入通道数1灰度图out_channels6, # 输出通道数6kernel_size5, # 卷积核大小5x5stride1, # 步长1), # 输出特征图 (6, 24, 24)nn.BatchNorm2d(6), # 批标准化nn.ReLU(), # ReLU 激活函数nn.MaxPool2d(kernel_size2), # 池化操作2x2区域- 输出 (6, 12, 12))# 第二层卷积输入 (6, 12, 12) - 输出 (16, 4, 4)self.conv2 nn.Sequential(nn.Conv2d(6, 16, 5, 1), # 卷积核大小5x5步长1 - 输出 (16, 8, 8)nn.BatchNorm2d(16),nn.ReLU(),nn.AvgPool2d(2), # 池化操作2x2区域- 输出 (16, 4, 4))# 全连接层self.fc nn.Sequential(nn.Linear(16*4*4,120),nn.Linear(120 , 84), # 120x1x1 展平后输入到全连接层 - 84个输出nn.Linear(84, 10) # 最后一层输出10个类别)def forward(self, x):x self.conv1(x)x self.conv2(x)x torch.flatten(x, 1) # 展平操作保持batch_size展平特征图output self.fc(x) # 通过全连接层进行分类return outputdef accuracy(predictions, labels):pred torch.max(predictions.data, 1)[1]rights pred.eq(labels.data.view_as(pred)).sum()return rights, len(labels)def train_one_epoch(model, criterion, optimizer, train_loader):model.train()train_rights []total_loss 0for batch_idx, (data, target) in enumerate(train_loader):optimizer.zero_grad()output model(data)loss criterion(output, target)loss.backward()optimizer.step()right accuracy(output, target)train_rights.append(right)total_loss loss.item()# 计算训练准确率train_r (sum([tup[0] for tup in train_rights]), sum([tup[1] for tup in train_rights]))avg_loss total_loss / len(train_loader)train_acc 100. * train_r[0] / train_r[1]return avg_loss, train_accdef evaluate(model, criterion, test_loader):model.eval()val_rights []total_loss 0with torch.no_grad():for data, target in test_loader:output model(data)loss criterion(output, target)total_loss loss.item()right accuracy(output, target)val_rights.append(right)# 计算测试准确率val_r (sum([tup[0] for tup in val_rights]), sum([tup[1] for tup in val_rights]))avg_loss total_loss / len(test_loader)val_acc 100. * val_r[0] / val_r[1]return avg_loss, val_acc# 实例化模型
net LetNet()
# 损失函数
criterion nn.CrossEntropyLoss()
# 优化器
optimizer optim.Adam(net.parameters(), lr0.001)# 训练和测试过程
train_losses []
train_accuracies []
test_losses []
test_accuracies []for epoch in range(num_epochs):print(fEpoch {epoch 1}/{num_epochs})# 训练阶段train_loss, train_acc train_one_epoch(net, criterion, optimizer, train_loader)train_losses.append(train_loss)train_accuracies.append(train_acc)# 测试阶段test_loss, test_acc evaluate(net, criterion, test_loader)test_losses.append(test_loss)test_accuracies.append(test_acc)print(f训练集损失: {train_loss:.4f}, 训练集准确率: {train_acc:.2f}%)print(f测试集损失: {test_loss:.4f}, 测试集准确率: {test_acc:.2f}%)# 可视化训练过程中的损失和准确率
epochs np.arange(1, num_epochs 1)# 绘制损失图
plt.figure(figsize(10, 5))
plt.subplot(1, 2, 1)
plt.plot(epochs, train_losses, labelloss_train)
plt.plot(epochs, test_losses, labelloss_test)
plt.xlabel(Epoch)
plt.ylabel(Loss)
plt.legend()
plt.title(loos)# 绘制准确率图
plt.subplot(1, 2, 2)
plt.plot(epochs, train_accuracies, labelAccuracy_train)
plt.plot(epochs, test_accuracies, labelAccuracy_test)
plt.xlabel(Epoch)
plt.ylabel(Accuracy (%))
plt.legend()
plt.title(Accuracy)plt.tight_layout()
plt.show()运行结果及调参 Epoch 1/3
训练集损失: 0.1695, 训练集准确率: 95.00%
测试集损失: 0.0622, 测试集准确率: 98.02%
Epoch 2/3
训练集损失: 0.0605, 训练集准确率: 98.13%
测试集损失: 0.0486, 测试集准确率: 98.31%
Epoch 3/3
训练集损失: 0.0475, 训练集准确率: 98.52%
测试集损失: 0.0376, 测试集准确率: 98.82%
这里使用全部数据我只设置了3个epoch准确率就已经很不错了~
调整为epoch 10,时输出结果为 可以看到有点要过拟合了训练集准确率一直上升但是测试集在epoch 4左右开始下降但是我发现epoch10之后又有上升的趋势于是改为epoch 14输出 Epoch 14/14
训练集损失: 0.0211, 训练集准确率: 99.34%
测试集损失: 0.0283, 测试集准确率: 99.16%
参考链接 详解MNIST数据集下载、解析及显示的Python实现-CSDN博客 对mnist的介绍真的很详细尤其是下载的方式 6.6. 卷积神经网络LeNet — 动手学深度学习 2.0.0 documentation 这本书中将LeNet最后一个卷积视为全连接 Lenet5经典论文解读 - 知乎 文章里详细解释了LeNet-5的七个层次并给出了详细的网络图 细品经典LeNet-1, LeNet-4, LeNet-5, Boosted LeNet-4-CSDN博客 博客回顾了LeNet系列神经网络模型包括LeNet-1、LeNet-4、LeNet-5 NNDL 实验六 卷积神经网络3LeNet实现MNIST_mnist.json.gz-CSDN博客 一位学长的博客哈哈哈