神经网络笔记
- 代码链接github
:wink:
Note
数据处理
train_data = torchvision.datasets.CIFAR10(
root='Datadir', train=True, transform=transforms.ToTensor(),download=True
)
- torchvision.datasets.CIFAR10:代表这是cifar10数据集,若为torchvision.datasets.MNIST则为mnist数据集
- root:数据集的存放位置
- train=True:代表这是训练集
- download=True:如果数据不存在就会自行下载
train_loader = Data.DataLoader(dataset=train_data, batch_size=4, shuffle=True, num_workers=2)
- dataset=train_data:代表从train_data加载数据
- batch_size: 批训练的数据个数
- shuffle: 是否要打乱数据(打乱比较好)
- num_workers: 多线程读取数据
训练模型
optimizer = optim.SGD(net.parameters(), lr=0.03)
- 定义优化器
- lr=0.03: 学习率为0.03
- SGD: 使用SGD优化器
loss_func = nn.CrossEntropyLoss()
- 定义损失函数
- CrossEntropyLoss:交叉熵损失
# 循环使用数据训练50次
for epoch in range(50):
# 训练
# 每次训练之前的初始化loss&acc
train_loss = 0
train_acc = 0
for i, data in enumerate(train_loader, 0):
# 得到数据
inputs, lables = data
# 包装数据
inputs, lables = Variable(inputs), Variable(lables)
# 梯度清零
optimizer.zero_grad()
# 将输入输进网络&forward
out = net(inputs)
# 计算损失
loss = loss_func(out, lables)
train_loss += loss.item()
# 计算正确率
pred = torch.max(out, 1)[1]
train_acc += (pred == lables).sum().item()
# backward&optimize
loss.backward()
optimizer.step()
train_loss += loss.data.item()
if i % 2000 == 1999:
# 格式化输出loss&acc
print('[%d,%5d] loss:%.6f' % (epoch+1, i+1, train_loss/2000))
print('[%d,%5d] acc: %.6f' % (epoch + 1, i + 1, train_acc / (2000 * lables.size(0))))
# 训练2000组数据打印数据之后的初始化
train_acc = 0
train_loss = 0
torch.save(net, 'Alex0.03.pkl')
# 测试
# 正确率初始化
train_acc1 = 0
for i, data in enumerate(test_loader, 0):
# 得到数据并包装数据
inputs, lables = data
inputs, lables = Variable(inputs), Variable(lables)
# 计算正确率
out = net(inputs)
pred = torch.max(out, 1)[1]
train_acc1 += (pred == lables).sum().item()
# 阶段性输出
if i % 1000 == 999:
print('testDataAcc:[%d,%5d] acc: %.6f' % (epoch + 1, i + 1, train_acc1 / (1000 * lables.size(0))))
train_acc1 = 0
全连接神经网络
note
- 每层的节点数和层数可自己随意定义
参考代码
卷积神经网络
参数计算
- 输入矩阵的格式:四个维度(样本数,图像高度,图像宽度,图像通道数)
- 卷积核(权重矩阵):四个维度(卷积核高,卷积核宽,输入通道数,输出通道数)
- 卷积核输入的通道数由输入矩阵的通道数决定
- 输出矩阵的通道数由卷积核的输出通道数决定
- 输出矩阵的高和宽由输入矩阵,卷积核,扫描方式(padding,stride)所决定
- 卷积之后的图像大小计算:outputSize = (inputSize + 2*padding - kernelSize)/stride + 1
LeNet AlexNet VGG ResNet GoogLeNet
leNet
-
cifar10数据集参考代码
[图片上传失败...(image-7348e4-1558405975880)] - 输入是32x32的图像
- C1是一个卷积层,卷积核为5x5,步长为1,没有填充,由(32-2*0-5)/1+1=28,得输出图像为28x28
- S2是一个降采样层,kernelSize等于2,步长为2,没有填充,得到输出为14x14
- C3是一个卷积层,卷积核大小为5x5,步长为1,没有填充,得输出图像为10x10
- S4是一个降采样层,kernelSize等于2,步长为2,没有填充,得到输出为5x5
- C5是一个卷积层,卷积核大小为5x5,步长为1,没有填充,得输出图像为1x1
- F6是一个全连接层
- 输出有十个参数
AlexNet
代码做了简化,使用单个运算核心运行的
[图片上传失败...(image-cfa94a-1558405975881)]
note未跟随代码
- 卷积部分分为上下两块,卷积使用数据要看连接的虚线
- LRN层:对当前层的输出结果做平滑处理
VGG
- cifar10数据集参考代码
- 连续conv较多,计算量巨大
ResNet
深度网络的退化问题
网络深度增加时,网络准确度出现饱和甚至开始下降
使用残差学习解决退化问题
残差学习相比原始特征直接学习更容易,当残差为0时,此时堆积层仅仅做了恒等映射.至少网络性能不会下降,实际上残差不会为0,也会使得堆积层在输入特征基础上学习到新的特征,从而有更好的性能
-
残差学习相当于一种短路机制
残差学习单元
[图片上传失败...(image-e97a42-1558405975881)]不同深度的ResNet网络
[图片上传失败...(image-88ec11-1558405975881)]
googLeNet
-
GoogLeNet 与传统神经网络相比提出了Inception结构,用于增加神经网络的宽度和深度,Inception模型主要考虑多个不同的卷积核能够增强网络的适应能力,4个分支在最后通过一个聚合操作合并
网友评论