视频教程
说明:
说明:
Pytorch的nn.Conv2d()详解
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 #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 %