1 目的
- 使用pytorch建模;
- 熟悉线性回归模型;
2 code部分
2.1 全连接层
# pytorch框架
import torch
import torch.nn.functional as F
from torch import nn,optim
from torchvision import datasets,transforms
from torch.utils.data import DataLoader
train_batch_size = 64
test_batch_size = 1000
img_size = 28
# load data,并将其转化为Tensor格式
train_dataset = torchvision.datasets.MNIST(root='./data',
train=True,
transform=transforms.ToTensor(),
download=False)
test_dataset = torchvision.datasets.MNIST(root='./data',
train=False,
transform=transforms.ToTensor(),
download=False)
# 每批的数据为64个,分批次, shuffle为打乱数据
train_loader=DataLoader(dataset=train_dataset,
batch_size=train_batch_size,
shuffle=True)
test_loader=DataLoader(dataset=test_dataset,
batch_size=test_batch_size,
shuffle=True)
class MnistLinearModel(nn.Module):
def __init__(self):
super(MnistLinearModel,self).__init__()
self.linear_1 = nn.Linear(1*img_size*img_size,100)
self.linear_2 = nn.Linear(100,10)
def forward(self,x):
x = self.linear_1(x.view(-1,1*28*28))
x = F.relu(x)
x = self.linear_2(x)
x = F.softmax(x)
return x
# 创建模型
mnist_net = MnistLinearModel()
# 优化器
optimizer = optim.Adam(mnist_net.parameters(), lr=1e-2)
# 损失函数
loss_fn = nn.CrossEntropyLoss()
def train():
mnist_net.train()
for i,data in enumerate(train_loader):
x,y=data
# 预测结果
y_pred=mnist_net(x)
# 计算损失
loss=loss_fn(y_pred,y)
# 梯度清0
optimizer.zero_grad()
# 计算梯度
loss.backward()
# 修改权值
optimizer.step()
def test():
mnist_net.eval()
correct=0
for i,data in enumerate(train_loader):
x,y=data
y_pred=mnist_net(x)
_,pred=torch.max(y_pred,1)
correct+=(pred==y).sum()
print('train 准确率:',correct.item()/len(train_dataset))
correct = 0
for i, data in enumerate(test_loader):
x,y=data
y_pred=mnist_net(x)
_,pred=torch.max(y_pred,1)
correct+=(pred==y).sum()
print('test 准确率:',correct.item()/len(test_dataset))
# 训练10次模型,不断修改权重
for epoch in range(1,11):
print('epoch:',epoch)
train()
test()
“”“
准确率: 0.9383833333333333
准确率: 0.9376
epoch: 2
准确率: 0.9447166666666666
准确率: 0.9434
epoch: 3
准确率: 0.955
准确率: 0.9505
epoch: 4
准确率: 0.95125
准确率: 0.9477
epoch: 5
准确率: 0.9489833333333333
准确率: 0.9421
epoch: 6
准确率: 0.94965
准确率: 0.9429
epoch: 7
准确率: 0.9516
准确率: 0.9507
epoch: 8
准确率: 0.954
准确率: 0.9508
epoch: 9
准确率: 0.9581166666666666
准确率: 0.9525
epoch: 10
准确率: 0.9566333333333333
准确率: 0.956
”“”
2.2 卷积层
- 卷积操作:保持局部结构不变性,区域化的先乘后加(sum(mulitply));
- 批标准化:针对同一个批次的数据(相同的通道)进行正太归一化操作;一般位于卷积操作之后,激活函数之前;
- 激活函数:
- 池化层。
- dropout。
- full connect;
基本的网络结构:
conv2d
def __init__(
self,
in_channels: int,
out_channels: int,
kernel_size: _size_2_t,
stride: _size_2_t = 1,
padding: _size_2_t = 0,
dilation: _size_2_t = 1,
groups: int = 1,
bias: bool = True,
padding_mode: str = 'zeros' # TODO: refine this type
):
in_channels:网络输入的通道数。
out_channels:网络输出的通道数。
kernel_size:卷积核的大小,如果该参数是一个整数q,那么卷积核的大小是qXq。
stride:步长。是卷积过程中移动的步长。默认情况下是1。一般卷积核在输入图像上的移动是自左至右,自上至下。如果参数是一个整数那么就默认在水平和垂直方向都是该整数。如果参数是stride=(2, 1),2代表着高(h)进行步长为2,1代表着宽(w)进行步长为1。
padding:填充,默认是0填充。
dilation:扩张,膨胀系数。一般情况下,卷积核与输入图像对应的位置之间的计算是相同尺寸的,也就是说卷积核的大小是3X3,那么它在输入图像上每次作用的区域是3X3,这种情况下dilation=0。当dilation=1时,表示的是下图这种情况。
尺寸的计算:
code
# pytorch框架
import torch
import torch.nn.functional as F
from torch import nn,optim
from torchvision import datasets,transforms
from torch.utils.data import DataLoader
train_batch_size = 64
test_batch_size = 1000
img_size = 28
# load data,并将其转化为Tensor格式
train_dataset = torchvision.datasets.MNIST(root='./data',
train=True,
transform=transforms.ToTensor(),
download=False)
test_dataset = torchvision.datasets.MNIST(root='./data',
train=False,
transform=transforms.ToTensor(),
download=False)
# 每批的数据为64个,分批次, shuffle为打乱数据
train_loader=DataLoader(dataset=train_dataset,
batch_size=train_batch_size,
shuffle=True)
test_loader=DataLoader(dataset=test_dataset,
batch_size=test_batch_size,
shuffle=True)
# nn.Module
class CNN(nn.Module):
# 初始化相关网络层
def __init__(self):
# 初始化父类
super(CNN,self).__init__()
# 定义第一个卷积层
self.conv1=nn.Sequential(nn.Conv2d(1,64,5,1,2),nn.ReLU(),nn.MaxPool2d(2,2))
# 定义第二个卷积层
self.conv2=nn.Sequential(nn.Conv2d(64,128,5,1,2),nn.ReLU(),nn.MaxPool2d(2,2))
# 定义全连接层
self.fc1=nn.Sequential(nn.Linear(128*7*7,1000),nn.Dropout(p=0.2),nn.ReLU())
self.fc2=nn.Sequential(nn.Linear(1000,10),nn.Softmax(dim=1))
# 定义传播函数
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = x.reshape(x.shape[0], -1)
x = self.fc1(x)
x = self.fc2(x)
return x
# 创建模型
mnist_net = CNN()
# 优化器
optimizer = optim.Adam(mnist_net.parameters(), lr=1e-2)
# 损失函数
loss_fn = nn.CrossEntropyLoss()
def train():
mnist_net.train()
for i,data in enumerate(train_loader):
x,y=data
# 预测结果
y_pred=mnist_net(x)
# 计算损失
loss=loss_fn(y_pred,y)
# 梯度清0
optimizer.zero_grad()
# 计算梯度
loss.backward()
# 修改权值
optimizer.step()
def test():
mnist_net.eval()
correct=0
for i,data in enumerate(train_loader):
x,y=data
y_pred=mnist_net(x)
_,pred=torch.max(y_pred,1)
correct+=(pred==y).sum()
print('train 准确率:',correct.item()/len(train_dataset))
correct = 0
for i, data in enumerate(test_loader):
x,y=data
y_pred=mnist_net(x)
_,pred=torch.max(y_pred,1)
correct+=(pred==y).sum()
print('test 准确率:',correct.item()/len(test_dataset))
# 训练10次模型,不断修改权重
for epoch in range(1,11):
print('epoch:',epoch)
train()
test()
“”“
epoch: 1
train 准确率: 0.9726666666666667
test 准确率: 0.9771
epoch: 2
train 准确率: 0.9763
test 准确率: 0.9741
epoch: 3
train 准确率: 0.98165
test 准确率: 0.9802
epoch: 4
train 准确率: 0.9870333333333333
test 准确率: 0.9861
epoch: 5
train 准确率: 0.98895
test 准确率: 0.9877
”“”