1. information
MNIST数据集有70,000张图片,其中训练集有60,000张,而测试集有10,000张.
数据集里的图片示例如下:
2. code
2.1 improt
import torch,torchvision
import torchvision.datasets,torch.utils.data
from tqdm.rich import trange
2.2 download datasets
train = torchvision.datasets.MNIST(
root='./datasets/mnist', #这里是下载训练集的文件夹
download=True, #True:需要下载; False:不下载
train=True, #是训练集还是测试集; True为训练集, False为测试集
transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize((0.1307,),(0.3081,))
])
)
test = torchvision.datasets.MNIST(
root='./datasets/mnist', #这里是下载测试集的文件夹
download=True, #True:需要下载; False:不下载
train=False, #是训练集还是测试集; True为训练集, False为测试集
transform=torchvision.transforms.Compose([
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize((0.1307,),(0.3081,))
])
)
2.3 load datasets
train_loader = torch.utils.data.DataLoader(
train,
batch_size=60, #每一批的图片为60张
shuffle=True #设置为随机打乱
)
test_loader = torch.utils.data.DataLoader(
test,
batch_size=60, #每一批的图片为60张
shuffle=True #设置为随机打乱
)
2.4 create model of multi-classification
class NET(torch.nn.Module):
def __init__(self):
super(NET,self).__init__()
self.model = torch.nn.Sequential(
torch.nn.Linear(28*28,1000),
torch.nn.ReLU(),
torch.nn.Linear(1000,1000),
torch.nn.ReLU(),
torch.nn.Linear(1000,500),
torch.nn.ReLU(),
torch.nn.Linear(500,10),
torch.nn.ReLU()
)
def forward(self,x):
x = self.model(x)
return x
2.5 train and evaluation
device = torch.device('cuda:0') #使用GPU加速
num_epochs = 10 #训练次数
model = NET().to(device) #使用GPU加速
loss = torch.nn.CrossEntropyLoss().to(device) #使用GPU加速
optimizer = torch.optim.SGD(model.parameters(),lr=0.001)
correct = 0
for epoch in trange(num_epochs):
for batch_index,(data,label) in enumerate(train_loader):
data,label = data.to(device),label.cuda() #使用GPU加速
data = data.view(-1,28*28) #将图片数据打平,由28*28转为1*784
predictions = model(data)
crossentropyloss = loss(predictions,label) #计算交叉熵损失函数
optimizer.zero_grad() #将梯度数据变零
crossentropyloss.backward() #计算梯度
optimizer.step() #更新权值系数
for (data,target) in test_loader:
data,target = data.to(device),target.cuda() #使用GPU加速
data = data.view(-1,28*28) #将图片打平
predicted = model(data)
predicted = torch.argmax(predicted,dim=1) #得到每行最大数的索引
compare = torch.eq(predicted,target) #比较2个张量
correct += torch.sum(compare).item()/len(target)
correct /= len(test_loader) #计算正确率
print('correct:{:.1f}%'.format(correct*100))
3. theory
3.1 Cross-Entropy Loss Function
假设真实的概率为
P
=
[
p
1
,
p
2
,
p
3
,
⋯
,
p
10
]
P=[p_1,p_2,p_3,\cdots ,p_{10}]
P=[p1,p2,p3,⋯,p10]
而预测的概率为
Q
=
[
q
1
,
q
2
,
q
3
,
⋯
,
q
10
]
Q=[q_1,q_2,q_3,\cdots ,q_{10}]
Q=[q1,q2,q3,⋯,q10]
交叉熵计算为
H
=
∑
i
=
1
10
p
i
l
o
g
1
q
i
H=\sum_{i=1}^{10}p_ilog\frac{1}{q_i}
H=i=1∑10pilogqi1
在pytorch中,先会将预测值经过softmax-log,然后得出Q.