第10讲:卷积 神经网络(基础篇)
视频教程
1.卷积神经网络
说明:
- 首先明确输入的张量维度多少,输出的张量维度多少,利用各种层(做特征提取),进行这个维度上或者是每个维度上尺寸大小的变化,最终把它映射到想要的输出的这个空间里面
- Feature Extraction:特征提取包括卷积、下采样
- Classification:全连接
2.n个输入通道与m个输出通道
说明:
- 3通道的输入,需要3通道的卷积核,进行数乘相加,输出
- 每一个卷积核它的通道数量要求和输入通道是一样的
说明; - 卷积核的总数有m个 = 输出通道的数目m个
- 卷积核的总数有多少个和你输出通道的数量是一样的
so~ - 卷积层要求输入输出是四维张量(B,C,W,H),全连接层的输入与输出都是二维张量(B,Input_feature)。
- 卷积层:明确:1.输入输出通道C,2.卷积核的size
3.代码图解
图1:卷积过程
图2:各个层描述
图3:计算结果
4.代码
import torch
from torchvision import transforms#图像处理
from torchvision import datasets#加载数据
from torch.utils.data import DataLoader#为了构建Dataloader
import torch.nn.functional as F#为了使用relu激活函数
import torch.optim as optim#优化器的包
# 1.prepare dataset
batch_size = 64
#要使用dataset,dataloader所以要设置batch容量
transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))])
#ToTensor讲原始图片转成图像张量(维度1->3,像素值属于【0,1】
#Normalize(均值,标准差)像素值切换成0,1分布
#加载训练集
train_dataset = datasets.MNIST(root='../dataset/mnist/', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
#加载测试集,都是pytorch看你需求自己下载的
test_dataset = datasets.MNIST(root='../dataset/mnist/', train=False, download=True, transform=transform)
test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)
#2.Design Model
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
#定义卷积模型:
# 第一个卷积层(图片channel是1所以第一个参数为输入通道1
#第二个参数:输出通道10(即这个卷积层需要10个卷积核
#第三个参数:卷积核尺寸:5*5)
self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)
#第二层同上:输入通道=上一层的输出通道
self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)
#需要一个池化层作用主要是通过下采样降低参数量
self.pooling = torch.nn.MaxPool2d(2)
#需要线性层做分类,通过view操作变成一维向量(图一:4*4*20=320)
self.fc = torch.nn.Linear(320,10)
def forward(self, x):
# Flatten data from (n, 1, 28, 28) to (n, 784)
batch_size = x.size(0)#batch大小是输入x的第0个维度:样本n
#输入x经过第一个卷积层 + 池化层 + relu激活
x = F.relu(self.pooling(self.conv1(x)))
#重复经历
x = F.relu(self.pooling(self.conv2(x)))
#将处理后二维的图片20x4x4张量转成向量,作为全连接网络的输入
x = x.view(batch_size,-1)
#用全连接层做转换,最后要用交叉熵计算损失,注意不要激活
x = self.fc(x)
return x
model = Net()#实例化为model
#如果需要把计算迁移到GPU,添加这两句:
# device = torch.device("cuda:0" if torch.cuda.is_available()else"cpu")
# model.to(device)
#3.construct Loss and Optimizer
#损失函数,来计算我们模型输出的值和标准值的差距
criterion = torch.nn.CrossEntropyLoss()
#定义一个优化器,他会反向的更改相应层的权重来训练模型
optimizer = optim.SGD(model.parameters(),lr=0.01, momentum=0.5)
#4.Train and Test
def train(epoch):#封装训练函数
running_loss = 0.0
for batch_idx, data in enumerate(train_loader,0):
inputs, target = data
#输入x,输出y
optimizer.zero_grad()
#清空过往梯度
#forward + backward + updata
outputs = model(inputs)
#forward 计算y^
loss = criterion(outputs, target)
#(y^,y)计算损失值
loss.backward()
#反向传播,计算当前梯度
optimizer.step()
#根据梯度更新网络参数
running_loss += loss.item()
#损失累计
#!loss拿出的值,而非构建计算图
#每300下输出一次数据
if batch_idx % 300 ==299:
print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1,running_loss / 300))
running_loss = 0.0
def test():#封装测试函数
correct = 0
total = 0
with torch.no_grad():#以下不用计算梯度
for data in test_loader:
images, labels = data
outputs = model(images)
_, predicted = torch.max(outputs.data, dim = 1)
#输出数据,dim =1检索每行最大值,并输出下标
#(不关心最大值是多少,所以用_,predicted是下标)
#dim = 1横向降维,dim = 0纵向降维
total += labels.size(0)
#正确率:两个张量的比较
correct += (predicted == labels).sum().item()
print('Accuracy on test set:%d %%' %(100 * correct / total))
if __name__ == '__main__':
for epoch in range(10):
train(epoch)
test()
结果:
[1, 300] loss: 0.661
[1, 600] loss: 0.178
[1, 900] loss: 0.141
Accuracy on test set:96 %
[2, 300] loss: 0.110
[2, 600] loss: 0.108
[2, 900] loss: 0.090
Accuracy on test set:97 %
[3, 300] loss: 0.087
[3, 600] loss: 0.075
[3, 900] loss: 0.075
Accuracy on test set:98 %
[4, 300] loss: 0.066
[4, 600] loss: 0.069
[4, 900] loss: 0.064
Accuracy on test set:98 %
[5, 300] loss: 0.061
[5, 600] loss: 0.054
[5, 900] loss: 0.059
Accuracy on test set:98 %
[6, 300] loss: 0.055
[6, 600] loss: 0.050
[6, 900] loss: 0.049
Accuracy on test set:98 %
[7, 300] loss: 0.042
[7, 600] loss: 0.051
[7, 900] loss: 0.048
Accuracy on test set:98 %
[8, 300] loss: 0.040
[8, 600] loss: 0.044
[8, 900] loss: 0.045
Accuracy on test set:98 %
[9, 300] loss: 0.041
[9, 600] loss: 0.041
[9, 900] loss: 0.039
Accuracy on test set:98 %
[10, 300] loss: 0.036
[10, 600] loss: 0.036
[10, 900] loss: 0.043
Accuracy on test set:98 %
5.参考
Pytorch的nn.Conv2d()详解另外一个小伙伴笔记