使用pyqt设计可视化的界面 pytorch 框架 如何构建基于深度学习的鸟类图像分类系统
文章目录
- 使用pyqt设计可视化的界面 pytorch 框架 如何构建基于深度学习的鸟类图像分类系统
- 1. 数据预处理
- 2. 模型定义与训练
- 3. 测试集评估
- 4. PyQt5界面设计
- 1. 导入必要的库
- 2. 数据预处理和加载
- 3. 模型定义
- 4. 训练模型
- 5. 绘制损失曲线
以下文字及代码仅供参考学习。
框架:pytorch
****数据集:525 物种, 84635 列, 2625 测试, 2625 验证图像 224X224X3 jpg
模型:"ResNet18","ResNet34","ResNet50","ResNet101","ResNet152","VGG11","VGG13","VGG16","VGG19","MobileNet_v2","Inception_v3",共11种模型预实现目标所需软件:
深度学习框架:pytorch
界面:使用pyqt设计了可视化的界面
框架:pytorch****
1
基于深度学习的鸟类图像分类系统,涉及数据预处理、模型训练、评估和可视化界面设计等多个步骤。以下是详细的代码实现,包括PyTorch模型训练和PyQt5界面设计。
1. 数据预处理
首先,对数据进行预处理,包括数据加载、数据增强等。
importtorchfromtorchvisionimportdatasets,transformsfromtorch.utils.dataimportDataLoader# 定义数据变换data_transforms={'train':transforms.Compose([transforms.RandomResizedCrop(224),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])]),'val':transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])]),}# 加载数据集data_dir='path_to_your_dataset'image_datasets={x:datasets.ImageFolder(os.path.join(data_dir,x),data_transforms[x])forxin['train','val']}dataloaders={x:DataLoader(image_datasets[x],batch_size=32,shuffle=True,num_workers=4)forxin['train','val']}dataset_sizes={x:len(image_datasets[x])forxin['train','val']}class_names=image_datasets['train'].classes2. 模型定义与训练
接下来,定义并训练多个模型。
importtorch.nnasnnimporttorch.optimasoptimfromtorchvisionimportmodelsdeftrain_model(model,criterion,optimizer,scheduler,num_epochs=50):best_acc=0.0forepochinrange(num_epochs):print(f'Epoch{epoch}/{num_epochs-1}')print('-'*10)# Each epoch has a training and validation phaseforphasein['train','val']:ifphase=='train':model.train()# Set model to training modeelse:model.eval()# Set model to evaluate moderunning_loss=0.0running_corrects=0# Iterate over data.forinputs,labelsindataloaders[phase]:inputs=inputs.to(device)labels=labels.to(device)# zero the parameter gradientsoptimizer.zero_grad()# forward# track history if only in trainwithtorch.set_grad_enabled(phase=='train'):outputs=model(inputs)_,preds=torch.max(outputs,1)loss=criterion(outputs,labels)# backward + optimize only if in training phaseifphase=='train':loss.backward()optimizer.step()# statisticsrunning_loss+=loss.item()*inputs.size(0)running_corrects+=torch.sum(preds==labels.data)ifphase=='train':scheduler.step()epoch_loss=running_loss/dataset_sizes[phase]epoch_acc=running_corrects.double()/dataset_sizes[phase]print(f'{phase}Loss:{epoch_loss:.4f}Acc:{epoch_acc:.4f}')# deep copy the modelifphase=='val'andepoch_acc>best_acc:best_acc=epoch_acc best_model_wts=copy.deepcopy(model.state_dict())print(f'Best val Acc:{best_acc:4f}')# load best model weightsmodel.load_state_dict(best_model_wts)returnmodel device=torch.device("cuda:0"iftorch.cuda.is_available()else"cpu")models_list=[models.resnet18(pretrained=True),models.resnet34(pretrained=True),models.resnet50(pretrained=True),models.resnet101(pretrained=True),models.resnet152(pretrained=True),models.vgg11(pretrained=True),models.vgg13(pretrained=True),models.vgg16(pretrained=True),models.vgg19(pretrained=True),models.mobilenet_v2(pretrained=True),models.inception_v3(pretrained=True)]formodelinmodels_list:num_ftrs=model.fc.in_features model.fc=nn.Linear(num_ftrs,len(class_names))model=model.to(device)criterion=nn.CrossEntropyLoss()optimizer=optim.SGD(model.parameters(),lr=0.001,momentum=0.9)scheduler=optim.lr_scheduler.StepLR(optimizer,step_size=7,gamma=0.1)model=train_model(model,criterion,optimizer,scheduler,num_epochs=50)3. 测试集评估
在测试集上评估每个模型,并将结果保存到CSV文件中。
importcsvdeftest_model(model,dataloader,class_names):model.eval()results=[]withtorch.no_grad():forinputs,labelsindataloader:inputs=inputs.to(device)labels=labels.to(device)outputs=model(inputs)_,preds=torch.max(outputs,1)forpred,labelinzip(preds,labels):results.append([class_names[pred],class_names[label]])returnresults test_dataloader=DataLoader(datasets.ImageFolder(os.path.join(data_dir,'test'),data_transforms['val']),batch_size=32,shuffle=False,num_workers=4)withopen('results.csv','w',newline='')asfile:writer=csv.writer(file)writer.writerow(['Predicted Class','True Class'])formodelinmodels_list:results=test_model(model,test_dataloader,class_names)writer.writerows(results)4. PyQt5界面设计
使用PyQt5设计一个简单的GUI界面。
importsysfromPyQt5.QtWidgetsimportQApplication,QMainWindow,QLabel,QPushButton,QVBoxLayout,QWidget,QFileDialog,QProgressBar,QTableWidget,QTableWidgetItemfromPyQt5.QtGuiimportQPixmapimportcv2classBirdClassificationApp(QMainWindow):def__init__(self):super().__init__()self.initUI()definitUI(self):self.setWindowTitle('基于卷积神经网络的鸟类图像分类')self.setGeometry(100,100,800,600)self.image_label=QLabel(self)self.image_label.setGeometry(20,20,300,300)self.model_label=QLabel('已加载模型: ResNet34',self)self.model_label.move(350,20)self.result_label=QLabel('预测结果: ABBOTTS BOOBY',self)self.result_label.move(350,50)self.load_image_button=QPushButton('加载图像',self)self.load_image_button.move(350,100)self.load_image_button.clicked.connect(self.load_image)self.load_folder_button=QPushButton('加载文件夹',self)self.load_folder_button.move(350,130)self.load_folder_button.clicked.connect(self.load_folder)self.classify_button=QPushButton('开始分类',self)self.classify_button.move(350,160)self.classify_button.clicked.connect(self.classify_image)self.clear_button=QPushButton('清除结果',self)self.clear_button.move(350,190)self.clear_button.clicked.connect(self.clear_results)self.progress_bar=QProgressBar(self)self.progress_bar.setGeometry(20,350,760,20)self.table_widget=QTableWidget(self)self.table_widget.setGeometry(20,400,760,180)self.table_widget.setColumnCount(2)self.table_widget.setHorizontalHeaderLabels(['预测类别','数量'])self.show()defload_image(self):options=QFileDialog.Options()file_name,_=QFileDialog.getOpenFileName(self,"选择图片","","Images (*.png *.xpm *.jpg *.bmp);;All Files (*)",options=options)iffile_name:pixmap=QPixmap(file_name)self.image_label.setPixmap(pixmap.scaled(300,300))defload_folder(self):folder_path=QFileDialog.getExistingDirectory(self,"选择文件夹")iffolder_path:print(f"Selected folder:{folder_path}")defclassify_image(self):# 这里添加分类逻辑self.progress_bar.setValue(100)self.table_widget.setItem(0,0,QTableWidgetItem('ABBOTTS BOOBY'))self.table_widget.setItem(0,1,QTableWidgetItem('1'))defclear_results(self):self.image_label.clear()self.table_widget.clearContents()self.table_widget.setRowCount(0)if__name__=='__main__':app=QApplication(sys.argv)ex=BirdClassificationApp()sys.exit(app.exec_())如图所示的训练和验证损失曲线,完整的代码来定义模型、数据加载器、训练循环以及绘制损失曲线。使用PyTorch和Matplotlib实现这一过程的详细代码。
1. 导入必要的库
importtorchimporttorch.nnasnnimporttorch.optimasoptimfromtorchvisionimportmodels,transforms,datasetsfromtorch.utils.dataimportDataLoaderimportmatplotlib.pyplotasplt2. 数据预处理和加载
# 定义数据变换data_transforms={'train':transforms.Compose([transforms.RandomResizedCrop(224),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])]),'val':transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])]),}# 加载数据集data_dir='path_to_your_dataset'image_datasets={x:datasets.ImageFolder(os.path.join(data_dir,x),data_transforms[x])forxin['train','val']}dataloaders={x:DataLoader(image_datasets[x],batch_size=32,shuffle=True,num_workers=4)forxin['train','val']}dataset_sizes={x:len(image_datasets[x])forxin['train','val']}class_names=image_datasets['train'].classes3. 模型定义
device=torch.device("cuda:0"iftorch.cuda.is_available()else"cpu")model=models.mobilenet_v2(pretrained=True)num_ftrs=model.classifier[1].in_features model.classifier[1]=nn.Linear(num_ftrs,len(class_names))model=model.to(device)criterion=nn.CrossEntropyLoss()optimizer=optim.SGD(model.parameters(),lr=0.001,momentum=0.9)scheduler=optim.lr_scheduler.StepLR(optimizer,step_size=7,gamma=0.1)4. 训练模型
deftrain_model(model,criterion,optimizer,scheduler,num_epochs=50):train_loss_history=[]val_loss_history=[]best_model_wts=copy.deepcopy(model.state_dict())best_acc=0.0forepochinrange(num_epochs):print(f'Epoch{epoch}/{num_epochs-1}')print('-'*10)# Each epoch has a training and validation phaseforphasein['train','val']:ifphase=='train':model.train()# Set model to training modeelse:model.eval()# Set model to evaluate moderunning_loss=0.0running_corrects=0# Iterate over data.forinputs,labelsindataloaders[phase]:inputs=inputs.to(device)labels=labels.to(device)# zero the parameter gradientsoptimizer.zero_grad()# forward# track history if only in trainwithtorch.set_grad_enabled(phase=='train'):outputs=model(inputs)_,preds=torch.max(outputs,1)loss=criterion(outputs,labels)# backward + optimize only if in training phaseifphase=='train':loss.backward()optimizer.step()# statisticsrunning_loss+=loss.item()*inputs.size(0)running_corrects+=torch.sum(preds==labels.data)ifphase=='train':scheduler.step()epoch_loss=running_loss/dataset_sizes[phase]epoch_acc=running_corrects.double()/dataset_sizes[phase]print(f'{phase}Loss:{epoch_loss:.4f}Acc:{epoch_acc:.4f}')ifphase=='train':train_loss_history.append(epoch_loss)else:val_loss_history.append(epoch_loss)# deep copy the modelifphase=='val'andepoch_acc>best_acc:best_acc=epoch_acc best_model_wts=copy.deepcopy(model.state_dict())print(f'Best val Acc:{best_acc:4f}')# load best model weightsmodel.load_state_dict(best_model_wts)returnmodel,train_loss_history,val_loss_history model,train_loss_history,val_loss_history=train_model(model,criterion,optimizer,scheduler,num_epochs=50)5. 绘制损失曲线
plt.figure(figsize=(10,6))plt.plot(train_loss_history,label='Train Loss')plt.plot(val_loss_history,label='Validation Loss')plt.title('mobilenet_v2 - Loss')plt.xlabel('Epoch')plt.ylabel('Loss')plt.legend()plt.show()以上代码将完成模型的训练,并绘制出与图片中类似的训练和验证损失曲线。请确保替换path_to_your_dataset为你的实际数据集路径。
代码示例,仅供参考学习。