目录
4.2.2 implemetaion of inception Module编辑
4.2.3 Inception Module 以及模型构建的实现代码
参考文章:
PyTorch 深度学习实践 第10讲_错错莫的博客-CSDN博客
- import torch
-
- in_channels, out_channels = 5, 10 #定义输入输出的通道数
- width, hight = 100, 100 #定义图片的大小
- kernel_size = 3 # 定义的卷积核是一个3*3的
- batch_size = 1
-
- #输入层
- input = torch.randn(batch_size,
- in_channels,
- width,
- hight
- )
-
- # 定义卷积层
- conv_layer = torch.nn.Conv2d(
- in_channels,
- out_channels,
- kernel_size=kernel_size
- )
-
- #定义输出层
- output = conv_layer(input)
-
- print(input.shape)
- print(output.shape)
- print(conv_layer.weight.shape)
- torch.Size([1, 5, 100, 100])
- torch.Size([1, 10, 98, 98])
- torch.Size([10, 5, 3, 3])
- import torch
-
- #以下数据假设是输入的图像像素点
- input =[
- 3,4,6,5,7,
- 2,4,6,8,2,
- 1,6,7,8,4,
- 9,7,4,6,2,
- 3,7,5,4,1
- ]
-
- input = torch.Tensor(input).view(1,1,5,5) #将input的数据转化为tensor类型,并设置B,C,W,H为1,1,5,5
-
- #padding填充
- conv_layer = torch.nn.Conv2d(1,1,kernel_size=3,padding=1,bias=False) #前两个数字对应的是输入与输出对应的通道数
-
- kernel = torch.Tensor([1,2,3,4,5,6,7,8,9]).view(1,1,3,3) # 构造卷积核,view(输出的通道(卷积核的个数),输入的通道数(卷积核的通道数),3*3)
- conv_layer.weight.data = kernel.data # 将卷积核的权重赋给卷积层
-
- output = conv_layer(input) #做卷积运算
- print(output)
-
-
- import torch
-
- #以下数据假设是输入的图像像素点
- input =[
- 3,4,6,5,7,
- 2,4,6,8,2,
- 1,6,7,8,4,
- 9,7,4,6,2,
- 3,7,5,4,1
- ]
-
- input = torch.Tensor(input).view(1,1,5,5) #将input的数据转化为tensor类型,并设置B,C,W,H为1,1,5,5
-
- #stride步长
- conv_layer = torch.nn.Conv2d(1,1,kernel_size=3,stride=2,bias=False)
-
- kernel = torch.Tensor([1,2,3,4,5,6,7,8,9]).view(1,1,3,3) # 构造卷积核,view(输出的通道(卷积核的个数),输入的通道数(卷积核的通道数),3*3)
- conv_layer.weight.data = kernel.data # 将卷积核的权重赋给卷积层
-
- output = conv_layer(input) #做卷积运算
- print(output)
-
-
- import torch
-
- #以下数据假设是输入的图像像素点
- input =[
- 3,4,6,5,7,
- 2,4,6,8,2,
- 1,6,7,8,4,
- 9,7,4,6,2,
- 3,7,5,4,1
- ]
-
- input = torch.Tensor(input).view(1,1,5,5) #将input的数据转化为tensor类型,并设置B,C,W,H为1,1,5,5
- #池化层
- maxpooling_layer = torch.nn.MaxPool2d(kernel_size=2)
- output = maxpooling_layer(input) #做卷积运算
- print(output)
-
-
代码说明:
1、torch.nn.Conv2d(1,10,kernel_size=3,stride=2,bias=False)
1是指输入的Channel,灰色图像是1维的;10是指输出的Channel,也可以说第一个卷积层需要10个卷积核;kernel_size=3,卷积核大小是3x3;stride=2进行卷积运算时的步长,默认为1;bias=False卷积运算是否需要偏置bias,默认为False。padding = 0,卷积操作是否补0。
2、self.fc = torch.nn.Linear(320, 10),这个320获取的方式,可以通过x = x.view(batch_size, -1) # print(x.shape)可得到(64,320),64指的是batch,320就是指要进行全连接操作时,输入的特征维度。
- import torch
- from torchvision import transforms
- from torchvision import datasets
- from torch.utils.data import DataLoader
- import torch.nn.functional as F
- import torch.optim as optim
-
- # prepare dataset
-
- batch_size = 64
- transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
-
- train_dataset = datasets.MNIST(root='../dataset/mnist/', train=True, download=True, transform=transform)
- train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
- test_dataset = datasets.MNIST(root='../dataset/mnist/', train=False, download=True, transform=transform)
- test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)
-
-
- # design model using class 构建网络模型
- class Net(torch.nn.Module):
- def __init__(self):
- super(Net, self).__init__()
- self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5) #卷积核为5*5
- self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)
- self.pooling = torch.nn.MaxPool2d(2)
- self.fc = torch.nn.Linear(320, 10) #全连接层,320 = 20*4*4
-
- def forward(self, x):
- # flatten data from (n,1,28,28) to (n, 784)
- batch_size = x.size(0) #样本的数据量
- x = F.relu(self.pooling(self.conv1(x))) #执行第一层卷积运算
- x = F.relu(self.pooling(self.conv2(x)))
- # 以下两步用于全连接运算
- x = x.view(batch_size, -1) # -1 此处自动算出的是320
- x = self.fc(x)
-
- return x
-
-
- model = Net()
-
- # construct loss and optimizer
- criterion = torch.nn.CrossEntropyLoss()
- optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
-
-
- # training cycle forward, backward, update
-
-
- def train(epoch):
- running_loss = 0.0
- for batch_idx, data in enumerate(train_loader, 0):
- inputs, target = data
- optimizer.zero_grad()
-
- outputs = model(inputs)
- loss = criterion(outputs, target)
- loss.backward()
- optimizer.step()
-
- running_loss += loss.item()
- 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)
- 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()
- C:\Users\ZARD\anaconda3\envs\PyTorch\python.exe C:/Users/ZARD/PycharmProjects/pythonProject/机器学习库/PyTorch实战课程内容/lecture10/CNN01.py
- Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
- Using downloaded and verified file: ../dataset/mnist/MNIST\raw\train-images-idx3-ubyte.gz
- Extracting ../dataset/mnist/MNIST\raw\train-images-idx3-ubyte.gz to ../dataset/mnist/MNIST\raw
-
- Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
- Using downloaded and verified file: ../dataset/mnist/MNIST\raw\train-labels-idx1-ubyte.gz
- Extracting ../dataset/mnist/MNIST\raw\train-labels-idx1-ubyte.gz to ../dataset/mnist/MNIST\raw
-
- Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
- Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to ../dataset/mnist/MNIST\raw\t10k-images-idx3-ubyte.gz
- 100%|██████████| 1648877/1648877 [00:30<00:00, 53892.68it/s]
- Extracting ../dataset/mnist/MNIST\raw\t10k-images-idx3-ubyte.gz to ../dataset/mnist/MNIST\raw
-
- Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz
- Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to ../dataset/mnist/MNIST\raw\t10k-labels-idx1-ubyte.gz
- 100%|██████████| 4542/4542 [00:03<00:00, 1153.06it/s]
- Extracting ../dataset/mnist/MNIST\raw\t10k-labels-idx1-ubyte.gz to ../dataset/mnist/MNIST\raw
-
- [1, 300] loss: 0.737
- [1, 600] loss: 0.213
- [1, 900] loss: 0.147
- accuracy on test set: 96 %
- [2, 300] loss: 0.118
- [2, 600] loss: 0.105
- [2, 900] loss: 0.084
- accuracy on test set: 97 %
- [3, 300] loss: 0.080
- [3, 600] loss: 0.071
- [3, 900] loss: 0.075
- accuracy on test set: 98 %
- [4, 300] loss: 0.065
- [4, 600] loss: 0.060
- [4, 900] loss: 0.064
- accuracy on test set: 98 %
- [5, 300] loss: 0.058
- [5, 600] loss: 0.054
- [5, 900] loss: 0.050
- accuracy on test set: 98 %
- [6, 300] loss: 0.046
- [6, 600] loss: 0.051
- [6, 900] loss: 0.049
- accuracy on test set: 98 %
- [7, 300] loss: 0.044
- [7, 600] loss: 0.046
- [7, 900] loss: 0.043
- accuracy on test set: 98 %
- [8, 300] loss: 0.040
- [8, 600] loss: 0.044
- [8, 900] loss: 0.038
- accuracy on test set: 98 %
- [9, 300] loss: 0.039
- [9, 600] loss: 0.037
- [9, 900] loss: 0.038
- accuracy on test set: 98 %
- [10, 300] loss: 0.038
- [10, 600] loss: 0.035
- [10, 900] loss: 0.034
- accuracy on test set: 98 %
-
- Process finished with exit code 0
- import torch
- from torchvision import transforms
- from torchvision import datasets
- from torch.utils.data import DataLoader
- import torch.nn.functional as F
- import torch.optim as optim
- import matplotlib.pyplot as plt
-
- # prepare dataset
-
- batch_size = 64
- transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
-
- train_dataset = datasets.MNIST(root='../dataset/mnist/', train=True, download=True, transform=transform)
- train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
- test_dataset = datasets.MNIST(root='../dataset/mnist/', train=False, download=True, transform=transform)
- test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)
-
- # design model using class
-
-
- class Net(torch.nn.Module):
- def __init__(self):
- super(Net, self).__init__()
- 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)
- 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)
- x = F.relu(self.pooling(self.conv1(x)))
- x = F.relu(self.pooling(self.conv2(x)))
- x = x.view(batch_size, -1) # -1 此处自动算出的是320
- # print("x.shape",x.shape)
- x = self.fc(x)
-
- return x
-
-
- model = Net()
- device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
- model.to(device)
-
- # construct loss and optimizer
- criterion = torch.nn.CrossEntropyLoss()
- optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
-
- # training cycle forward, backward, update
-
-
- def train(epoch):
- running_loss = 0.0
- for batch_idx, data in enumerate(train_loader, 0):
- inputs, target = data
- inputs, target = inputs.to(device), target.to(device)
- optimizer.zero_grad()
-
- outputs = model(inputs)
- loss = criterion(outputs, target)
- loss.backward()
- optimizer.step()
-
- running_loss += loss.item()
- 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
- images, labels = images.to(device), labels.to(device)
- outputs = model(images)
- _, predicted = torch.max(outputs.data, dim=1)
- total += labels.size(0)
- correct += (predicted == labels).sum().item()
- print('accuracy on test set: %d %% ' % (100*correct/total))
- return correct/total
-
-
- if __name__ == '__main__':
- epoch_list = []
- acc_list = []
-
- for epoch in range(10):
- train(epoch)
- acc = test()
- epoch_list.append(epoch)
- acc_list.append(acc)
-
- plt.plot(epoch_list,acc_list)
- plt.ylabel('accuracy')
- plt.xlabel('epoch')
- plt.show()
-
如上class Net网络结构的第二层卷积的输入为88,是因为在其 froward()函数中,在调用第二层卷积self.conv2之前已经调用了InceptionA类的实例,而InceptionA类实例返回的结果是各网络分支所得的通道数之和,即24*3+16=88.
- #将某分支网络抽象为一个Inception类
- class Inception(nn.Module):
- def __init__(self,in_channels):
- super(Inception,self).__init__()
- #定义如下4个分支结构
- self.branch1x1 = nn.Conv2d(in_channels,16,kernel_size=1) # 该分支为一层卷积核为1*1的16通道的卷积层
-
- #该分支为由两层构成,第一层卷积核1*1,输出通道为16;第二层卷积核为5*5,输出通道为24
- self.branch5x5_1 = nn.Conv2d(in_channels,16,kernel_size=1)
- self.branch5x5_2 = nn.Conv2d(16,24,kernel_size=5,padding=2)
-
- #第三分支
- self.branch3x3_1 = nn.Conv2d(in_channels,16,kernel_size=1)
- self.branch3x3_2 = nn.Conv2d(16,24,kernel_size=3,padding=1)
- self.branch3x3_3 = nn.Conv2d(24,24,kernel_size=3,padding=1)
-
- #第四分支:池化分支
- self.branch_pool = nn.Conv2d(in_channels,24,kernel_size=1)
-
- #计算各层分支的卷积和
- def forward(self,x):
- branch1x1 = self.branch1x1(x)
-
- branch5x5 = self.branch5x5_1(x)
- branch5x5 = self.branch5x5_2(branch5x5)
-
- branch3x3 = self.branch3x3_1(x)
- branch3x3 = self.branch3x3_3(branch3x3)
- branch3x3 = self.branch3x3_3(branch3x3)
-
- branch_pool = F.avg_pool2d(x,kernel_size=3,stride=1,padding=1)
- branch_pool = self.branch_pool(branch_pool)
-
- output = [branch1x1,branch5x5,branch3x3,branch_pool]
- return torch.cat(output,dim=1)
-
- class Net(nn.Module):
- def __init__(self):
- super(Net, self).__init__()
- self.conv1 = nn.Conv2d(1,10,kernel_size=5)
- self.conv2 = nn.Conv2d(88,20,kernel_size=5)
-
- #实例化分支网络结构Inception
- self.incep1 = Inception(in_channels=10)
- self.incep2 = Inception(in_channels=20)
-
- self.mp = nn.MaxPool2d(2) #池化
- self.fc = nn.Linear(1408,10) #实例化全连接层,全连接层的实质就是一个线性层
-
- def forward(self,x):
- in_side = x.size(0)
- x = F.relu(self.mp(self.conv1(x)))
- x = self.incep1(x)
- x = F.relu(self.mp(self.conv2(x)))
- x = self.incep2(x)
- #全连接层
- x = x.view(in_side,-1)
- x = self.fc(x)
- return x
- import torch
- import torch.nn as nn
- from torchvision import transforms
- from torchvision import datasets
- from torch.utils.data import DataLoader
- import torch.nn.functional as F
- import torch.optim as optim
-
- # prepare datasets 数据集的准备
-
- batch_size = 64
- transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]) # 归一化,均值和方差
-
- train_dataset = datasets.MNIST(root='../dataset/mnist/', train=True, download=True, transform=transform)
- train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
-
- test_dataset = datasets.MNIST(root='../dataset/mnist/', train=False, download=True, transform=transform)
- test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)
-
- #将某分支网络抽象为一个Inception类
- class Inception(nn.Module):
- def __init__(self,in_channels):
- super(Inception,self).__init__()
- #定义如下4个分支结构
- self.branch1x1 = nn.Conv2d(in_channels, 16, kernel_size=1) # 该分支为一层卷积核为1*1的16通道的卷积层
-
- #该分支为由两层构成,第一层卷积核1*1,输出通道为16;第二层卷积核为5*5,输出通道为24
- self.branch5x5_1 = nn.Conv2d(in_channels, 16, kernel_size=1)
- self.branch5x5_2 = nn.Conv2d(16, 24, kernel_size=5, padding=2)
-
- #第三分支
- self.branch3x3_1 = nn.Conv2d(in_channels, 16, kernel_size=1)
- self.branch3x3_2 = nn.Conv2d(16, 24, kernel_size=3, padding=1)
- self.branch3x3_3 = nn.Conv2d(24, 24, kernel_size=3, padding=1)
-
- #第四分支:池化分支
- self.branch_pool = nn.Conv2d(in_channels,24,kernel_size=1)
-
- #计算各层分支的卷积和
- def forward(self,x):
- branch1x1 = self.branch1x1(x)
-
- branch5x5 = self.branch5x5_1(x)
- branch5x5 = self.branch5x5_2(branch5x5)
-
- branch3x3 = self.branch3x3_1(x)
- branch3x3 = self.branch3x3_2(branch3x3)
- branch3x3 = self.branch3x3_3(branch3x3)
-
- branch_pool = F.avg_pool2d(x,kernel_size=3,stride=1,padding=1)
- branch_pool = self.branch_pool(branch_pool)
-
- output = [branch1x1,branch5x5,branch3x3,branch_pool]
- return torch.cat(output,dim=1)
-
- class Net(nn.Module):
- def __init__(self):
- super(Net, self).__init__()
- self.conv1 = nn.Conv2d(1,10,kernel_size=5)
- self.conv2 = nn.Conv2d(88,20,kernel_size=5)
-
- #实例化分支网络结构Inception
- self.incep1 = Inception(in_channels=10)
- self.incep2 = Inception(in_channels=20)
-
- self.mp = nn.MaxPool2d(2) #池化
- self.fc = nn.Linear(1408,10) #实例化全连接层,全连接层的实质就是一个线性层
-
- def forward(self,x):
- in_side = x.size(0)
- x = F.relu(self.mp(self.conv1(x)))
- x = self.incep1(x)
- x = F.relu(self.mp(self.conv2(x)))
- x = self.incep2(x)
- #全连接层
- x = x.view(in_side,-1)
- x = self.fc(x)
- return x
-
-
- model = Net()
-
- # construct loss and optimizer
- criterion = torch.nn.CrossEntropyLoss()
- optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
-
-
- # training cycle forward, backward, update
-
-
- def train(epoch):
- running_loss = 0.0
- for batch_idx, data in enumerate(train_loader, 0):
- inputs, target = data
- optimizer.zero_grad()
-
- outputs = model(inputs)
- loss = criterion(outputs, target)
- loss.backward()
- optimizer.step()
-
- running_loss += loss.item()
- 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)
- 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()
-
-
-
-
-
-
结果:
- C:\Users\ZARD\anaconda3\envs\PyTorch\python.exe C:/Users/ZARD/PycharmProjects/pythonProject/机器学习库/PyTorch实战课程内容/lecture10/CNN_plus.py
- [1, 300] loss: 0.884
- [1, 600] loss: 0.224
- [1, 900] loss: 0.144
- accuracy on test set: 96 %
- [2, 300] loss: 0.108
- [2, 600] loss: 0.095
- [2, 900] loss: 0.087
- accuracy on test set: 97 %
- [3, 300] loss: 0.077
- [3, 600] loss: 0.068
- [3, 900] loss: 0.069
- accuracy on test set: 98 %
- [4, 300] loss: 0.060
- [4, 600] loss: 0.060
- [4, 900] loss: 0.062
- accuracy on test set: 98 %
代码:
-
- # design model using class
- class ResidualBlock(nn.Module):
- def __init__(self, channels):
- super(ResidualBlock, self).__init__()
- self.channels = channels
- self.conv1 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
- self.conv2 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
-
- def forward(self, x):
- y = F.relu(self.conv1(x))
- y = self.conv2(y)
- return F.relu(x + y)
-
- class Net(nn.Module):
- def __init__(self):
- super(Net, self).__init__()
- self.conv1 = nn.Conv2d(1, 16, kernel_size=5)
- self.conv2 = nn.Conv2d(16, 32, kernel_size=5) # 88 = 24x3 + 16
-
- self.rblock1 = ResidualBlock(16)
- self.rblock2 = ResidualBlock(32)
-
- self.mp = nn.MaxPool2d(2)
- self.fc = nn.Linear(512, 10) # 暂时不知道1408咋能自动出来的
-
-
- def forward(self, x):
- in_size = x.size(0)
-
- x = self.mp(F.relu(self.conv1(x)))
- x = self.rblock1(x)
- x = self.mp(F.relu(self.conv2(x)))
- x = self.rblock2(x)
-
- x = x.view(in_size, -1)
- x = self.fc(x)
- return x
-
完整代码:
- import torch
- import torch.nn as nn
- from torchvision import transforms
- from torchvision import datasets
- from torch.utils.data import DataLoader
- import torch.nn.functional as F
- import torch.optim as optim
-
- # prepare dataset
-
- batch_size = 64
- transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]) # 归一化,均值和方差
-
- train_dataset = datasets.MNIST(root='../dataset/mnist/', train=True, download=True, transform=transform)
- train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
- test_dataset = datasets.MNIST(root='../dataset/mnist/', train=False, download=True, transform=transform)
- test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)
-
-
- # design model using class
- class ResidualBlock(nn.Module):
- def __init__(self, channels):
- super(ResidualBlock, self).__init__()
- self.channels = channels
- self.conv1 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
- self.conv2 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
-
- def forward(self, x):
- y = F.relu(self.conv1(x))
- y = self.conv2(y)
- return F.relu(x + y)
-
-
- class Net(nn.Module):
- def __init__(self):
- super(Net, self).__init__()
- self.conv1 = nn.Conv2d(1, 16, kernel_size=5)
- self.conv2 = nn.Conv2d(16, 32, kernel_size=5) # 88 = 24x3 + 16
-
- self.rblock1 = ResidualBlock(16)
- self.rblock2 = ResidualBlock(32)
-
- self.mp = nn.MaxPool2d(2)
- self.fc = nn.Linear(512, 10) # 暂时不知道1408咋能自动出来的
-
- def forward(self, x):
- in_size = x.size(0)
-
- x = self.mp(F.relu(self.conv1(x)))
- x = self.rblock1(x)
- x = self.mp(F.relu(self.conv2(x)))
- x = self.rblock2(x)
-
- x = x.view(in_size, -1)
- x = self.fc(x)
- return x
-
-
- model = Net()
-
- # construct loss and optimizer
- criterion = torch.nn.CrossEntropyLoss()
- optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
-
-
- # training cycle forward, backward, update
-
-
- def train(epoch):
- running_loss = 0.0
- for batch_idx, data in enumerate(train_loader, 0):
- inputs, target = data
- optimizer.zero_grad()
-
- outputs = model(inputs)
- loss = criterion(outputs, target)
- loss.backward()
- optimizer.step()
-
- running_loss += loss.item()
- 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)
- 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()
运行结果:
- C:\Users\ZARD\anaconda3\envs\PyTorch\python.exe C:/Users/ZARD/PycharmProjects/pythonProject/机器学习库/PyTorch实战课程内容/lecture10/aaa.py
- [1, 300] loss: 0.509
- [1, 600] loss: 0.155
- [1, 900] loss: 0.107
- accuracy on test set: 97 %
- [2, 300] loss: 0.087
- [2, 600] loss: 0.076
- [2, 900] loss: 0.073
- accuracy on test set: 98 %
- import torch
- from torch.utils.data import DataLoader #我们要加载数据集的
- from torchvision import transforms #数据的原始处理
- from torchvision import datasets #pytorch十分贴心的为我们直接准备了这个数据集
- import torch.nn.functional as F#激活函数
- import torch.optim as optim
-
- batch_size = 64
- #我们拿到的图片是pillow,我们要把他转换成模型里能训练的tensor也就是张量的格式
- transform = transforms.Compose([transforms.ToTensor()])
-
- #加载训练集,pytorch十分贴心的为我们直接准备了这个数据集,注意,即使你没有下载这个数据集
- #在函数中输入download=True,他在运行到这里的时候发现你给的路径没有,就自动下载
- train_dataset = datasets.MNIST(root='../data', train=True, download=True, transform=transform)
- train_loader = DataLoader(dataset=train_dataset, shuffle=True, batch_size=batch_size)
- #同样的方式加载一下测试集
- test_dataset = datasets.MNIST(root='../data', train=False, download=True, transform=transform)
- test_loader = DataLoader(dataset=test_dataset, shuffle=False, batch_size=batch_size)
-
- #接下来我们看一下模型是怎么做的
- class Net(torch.nn.Module):
- def __init__(self):
- super(Net, self).__init__()
- #定义了我们第一个要用到的卷积层,因为图片输入通道为1,第一个参数就是1
- #输出的通道为10,kernel_size是卷积核的大小,这里定义的是5x5的
- 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)
- #最后是我们做分类用的线性层
- 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) #这里面的0是x大小第1个参数,自动获取batch大小
- #输入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) # flatten
- #经过线性层,确定他是0~9每一个数的概率
- x = self.fc(x)
- return x
-
- model = Net()#实例化模型
- #把计算迁移到GPU
- device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
- model.to(device)
-
- #定义一个损失函数,来计算我们模型输出的值和标准值的差距
- criterion = torch.nn.CrossEntropyLoss()
- #定义一个优化器,训练模型咋训练的,就靠这个,他会反向的更改相应层的权重
- optimizer = optim.SGD(model.parameters(),lr=0.1,momentum=0.5)#lr为学习率
-
-
- def train(epoch):
- running_loss = 0.0
- for batch_idx, data in enumerate(train_loader, 0):#每次取一个样本
- inputs, target = data
- inputs, target = inputs.to(device), target.to(device)
- #优化器清零
- optimizer.zero_grad()
- # 正向计算一下
- outputs = model(inputs)
- #计算损失
- loss = criterion(outputs, target)
- #反向求梯度
- loss.backward()
- #更新权重
- optimizer.step()
- #把损失加起来
- running_loss += loss.item()
- #每300次输出一下数据
- if batch_idx % 300 == 299:
- print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 2000))
- running_loss = 0.0
-
- def test():
- correct = 0
- total = 0
- with torch.no_grad():#不用算梯度
- for data in test_loader:
- inputs, target = data
- inputs, target = inputs.to(device), target.to(device)
- outputs = model(inputs)
- #我们取概率最大的那个数作为输出
- _, predicted = torch.max(outputs.data, dim=1)
- total += target.size(0)
- #计算正确率
- correct += (predicted == target).sum().item()
- print('Accuracy on test set: %d %% [%d/%d]' % (100 * correct / total, correct, total))
-
-
- if __name__=='__main__':
- for epoch in range(10):
- train(epoch)
- if epoch % 10 == 9:
- test()
-
-
-
卷积:
(1) 辨析“一个卷积核”和“一个卷积核的一个通道”。一个卷积核可能包含多个通道。卷积核的通道数cahnnel是由被其处理的数据决定的。比如,被做卷积处理的数据的channel=3,那么就需要一个3通道的卷积核来进行卷积操作。将这3通道处理的数据对应相加,就变成了1通道,这样就实现了降维操作。
卷积神经网络进阶:
(1)1*1卷积的作用在于改变输入数据的通道。其好处在于,使用1*1卷积后,会极大降低计算周期。
(2)将不同的网络结构抽象为Inception类,即将不同的网络分支定义在一个class Inception(nn.Module)中,并将计算得到的值通过torch.cat()进行拼接,并作为forward()函数的返回值。(将某分支网络抽象为一个Inception类,然后计算各层分支的卷积和)
(3)在构造的网络class Net(nn.Module)中调用如上定义的Inception类,要注意的是,调用Inception类的实例后,数据的通道数就变成了Inception类实例返回的各个网络分支结构的通道数之和,因此在调用Inception类的实例后,下一网络层的输入通道数就应该是各个网络分支结构的通道数之和。
(4)residual Network:在训练网络的过程中,在回传时可能会存在梯度消失的问题。解决的方法是先将F(x)与x相加,再通过激活函数去激活。(其实这一部分了解得还还不够丰富,后续学习需要注意)