深度学习-利用预训练的 ResNet 和 DenseNet 模型进行医学影像诊断
下面将分别展示基于 PyTorch 框架,利用预训练的 ResNet 和 DenseNet 模型进行医学影像诊断以提高准确率的代码实现。以肺炎 X 光影像诊断为例,假设数据集已经按照训练集和测试集划分好,每个类别存放在不同文件夹中。
1. 安装必要的库
pip install torch torchvision numpy matplotlib pandas
2. 使用 ResNet 实现医学影像诊断
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms, models
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import numpy as np
# 数据预处理
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# 加载数据集
train_dataset = datasets.ImageFolder(root='path/to/train_data', transform=transform)
test_dataset = datasets.ImageFolder(root='path/to/test_data', transform=transform)
# 创建数据加载器
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
# 加载预训练的 ResNet 模型
model = models.resnet18(pretrained=True)
num_ftrs = model.fc.in_features
# 修改最后一层全连接层以适应二分类任务
model.fc = nn.Linear(num_ftrs, 2)
# 定义设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练模型
num_epochs = 10
train_losses = []
for epoch in range(num_epochs):
running_loss = 0.0
model.train()
for i, (images, labels) in enumerate(train_loader):
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
epoch_loss = running_loss / len(train_loader)
train_losses.append(epoch_loss)
print(f'Epoch {epoch + 1}/{num_epochs}, Loss: {epoch_loss:.4f}')
# 绘制训练损失曲线
plt.plot(train_losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss')
plt.show()
# 评估模型
model.eval()
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print(f'Test Accuracy: {accuracy:.2f}%')
3. 使用 DenseNet 实现医学影像诊断
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms, models
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import numpy as np
# 数据预处理
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# 加载数据集
train_dataset = datasets.ImageFolder(root='path/to/train_data', transform=transform)
test_dataset = datasets.ImageFolder(root='path/to/test_data', transform=transform)
# 创建数据加载器
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
# 加载预训练的 DenseNet 模型
model = models.densenet121(pretrained=True)
num_ftrs = model.classifier.in_features
# 修改最后一层全连接层以适应二分类任务
model.classifier = nn.Linear(num_ftrs, 2)
# 定义设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练模型
num_epochs = 10
train_losses = []
for epoch in range(num_epochs):
running_loss = 0.0
model.train()
for i, (images, labels) in enumerate(train_loader):
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
epoch_loss = running_loss / len(train_loader)
train_losses.append(epoch_loss)
print(f'Epoch {epoch + 1}/{num_epochs}, Loss: {epoch_loss:.4f}')
# 绘制训练损失曲线
plt.plot(train_losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss')
plt.show()
# 评估模型
model.eval()
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print(f'Test Accuracy: {accuracy:.2f}%')
4. 代码解释
数据预处理
使用 transforms.Compose
定义了数据预处理操作,包括调整图像大小、转换为张量和归一化。
数据集加载
使用 datasets.ImageFolder
加载训练集和测试集,DataLoader
用于批量加载数据。
模型加载与修改
- ResNet:加载预训练的
resnet18
模型,获取最后一层全连接层的输入特征数,将其替换为适应二分类任务的全连接层。 - DenseNet:加载预训练的
densenet121
模型,获取分类器层的输入特征数,将其替换为适应二分类任务的全连接层。
训练与评估
- 将模型移动到 GPU(如果可用)上进行训练和评估。
- 使用交叉熵损失函数和 Adam 优化器进行训练。
- 在每个 epoch 中记录训练损失,并绘制训练损失曲线。
- 在测试集上评估模型的准确率。
5. 注意事项
- 请将
path/to/train_data
和path/to/test_data
替换为实际的数据集路径。 - 训练过程可能需要较长时间,尤其是在 CPU 上运行时。建议使用 GPU 加速训练。
- 可以根据实际情况调整超参数,如学习率、训练轮数等,以获得更好的诊断准确率。