Fashion_mnist数据集 CNN分类

上一次CNN的作业,供大家参考
```python
'''
-*- coding: utf-8 -*- 
@Time : 2021/7/26 11:47
@Author : Small_Volcano 
@File : fashion_mnist-cnn.py.py 
'''
import copy
import time
import torch
import torch.nn as nn
import torch.utils.data as Data
from torch.optim import Adam
from torchvision import transforms
from torchvision.datasets import FashionMNIST
from sklearn.metrics import accuracy_score
import pandas as pd
import matplotlib.pyplot as plt

#使用FashionMNIST数据,准备训练数据集
train_data = FashionMNIST(root="../resourses/datasets/",
                          train=True,
                          transform=transforms.ToTensor(),  #转换为tensor类型
                          download=False)
#对测试集进行处理
test_data = FashionMNIST(root="../resourses/datasets/",
                         train=False,
                         download=False)
#定义一个数据加载器
train_loader = Data.DataLoader(dataset=train_data,
                               batch_size=64,   #每小批量64
                               shuffle=False,   #是否打乱
                               num_workers=0)   #是否多进程

#为数据添加一个通道维度,并且取值范围缩放到0-1之间 为测试准备
test_data_x = test_data.data.type(torch.FloatTensor) / 255.0
test_data_x = torch.unsqueeze(test_data_x,dim=1)
test_data_y = test_data.targets #测试集的标签


#搭建卷积神经网络
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        #定义第一个卷积层
        self.conv1 = nn.Sequential(
            nn.Conv2d(in_channels=1,    #2d代表二维的 输入层数为1
                      out_channels=16,  #输出高度16   16个卷积核
                      kernel_size=3,    #卷积核尺寸3*3
                      stride=1,         #步长为1
                      padding=1),       #卷积后:(1*28*28)->(16*28*28)
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2,stride=2) #池化后:(16*28*28)->(16*14*14)
        )
        #定义第二个卷积层
        self.conv2 = nn.Sequential(
            nn.Conv2d(in_channels=16,out_channels=32,kernel_size=3,stride=1,padding=0),#卷积后:(16*14*14)->(32*12*12)
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2,stride=2) #池化后:(32*12*12)->(32*6*6)
        )
        #定义全连接层
        self.classifier = nn.Sequential(
            nn.Linear(32*6*6,256), #长方体变平面
            nn.ReLU(),
            nn.Linear(256,128),
            nn.ReLU(),
            nn.Linear(128,10)      #分为10类
        )

    #定义网络的前向传播路径
    def forward(self,x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.view(x.size(0),-1) #展平多维的卷积图层
        output = self.classifier(x)
        return output

#输出网络结构
net = Net() #创建实例
print(net)

#定义网络的训练过程函数
def train_model(model,traindataloader,train_rate,criterion,optimizer,num_epochs=25):
    #train_rate:训练集中训练数量的百分比
    #计算训练使用的batch数量
    batch_num = len(traindataloader)
    train_batch_num = round(batch_num * train_rate) #前train_rate(80%)的batch进行训练
    #复制最好模型的参数
    best_model_wts = copy.deepcopy(model.state_dict())
    best_acc = 0.0
    train_loss_all = []
    train_acc_all = []
    val_loss_all = []
    val_acc_all = []
    since = time.time()
    for epoch in range(num_epochs):
        print('Epoch {}/{}'.format(epoch,num_epochs-1)) #格式化字符串
        print('-' * 10)
        #每个epoch有两个训练阶段
        train_loss = 0.0
        train_corrects = 0
        train_num = 0
        val_loss = 0.0
        val_corrects = 0
        val_num = 0
        for step,(b_x,b_y) in enumerate(traindataloader):   #取标签和样本
            if step < train_batch_num:                      #前train_rate(80%)的batch进行训练
                model.train()                               #设置模型为训练模式,对Droopou有用
                output = model(b_x)                         #取得模型预测结果
                pre_lab = torch.argmax(output,1)            #横向获得最大值位置
                loss = criterion(output,b_y)        #loss是一个batch的loss,每个样本的loss均值?
                optimizer.zero_grad()               #梯度清零
                loss.backward()                     #计算梯度 对loss的反向传播
                optimizer.step()                    #修改权值
                train_loss += loss.item() * b_x.size(0)             #此处的b_x.size(0)=batch_size。此处相当于一个batch的loss?计算的是整体训练的loss
                train_corrects += torch.sum(pre_lab == b_y.data)    #训练正确个数
                train_num += b_x.size(0)
            else:
                model.eval()              #设置模型为验证模式
                output = model(b_x)
                pre_lab = torch.argmax(output,1)
                loss = criterion(output,b_y)
                val_loss += loss.item() * b_x.size(0)
                val_corrects += torch.sum(pre_lab == b_y.data)
                val_num += b_x.size(0)
        #计算训练集和验证集上的损失和精度
        train_loss_all.append(train_loss / train_num)       #一个epoch上的loss
        train_acc_all.append(train_corrects.double().item() / train_num)
        val_loss_all.append(val_loss / val_num)
        val_acc_all.append(val_corrects.double().item() / val_num)

        print('{} Train Loss: {:.4f} Train Acc: {:.4f}'.format(epoch,train_loss_all[-1],train_acc_all[-1])) #此处-1没搞明白
        print('{} Val Loss: {:.4f} Val Acc: {:.4f}'.format(epoch,val_loss_all[-1],val_acc_all[-1]))
        #拷贝模型最高精度下的参数
        if val_acc_all[-1] > best_acc:
            best_acc = val_acc_all[-1]
            best_model_wts = copy.deepcopy(model.state_dict())
        time_use = time.time() - since
        print("Train and val complete in {:.0f}m {:.0f}s".format(time_use // 60,time_use % 60)) #训练用时
    #使用最好模型的参数
    model.load_state_dict(best_model_wts)
    #组成数据表格train_process打印
    train_process = pd.DataFrame(data={"epoch":range(num_epochs),
                                       "train_loss_all":train_loss_all,
                                       "val_loss_all":val_loss_all,
                                       "train_acc_all":train_acc_all,
                                       "val_acc_all":val_acc_all})
    return model,train_process
#对模型进行训练
optimizer = Adam(net.parameters(),lr=0.0003) #优化器
criterion = nn.CrossEntropyLoss()   #使用交叉熵作为损失函数
net,train_process = train_model(net,train_loader,0.8,   #使用训练集的20%作为验证
                                criterion,optimizer,num_epochs=25)
#可视化模型训练过程中
plt.figure(figsize=(12,4))
plt.subplot(1,2,1)
plt.plot(train_process.epoch,train_process.train_loss_all,"ro-",label="Train loss")
plt.plot(train_process.epoch,train_process.val_loss_all,"bs-",label="Val loss")
plt.legend()
plt.xlabel("epoch")
plt.ylabel("Loss")
plt.subplot(1,2,2)
plt.plot(train_process.epoch,train_process.train_acc_all,"ro-",label="Train acc")
plt.plot(train_process.epoch,train_process.val_acc_all,"bs-",label="Val acc")
plt.xlabel("epoch")
plt.ylabel("acc")
plt.legend()
plt.show()

#对测试集进行预测,并可视化预测结果。计算模型的泛化能力
net.eval()
output = net(test_data_x)
pre_lab = torch.argmax(output,1)
acc = accuracy_score(test_data_y,pre_lab)
print("在测试集上的预测精度为:",acc)


'''Net(
  (conv1): Sequential(
    (0): Conv2d(1, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU()
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (conv2): Sequential(
    (0): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1))
    (1): ReLU()
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (classifier): Sequential(
    (0): Linear(in_features=1152, out_features=256, bias=True)
    (1): ReLU()
    (2): Linear(in_features=256, out_features=128, bias=True)
    (3): ReLU()
    (4): Linear(in_features=128, out_features=10, bias=True)
  )
)
Epoch 0/24
----------
0 Train Loss: 0.7203 Train Acc: 0.7342
0 Val Loss: 0.4867 Val Acc: 0.8244
Train and val complete in 0m 45s
Epoch 1/24
----------
1 Train Loss: 0.4360 Train Acc: 0.8426
1 Val Loss: 0.3962 Val Acc: 0.8585
Train and val complete in 1m 34s
Epoch 2/24
----------
2 Train Loss: 0.3676 Train Acc: 0.8693
2 Val Loss: 0.3573 Val Acc: 0.8717
Train and val complete in 2m 26s
Epoch 3/24
----------
3 Train Loss: 0.3308 Train Acc: 0.8815
3 Val Loss: 0.3362 Val Acc: 0.8798
Train and val complete in 3m 9s
Epoch 4/24
----------
4 Train Loss: 0.3049 Train Acc: 0.8899
4 Val Loss: 0.3226 Val Acc: 0.8844
Train and val complete in 3m 56s
Epoch 5/24
----------
5 Train Loss: 0.2848 Train Acc: 0.8968
5 Val Loss: 0.3138 Val Acc: 0.8865
Train and val complete in 4m 39s
Epoch 6/24
----------
6 Train Loss: 0.2679 Train Acc: 0.9030
6 Val Loss: 0.3027 Val Acc: 0.8920
Train and val complete in 5m 20s
Epoch 7/24
----------
7 Train Loss: 0.2535 Train Acc: 0.9085
7 Val Loss: 0.2963 Val Acc: 0.8955
Train and val complete in 6m 6s
Epoch 8/24
----------
8 Train Loss: 0.2404 Train Acc: 0.9134
8 Val Loss: 0.2873 Val Acc: 0.8986
Train and val complete in 6m 47s
Epoch 9/24
----------
9 Train Loss: 0.2285 Train Acc: 0.9176
9 Val Loss: 0.2781 Val Acc: 0.9025
Train and val complete in 7m 33s
Epoch 10/24
----------
10 Train Loss: 0.2172 Train Acc: 0.9222
10 Val Loss: 0.2716 Val Acc: 0.9039
Train and val complete in 8m 15s
Epoch 11/24
----------
11 Train Loss: 0.2063 Train Acc: 0.9262
11 Val Loss: 0.2640 Val Acc: 0.9074
Train and val complete in 8m 55s
Epoch 12/24
----------
12 Train Loss: 0.1960 Train Acc: 0.9292
12 Val Loss: 0.2590 Val Acc: 0.9091
Train and val complete in 9m 35s
Epoch 13/24
----------
13 Train Loss: 0.1862 Train Acc: 0.9328
13 Val Loss: 0.2563 Val Acc: 0.9113
Train and val complete in 10m 15s
Epoch 14/24
----------
14 Train Loss: 0.1768 Train Acc: 0.9366
14 Val Loss: 0.2525 Val Acc: 0.9123
Train and val complete in 10m 56s
Epoch 15/24
----------
15 Train Loss: 0.1676 Train Acc: 0.9401
15 Val Loss: 0.2510 Val Acc: 0.9135
Train and val complete in 11m 36s
Epoch 16/24
----------
16 Train Loss: 0.1584 Train Acc: 0.9439
16 Val Loss: 0.2502 Val Acc: 0.9146
Train and val complete in 12m 17s
Epoch 17/24
----------
17 Train Loss: 0.1504 Train Acc: 0.9473
17 Val Loss: 0.2517 Val Acc: 0.9135
Train and val complete in 12m 58s
Epoch 18/24
----------
18 Train Loss: 0.1420 Train Acc: 0.9505
18 Val Loss: 0.2571 Val Acc: 0.9136
Train and val complete in 13m 39s
Epoch 19/24
----------
19 Train Loss: 0.1337 Train Acc: 0.9527
19 Val Loss: 0.2606 Val Acc: 0.9124
Train and val complete in 14m 20s
Epoch 20/24
----------
20 Train Loss: 0.1258 Train Acc: 0.9561
20 Val Loss: 0.2673 Val Acc: 0.9123
Train and val complete in 15m 1s
Epoch 21/24
----------
21 Train Loss: 0.1185 Train Acc: 0.9584
21 Val Loss: 0.2773 Val Acc: 0.9097
Train and val complete in 15m 43s
Epoch 22/24
----------
22 Train Loss: 0.1109 Train Acc: 0.9615
22 Val Loss: 0.2915 Val Acc: 0.9077
Train and val complete in 16m 24s
Epoch 23/24
----------
23 Train Loss: 0.1043 Train Acc: 0.9640
23 Val Loss: 0.3015 Val Acc: 0.9071
Train and val complete in 17m 5s
Epoch 24/24
----------
24 Train Loss: 0.0973 Train Acc: 0.9666
24 Val Loss: 0.3209 Val Acc: 0.9044
Train and val complete in 17m 44s
在测试集上的预测精度为: 0.9112
'''

你可能感兴趣的:(深度学习,卷积神经网络,python,pytorch)