这次使用的是深度学习,运用的卷积神经网络,通过学习,发现baseline里使用了CUDA 加速,但是在我安装好torch包之后,发现输出的是False,没有办法,搜了一些方式,但是都不太行。。就更改了一下代码,把使用GPU的部分都删掉了,打算全用CPU来运算,但是还是报错,发现是使用多线程的原因,所以又改成了单线程,就可以正常出结果了。
不过不知道是不是没用GPU和多线程的这个的原因,我得到了一个炸裂的分数。。。
我觉得有问题,又运行了一下,重新提交分数就变成了0.74214,看来不是,只能说这个模型可能不是很稳定。。之后再对代码进行修改补充把。。
这次大概就是这样,最近有些忙,时间比较紧,第三次任务希望结果会更好吧。
最后贴一下删掉GPU,并且改为单线程的代码
import os
import glob
import argparse
import pandas as pd
import numpy as np
from tqdm import tqdm
import cv2
from PIL import Image
from sklearn.model_selection import train_test_split, StratifiedKFold, KFold
import torch
# 设置随机数生成器的种子,保证结果可复现
torch.manual_seed(0)
import torchvision.models as models
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from torch.utils.data.dataset import Dataset
import nibabel as nib
from nibabel.viewers import OrthoSlicer3D
# 获取训练集图像路径
train_path = glob.glob('./脑PET图像分析和疾病预测挑战赛公开数据/Train/*/*')
# 获取测试集图像路径
test_path = glob.glob('./脑PET图像分析和疾病预测挑战赛公开数据/Test/*')
# 打乱训练集路径列表
np.random.shuffle(train_path)
# 打乱测试集路径列表
np.random.shuffle(test_path)
# 用于缓存图像数据,避免重复读取
DATA_CACHE = {}
# 自定义数据集类,用于处理图像数据集
class XunFeiDataset(Dataset):
def __init__(self, img_path, transform=None):
self.img_path = img_path
if transform is not None:
self.transform = transform
else:
self.transform = None
def __getitem__(self, index):
if self.img_path[index] in DATA_CACHE:
img = DATA_CACHE[self.img_path[index]]
else:
img = nib.load(self.img_path[index])
img = img.dataobj[:, :, :, 0]
DATA_CACHE[self.img_path[index]] = img
idx = np.random.choice(range(img.shape[-1]), 50)
img = img[:, :, idx]
img = img.astype(np.float32)
if self.transform is not None:
img = self.transform(image=img)['image']
img = img.transpose([2, 0, 1])
return img, torch.from_numpy(np.array(int('NC' in self.img_path[index])))
def __len__(self):
return len(self.img_path)
import albumentations as A
# 对训练数据集进行数据预处理
train_loader = torch.utils.data.DataLoader(
XunFeiDataset(
train_path[:-10], # 不包括最后10个图像的路径
A.Compose([
A.RandomRotate90(), # 随机旋转90度
A.RandomCrop(120, 120), # 随机裁剪为120×120大小
A.HorizontalFlip(p=0.5), # 水平翻转概率为0.5
A.RandomContrast(p=0.5), # 随机对比度调整概率为0.5
A.RandomBrightnessContrast(p=0.5), # 随机亮度对比度调整概率为0.5
])
), batch_size=2, # 批大小为2
shuffle=True # 在每个训练周期开始时打乱数据顺序
)
# 对验证数据集进行数据预处理
val_loader = torch.utils.data.DataLoader(
XunFeiDataset(train_path[-10:],
A.Compose([
A.RandomCrop(120, 120),
])
), batch_size=2, shuffle=False
)
# 对测试数据集进行数据预处理
test_loader = torch.utils.data.DataLoader(
XunFeiDataset(test_path,
A.Compose([
A.RandomCrop(128, 128),
A.HorizontalFlip(p=0.5), # 水平翻转概率为0.5
A.RandomContrast(p=0.5), # 随机对比度调整概率为0.5
])
), batch_size=2, shuffle=False
)
# 定义自定义的XunFeiNet模型类
class XunFeiNet(nn.Module):
def __init__(self):
super(XunFeiNet, self).__init__()
model = models.resnet18(True)
model.conv1 = torch.nn.Conv2d(50, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
model.avgpool = nn.AdaptiveAvgPool2d(1)
model.fc = nn.Linear(512, 2)
self.resnet = model
def forward(self, img):
out = self.resnet(img)
return out
model = XunFeiNet()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.AdamW(model.parameters(), 0.001)
# 训练函数
def train(train_loader, model, criterion, optimizer):
model.train()
train_loss = 0.0
for i, (input, target) in enumerate(train_loader):
output = model(input)
loss = criterion(output, target.long())
optimizer.zero_grad()
loss.backward()
optimizer.step()
if i % 20 == 0:
print(loss.item())
train_loss += loss.item()
return train_loss / len(train_loader)
# 验证函数
def validate(val_loader, model, criterion):
model.eval()
val_acc = 0.0
with torch.no_grad():
for i, (input, target) in enumerate(val_loader):
output = model(input)
loss = criterion(output, target.long())
val_acc += (output.argmax(1) == target).sum().item()
return val_acc / len(val_loader.dataset)
# 训练循环
for _ in range(3):
train_loss = train(train_loader, model, criterion, optimizer)
val_acc = validate(val_loader, model, criterion)
train_acc = validate(train_loader, model, criterion)
print(f'Epoch {_ + 1}: Train Loss: {train_loss}, Train Acc: {train_acc}, Val Acc: {val_acc}')
# 预测函数
def predict(test_loader, model, criterion):
model.eval()
val_acc = 0.0
test_pred = []
with torch.no_grad():
for i, (input, target) in enumerate(test_loader):
output = model(input)
test_pred.append(output.data.cpu().numpy())
return np.vstack(test_pred)
pred = None
# 对测试集进行预测
for _ in range(10):
if pred is None:
pred = predict(test_loader, model, criterion)
else:
pred += predict(test_loader, model, criterion)
# 生成提交文件
submit = pd.DataFrame(
{
'uuid': [int(x.split('\\')[-1][:-4]) for x in test_path],
'label': pred.argmax(1)
})
submit['label'] = submit['label'].map({1: 'NC', 0: 'MCI'})
submit = submit.sort_values(by='uuid')
submit.to_csv('submit2.csv', index=None)