化妆品企业网站建设的缺点,网站标题字符,广东网站建设开发,象山县建设工程招投标网站经典神经网络-LeNets5
1998年Yann LeCun等提出的第一个用于手写数字识别问题并产生实际商业#xff08;邮政行业#xff09;价值的卷积神经网络
参考#xff1a;论文笔记#xff1a;Gradient-Based Learning Applied to Document Recognition-CSDN博客
1 网络模型结构
…经典神经网络-LeNets5
1998年Yann LeCun等提出的第一个用于手写数字识别问题并产生实际商业邮政行业价值的卷积神经网络
参考论文笔记Gradient-Based Learning Applied to Document Recognition-CSDN博客
1 网络模型结构
整体结构解读 输入图像32×32×1
三个卷积层
C1输入图片32×326个5×5卷积核 输出特征图大小28×2832-5128一个bias参数
可训练参数一共有5×51×6156
C3 输入图片14×14,16个5×5卷积核有6×36×43×41×660个通道输出特征图大小10×1014-5/11一个bias参数
可训练参数一共有63×5×516×4×5×513×4×5×511×6×5×511516
C3的非密集的特征图连接 C3的前6个特征图与S2层相连的3个特征图相连接后面6个特征图与S2层相连的4个特征图相连 接后面3个特征图与S2层部分不相连的4个特征图相连接最后一个与S2层的所有特征图相连。 采用非密集连接的方式打破对称性同时减少计算量共60组卷积核。主要是为了节省算力。
C5输入图片5×5,16个5×5卷积核包括120×16个5×5卷积核 输出特征图大小1×15-51一个bias参数
可训练参数一共有120×16×5×5148120
两个池化层S2和S4
都是2×2的平均池化并添加了非线性映射
S2下采样层输入28×28采样区域2×2输入相加乘以一个可训练参数 再加上一个可训练偏置使用sigmoid激活输出特征图大小14×1428/2
S4下采样层输入10×10采样区域2×2输入相加乘以一个可训练参数 再加上一个可训练偏置使用sigmoid激活输出特征图大小5×510/2
两个全连接层
第一个全连接层输入120维向量输出84个神经元计算输入向量和权重向量之间的点积再加上一个偏置结果通过sigmoid函数输出。84的原因是字符编码是ASCII编码用7×12大小的位图表示-1白色1黑色84可以用于对每一个像素点的值进行估计。
第二个全连接层Output层-输出层输出 10个神经元 共有10个节点代表数字0-9。
所有激活函数采用Sigmoid
2 网络模型实现
2.1模型定义
import torch
import torch.nn as nn
class LeNet5s(nn.Module):def __init__(self):super(LeNet5s, self).__init__() # 继承父类# 第一个卷积层self.C1 nn.Sequential(nn.Conv2d(in_channels1, # 输入通道out_channels6, # 输出通道kernel_size5, # 卷积核大小),nn.ReLU(),)# 池化平均池化self.S2 nn.AvgPool2d(kernel_size2)
# C3:3通道特征融合单元self.C3_unit_6x3 nn.Conv2d(in_channels3,out_channels1,kernel_size5,)# C3:4通道特征融合单元self.C3_unit_6x4 nn.Conv2d(in_channels4,out_channels1,kernel_size5,)
# C3:4通道特征融合单元剔除中间的1通道self.C3_unit_3x4_pop1 nn.Conv2d(in_channels4,out_channels1,kernel_size5,)
# C3:6通道特征融合单元self.C3_unit_1x6 nn.Conv2d(in_channels6,out_channels1,kernel_size5,)
# S4:池化self.S4 nn.AvgPool2d(kernel_size2)# 全连接层self.fc1 nn.Sequential(nn.Linear(in_features16 * 5 * 5, out_features120), nn.ReLU())self.fc2 nn.Sequential(nn.Linear(in_features120, out_features84), nn.ReLU())self.fc3 nn.Linear(in_features84, out_features10)
def forward(self, x):# 训练数据批次大小batch_sizenum x.shape[0]
x self.C1(x)x self.S2(x)# 生成一个empty张量outchannel torch.empty((num, 0, 10, 10))# 6个3通道的单元for i in range(6):# 定义一个元组存储要提取的通道特征的下标channel_idx tuple([j % 6 for j in range(i, i 3)])x1 self.C3_unit_6x3(x[:, channel_idx, :, :])outchannel torch.cat([outchannel, x1], dim1)
# 6个4通道的单元for i in range(6):# 定义一个元组存储要提取的通道特征的下标channel_idx tuple([j % 6 for j in range(i, i 4)])x1 self.C3_unit_6x4(x[:, channel_idx, :, :])outchannel torch.cat([outchannel, x1], dim1)
# 3个4通道的单元先拿五个干掉中那一个for i in range(3):# 定义一个元组存储要提取的通道特征的下标channel_idx tuple([j % 6 for j in range(i, i 5)])# 删除第三个元素channel_idx channel_idx[:2] channel_idx[3:]print(channel_idx)x1 self.C3_unit_3x4_pop1(x[:, channel_idx, :, :])outchannel torch.cat([outchannel, x1], dim1)
x1 self.C3_unit_1x6(x)# 平均池化outchannel torch.cat([outchannel, x1], dim1)outchannel nn.ReLU()(outchannel)
x self.S4(outchannel)# 对数据进行变形x x.view(x.size(0), -1)# 全连接层x self.fc1(x)x self.fc2(x)# TODO:SOFTMAXoutput self.fc3(x)
return output
def test001():net LeNet5s()# 随机一个测试数据input torch.randn(128, 1, 32, 32)output net(input)print(output.shape)pass
if __name__ __main__:test001()
2.2全局变量
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import os
dir os.path.dirname(__file__)
modelpath os.path.join(dir, weight/model.pth)
datapath os.path.join(dir, data)
# 数据预处理和加载
transform transforms.Compose([transforms.Resize((32, 32)), # 调整输入图像大小为32x32transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,)),]
)
2.3模型训练
def train():
trainset torchvision.datasets.MNIST(rootdatapath, trainTrue, downloadTrue, transformtransform)trainloader torch.utils.data.DataLoader(trainset, batch_size32, shuffleTrue)
# 实例化模型net LeNet5()
# 使用MSELoss作为损失函数criterion nn.MSELoss()
# 使用SGD优化器optimizer optim.SGD(net.parameters(), lr0.01, momentum0.9)
# 训练模型num_epochs 10for epoch in range(num_epochs):running_loss 0.0for i, data in enumerate(trainloader, 0):inputs, labels data
# 将labels转换为one-hot编码labels_one_hot torch.zeros(labels.size(0), 10).scatter_(1, labels.view(-1, 1), 1.0)labels_one_hot labels_one_hot.to(torch.float32)optimizer.zero_grad()outputs net(inputs)loss criterion(outputs, labels_one_hot)loss.backward()optimizer.step()
running_loss loss.item()if i % 100 99:print(f[{epoch 1}, {i 1}] loss: {running_loss / 100:.3f})running_loss 0.0# 保存模型参数torch.save(net.state_dict(), modelpath)print(Finished Training)
2.4验证
def vaild():
testset torchvision.datasets.MNIST(rootdatapath, trainFalse, downloadTrue, transformtransform)testloader torch.utils.data.DataLoader(testset, batch_size32, shuffleFalse)# 实例化模型net LeNet5()net.load_state_dict(torch.load(modelpath))# 在测试集上测试模型correct 0total 0with torch.no_grad():for data in testloader:images, labels dataoutputs net(images)_, predicted torch.max(outputs.data, 1)total labels.size(0)correct (predicted labels).sum().item()
print(f验证集: {100 * correct / total:.2f}%)