当前位置:   article > 正文

如何训练一个图像分类的模型_如何准备图像分类数据集,可以使得训练出来的分类模型更加精确

如何准备图像分类数据集,可以使得训练出来的分类模型更加精确

2023/12/6

以下给出文字描述以及简略代码,具体实现请根据实际情况进行更改!

1.准备数据集:收集数据集,尽可能包含样本多样,使训练的模型的鲁棒性更好。对数据集进行划分,划分为测试集,训练集,验证集

2.对数据集进行预处理:包括更改尺寸、水平翻转、灰度化、归一化等操作,以防止模型出现拟合的现象。

3.选择模型:可以是vgg、resnet、iception、efficientnet等,根据实际情况对模型进行调整,如人脸真假二分类问题,需要将更改输出的类别数目为2。添加正则化、归一化,防止模型出现过拟合的问题。

4.损失函数和优化器的选择:对于真假二分类的问题损失函数一般是交叉熵损失函数,优化器是Adam优化器。

5.对模型进行训练

6.模型评估:通过准确率、损失率以及混淆矩阵对模型进行评估,再根据结果对模型进行调整。

以下是简单的代码描述,根据实际问题进行修改:
 

1.导入必要的包

import os
os.environ['TORCH_USE_CUDA_DSA'] = '1'
import os
os.environ['CUDA_LAUNCH_BLOCKING'] = '1'
import torch
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
from torchvision.datasets import ImageFolder
from efficientnet_pytorch import EfficientNet
import torch.nn as nn
import torchvision.models as models
import torch.optim as optim

2.# 自定义数据集类
class MyDataset(Dataset):
    def __init__(self, root, transform=None):
        self.dataset = ImageFolder(root, transform=transform)#transformer对数据进行操纵

 # 获取ImageFolder对象的classes属性,其class属性为train、validation、test
         self.classes = self.dataset.classes 
    def __len__(self):
        return len(self.dataset)
    def __getitem__(self, idx):
        img, label = self.dataset[idx]
        return img, label
# 数据预处理和增强
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]),
])#对图像进行归一化


# 创建自定义数据集实例
dataset = MyDataset(root='这里填写相对项目的相对路径', transform=transform)
# 输出类别信息
print("Classes:", dataset.classes)

# 创建数据加载器
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)

# 加载预训练的 EfficientNet 模型
#model = models.efficientnet_b4(pretrained=True)
model = EfficientNet.from_pretrained('efficientnet-b4')

# 查看模型的结构
print(model)
# 获取全连接层的输入
feature = model._fc.in_features
model._fc = nn.Linear(in_features=feature,out_features=2,bias=True)#更改模型的输出

#查看更改后的模型的参数是否符合自己的分类要求
print(model)

3.# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

4.# 训练模型
num_epochs = 10#根据实际情况进行更改
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)#将模型加载到GPU上

for epoch in range(num_epochs):
    running_loss = 0.0
    for i, (inputs, labels) in enumerate(dataloader):
        inputs, labels = inputs.to(device), labels.to(device)  # Move data to GPU

        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputslabels)
        loss.backward()#反向传递误差
        optimizer.step()


        running_loss += loss.item()
        if i % 10 == 9:  # Print every 10 mini-batches
            print(f'Epoch [{epoch + 1}/{num_epochs}], '
                  f'Step [{i + 1}/{len(dataloader)}], '
                  f'Loss: {running_loss / 10:.4f}')
            running_loss = 0.0


    print(f'Epoch {epoch + 1}/{num_epochs}, Loss: {loss.item()}')

# Save the trained model保存训练好的模型参数
torch.save(model.state_dict(), 'my_model.pth')

----------对训练的优化,可以对上面的训练模型的部分进行添加

# 初始化存储训练过程中的损失和准确率
train_losses = []
train_accuracies = []

for epoch in range(num_epochs):
    running_loss = 0.0
    correct_predictions = 0
    total_samples = 0

    for i, (inputs, labels) in enumerate(dataloader):
        inputs, labels = inputs.to(device), labels.to(device)

        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        unning_loss += loss.item()

        # 计算准确率
        _, predicted = torch.max(outputs.data, 1)
        total_samples += labels.size(0)
        correct_predictions += (predicted == labels).sum().item()

        if i % 10 == 9:
            print(f'Epoch [{epoch + 1}/{num_epochs}], '
                  f'Step [{i + 1}/{len(dataloader)}], '
                  f'Loss: {running_loss / 10:.4f}')
            running_loss = 0.0

    # 计算并保存准确率
    accuracy = correct_predictions / total_samples
    train_accuracies.append(accuracy)

    # 计算平均损失并保存
    average_loss = running_loss / len(dataloader)
    train_losses.append(average_loss)

    print(f'Epoch {epoch + 1}/{num_epochs}, Loss: {average_loss}, Accuracy: {accuracy}')

# 绘制训练过程图表
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(range(1, num_epochs + 1), train_losses, label='Training Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(range(1, num_epochs + 1), train_accuracies, label='Training Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()

plt.show()

小结:暂时记录这么多以后学的多了,再对上面进行修改

贴个代码,这个是图像二分类的问题,可根据自己的实际情况进行修改

  1. import os
  2. os.environ['TORCH_USE_CUDA_DSA'] = '1'
  3. import os
  4. os.environ['CUDA_LAUNCH_BLOCKING'] = '1'
  5. import torch
  6. from torch.utils.data import Dataset, DataLoader
  7. from torchvision import transforms
  8. from torchvision.datasets import ImageFolder
  9. from efficientnet_pytorch import EfficientNet
  10. import torch.nn as nn
  11. import torchvision.models as models
  12. import torch.optim as optim
  13. import matplotlib.pyplot as plt
  14. import numpy as np
  15. # 自定义数据集类
  16. class MyDataset(Dataset):
  17. def __init__(self, root, transform=None):
  18. self.dataset = ImageFolder(root, transform=transform)
  19. self.classes = self.dataset.classes # 获取ImageFolder对象的classes属性
  20. def __len__(self):
  21. return len(self.dataset)
  22. def __getitem__(self, idx):
  23. img, label = self.dataset[idx]
  24. return img, label
  25. # 数据预处理和增强
  26. transform = transforms.Compose([
  27. transforms.Resize((224, 224)),
  28. transforms.ToTensor(),
  29. transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
  30. ])
  31. # 创建自定义数据集实例
  32. dataset = MyDataset(root='相对于项目的--数据集的路径', transform=transform)
  33. # 输出类别信息
  34. print("Classes:", dataset.classes)
  35. # 创建数据加载器
  36. dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
  37. # 加载预训练的 EfficientNet 模型
  38. #model = models.efficientnet_b4(pretrained=True)
  39. model = EfficientNet.from_pretrained('efficientnet-b4')
  40. # 查看模型的结构
  41. #print(model)
  42. # 获取全连接层
  43. feature = model._fc.in_features
  44. num_classes = 3
  45. model._fc = nn.Linear(in_features=feature,out_features=3,bias=True)
  46. #print(model)
  47. # 定义损失函数和优化器
  48. criterion = nn.CrossEntropyLoss()
  49. optimizer = optim.Adam(model.parameters(), lr=0.001)
  50. # 训练模型
  51. num_epochs = 1
  52. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  53. model.to(device)
  54. # 初始化存储训练过程中的损失和准确率
  55. train_losses = []
  56. train_accuracies = []
  57. #初始化变量跟踪准确率
  58. total = 0
  59. correct = 0
  60. for epoch in range(num_epochs):
  61. running_loss = 0.0
  62. correct_predictions = 0
  63. total_samples = 0
  64. for i, data in enumerate(dataloader,0):
  65. inputs, labels = inputs.to(device), labels.to(device)
  66. optimizer.zero_grad()
  67. outputs = model(inputs)
  68. loss = criterion(outputs, labels)
  69. loss.backward()
  70. optimizer.step()
  71. running_loss += loss.item()
  72. # 计算准确率
  73. _, predicted = torch.max(outputs.data, 1)
  74. total_samples += labels.size(0)
  75. correct_predictions += (predicted == labels).sum().item()
  76. # Print statistics every 10 steps每10步记录一次
  77. if i % 10 == 9:
  78. print(f'Epoch [{epoch + 1}/{num_epochs}], '
  79. f'Step [{i + 1}/{len(dataloader)}], '
  80. f'Loss: {running_loss / 10:.4f},'
  81. f'Accuracy: {(correct / total) * 100:.2f}%')
  82. running_loss = 0.0
  83. # 计算并保存准确率
  84. accuracy = correct_predictions / total_samples
  85. train_accuracies.append(accuracy)
  86. # 计算平均损失并保存
  87. average_loss = running_loss / len(dataloader)
  88. train_losses.append(average_loss)
  89. print(f'Epoch {epoch + 1}/{num_epochs}, Loss: {average_loss}, Accuracy: {accuracy}')
  90. # 绘制训练过程图表
  91. plt.figure(figsize=(12, 4))
  92. plt.subplot(1, 2, 1)
  93. plt.plot(range(1, num_epochs + 1), train_losses, label='Training Loss')
  94. plt.xlabel('Epoch')
  95. plt.ylabel('Loss')
  96. plt.legend()
  97. plt.subplot(1, 2, 2)
  98. plt.plot(range(1, num_epochs + 1), train_accuracies, label='Training Accuracy')
  99. plt.xlabel('Epoch')
  100. plt.ylabel('Accuracy')
  101. plt.legend()
  102. plt.show()
  103. # Save the trained model
  104. torch.save(model.state_dict(), 'model_efficient.pth')

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/686457
推荐阅读
相关标签
  

闽ICP备14008679号