因为临近期末,老师让我们做一个期末项目,因为平时上课都在划水,所以这也是我第一个自己写的深度学习项目,写上博客留作纪念。
数据集是这样的
总共有7000张图片
首先先导入相关包
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms
import cv2
定义超参数`
BATCH_SIZE=32 #定义超参数,每次处理32张图片
DEVICE=torch.device("cuda" if torch.cuda.is_available() else "cpu" )#检测电脑上是否有GPU,如果有就使用GPU,如果没有就使用cpu
EPOCHS=20 #将数据集训练20轮
对图片做预处理
Pipline=transforms.Compose(
[
transforms.ToTensor( ),#将图片转化为tensor
transforms.Normalize((0.1307),(0.3081))#降低模型复杂度,官网提供的数据
]
)#对图像作相应处理
将数据集按照3:1划分训练集和测试集并分到不同文件夹中
import shutil
PATH='C:\\Users\\admin\\Desktop\\deeplearning\\PalmBigDataBase\\'
for i in range(1,386):
for j in range(1,10):
if j%3!=0:
shutil.move(PATH+'P_F_'+str(i)+'_'+str(j)+'.bmp','C:\\Users\\admin\\Desktop\\train') #将一个文件夹下的图片分到不同文件夹
elif j%3==0:
shutil.move(PATH+'P_F_'+str(i)+'_'+str(j)+'.bmp','C:\\Users\\admin\\Desktop\\test')
加载数据集
from torch.utils.data import DataLoader
from torch.utils.data import TensorDataset
import numpy as np
import os
import re
import cv2
train_set=[]
train_label=[]
test_set=[]
train_dataset=[]
test_label=[]
test_dataset=[]
for filename in os.listdir('C:\\Users\\admin\\Desktop\\train'):
imgPath='C:\\Users\\admin\\Desktop\\train'
img=cv2.imread(imgPath+'\\'+filename,0)#循环读取该目录下的所有图片
train_label.append(int(re.findall(r"\d+",filename)[0]))#将图片名的第一个数字作为该图片的类
train_set.append(Pipline(img).numpy().tolist())#对图片作pipline操作后转化为数组
train_dataset=TensorDataset(torch.tensor(train_set),torch.tensor(train_label))#对两个列表进行压缩后作为训练集
for filename in os.listdir('C:\\Users\\admin\\Desktop\\test'):
imgPath='C:\\Users\\admin\\Desktop\\test'
img=cv2.imread(imgPath+'\\'+filename,0)
test_label.append(int(re.findall(r"\d+",filename)[0]))
test_set.append(Pipline(img).numpy().tolist())
test_dataset=TensorDataset(torch.tensor(test_set),torch.tensor(test_label))#对两个列表进行压缩后作为测试集
TrainLoader=DataLoader(train_dataset,batch_size=BATCH_SIZE,shuffle=True)#加载训练集
TestLoader=DataLoader(test_dataset,batch_size=BATCH_SIZE,shuffle=True)#加载测试集
关于TensorDataset函数,这篇博客讲的很详细,看了就能懂
https://blog.csdn.net/qq_40211493/article/details/107529148
构建cnn网络
class net(nn.Module):
def __init__(self):
super().__init__()
self.conv1=nn.Conv2d(1,10,5)#进行2d卷积,因为是灰度图像,所以初试通道是1。输入通道为1,输出通道是10,进行5*5的2d卷积
self.conv2=nn.Conv2d(10,20,3)
self.fc1=nn.Linear(20*60*60,500)
self.fc2=nn.Linear(500,386)#要分386类
def forward(self,x):
input_size=x.size(0) #batch_size)
x=self.conv1(x) # 输入:batch *1*128*128 输出 batch *10*124*124
x=F.relu(x) #size保持不变
x=F.max_pool2d(x,2,2) #输入 batch *10*124*124 输出batch*10*62*62,对图片进行压缩,减少运算。
x=self.conv2(x) #输入 batch*10*62*62 输出 batch*20*60*60
x=F.relu(x)#激活层,不改变图片的shape,每次卷积之后进行一次激活,输出一个非线性函数,增强神经元的表达能力
x=x.view(input_size,-1) #将图片转化为一维线性
x=self.fc1(x)#输入 batch*30*60*60 输出 batch*500
x=F.relu(x)
x=self.fc2(x)#输入 batch*500 输出 batch*386
out_put=F.log_softmax(x,dim=1)#计算损失函数,输出概率最大的类别
return out_put
创建优化器
model=net().to(DEVICE)#创建模型,将模型部署到设备上
optimizer=optim.Adam(model.parameters())#对参数进行优化
对模型进行训练和测试
def train_model(model,optimizer,epoch,device,TrainLoader):
model.train()#模型训练
for (batch_index ,data) in enumerate(TrainLoader):
x_data,label=data
x_data =x_data.to(device)
label =label.to(device)
optimizer.zero_grad()#梯度初始化为0
output=model(x_data)
loss=F.cross_entropy(output,label)#计算损失
loss.backward()
optimizer.step()
if batch_index %300 ==0:
print("Train Epoch:{} \t Loss:{:.6f}".format(epoch,loss.item()))
def test(model,device,TestLoader):
model.eval() #模型验证
correct=0.0 #正确率
test_loss=0.0 #测试损失
with torch.no_grad(): #不会计算梯度,也不会进行反向传播
for(batch_index ,data) in enumerate(TestLoader):
y_data,label=data
y_data=y_data.to(device) #部署到DEVICE上
label =label.to(device)
output=model(y_data) #测试数据
test_loss+=F.cross_entropy(output,label).item() #计算测试损失
pred=output.max(1,keepdim=True)[1] #[0]值 [1]索引 找到概率值最大的下标
# pred=torch.max(output,dimm=1)
# pred=output.argmax(dim=1)
correct+=pred.eq(label.view_as(pred)).sum().item() #累计正确的值
test_loss/=len(TestLoader.dataset)
print("Test -- Average loss:{:.4f},Accuracy:{:.3f}\n".format(test_loss,100.0*correct/len(TestLoader.dataset)))
训练
for epoch in range(1,EPOCHS+1):
train_model(model,optimizer,epoch,DEVICE,TrainLoader)
test(model,DEVICE,TestLoader)
运行结果展示
祝大家天天开心,万事如意