实验一 :利用卷积神经网络识别CIFAR10图片

import torch
import torchvision
# 预处理和加载数据集
from torchvision import datasets,transforms
# 分批加载打包数据
from torch.utils.data import DataLoader
# 神经网络模型
import torch.nn as nn
# 激活函数
import torch.nn.functional as F
# 加载优化器
import torch.optim as optim
# 可视化
import matplotlib.pyplot as plt
import numpy as np
import os
import matplotlib.pyplot as plt
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"# 定义训练轮数
epoch_num = 20
# 定义学习率
lr = 0.1
momentum = 0.5
# 对图像预处理
transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
# 加载数据集
train_set = datasets.CIFAR10('\data2',train = True,transform = transform,download = False)
test_set  = datasets.CIFAR10('\data2',train = False,transform = transform,download = False)
# 分批加载
train_data = DataLoader(train_set,batch_size = 4,shuffle = True)
test_data  = DataLoader(test_set ,batch_size = 4,shuffle = True)
# 定义卷积神经网络模型(卷积+池化+卷积+池化+平均池化+全连接层)
class Net(nn.Module):
    def __init__(self,input_dim,conv1_dim,conv2_dim,out_dim,kernel):
        super().__init__()
        self.conv1 = nn.Sequential(nn.Conv2d(input_dim,conv1_dim,kernel),nn.ReLU(True))
        self.pool1 = nn.MaxPool2d(2,2)
        self.conv2 = nn.Sequential(nn.Conv2d(conv1_dim,conv2_dim,kernel),nn.ReLU(True))
        self.pool2 = nn.MaxPool2d(2,2)
        self.aap =  nn.AdaptiveAvgPool2d(1)
        self.Lin = nn.Linear(conv2_dim,out_dim)
    def forward(self,x): 
#         输入的x应该是四维的tensor
        x = self.conv1(x)
        x = self.pool1(x)
        x = self.conv2(x)
        x = self.pool2(x) 
        x = self.aap(x)
#         全连接神经网络要求输入的数据是2维tensor。
        x = x.view(x.shape[0],-1)
        x = self.Lin(x)
        return x
module = Net(3,16,36,10,5)
device = torch.device('cpu')
module = module.to(device)
# 定义优化器
optimizer = optim.SGD(module.parameters(),lr = lr,momentum=momentum)
# 定义损失函数
loss_fun = nn.CrossEntropyLoss()
# 分别用来保存训练过程和测试过程中的损失和精确度
train_losses = []
train_accury = []
test_losses = []
test_accury = []
# 动态调整学习率
# def ajust_learning_rate(optimizer,lr):
#     for param_group in optimizer.param_groups:
#         param_group['lr']=lr
for epoch in range(epoch_num):
    if epoch%2==0:
        lr = lr*0.9
        optimizer.param_groups[0]['lr'] = lr
#         ajust_learning_rate(optimizer,lr)
#     用来计算训练过程中的损失和精确度
    train_loss = 0
    train_acc = 0
    module.train()
    for img ,label in train_data:
        img = img.to(device)
        label = label.to(device)
#         
        out = module(img)
    
        loss = loss_fun(out,label)
        train_loss+=loss.item()/img.shape[0]
#        梯度清0+ 反向传播+更新优化器中的参数
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        _,prediction = out.max(1)
        
        correct_num = (prediction==label).sum().item()
        train_acc+=correct_num/img.shape[0]
    train_losses.append(train_loss/len(train_data))
    train_accury.append(train_acc/len(train_data))
    
#     print('epoch:{}  train_loss:{:.4f}  train_acc:{:.4f}'.format(epoch,train_loss/len(train_data),train_acc/len(train_data)))
    module.eval()
    with torch.no_grad():
        test_loss = 0
        test_acc = 0
        for img,label in test_data:
            img = img.to(device)
            label = label.to(device)
            out = module(img)
            loss = loss_fun(out,label)
            
            test_loss+=loss.item()/img.shape[0]
            
            _,prediction = out.max(1)
            correct_num = (prediction==label).sum().item()
            test_acc +=correct_num/img.shape[0]
        print('epoch:{}  train_loss:{:.4f}  ,  train_acc:{:.4f}  ,  test_loss:{:.4f}  ,  test_acc:{:.4f}'.format(epoch,train_loss/len(train_data),
               train_acc/len(train_data),test_loss/len(test_data),test_acc/len(test_data)))
        test_losses.append(test_loss/len(test_data))
        test_accury.append(test_acc/len(test_data))
            

可视化部分:

# 训练损失和精确度可视化
plt.plot(np.arange(len(test_losses)),test_losses,c='r',lw = 2)
plt.plot(np.arange(len(train_losses)),train_losses,c='b',lw = 2)
plt.legend(['Train_losses','test_losses'])

plt.plot(np.arange(len(test_losses)),test_accury,c='r',lw = 2)
plt.plot(np.arange(len(train_losses)),train_accury,c='b',lw = 2)
plt.legend(['Train_losses','test_losses'])
# 训练数据集可视化
kinds = ['plane','automobile','bird','cat','deer','dog','frog','horse','ship','truck']
dire = iter(train_data)
img ,label = dire.next()
imges = img
# torchvision.utils.make_grid 将若干个图像拼接成一个图像,z主要参数为输入的tensort,
# nrow用来调整排列方式,行数为 (batch_size % nrow) +1
img = torchvision.utils.make_grid(img,nrow=4,padding = 8)
# 反归一化处理((img-0.5)/0.5)的逆过程,就是img*0.5+0.5
img = img/2+0.5
npimg = img.numpy()
# 经过torchvision.utils.make_grid处理后,我们的img已经变成了3维(c,h,w)分布的图像,将它转化成(h,w,c)分布的图像
newimg = np.transpose(npimg,(1,2,0))
plt.imshow(newimg)

out = module(imges)
_,prediction = out.max(1)

label = label.numpy() 

print("Real label: ")
for i in label:
    print(kinds[i],end=" ")
pre = prediction.numpy()
print("\n")
print("predicted label: ")
for i in pre:
    print(kinds[i],end=" ")

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