照片链接:6种花卉 每种200+张http://xn--https-bl8js66z7n7i//pan.baidu.com/s/1fVXFHKQqiSL6zuEgx2T27w%20%20%E6%8F%90%E5%8F%96%E7%A0%81%EF%BC%9Aa56t若是先要跟多照片可以使用下方链接去爬取照片
不过爬取完的照片存在一些无用照片需要清洗一下
爬虫https://blog.csdn.net/weixin_52486467/article/details/127152598CNN模型简单介绍一下:
使用的是AlexNet模型:一共五层网络层和3个全连接层
Model( (layer1): Sequential( (0): Conv2d(3, 96, kernel_size=(8, 8), stride=(4, 4)) (1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (2): ReLU(inplace=True) ) (layer2): Sequential( (0): Conv2d(96, 256, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)) (1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (2): ReLU(inplace=True) ) (layer3): Sequential( (0): Conv2d(256, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU(inplace=True) ) (layer4): Sequential( (0): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU(inplace=True) ) (layer5): Sequential( (0): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) ) (fc1): Sequential( (0): Flatten(start_dim=1, end_dim=-1) (1): Linear(in_features=12544, out_features=4096, bias=True) ) (fc2): Linear(in_features=4096, out_features=4096, bias=True) (fc3): Linear(in_features=4096, out_features=6, bias=True) )
Cnov2d:2D卷积 ,主要参数在上方都使用了
Maxpool2d: 池化,
作用的查看下方连接有介绍到:
CNN神经网络https://blog.csdn.net/weixin_52486467/article/details/126141503
代码:
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import transforms,datasets
from torch.utils.data import DataLoader,dataset
import os
import cv2
from PIL import Image
import matplotlib.pyplot as plt
#数据准备
EPOCHS = 10
BATCH_SIZE = 16
LR = 0.001
DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu' #能使用GPU便使用GPU
transform = transforms.Compose([
transforms.Resize((244,244)),
transforms.ToTensor(),
transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))
])
train_ds = datasets.ImageFolder('../Flower_picture/train-dataset/',transform)
test_ds = datasets.ImageFolder('../Flower_picture/test-dataset/',transform)
train_dl = DataLoader(train_ds,BATCH_SIZE,shuffle=True)
test_dl = DataLoader(test_ds,BATCH_SIZE,shuffle=False)
#定义模型
class Model(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(3,96,kernel_size=8,stride=4,padding=0),#输出(96,55,55)
nn.MaxPool2d(2),#输出(96,27,27)
nn.ReLU(inplace=True),
)
self.layer2 = nn.Sequential(
nn.Conv2d(96,256,5,1,2), #输出(256,27,27)
nn.MaxPool2d(2), #输出(256,13,13)
nn.ReLU(inplace=True),
)
self.layer3 = nn.Sequential(
nn.Conv2d(256,384,3,1,1), #输出(384,13,13)
nn.ReLU(inplace=True)
)
self.layer4 = nn.Sequential(
nn.Conv2d(384,384,3,1,1), #输出(384,13,13)
nn.ReLU(inplace=True)
)
self.layer5 = nn.Sequential(
nn.Conv2d(384,256,3,1,1),#输出(256,13,13)
nn.MaxPool2d(2), #输出(256,6,6)
)
#全连接层
self.fc1 = nn.Sequential(
nn.Flatten(),
nn.Linear(256*7*7,4096))
self.fc2 = nn.Linear(4096,4096)
self.fc3 = nn.Linear(4096,6)
def forward(self,x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
x = self.layer5(x)
# x = x.reshape(-1,256*7*7)
x = self.fc1(x)
x = self.fc2(x)
x = self.fc3(x)
return x
#测试模型是否能运行 单独运行后注释掉
net = Model()
net.to(DEVICE)
loss_fn = nn.CrossEntropyLoss()
opt = torch.optim.SGD(net.parameters(),lr=LR,momentum=0.9)
imgs, lables = next(iter(train_dl))
net(imgs.to(DEVICE))
#定义训练函数
def fif(epoch,model,device,train_dl,test_dl,loss_fn,opt):
loss_,acc,correct = 0,0,0
size = len(train_ds)
total = len(test_ds)
for idx,data in enumerate(train_dl):
imgs, lables = data
imgs,lables = imgs.to(device),lables.to(device)#加载到内存
pred = model(imgs)
loss = loss_fn(pred,lables)
# print('loss:',loss)
# print('label:',lables)
opt.zero_grad()
loss.backward()
opt.step()
loss_+=loss
# print('idx:',idx)
if idx%10==9:
print(f'epoch:{epoch+1} {idx+1} loss:{loss_/10:.3f}')
loss =0 #每次清零
acc +=(pred.argmax(1)==lables).type(torch.float).sum().item()
print(f'【当前的准确率:{acc/size:.3f}】')
with torch.no_grad():
for idx,data in enumerate(test_dl):
imgs, lables = data
imgs,lables = imgs.to(device),lables.to(device)
pred = model(imgs)
correct+=(pred.argmax(1)==lables).type(torch.float).sum().item()
print(f'【test当前准确率:{correct/total:.3f}】')
#调用训练函数开始训练
for epoch in range(EPOCHS):
fif(epoch,net,DEVICE,train_dl,test_dl,loss_fn,opt)
#定义字典 以便下面输出预测值
flower_dic = dict(zip(test_ds.class_to_idx.values(), test_ds.class_to_idx.keys()))
img_path = '../Flower_picture/test-dataset/dandelion/00b56fea1ec68d8e6019a167073a623d.jpeg' #自行更改路径
img = Image.open(img_path).convert('RGB')
plt.imshow(img)
img = transform(img)
img = torch.reshape(img, (1, 3, 244, 244))
flower_dic[net(img.to(DEVICE)).argmax(1).item()]
模型还可以优化:
1、在每个网络层添加激活函数
2、test_ds 测试集我使用的照片只有两张 正常情况测试集取全部照片的0.2-0.3之间