目录
第五篇博客感言
勤能补拙。
任务描述
如题,利用神经网络进行微波图像分类,数据集是七类战斗车辆的微波图像(已分类),利用这些数据集训练好网络后,对测试集(未分类)进行分类,将分类结果上传到kaggle与正确结果对比得到准确率。要求准确率尽可能高。部分数据集内容如下:
模型选择和代码实现
总共测试了三个经典的图像分类网络模型:LeNet、VGG和AlexNet。前两者准确率均在70%左右,考虑调整网络参数或者增强数据集,但都没有很好的效果,遂放弃,进而选择AlexNet,达到了至少94%的分类准确率。
本来以为写一个神经网络训练模型的代码很困难,毕竟我是电子信息出身,这方面实在知之甚少。但是多亏了pytorch,现在可以直接调用这些网络模型。所以需要掌握的是如何去编写整个训练和测试的流程,而这件事确实是有套路的:
1)数据提取、转换和增强
2)定义网络结构并设定参数
3)训练模型
4)测试
以AlexNet网络为例:
from torchvision import models
import pandas as pd
from torchsummary import summary
import torch
import torch.nn as nn
from torchvision import transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
#数据提取、转换和增强
transform = transforms.Compose([
transforms.Resize(224),
transforms.RandomHorizontalFlip(), #随机翻转
transforms.ToTensor(), # 转为 Tensor
transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)),# 归一化
])
test_transform = transforms.Compose([
transforms.Resize(224),
transforms.ToTensor(), # 转为 Tensor
transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)),# 归一化
])
train_data_dir = "train"
train_data = ImageFolder(train_data_dir, transform=transform)
train_data_loader = DataLoader(train_data, batch_size=16, shuffle=True,num_workers=0)
val_data_dir = "val"
val_data = ImageFolder(val_data_dir, transform=transform)
val_data_loader = DataLoader(val_data, batch_size=16, shuffle=True,num_workers=0)
test_data_dir = "test"
test_data = ImageFolder(test_data_dir, transform=test_transform)
test_data_loader = DataLoader(test_data)
#定义网络结构
classes = 7
alexnet = models.alexnet(pretrained=True)
alexnet.classifier[6] = nn.Linear(alexnet.classifier[6].in_features, classes)
alexnet.classifier[5] = nn.Sequential(
alexnet.classifier[5]
)
alexnet.classifier[6] = nn.Sequential(
nn.Linear(alexnet.classifier[6].in_features, classes)
)
#各参数设置
net = alexnet
optimizer = torch.optim.Adam(net.parameters(),lr=0.0001, weight_decay=1e-5)
loss_func = nn.CrossEntropyLoss()
num_epoch = 1
#训练模型
for epoch in range(num_epoch): # 设置训练的迭代次数
print(f"epoch{epoch + 1}\n-------------------")
loss, current, n = 0.0, 0.0, 0
#训练集
net.train()
for i, data in enumerate(train_data_loader, 0):
# 输入数据
inputs, labels = data
# forward + backward
outputs = net(inputs)
# 计算损失值
#loss = criterion(outputs, labels)
cur_loss = loss_func(outputs, labels)
_, pred = torch.max(outputs, axis=1)
# 计算每批次的准确率, output.shape[0]为该批次的多少
cur_acc = torch.sum(labels == pred) / outputs.shape[0]
# 反向传播
optimizer.zero_grad()
cur_loss.backward()
optimizer.step()
# 取出loss值和精度值
loss += cur_loss.item()
current += cur_acc.item()
n = n + 1
print('train_loss' + str(loss / n) + ' ' + 'train_acc' + str(current / n))
#验证集
net.eval()
for i, data in enumerate(val_data_loader, 0):
# 输入数据
inputs, labels = data
# forward + backward
outputs = net(inputs)
# 计算损失值
#loss = criterion(outputs, labels)
cur_loss = loss_func(outputs, labels)
_, pred = torch.max(outputs, axis=1)
# 计算每批次的准确率, output.shape[0]为该批次的多少
cur_acc = torch.sum(labels == pred) / outputs.shape[0]
# 取出loss值和精度值
loss += cur_loss.item()
current += cur_acc.item()
n = n + 1
print('val_loss' + str(loss / n) + ' ' + 'val_acc' + str(current / n))
#测试集
pred, target = [], []
net.eval()
for idx_, (image_, _) in enumerate(test_data_loader): # For every batch of data...
# noinspection PyCallingNonCallable
output_ = net(image_) # Generate our predictions
pred.append(output_.argmax(dim=1).item())
result = pd.DataFrame(pred, columns=['category'])
result.index.name = 'id'
result.to_csv('result_alexnet.csv')
print('Finished Training')
net = net.to("cuda:0")
summary(net,input_size=(3,224,224))
源码和报告
所有代码、汇报ppt和项目报告均在下面的链接中。
https://withbreeze.lanzouv.com/iyvBT257jtib
密码:cbvq
欢迎交流讨论!