b2c商城網(wǎng)站網(wǎng)站搜什么關(guān)鍵詞
基于WIN10的64位系統(tǒng)演示
一、寫(xiě)在前面
上期我們基于TensorFlow環(huán)境介紹了多分類(lèi)建模的誤判病例分析。
本期以健康組、肺結(jié)核組、COVID-19組、細(xì)菌性(病毒性)肺炎組為數(shù)據(jù)集,基于Pytorch環(huán)境,構(gòu)建SqueezeNet多分類(lèi)模型,分析誤判病例,因?yàn)樗K俣瓤臁?/p>
同樣,基于GPT-4輔助編程。
二、誤判病例分析實(shí)戰(zhàn)
使用胸片的數(shù)據(jù)集:肺結(jié)核病人和健康人的胸片的識(shí)別。其中,健康人900張,肺結(jié)核病人700張,COVID-19病人549張、細(xì)菌性(病毒性)肺炎組900張,分別存入單獨(dú)的文件夾中。
直接分享代碼:
######################################導(dǎo)入包###################################
import copy
import torch
import torchvision
import torchvision.transforms as transforms
from torchvision import models
from torch.utils.data import DataLoader
from torch import optim, nn
from torch.optim import lr_scheduler
import os
import matplotlib.pyplot as plt
import warnings
import numpy as npwarnings.filterwarnings("ignore")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 設(shè)置GPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")################################導(dǎo)入數(shù)據(jù)集#####################################
from torchvision import datasets, transforms
from torch.nn.functional import softmax
from PIL import Image
import pandas as pd
import torch.nn as nn
import timm
from torch.optim import lr_scheduler# 自定義的數(shù)據(jù)集類(lèi)
class ImageFolderWithPaths(datasets.ImageFolder):def __getitem__(self, index):original_tuple = super(ImageFolderWithPaths, self).__getitem__(index)path = self.imgs[index][0]tuple_with_path = (original_tuple + (path,))return tuple_with_path# 數(shù)據(jù)集路徑
data_dir = "./MTB-1"# 圖像的大小
img_height = 256
img_width = 256# 數(shù)據(jù)預(yù)處理
data_transforms = {'train': transforms.Compose([transforms.RandomResizedCrop(img_height),transforms.RandomHorizontalFlip(),transforms.RandomVerticalFlip(),transforms.RandomRotation(0.2),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]),'val': transforms.Compose([transforms.Resize((img_height, img_width)),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]),
}# 加載數(shù)據(jù)集
full_dataset = ImageFolderWithPaths(data_dir, transform=data_transforms['train'])# 獲取數(shù)據(jù)集的大小
full_size = len(full_dataset)
train_size = int(0.8 * full_size) # 假設(shè)訓(xùn)練集占70%
val_size = full_size - train_size # 驗(yàn)證集的大小# 隨機(jī)分割數(shù)據(jù)集
torch.manual_seed(0) # 設(shè)置隨機(jī)種子以確保結(jié)果可重復(fù)
train_dataset, val_dataset = torch.utils.data.random_split(full_dataset, [train_size, val_size])# 應(yīng)用數(shù)據(jù)增強(qiáng)到訓(xùn)練集和驗(yàn)證集
train_dataset.dataset.transform = data_transforms['train']
val_dataset.dataset.transform = data_transforms['val']# 創(chuàng)建數(shù)據(jù)加載器
batch_size = 8
train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=0)
val_dataloader = torch.utils.data.DataLoader(val_dataset, batch_size=batch_size, shuffle=True, num_workers=0)dataloaders = {'train': train_dataloader, 'val': val_dataloader}
dataset_sizes = {'train': len(train_dataset), 'val': len(val_dataset)}
class_names = full_dataset.classes# 獲取數(shù)據(jù)集的類(lèi)別
class_names = full_dataset.classes# 保存預(yù)測(cè)結(jié)果的列表
results = []###############################定義SqueezeNet模型################################
# 定義SqueezeNet模型
model = models.squeezenet1_1(pretrained=True) # 這里以SqueezeNet 1.1版本為例
num_ftrs = model.classifier[1].in_channels# 根據(jù)分類(lèi)任務(wù)修改最后一層
# 這里我們改變模型的輸出層為4,因?yàn)槲覀冏龅氖撬姆诸?lèi)
model.classifier[1] = nn.Conv2d(num_ftrs, 4, kernel_size=(1,1))# 修改模型最后的輸出層為我們需要的類(lèi)別數(shù)
model.num_classes = 4model = model.to(device)# 打印模型摘要
print(model)#############################編譯模型#########################################
# 定義損失函數(shù)
criterion = nn.CrossEntropyLoss()# 定義優(yōu)化器
optimizer = torch.optim.Adam(model.parameters())# 定義學(xué)習(xí)率調(diào)度器
exp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)# 開(kāi)始訓(xùn)練模型
num_epochs = 20# 初始化記錄器
train_loss_history = []
train_acc_history = []
val_loss_history = []
val_acc_history = []for epoch in range(num_epochs):print('Epoch {}/{}'.format(epoch, num_epochs - 1))print('-' * 10)# 每個(gè)epoch都有一個(gè)訓(xùn)練和驗(yàn)證階段for phase in ['train', 'val']:if phase == 'train':model.train() # 設(shè)置模型為訓(xùn)練模式else:model.eval() # 設(shè)置模型為評(píng)估模式running_loss = 0.0running_corrects = 0# 遍歷數(shù)據(jù)for inputs, labels, paths in dataloaders[phase]:inputs = inputs.to(device)labels = labels.to(device)# 零參數(shù)梯度optimizer.zero_grad()# 前向with torch.set_grad_enabled(phase == 'train'):outputs = model(inputs)_, preds = torch.max(outputs, 1)loss = criterion(outputs, labels)# 只在訓(xùn)練模式下進(jìn)行反向和優(yōu)化if phase == 'train':loss.backward()optimizer.step()# 統(tǒng)計(jì)running_loss += loss.item() * inputs.size(0)running_corrects += torch.sum(preds == labels.data)epoch_loss = running_loss / dataset_sizes[phase]epoch_acc = (running_corrects.double() / dataset_sizes[phase]).item()# 記錄每個(gè)epoch的loss和accuracyif phase == 'train':train_loss_history.append(epoch_loss)train_acc_history.append(epoch_acc)else:val_loss_history.append(epoch_loss)val_acc_history.append(epoch_acc)print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))print()# 保存模型
torch.save(model.state_dict(), 'SqueezeNet_model-m-s.pth')# 加載最佳模型權(quán)重
#model.load_state_dict(best_model_wts)
#torch.save(model, 'shufflenet_best_model.pth')
#print("The trained model has been saved.")
###########################誤判病例分析#################################
import os
import pandas as pd
from collections import defaultdict# 判定組別的字典
group_dict = {("COVID-19", "Normal"): "B",("COVID-19", "Pneumonia"): "C",("COVID-19", "Tuberculosis"): "D",("Normal", "COVID-19"): "E",("Normal", "Pneumonia"): "F",("Normal", "Tuberculosis"): "G",("Pneumonia", "COVID-19"): "H",("Pneumonia", "Normal"): "I",("Pneumonia", "Tuberculosis"): "J",("Tuberculosis", "COVID-19"): "K",("Tuberculosis", "Normal"): "L",("Tuberculosis", "Pneumonia"): "M",
}# 創(chuàng)建一個(gè)字典來(lái)保存所有的圖片信息
image_predictions = {}# 循環(huán)遍歷所有數(shù)據(jù)集(訓(xùn)練集和驗(yàn)證集)
for phase in ['train', 'val']:# 設(shè)置模型的狀態(tài)model.eval()# 遍歷數(shù)據(jù)for inputs, labels, paths in dataloaders[phase]:inputs = inputs.to(device)labels = labels.to(device)# 計(jì)算模型的輸出with torch.no_grad():outputs = model(inputs)_, preds = torch.max(outputs, 1)# 循環(huán)遍歷每一個(gè)批次的結(jié)果for path, pred in zip(paths, preds):# 提取圖片的類(lèi)別actual_class = os.path.split(os.path.dirname(path))[-1] # 提取圖片的名稱(chēng)image_name = os.path.basename(path)# 獲取預(yù)測(cè)的類(lèi)別predicted_class = class_names[pred]# 判斷預(yù)測(cè)的分組類(lèi)型if actual_class == predicted_class:group_type = 'A'elif (actual_class, predicted_class) in group_dict:group_type = group_dict[(actual_class, predicted_class)]else:group_type = 'Other' # 如果沒(méi)有匹配的條件,可以歸類(lèi)為其他# 保存到字典中image_predictions[image_name] = [phase, actual_class, predicted_class, group_type]# 將字典轉(zhuǎn)換為DataFrame
df = pd.DataFrame.from_dict(image_predictions, orient='index', columns=['Dataset Type', 'Actual Class', 'Predicted Class', 'Group Type'])# 保存到CSV文件中
df.to_csv('result-m-s.csv')
四、改寫(xiě)過(guò)程
先說(shuō)策略:首先,先把二分類(lèi)的誤判病例分析代碼改成四分類(lèi)的;其次,用咒語(yǔ)讓GPT-4幫我們續(xù)寫(xiě)代碼已達(dá)到誤判病例分析。
提供咒語(yǔ)如下:
①改寫(xiě){代碼1},改變成4分類(lèi)的建模。代碼1為:{XXX};
②在{代碼1}的基礎(chǔ)上改寫(xiě)代碼,達(dá)到下面要求:
(1)首先,提取出所有圖片的“原始圖片的名稱(chēng)”、“屬于訓(xùn)練集還是驗(yàn)證集”、“預(yù)測(cè)為分組類(lèi)型”;文件的路勁格式為:例如,“MTB-1\Normal\XXX.png”屬于Normal,“MTB-1\COVID-19\XXX.jpg”屬于COVID-19,“MTB-1\Pneumonia\XXX.jpeg”屬于Pneumonia,“MTB-1\Tuberculosis\XXX.png”屬于Tuberculosis;
(2)其次,根據(jù)樣本預(yù)測(cè)結(jié)果,把樣本分為以下若干組:(a)預(yù)測(cè)正確的圖片,全部判定為A組;(b)本來(lái)就是COVID-19的圖片,預(yù)測(cè)為Normal,判定為B組;(c)本來(lái)就是COVID-19的圖片,預(yù)測(cè)為Pneumonia,判定為C組;(d)本來(lái)就是COVID-19的圖片,預(yù)測(cè)為T(mén)uberculosis,判定為D組;(e)本來(lái)就是Normal的圖片,預(yù)測(cè)為COVID-19,判定為E組;(f)本來(lái)就是Normal的圖片,預(yù)測(cè)為Pneumonia,判定為F組;(g)本來(lái)就是Normal的圖片,預(yù)測(cè)為T(mén)uberculosis,判定為G組;(h)本來(lái)就是Pneumonia的圖片,預(yù)測(cè)為COVID-19,判定為H組;(i)本來(lái)就是Pneumonia的圖片,預(yù)測(cè)為Normal,判定為I組;(j)本來(lái)就是Pneumonia的圖片,預(yù)測(cè)為T(mén)uberculosis,判定為J組;(k)本來(lái)就是Tuberculosis的圖片,預(yù)測(cè)為COVID-19,判定為H組;(l)本來(lái)就是Tuberculosis的圖片,預(yù)測(cè)為Normal,判定為I組;(m)本來(lái)就是Tuberculosis的圖片,預(yù)測(cè)為Pneumonia,判定為J組;
(3)居于以上計(jì)算的結(jié)果,生成一個(gè)名為result-m.csv表格文件。列名分別為:“原始圖片的名稱(chēng)”、“屬于訓(xùn)練集還是驗(yàn)證集”、“預(yù)測(cè)為分組類(lèi)型”、“判定的組別”。其中,“原始圖片的名稱(chēng)”為所有圖片的圖片名稱(chēng);“屬于訓(xùn)練集還是驗(yàn)證集”為這個(gè)圖片屬于訓(xùn)練集還是驗(yàn)證集;“預(yù)測(cè)為分組類(lèi)型”為模型預(yù)測(cè)該樣本是哪一個(gè)分組;“判定的組別”為根據(jù)步驟(2)判定的組別,從A到J一共十組選擇一個(gè)。
(4)需要把所有的圖片都進(jìn)行上面操作,注意是所有圖片,而不只是一個(gè)批次的圖片。
代碼1為:{XXX}
③還需要根據(jù)報(bào)錯(cuò)做一些調(diào)整即可,自行調(diào)整。
最后,看看結(jié)果:
模型只運(yùn)行了2次,所以效果很差哈,全部是預(yù)測(cè)成了COVID-19。
四、數(shù)據(jù)
鏈接:https://pan.baidu.com/s/1rqu15KAUxjNBaWYfEmPwgQ?pwd=xfyn
提取碼:xfyn
五、結(jié)語(yǔ)
深度學(xué)習(xí)圖像分類(lèi)的教程到此結(jié)束,洋洋灑灑29篇,涉及到的算法和技巧也夠發(fā)一篇SCI了。當(dāng)然,圖像識(shí)別還有圖像分割和目標(biāo)識(shí)別兩塊內(nèi)容,就放到最后再說(shuō)了。下一趴,我們來(lái)介紹時(shí)間序列建模!!!