一步步完整实现VGGNet分类自己数据集(pytorch ,自己图像数据集准备,前一篇博客的细化)

1 数据准备
1.1 图片路径和标签生成txt文件
1.1.1 原始数据形式如下图
文件格式
说明:Srinivasan2014文件夹→文件夹下有Train和Test两个子文件夹→每个文件夹下有类别名称为文件夹名的子文件夹→图像数据
1.1.2 生成的路径和形式
生成形式
1.2 代码 preprocess.py

import os
import glob

import sys 
sys.path.append("..") 
import random

def file_txt():
    BASE ='Srinivasan2014/'
    traindata_path = BASE + '/Train/'
    #类别数
    labels = os.listdir(traindata_path)
    valdata_path =BASE + '/Test/'
    ##写train.txt文件
    txtpath = BASE

    for index, label in enumerate(labels):
        imglist = glob.glob(os.path.join(traindata_path,label, '*.tif'))
        # print(imglist)
        random.shuffle(imglist)
        print(len(imglist))
        trainlist = imglist[:int(0.8*len(imglist))]
        vallist = imglist[(int(0.8*len(imglist))+1):]
        with open(txtpath + 'train.txt', 'a')as f:
            for img in trainlist:
                #第一类赋予标签0,第二类标签1,以此类推
                #保存为(label_file image_label)的形式
                f.write(img + ' ' + str(index))
                f.write('\n')

        with open(txtpath + 'val.txt', 'a')as f:
            for img in vallist:
                f.write(img + ' ' + str(index))
                f.write('\n')

    for index1, label1 in enumerate(labels):
        print(label1)
        imglist1 = glob.glob(os.path.join(valdata_path,label1, '*.tif'))
        random.shuffle(imglist1)
        with open(txtpath + 'test.txt', 'a')as f1:
            for img1 in imglist1:
                f1.write(img1 + ' ' + str(index1))
                f1.write('\n')
    
if __name__ == '__main__':
    file_txt()
    

2 准备喂入神经网络的形式
2.1 代码 data_pre.py

from torch.utils.data import Dataset, DataLoader
import torch
import numpy as np
from PIL import Image
from torchvision import transforms

def transform(size=300):
    train_transform = transforms.Compose([
        transforms.Resize((size, size)),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.5,0.5,0.5], std=[0.5,0.5,0.5]),
    ])
    return train_transform

class  SelfCustomDataset(Dataset):
    def __init__(self, label_file):
        
        self.transform=transform()
        with open(label_file, 'r') as f:
            #label_file的格式, (label_file image_label)
            #拆开图像路径和标签
            self.imgs = list(map(lambda line: line.strip().split(' '), f))

    def __getitem__(self, index):
        
        img_path, label = self.imgs[index]
        img = Image.open(img_path).convert('RGB')
        img=self.transform(img)

        return img, torch.from_numpy(np.array(int(label)))
 
    def __len__(self):
        return len(self.imgs)

def load_data():
    batch_size =16
    
    train_label_dir = 'Srinivasan2014/train.txt'
    train_datasets = SelfCustomDataset(train_label_dir)
    train_loader = DataLoader(train_datasets, batch_size=batch_size, shuffle=True, num_workers=0)
    
    val_label_dir ='Srinivasan2014/test.txt'
    val_datasets = SelfCustomDataset(val_label_dir)
    val_loader = DataLoader(val_datasets, batch_size=batch_size, shuffle=True, num_workers=0)
    
    return train_loader,val_loader

if __name__=="__main__":
    train_loader,val_loader=load_data()
    for i, (images, labels) in enumerate(train_loader):
        print('data shape')
        print(images.shape)
        print("***"*10)
        print('label shape')
        print(labels.shape)
        break
    

2.2 输出格式
输出测试
3代码测试
3.1 VGG网络结构 model.py

from torchvision import models
import torch.nn as nn
class VGGnet(nn.Module):
    def __init__(self,feature_extract=True,num_classes=3):
        super(VGGnet, self).__init__()
        model = models.vgg16(pretrained=True)
        self.features = model.features
        set_parameter_requires_grad(self.features, feature_extract)#固定特征提取层参数
        #自适应输出宽高尺寸为7×7
        self.avgpool=model.avgpool
        self.classifier = nn.Sequential(
            nn.Linear(512*7*7 , 1024),
            nn.ReLU(),
            nn.Linear(1024, 1024),
            nn.ReLU(),
            nn.Linear(1024, num_classes)
        )
        
    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
#        print(x.shape)
        x = x.view(x.size(0), 512*7*7)
        out=self.classifier(x)
        return out
    
def set_parameter_requires_grad(model, feature_extracting):
    if feature_extracting:
        for param in model.parameters():
            param.requires_grad = False
            
if __name__=="__main__":
    import torch
    from torchsummary import summary
    device=torch.device('cuda' if torch.cuda.is_available() else 'cpu' )
    model=VGGnet().to(device)
    summary(model,(3,300,300)) 

3.2 测试代码主函数 main.py

import torch.nn as nn
from model import VGGnet
import torch
from data_pre import load_data

train_loader,test_loader=load_data()

learning_rate=0.001
num_epochs = 2               # train the training data n times, to save time, we just train 1 epoch
LR = 0.01 

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model=VGGnet().to(device)
 
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
# In[]
total_step = len(train_loader)
for epoch in range(num_epochs):
    correct = 0
    total = 0
    for i, (images, labels) in enumerate(train_loader):
#            print(images.shape)
#            break
        images = images.to(device)
        labels = labels.to(device)
 
        # Forward pass
        outputs = model(images)
        loss = criterion(outputs, labels.long())
 
        # Backward and optimize
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
 
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels.long()).sum().item()
        
        if (i + 1) % 2 == 0:
            print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'
                  .format(epoch + 1, num_epochs, i + 1, total_step, loss.item()))
            
        print('Train Accuracy  {} %'.format(100 * correct / total))

model.eval()  #
with torch.no_grad():
    correct = 0
    total = 0
    for images, labels in test_loader:
        images = images.to(device)
        labels = labels.to(device)
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels.long()).sum().item()

    print('Test Accuracy  {} %'.format(100 * correct / total))

3.3测试结果(没用验证集)
结果
4.代码及数据集打包
百度云
提取码:ofmq

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要使用PyTorch训练自己的数据集时,可以使用迁移学习的方法,其中包括使用预训练的VGG模型。首先,你需要加载VGG16预训练模型的权重,然后更改模型的分类层来适应你的数据集。 以下是一个示例代码,演示如何使用VGG16训练自己的数据集: ```python import torch import torch.nn as nn from torchvision import models # 加载VGG16模型的预训练权重 vgg = models.vgg16(pretrained=True) # 更改分类层 num_classes = 2 # 自定义分类的类别数量,这里设置为2 vgg.classifier = nn.Sequential( nn.Linear(25088, 4096), nn.ReLU(True), nn.Dropout(), nn.Linear(4096, 4096), nn.ReLU(True), nn.Dropout(), nn.Linear(4096, num_classes) ) # 创建自己的数据集,此处省略数据加载和预处理的步骤 # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(vgg.parameters(), lr=0.001) # 训练模型 for epoch in range(num_epochs): for images, labels in dataloader: # 向传播 outputs = vgg(images) loss = criterion(outputs, labels) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() # 在训练完毕后,你可以保存模型的权重 torch.save(vgg.state_dict(), 'vgg_model.pth') ``` 请注意,以上代码为简化示例,并省略了数据加载和预处理的步骤。你需要根据自己的数据集进行适当的修改和调整。还需要根据实际情况来选择合适的损失函数和优化器。 希望这个示例能对你有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [pytorch用自己数据训练VGG16](https://blog.csdn.net/Eyesleft_being/article/details/118757500)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [用pytorchVGG网络训练自己的数据集,以及如何加载预训练网络](https://blog.csdn.net/gbz3300255/article/details/107614203)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值