深度学习的鸟类图像分类系统

发布时间:2026/10/7 20:42:43
深度学习的鸟类图像分类系统 使用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_dirpath_to_your_datasetimage_datasets{x:datasets.ImageFolder(os.path.join(data_dir,x),data_transforms[x])forxin[train,val]}dataloaders{x:DataLoader(image_datasets[x],batch_size32,shuffleTrue,num_workers4)forxin[train,val]}dataset_sizes{x:len(image_datasets[x])forxin[train,val]}class_namesimage_datasets[train].classes2. 模型定义与训练接下来定义并训练多个模型。importtorch.nnasnnimporttorch.optimasoptimfromtorchvisionimportmodelsdeftrain_model(model,criterion,optimizer,scheduler,num_epochs50):best_acc0.0forepochinrange(num_epochs):print(fEpoch{epoch}/{num_epochs-1})print(-*10)# Each epoch has a training and validation phaseforphasein[train,val]:ifphasetrain:model.train()# Set model to training modeelse:model.eval()# Set model to evaluate moderunning_loss0.0running_corrects0# Iterate over data.forinputs,labelsindataloaders[phase]:inputsinputs.to(device)labelslabels.to(device)# zero the parameter gradientsoptimizer.zero_grad()# forward# track history if only in trainwithtorch.set_grad_enabled(phasetrain):outputsmodel(inputs)_,predstorch.max(outputs,1)losscriterion(outputs,labels)# backward optimize only if in training phaseifphasetrain:loss.backward()optimizer.step()# statisticsrunning_lossloss.item()*inputs.size(0)running_correctstorch.sum(predslabels.data)ifphasetrain:scheduler.step()epoch_lossrunning_loss/dataset_sizes[phase]epoch_accrunning_corrects.double()/dataset_sizes[phase]print(f{phase}Loss:{epoch_loss:.4f}Acc:{epoch_acc:.4f})# deep copy the modelifphasevalandepoch_accbest_acc:best_accepoch_acc best_model_wtscopy.deepcopy(model.state_dict())print(fBest val Acc:{best_acc:4f})# load best model weightsmodel.load_state_dict(best_model_wts)returnmodel devicetorch.device(cuda:0iftorch.cuda.is_available()elsecpu)models_list[models.resnet18(pretrainedTrue),models.resnet34(pretrainedTrue),models.resnet50(pretrainedTrue),models.resnet101(pretrainedTrue),models.resnet152(pretrainedTrue),models.vgg11(pretrainedTrue),models.vgg13(pretrainedTrue),models.vgg16(pretrainedTrue),models.vgg19(pretrainedTrue),models.mobilenet_v2(pretrainedTrue),models.inception_v3(pretrainedTrue)]formodelinmodels_list:num_ftrsmodel.fc.in_features model.fcnn.Linear(num_ftrs,len(class_names))modelmodel.to(device)criterionnn.CrossEntropyLoss()optimizeroptim.SGD(model.parameters(),lr0.001,momentum0.9)scheduleroptim.lr_scheduler.StepLR(optimizer,step_size7,gamma0.1)modeltrain_model(model,criterion,optimizer,scheduler,num_epochs50)3. 测试集评估在测试集上评估每个模型并将结果保存到CSV文件中。importcsvdeftest_model(model,dataloader,class_names):model.eval()results[]withtorch.no_grad():forinputs,labelsindataloader:inputsinputs.to(device)labelslabels.to(device)outputsmodel(inputs)_,predstorch.max(outputs,1)forpred,labelinzip(preds,labels):results.append([class_names[pred],class_names[label]])returnresults test_dataloaderDataLoader(datasets.ImageFolder(os.path.join(data_dir,test),data_transforms[val]),batch_size32,shuffleFalse,num_workers4)withopen(results.csv,w,newline)asfile:writercsv.writer(file)writer.writerow([Predicted Class,True Class])formodelinmodels_list:resultstest_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_labelQLabel(self)self.image_label.setGeometry(20,20,300,300)self.model_labelQLabel(已加载模型: ResNet34,self)self.model_label.move(350,20)self.result_labelQLabel(预测结果: ABBOTTS BOOBY,self)self.result_label.move(350,50)self.load_image_buttonQPushButton(加载图像,self)self.load_image_button.move(350,100)self.load_image_button.clicked.connect(self.load_image)self.load_folder_buttonQPushButton(加载文件夹,self)self.load_folder_button.move(350,130)self.load_folder_button.clicked.connect(self.load_folder)self.classify_buttonQPushButton(开始分类,self)self.classify_button.move(350,160)self.classify_button.clicked.connect(self.classify_image)self.clear_buttonQPushButton(清除结果,self)self.clear_button.move(350,190)self.clear_button.clicked.connect(self.clear_results)self.progress_barQProgressBar(self)self.progress_bar.setGeometry(20,350,760,20)self.table_widgetQTableWidget(self)self.table_widget.setGeometry(20,400,760,180)self.table_widget.setColumnCount(2)self.table_widget.setHorizontalHeaderLabels([预测类别,数量])self.show()defload_image(self):optionsQFileDialog.Options()file_name,_QFileDialog.getOpenFileName(self,选择图片,,Images (*.png *.xpm *.jpg *.bmp);;All Files (*),optionsoptions)iffile_name:pixmapQPixmap(file_name)self.image_label.setPixmap(pixmap.scaled(300,300))defload_folder(self):folder_pathQFileDialog.getExistingDirectory(self,选择文件夹)iffolder_path:print(fSelected 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__:appQApplication(sys.argv)exBirdClassificationApp()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_dirpath_to_your_datasetimage_datasets{x:datasets.ImageFolder(os.path.join(data_dir,x),data_transforms[x])forxin[train,val]}dataloaders{x:DataLoader(image_datasets[x],batch_size32,shuffleTrue,num_workers4)forxin[train,val]}dataset_sizes{x:len(image_datasets[x])forxin[train,val]}class_namesimage_datasets[train].classes3. 模型定义devicetorch.device(cuda:0iftorch.cuda.is_available()elsecpu)modelmodels.mobilenet_v2(pretrainedTrue)num_ftrsmodel.classifier[1].in_features model.classifier[1]nn.Linear(num_ftrs,len(class_names))modelmodel.to(device)criterionnn.CrossEntropyLoss()optimizeroptim.SGD(model.parameters(),lr0.001,momentum0.9)scheduleroptim.lr_scheduler.StepLR(optimizer,step_size7,gamma0.1)4. 训练模型deftrain_model(model,criterion,optimizer,scheduler,num_epochs50):train_loss_history[]val_loss_history[]best_model_wtscopy.deepcopy(model.state_dict())best_acc0.0forepochinrange(num_epochs):print(fEpoch{epoch}/{num_epochs-1})print(-*10)# Each epoch has a training and validation phaseforphasein[train,val]:ifphasetrain:model.train()# Set model to training modeelse:model.eval()# Set model to evaluate moderunning_loss0.0running_corrects0# Iterate over data.forinputs,labelsindataloaders[phase]:inputsinputs.to(device)labelslabels.to(device)# zero the parameter gradientsoptimizer.zero_grad()# forward# track history if only in trainwithtorch.set_grad_enabled(phasetrain):outputsmodel(inputs)_,predstorch.max(outputs,1)losscriterion(outputs,labels)# backward optimize only if in training phaseifphasetrain:loss.backward()optimizer.step()# statisticsrunning_lossloss.item()*inputs.size(0)running_correctstorch.sum(predslabels.data)ifphasetrain:scheduler.step()epoch_lossrunning_loss/dataset_sizes[phase]epoch_accrunning_corrects.double()/dataset_sizes[phase]print(f{phase}Loss:{epoch_loss:.4f}Acc:{epoch_acc:.4f})ifphasetrain:train_loss_history.append(epoch_loss)else:val_loss_history.append(epoch_loss)# deep copy the modelifphasevalandepoch_accbest_acc:best_accepoch_acc best_model_wtscopy.deepcopy(model.state_dict())print(fBest 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_historytrain_model(model,criterion,optimizer,scheduler,num_epochs50)5. 绘制损失曲线plt.figure(figsize(10,6))plt.plot(train_loss_history,labelTrain Loss)plt.plot(val_loss_history,labelValidation Loss)plt.title(mobilenet_v2 - Loss)plt.xlabel(Epoch)plt.ylabel(Loss)plt.legend()plt.show()以上代码将完成模型的训练并绘制出与图片中类似的训练和验证损失曲线。请确保替换path_to_your_dataset为你的实际数据集路径。代码示例仅供参考学习。