训练自己的分类数据集

EfficientNet 训练测试自己的分类数据集 EfficientNet 训练测试自己的分类数据集 Google团队19年的EfficientNet和EfficientDet在图像分类和目标检测方面都取得了惊艳的效果。EfficientNet既快又准,目测这两年将会成为比ResNet更广泛使用的Backbone。下面简单介绍在自己的分类数据集上运行EfficientNet。 1. 准备代码 Pytorch版本官方代码在这:EfficientNe... 阅读详情

1.数据集准备

准备你要进行分类的数据集,可以自己拍摄,可以网上进行爬取。

  • 将不同类的数据图片放在单独文件夹中(每种类别数据尽可能均衡、数目尽可能多)
    在这里插入图片描述
    在网上爬取数据的python代码:
import os
import time
import requests
import urllib3
urllib3.disable_warnings()
from tqdm import tqdm #进度条库
import os


def craw_single_class(keyword, DOWNLOAD_NUM=50):
    """
    参数说明:
    keyword: 爬取对象
    DOWNLOAD_NUM:爬取的数量
    """
    ########################HTTP请求参数###############################
    cookies = {
        'BDqhfp': '%E7%8B%97%E7%8B%97%26%26NaN-1undefined%26%2618880%26%2621',
        'BIDUPSID': '06338E0BE23C6ADB52165ACEB972355B',
        'PSTM': '1646905430',
        'BAIDUID': '104BD58A7C408DABABCAC9E0A1B184B4:FG=1',
        'BDORZ': 'B490B5EBF6F3CD402E515D22BCDA1598',
        'H_PS_PSSID': '35836_35105_31254_36024_36005_34584_36142_36120_36032_35993_35984_35319_26350_35723_22160_36061',
        'BDSFRCVID': '8--OJexroG0xMovDbuOS5T78igKKHJQTDYLtOwXPsp3LGJLVgaSTEG0PtjcEHMA-2ZlgogKK02OTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0M5',
        'H_BDCLCKID_SF': 'tJPqoKtbtDI3fP36qR3KhPt8Kpby2D62aKDs2nopBhcqEIL4QTQM5p5yQ2c7LUvtynT2KJnz3Po8MUbSj4QoDjFjXJ7RJRJbK6vwKJ5s5h5nhMJSb67JDMP0-4F8exry523ioIovQpn0MhQ3DRoWXPIqbN7P-p5Z5mAqKl0MLPbtbb0xXj_0D6bBjHujtT_s2TTKLPK8fCnBDP59MDTjhPrMypomWMT-0bFH_-5L-l5js56SbU5hW5LSQxQ3QhLDQNn7_JjOX-0bVIj6Wl_-etP3yarQhxQxtNRdXInjtpvhHR38MpbobUPUDa59LUvEJgcdot5yBbc8eIna5hjkbfJBQttjQn3hfIkj0DKLtD8bMC-RDjt35n-Wqxobbtof-KOhLTrJaDkWsx7Oy4oTj6DD5lrG0P6RHmb8ht59JROPSU7mhqb_3MvB-fnEbf7r-2TP_R6GBPQtqMbIQft20-DIeMtjBMJaJRCqWR7jWhk2hl72ybCMQlRX5q79atTMfNTJ-qcH0KQpsIJM5-DWbT8EjHCet5DJJn4j_Dv5b-0aKRcY-tT5M-Lf5eT22-usy6Qd2hcH0KLKDh6gb4PhQKuZ5qutLTb4QTbqWKJcKfb1MRjvMPnF-tKZDb-JXtr92nuDal5TtUthSDnTDMRhXfIL04nyKMnitnr9-pnLJpQrh459XP68bTkA5bjZKxtq3mkjbPbDfn02eCKuj6tWj6j0DNRabK6aKC5bL6rJabC3b5CzXU6q2bDeQN3OW4Rq3Irt2M8aQI0WjJ3oyU7k0q0vWtvJWbbvLT7johRTWqR4enjb3MonDh83Mxb4BUrCHRrzWn3O5hvvhKoO3MA-yUKmDloOW-TB5bbPLUQF5l8-sq0x0bOte-bQXH_E5bj2qRCqVIKa3f',
        'BDSFRCVID_BFESS': '8--OJexroG0xMovDbuOS5T78igKKHJQTDYLtOwXPsp3LGJLVgaSTEG0PtjcEHMA-2ZlgogKK02OTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0M5',
        'H_BDCLCKID_SF_BFESS': 'tJPqoKtbtDI3fP36qR3KhPt8Kpby2D62aKDs2nopBhcqEIL4QTQM5p5yQ2c7LUvtynT2KJnz3Po8MUbSj4QoDjFjXJ7RJRJbK6vwKJ5s5h5nhMJSb67JDMP0-4F8exry523ioIovQpn0MhQ3DRoWXPIqbN7P-p5Z5mAqKl0MLPbtbb0xXj_0D6bBjHujtT_s2TTKLPK8fCnBDP59MDTjhPrMypomWMT-0bFH_-5L-l5js56SbU5hW5LSQxQ3QhLDQNn7_JjOX-0bVIj6Wl_-etP3yarQhxQxtNRdXInjtpvhHR38MpbobUPUDa59LUvEJgcdot5yBbc8eIna5hjkbfJBQttjQn3hfIkj0DKLtD8bMC-RDjt35n-Wqxobbtof-KOhLTrJaDkWsx7Oy4oTj6DD5lrG0P6RHmb8ht59JROPSU7mhqb_3MvB-fnEbf7r-2TP_R6GBPQtqMbIQft20-DIeMtjBMJaJRCqWR7jWhk2hl72ybCMQlRX5q79atTMfNTJ-qcH0KQpsIJM5-DWbT8EjHCet5DJJn4j_Dv5b-0aKRcY-tT5M-Lf5eT22-usy6Qd2hcH0KLKDh6gb4PhQKuZ5qutLTb4QTbqWKJcKfb1MRjvMPnF-tKZDb-JXtr92nuDal5TtUthSDnTDMRhXfIL04nyKMnitnr9-pnLJpQrh459XP68bTkA5bjZKxtq3mkjbPbDfn02eCKuj6tWj6j0DNRabK6aKC5bL6rJabC3b5CzXU6q2bDeQN3OW4Rq3Irt2M8aQI0WjJ3oyU7k0q0vWtvJWbbvLT7johRTWqR4enjb3MonDh83Mxb4BUrCHRrzWn3O5hvvhKoO3MA-yUKmDloOW-TB5bbPLUQF5l8-sq0x0bOte-bQXH_E5bj2qRCqVIKa3f',
        'indexPageSugList': '%5B%22%E7%8B%97%E7%8B%97%22%5D',
        'cleanHistoryStatus': '0',
        'BAIDUID_BFESS': '104BD58A7C408DABABCAC9E0A1B184B4:FG=1',
        'BDRCVFR[dG2JNJb_ajR]': 'mk3SLVN4HKm',
        'BDRCVFR[-pGxjrCMryR]': 'mk3SLVN4HKm',
        'ab_sr': '1.0.1_Y2YxZDkwMWZkMmY2MzA4MGU0OTNhMzVlNTcwMmM2MWE4YWU4OTc1ZjZmZDM2N2RjYmVkMzFiY2NjNWM4Nzk4NzBlZTliYWU0ZTAyODkzNDA3YzNiMTVjMTllMzQ0MGJlZjAwYzk5MDdjNWM0MzJmMDdhOWNhYTZhMjIwODc5MDMxN2QyMmE1YTFmN2QyY2M1M2VmZDkzMjMyOThiYmNhZA==',
        'delPer': '0',
        'PSINO': '2',
        'BA_HECTOR': '8h24a024042g05alup1h3g0aq0q',
    }

    headers = {
        'Connection': 'keep-alive',
        'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"',
        'Accept': 'text/plain, */*; q=0.01',
        'X-Requested-With': 'XMLHttpRequest',
        'sec-ch-ua-mobile': '?0',
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36',
        'sec-ch-ua-platform': '"macOS"',
        'Sec-Fetch-Site': 'same-origin',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Dest': 'empty',
        'Referer': 'https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1647837998851_R&pv=&ic=&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&dyTabStr=MCwzLDIsNiwxLDUsNCw4LDcsOQ%3D%3D&ie=utf-8&sid=&word=%E7%8B%97%E7%8B%97',
        'Accept-Language': 'zh-CN,zh;q=0.9',
    }
    ############################创建文件夹################################
    if os.path.exists('dataset/' + keyword):
        print('文件夹 dataset/{} 已存在,之后直接将爬取到的图片保存至该文件夹中'.format(keyword))
    else:
        os.makedirs('dataset/{}'.format(keyword))
        print('新建文件夹:dataset/{}'.format(keyword))
    #####################爬取并保存图像文件至本地#########################
    count = 1
    with tqdm(total=DOWNLOAD_NUM, position=0, leave=True) as pbar:
        num = 0  # 爬取第几张
        FLAG = True  # 是否继续爬取
        while FLAG:
            page = 30 * count
            params = (
                ('tn', 'resultjson_com'),
                ('logid', '12508239107856075440'),
                ('ipn', 'rj'),
                ('ct', '201326592'),
                ('is', ''),
                ('fp', 'result'),
                ('fr', ''),
                ('word', f'{keyword}'),
                ('queryWord', f'{keyword}'),
                ('cl', '2'),
                ('lm', '-1'),
                ('ie', 'utf-8'),
                ('oe', 'utf-8'),
                ('adpicid', ''),
                ('st', '-1'),
                ('z', ''),
                ('ic', ''),
                ('hd', ''),
                ('latest', ''),
                ('copyright', ''),
                ('s', ''),
                ('se', ''),
                ('tab', ''),
                ('width', ''),
                ('height', ''),
                ('face', '0'),
                ('istype', '2'),
                ('qc', ''),
                ('nc', '1'),
                ('expermode', ''),
                ('nojc', ''),
                ('isAsync', ''),
                ('pn', f'{page}'),
                ('rn', '30'),
                ('gsm', '1e'),
                ('1647838001666', ''),
            )
            response = requests.get('https://image.baidu.com/search/acjson', headers=headers, params=params,
                                    cookies=cookies)
            if response.status_code == 200:
                try:
                    json_data = response.json().get("data")

                    if json_data:
                        for x in json_data:
                            type = x.get("type")
                            if type not in ["gif"]:  # 剔除gif格式的图片
                                img = x.get("thumbURL")
                                fromPageTitleEnc = x.get("fromPageTitleEnc")
                                try:
                                    resp = requests.get(url=img, verify=False)
                                    time.sleep(1)
                                    # print(f"链接 {img}")

                                    # 保存文件名
                                    # file_save_path = f'dataset/{keyword}/{keyword}_{num}-{fromPageTitleEnc}.{type}'
                                    file_save_path = f'dataset/{keyword}/{num}.{type}'
                                    with open(file_save_path, 'wb') as f:
                                        f.write(resp.content)
                                        f.flush()
                                        # print('第 {} 张图像 {} 爬取完成'.format(num, fromPageTitleEnc))
                                        num += 1
                                        pbar.update(1)  # 进度条更新

                                    # 爬取数量达到要求
                                    if num > DOWNLOAD_NUM:
                                        FLAG = False
                                        print('{} 张图像爬取完毕'.format(num))
                                        break

                                except Exception:
                                    pass
                except:
                    pass
            else:
                break

            count += 1

craw_single_class('鸟', DOWNLOAD_NUM = 500)

2. 数据增强

比如说:旋转、翻转、增强对比度、高斯噪点、椒盐噪点等
可以通过Python OpenCV来实现。
以下是一些数据增强的代码(效果可能不好,参数需要自己调节)

import random
import os
from PIL import Image, ImageEnhance
import numpy as np

# 图片文件夹路径
srcPath = r'E:\\文档\\24-25(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\CNN_Classifier\\dataset\\小熊猫'
dstPath = r'E:\\文档\\24-25(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\CNN_Classifier\\dataset\\小熊猫_augmented'


def IncreaseImage(srcPath, dstPath):
    for filename in os.listdir(srcPath):
        # 拼接完整的文件或文件夹路径
        srcFile = os.path.join(srcPath, filename)
        dstFile = os.path.join(dstPath, filename)

        # 如果是文件就处理
        if os.path.isfile(srcFile):
            try:
                img = Image.open(srcFile)
                # img = img.resize((224, 224), Image.LANCZOS)

                # 确保目标文件夹存在
                os.makedirs(dstPath, exist_ok=True)

                # 保存不同变换的图片
                img.save(dstFile)
                img.transpose(Image.ROTATE_90).save(dstFile.replace('.', '_r90.'))
                img.transpose(Image.FLIP_LEFT_RIGHT).save(dstFile.replace('.', '_flipped.'))
                img.transpose(Image.FLIP_TOP_BOTTOM).save(dstFile.replace('.', '_flipped_tb.'))

                # 使用固定的增强因子
                factor = np.random.randint(11, 20) / 10
                ImageEnhance.Contrast(img).enhance(factor).save(dstFile.replace('.', '_contrast.'))
                ImageEnhance.Color(img).enhance(factor).save(dstFile.replace('.', '_color.'))
                ImageEnhance.Sharpness(img).enhance(factor).save(dstFile.replace('.', '_sharp.'))

                # 添加黑白噪声
                def salt_and_pepper_noise(img, proportion=0.03):
                    noise_img = img.copy()
                    pixels = noise_img.load()
                    height, width = noise_img.size
                    num = int(height * width * proportion)
                    for i in range(num):
                        w = random.randint(0, width - 1)
                        h = random.randint(0, height - 1)
                        pixels[h, w] = (0, 0, 0) if random.random() < 0.5 else (255, 255, 255)
                    return noise_img

                salt_and_pepper_noise(img).save(dstFile.replace('.', '_noise.'))

                print(f"Processed {dstFile}")

            except Exception as e:
                print(f"Failed to process {dstFile}: {e}")

        # 如果是文件夹就递归
        elif os.path.isdir(srcFile):
            new_dst_path = os.path.join(dstPath, filename)
            IncreaseImage(srcFile, new_dst_path)


if __name__ == '__main__':
    IncreaseImage(srcPath, dstPath)

3. 数据集划分

将每个类别图片随机划分为训练集和测试集。

  • 假设三个类别,训练集文件夹下就应该包含3个类别的训练集子文件;测试集文件下就应该包含三个类别的测试集子文件。
    在这里插入图片描述
    数据集划分代码:
# import numpy as np
import os
import random
import shutil
path = r'E:\\教学资料\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\鸟'  # 原始数据集的路径
path1 = r'E:\\教学资料\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\train\\bird'  # 训练集
path2 = r'E:\\教学资料\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\test\\bird'  # 测试集

def datasetImage(path, path1,path2):
    for filename in os.listdir(path):
        if not os.path.exists(path1):
            os.makedirs(path1)
        if not os.path.exists(path2):
            os.makedirs(path2)
            
        pathfile = os.path.join(path, filename)
        if os.path.isdir(pathfile):# 如果是文件夹就递归
            datasetImage(pathfile, path1, path2)
    # 如果是文件就处理
    if os.path.isfile(pathfile):
        data = os.listdir(path)
        t = int(len(data) * 0.8)
        for i in range(len(data)):
            random.shuffle(data)  # 打乱数据
        for z in range(len(data)):  # 将数据按8:2分到train和test中
            print('z:', z, '\n')
            pic_path = path + '\\' + data[z]
            print('pic_path:', pic_path)
            if z < t:
                obj_path = path1 + '\\' + data[z]
                shutil.copyfile(pic_path, obj_path)
                print('train:', obj_path)
            else:
                obj_path = path2 + '\\' + data[z]
                print('test:', obj_path)  # 显示分类情况
                shutil.copyfile(pic_path, obj_path)  # 往train、val中复制图片

            if (os.path.exists(pic_path)):
                shutil.copyfile(pic_path, obj_path)


if __name__=='__main__':
    datasetImage(path,path1,path2)

4.设计模型进行训练

对之前学的CNN模型进行魔改,模型训练框架基本都不变!

  • 数据准备
  • 设计模型
  • 损失函数和优化器
  • 模型训练
    注意:这里我们没有使用plt函数来绘制损失曲线图,而是使用了tesorboard来记录训练情况。

4.1. 随便乱写的网络

import os
import numpy as np
import numpy as np
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader #For constructing DataLoader
from torchvision import transforms #For constructing DataLoader
from torchvision import datasets #For constructing DataLoader
import torch.nn.functional as F #For using function relu()
from torch.utils.tensorboard import SummaryWriter


# torch.cuda.current_device()
# torch.cuda.empty_cache()
# torch.cuda._initialized = True

batch_size=2
epochs=10
transform=transforms.Compose([transforms.Resize((224,224)),
                              transforms.ToTensor(),#Convert the PIL Image to Tensor.
                              transforms.Normalize((0.1307,),(0.3081,))])#The parameters are mean and std respectively.

train_dataset = datasets.ImageFolder('E:\\教学资料_yu\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\train\\',transform=transform)#获取路径,返回的是所有图的data、label
test_dataset = datasets.ImageFolder('E:\\教学资料_yu\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\test\\',transform=transform)
train_loader = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)
test_loader = DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=False)

writer = SummaryWriter('E:\\教学资料_yu\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\runs\\log\\', comment='Net')

class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1=nn.Conv2d(3,32,kernel_size=5)
        self.conv2=nn.Conv2d(32,64,kernel_size=5)
        self.conv3=nn.Conv2d(64,128,kernel_size=5,padding=1,bias=False)
        self.conv4=nn.Conv2d(128,256,kernel_size=1,padding=1,bias=False)

        self.pooling1=nn.MaxPool2d(2)
        self.pooling2 = nn.MaxPool2d(2)
        self.pooling3 = nn.MaxPool2d(2)
        self.pooling4 = nn.MaxPool2d(2)

        self.allBN =nn.BatchNorm2d(256)

        self.fc=torch.nn.Linear(43264,4)

    def forward(self,x):
        # Flatten data from (n, 1,224, 224) to (n, )

        x=self.conv1(x)
        x = F.relu(x)
        x=self.pooling1(x)


       # x=F.relu(self.pooling(self.conv1(x)))#(n,16,110,110)

        x=self.conv2(x)
        x = F.relu(x)
        x=self.pooling2(x)

        #x=F.relu(self.pooling(self.conv2(x)))#(n,32,53,53)

        x=self.conv3(x)
        x = F.relu(x)
        x=self.pooling3(x)


        #x=F.relu(self.pooling(self.conv3(x)))#(n,64,25,25)

        x=self.conv4(x)
        x = F.relu(x)
        x=self.pooling4(x)
        x=self.allBN(x)

       # x = F.relu(self.pooling(self.conv4(x)))  # (n,256,13,13)

        batch_size = x.size(0)  # (n,3,28,28)
        out=x.view(batch_size,-1)#flatten
        out=self.fc(out)
        out = F.dropout(out, 0.6, training=self.training)
        return out

model=Net()

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
#Define device as the first visible cuda device if we have CUDA available.

model.to(device)
# Convert parameters and buffers of all modules to CUDA Tensor.

criterion=torch.nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(model.parameters(),lr=0.01,momentum=0.5)
def train(epoch):
    total=0.0
    correct=0.0
    running_loss=0.0
    for batch_id,data in enumerate(train_loader,0):
        inputs,target=data
        inputs,target=inputs.to(device),target.to(device)
        #Send the inputs and targets at every step to the GPU
        optimizer.zero_grad()

        # forward + backward + update

        outputs=model(inputs)
        loss=criterion(outputs,target)
        loss.backward()
        optimizer.step()
        running_loss +=loss.item()
        #print('[%d,%5d] loss: %.3f' % (epoch + 1, batch_id, running_loss ))
        #running_loss = 0.0

        predicted = torch.argmax(outputs.data, dim=1)
        total += target.size(0)
        correct += (predicted == target).sum().item()
        accuracy = 100 * correct / total

        if (batch_id)% 100==99:
             print('[%d,%5d] loss: %.3f' % (epoch+1,batch_id,running_loss/100))
             running_loss=0.0
             print('Accuracy on train set : %d %% [%d/%d]' % (100 * correct / total, correct, total))




    writer.add_scalar('train accuracy',accuracy, epoch)
    writer.add_scalar('train loss', running_loss, epoch)

    writer.add_graph(model, (inputs,))
    writer.flush()

def test():
    correct=0
    total=0
    #predata = []
    #lable = []
    with torch.no_grad():
        for batch_id,data in enumerate(test_loader,0):
            inputs,target=data
            inputs,target=inputs.to(device),target.to(device)
            #Send the inputs and targets at every step to the GPU
            outputs=model(inputs)
            predicted=torch.argmax(outputs.data,dim=1)
            #predata.append(predicted.item())
            #lable.append(target.item())
            total+=target.size(0)
            correct+=(predicted==target).sum().item()
        print('Accuracy on test set : %d %% [%d/%d]'%(100*correct/total,correct,total))

        #print(predata)
        #print(lable)
        #print(test_dataset.class_to_idx)

    writer.add_scalar('test accuracy', 100*correct/total, epoch)
    writer.flush()
if __name__ == '__main__':
    for epoch in range(epochs):
        train(epoch)
        test()

    torch.save((model.state_dict(), 'E:\\教学资料_yu\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\runs\\result\\try.pt')
    writer.flush()
    writer.close()

#print(train_dataset[0][0].size())
#展示图像,乘标准差加均值,再转回PIL Image(上述过程的逆过程)
# show=transforms.ToPILImage()
# show(train_dataset[0][0]*0.5+0.5)

# print(train_dataset.class_to_idx) #查看类别名,及对应的标签。
# print(train_dataset.imgs)  #查看路径里所有的图片,及对应的标签
# print(train_dataset[0][1]) #第1张图的label
# print(train_dataset[0][0])#第1张图的data

结果:

Accuracy on train set : 37 % [150/400]
[9, 299] loss: 1.504
Accuracy on train set : 38 % [231/600]
[9, 399] loss: 1.488
Accuracy on train set : 38 % [309/800]
[9, 499] loss: 1.418
Accuracy on train set : 38 % [383/1000]
Accuracy on test set : 37 % [106/286]
[10, 99] loss: 1.560
Accuracy on train set : 41 % [83/200]
[10, 199] loss: 1.405
Accuracy on train set : 40 % [162/400]
[10, 299] loss: 1.351
Accuracy on train set : 40 % [244/600]
[10, 399] loss: 1.471
Accuracy on train set : 39 % [318/800]
[10, 499] loss: 1.459
Accuracy on train set : 38 % [388/1000]
Accuracy on test set : 38 % [109/286]

tensorboard查看训练曲线: tensorboard --logdir=E:\\教学资料\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\runs\\log
TensorBoard 2.16.2 at http://localhost:6006/ (Press CTRL+C to quit)
在这里插入图片描述

训练结果非常垃圾!

4.2. 借鉴优秀的网络模型(MobileNetV3)

import os
import numpy as np
import numpy as np
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader #For constructing DataLoader
from torchvision import transforms #For constructing DataLoader
from torchvision import datasets #For constructing DataLoader
import torch.nn.functional as F #For using function relu()
from torch.utils.tensorboard import SummaryWriter



# torch.cuda.current_device()
# torch.cuda.empty_cache()
# torch.cuda._initialized = True

batch_size=2
epochs=10
transform=transforms.Compose([transforms.Resize((224,224)),
                              transforms.ToTensor(),#Convert the PIL Image to Tensor.
                              transforms.Normalize((0.1307,),(0.3081,))])#The parameters are mean and std respectively.

train_dataset = datasets.ImageFolder('E:\\教学资料_yu\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\train\\',transform=transform)#获取路径,返回的是所有图的data、label
test_dataset = datasets.ImageFolder('E:\\教学资料_yu\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\test\\',transform=transform)
train_loader = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)
test_loader = DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=False)

writer = SummaryWriter('E:\\教学资料_yu\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\runs\\log\\', comment='Net')




class hswish(nn.Module):
    def __init__(self, inplace=True):
        super(hswish, self).__init__()
        self.inplace = inplace

    def forward(self, x):
        f = nn.functional.relu6(x + 3., inplace=self.inplace) / 6.
        return x * f


class hsigmoid(nn.Module):
    def __init__(self, inplace=True):
        super(hsigmoid, self).__init__()
        self.inplace = inplace

    def forward(self, x):
        f = nn.functional.relu6(x + 3., inplace=self.inplace) / 6.
        return f


class SeModule(nn.Module):
    def __init__(self, in_channels, se_ratio=0.25):
        super(SeModule, self).__init__()
        self.se_reduce = nn.Conv2d(in_channels, int(in_channels * se_ratio), kernel_size=1, stride=1, padding=0)
        self.se_expand = nn.Conv2d(int(in_channels * se_ratio), in_channels, kernel_size=1, stride=1, padding=0)

    def forward(self, x):
        s = nn.functional.adaptive_avg_pool2d(x, 1)
        s = self.se_expand(nn.functional.relu(self.se_reduce(s), inplace=True))
        return x * s.sigmoid()


class ConvBlock(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride, padding, groups=1):
        super(ConvBlock, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding, groups=groups, bias=False)
        self.bn = nn.BatchNorm2d(out_channels)
        self.act = hswish()

    def forward(self, x):
        return self.act(self.bn(self.conv(x)))


class SqueezeExcitation(nn.Module):
    def __init__(self, in_channel, out_channel, reduction=4):
        super(SqueezeExcitation, self).__init__()
        self.pool = nn.AdaptiveAvgPool2d(1)
        self.fc1 = nn.Conv2d(in_channel, out_channel // reduction, kernel_size=1, stride=1)
        self.relu = nn.ReLU(inplace=True)
        self.fc2 = nn.Conv2d(out_channel // reduction, out_channel, kernel_size=1, stride=1)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        out = self.pool(x)
        out = self.fc1(out)
        out = self.relu(out)
        out = self.fc2(out)
        out = self.sigmoid(out)
        return out


class ResidualBlock(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride, use_se=True):
        super(ResidualBlock, self).__init__()
        self.conv1 = ConvBlock(in_channels, out_channels, kernel_size, stride, kernel_size // 2)
        self.conv2 = ConvBlock(out_channels, out_channels, kernel_size, 1, kernel_size // 2)
        self.use_se = use_se
        if use_se:
            self.se = SqueezeExcitation(out_channels, out_channels)
        self.shortcut = nn.Sequential()
        if stride != 1 or in_channels != out_channels:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(out_channels)
            )

    def forward(self, x):
        out = self.conv1(x)
        out = self.conv2(out)
        if self.use_se:
            out = out * self.se(out)
        out += self.shortcut(x)
        out = nn.functional.relu(out, inplace=True)
        return out



class MobileNetV3(nn.Module):
    def __init__(self, num_classes=1000):
        super(MobileNetV3, self).__init__()

        self.conv1 = ConvBlock(3, 16, 3, 2, 1)  # 1/2
        self.bottlenecks = nn.Sequential(
            ResidualBlock(16, 16, 3, 2, False),  # 1/4
            ResidualBlock(16, 72, 3, 2, False),  # 1/8
            ResidualBlock(72, 72, 3, 1, False),
            ResidualBlock(72, 72, 3, 1, True),
            ResidualBlock(72, 96, 3, 2, True),  # 1/16
            ResidualBlock(96, 96, 3, 1, True),
            ResidualBlock(96, 96, 3, 1, True),
            ResidualBlock(96, 240, 5, 2, True),  # 1/32
            ResidualBlock(240, 240, 5, 1, True),
            ResidualBlock(240, 240, 5, 1, True),
            ResidualBlock(240, 480, 5, 1, True),
            ResidualBlock(480, 480, 5, 1, True),
            ResidualBlock(480, 480, 5, 1, True),
        )
        self.conv2 = ConvBlock(480, 576, 1, 1, 0, groups=2)
        self.conv3 = nn.Conv2d(576, 1024, kernel_size=1, stride=1, padding=0, bias=False)
        self.bn = nn.BatchNorm2d(1024)
        self.act = hswish()
        self.pool = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Linear(1024, num_classes)

    def forward(self, x):
        out = self.conv1(x)
        out = self.bottlenecks(out)
        out = self.conv2(out)
        out = self.conv3(out)
        out = self.bn(out)
        out = self.act(out)
        out = self.pool(out)
        out = out.reshape(out.size(0), -1)
        out = self.fc(out)
        return out


model=MobileNetV3(num_classes=3)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
#Define device as the first visible cuda device if we have CUDA available.

model.to(device)
# Convert parameters and buffers of all modules to CUDA Tensor.

criterion=torch.nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(model.parameters(),lr=0.01,momentum=0.5)
def train(epoch):
    total=0.0
    correct=0.0
    running_loss=0.0
    for batch_id,data in enumerate(train_loader,0):
        inputs,target=data
        inputs,target=inputs.to(device),target.to(device)
        #Send the inputs and targets at every step to the GPU
        optimizer.zero_grad()

        # forward + backward + update

        outputs=model(inputs)
        loss=criterion(outputs,target)
        loss.backward()
        optimizer.step()
        running_loss +=loss.item()
        # print('[%d,%5d] loss: %.3f' % (epoch + 1, batch_id, running_loss ))
        # running_loss = 0.0

        predicted = torch.argmax(outputs.data, dim=1)
        total += target.size(0)
        correct += (predicted == target).sum().item()
        accuracy = 100 * correct / total

        if (batch_id)% 100==99:
             print('[%d,%5d] loss: %.3f' % (epoch+1,batch_id,running_loss/100))
             running_loss=0.0
             print('Accuracy on train set : %d %% [%d/%d]' % (100 * correct / total, correct, total))



    writer.add_scalar('train accuracy',accuracy, epoch)
    writer.add_scalar('train loss', running_loss, epoch)

    writer.add_graph(model, (inputs,))
    writer.flush()

def test():
    correct=0
    total=0
    #predata = []
    #lable = []
    with torch.no_grad():
        for batch_id,data in enumerate(test_loader,0):
            inputs,target=data
            inputs,target=inputs.to(device),target.to(device)
            #Send the inputs and targets at every step to the GPU
            outputs=model(inputs)
            predicted=torch.argmax(outputs.data,dim=1)
            #predata.append(predicted.item())
            #lable.append(target.item())
            total+=target.size(0)
            correct+=(predicted==target).sum().item()
        print('Accuracy on test set : %d %% [%d/%d]'%(100*correct/total,correct,total))
        #print(predata)
        #print(lable)
        #print(test_dataset.class_to_idx)

    writer.add_scalar('test accuracy', 100*correct/total, epoch)
    writer.flush()
if __name__ == '__main__':
    for epoch in range(epochs):
        train(epoch)
        test()

    torch.save((model.state_dict(), 'E:\\教学资料_yu\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\runs\\result\\try1.pt')
    writer.flush()
    writer.close()

#print(train_dataset[0][0].size())
#展示图像,乘标准差加均值,再转回PIL Image(上述过程的逆过程)
# show=transforms.ToPILImage()
# show(train_dataset[0][0]*0.5+0.5)

# print(train_dataset.class_to_idx) #查看类别名,及对应的标签。
# print(train_dataset.imgs)  #查看路径里所有的图片,及对应的标签
# print(train_dataset[0][1]) #第1张图的label
# print(train_dataset[0][0])#第1张图的data

结果:

[9, 499] loss: 0.778
Accuracy on train set : 61 % [618/1000]
Accuracy on test set : 48 % [139/286]
[10, 99] loss: 0.840
Accuracy on train set : 62 % [124/200]
[10, 199] loss: 0.823
Accuracy on train set : 60 % [242/400]
[10, 299] loss: 0.790
Accuracy on train set : 62 % [372/600]
[10, 399] loss: 0.730
Accuracy on train set : 63 % [506/800]
[10, 499] loss: 0.767
Accuracy on train set : 63 % [633/1000]
Accuracy on test set : 51 % [148/286]

tensorboard:
在这里插入图片描述
在这里插入图片描述

5.训练好的模型进行预测

从网上找一些新数据,让模型输出预测结果:

def eval():
    #加载pt文件
    model_path='dataset/动物/runs/result/try1.pt'
    model_dict=torch.load(model_path,map_location=device)

    #加载模型参数
    model.load_state_dict(model_dict)
    model.eval()

    #加载数据
    dir = 'F:\教学资料\\23-24(2)教学资料\\深度学习框架与应用\\代码\\Pytorch教学代码\\dataset\\动物\\eval\\'
    for filename in os.listdir(dir):
        # 拼接完整的文件或文件夹路径
        eval_imge_path = os.path.join(dir, filename)
        eval_imge = Image.open(eval_imge_path)#读取图片
        input_tensor = transform(eval_imge)#转化为tensor
        input_batch = input_tensor.unsqueeze(0)
        input_batch = input_batch.to(device)#切换到GPU或者cpu
        #预测
        with torch.no_grad():
            outputs = model(input_batch)
            predicted = torch.argmax(outputs.data, dim=1)
            print('predicted:',predicted.item())

结果:

predicted: 0
predicted: 2
predicted: 1
predicted: 0
predicted: 0

序号对应分别为:
在这里插入图片描述

5. 模型封装为ONNX

def onnx_export():
    # 加载模型(正确方式)
    model_path = 'dataset/动物/runs/result/try2.pt'
    model_dict = torch.load(model_path, map_location=device)
    #加载模型参数
    model.load_state_dict(model_dict)
    model.eval()  # 设置为评估模式
    x = torch.randn(1, 3, 224, 224).to(device)

    # 导出ONNX模型
    with torch.no_grad():
        torch.onnx.export(
            model,  # 要转换的模型对象
            x,  # 模型的示例输入
            'dataset/动物/runs/result/try2.onnx',  # 导出的ONNX文件名
            opset_version=11,  # ONNX算子集版本
            input_names=['input'],  # 输入Tensor的名称
            output_names=['output'],  # 输出Tensor的名称
            dynamic_axes={'input': {0: 'batch_size'}, 'output': {0: 'batch_size'}}  # 支持动态batch
        )

    print("ONNX模型导出成功!")

分析:

  • 以上只改了网络结构,模型并没有完全收敛。
  • 因此还可以增加epoch、batch_size、调整超参数进行优化!
  • 另外,爬取数据里面也有错误的数据,记得删除,否则会影响训练,爬取数据背景差异大,这也是训练困难的因素之一!

练习:

请尝试用各种经典网络进行优化模型,训练得到更好的结果!

EfficientNet 训练自己的分类数据集 参考乱觉先森的这篇文章:EfficientNet 训练测试自己的分类数据集 1、下载代码 Levigty/EfficientNet-Pytorch可快速使用。(这里顺便提一下EfficientNet的pytorch版官方代码) 2、准备数据集 格式如下: 3、下载预训练模型 可复制链接至迅雷下载更快https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/efficientnet-b0-355c32eb.. 阅读详情

相关推荐

TensorFlow学习——FashionMnist数据集分类训练

按照tensorflow官网写的代码,在导入数据集部分,由于数据集无法自动导入,使用了自定义的导入模块 # -*- coding: utf-8 -*- """ Created on Wed Sep 11 12:26:02 2019 @author: Lenovo """ #将新版本特性引入当前版本中 from __future__ import absolute_import, divisio...

chicken3wings的博客 1178

64个热门图像分类数据集免费、高速资源分享,涵盖通用视觉、食物、艺术、医疗等多种场景

本期将分享64个图像分类任务相关的热门公开数据集资源

OpenDataLab的博客 2万+

【ML】机器学习数据集:sklearn中分类数据集介绍

在机器学习的教程中,我们会看到很多的demo,这些demo都是基于python中自带的数据集。今天我们将介绍sklearn中几个常用的分类预测数据集。

学无止境、积少成多、厚积薄发 1万+

ML(2)-图像分类常用数据集

模式识别-数据集1 CIFAR-102.MNIST3.LUN 在训练神经网络进行图像识别分类时,常会用到一些通用的数据集合。利用这些数据集合可以对比不同模型的性能差异。下文整理常用的图片数据集合持续更新中)。 基本信息对比表格: 数据集合 类别数 图像数/类 训练集 测试集 图像大小 格式 数据集大小 图像内容 CIFAR-10 10 6k 5w 1w 32*32 RGB 163M...

sinat_40624829的博客 7407

训练神经网络对服装数据集进行分类

本指南会训练一个对服饰(例如运动鞋和衬衫)图像进行分类的神经网络模型。即使您不了解所有细节也没关系,本教程只是简要介绍了一个完整的 TensorFlow 程序,而且后续我们会详细介绍。 本指南使用的是 tf.keras,它是一种用于在 TensorFlow 中构建和训练模型的高阶 API。 # TensorFlow and tf.keras import tensorflow as tf from...

weixin_41697507的博客 3338

标准分类的数据集

用于分类的标准数据集,包括iris,wine,breast,glass四个数据集,方便聚类实现

pytorch——AlexNet——训练花分类数据集

pytorch图像分类篇:3.搭建AlexNet并训练花分类数据集_fun1024-优快云博客_alexnet分类pytorch 宝藏博主:霹雳吧啦Wz_太阳花的小绿豆_优快云博客-深度学习,Tensorflow,软件安装领域博主 目录 数据集下载 训练集与测试集划分 “split_data.py” Alexnet讲解: 名称解读 1)过拟合: 2) Dropout: 3)gpu 1. model.py 2. train.py 先对训练集的预处理 1)tra...

heart_6662的博客 1万+

用于进行分类算法的8个数据集

用于进行分类算法的8个数据集

pytorch图像分类篇:3.搭建AlexNet并训练花分类数据集

AlexNet——pytorch 图像分类

fun1024 3万+

VQGAN实战:从文本到高清图像的保姆级生成教程(含PyTorch代码)

本文详细介绍了VQGAN(Vector Quantized Generative Adversarial Network)在文本到高清图像生成中的应用,提供了从环境配置到模型加载、文本编码及图像生成的完整PyTorch代码教程。通过实战案例和高级调优技巧,帮助开发者快速掌握VQGAN的核心技术,实现百万像素级的高清图像生成。

u8v9w0x1y的博客 649

FPGA编译加速实战:6大可落地的Vivado优化策略

FPGA编译本质上是NP-hard约束满足问题求解,而非传统软件编译;Vivado作为时序驱动的硬件实现工具链,其耗时瓶颈集中在Implementation阶段的布局布线(PnR)与逻辑优化。理解这一原理,才能跳出‘加线程’‘升版本’等表面优化,转向精准时序约束、增量编译、物理锚点控制、IP配置精简等工程级干预。这些技术手段直接作用于Vivado的Tcl执行流与底层求解空间,显著压缩搜索范围、减少无效迭代——尤其适用于Zynq/UltraScale等中大型项目(LUT > 80K、多时钟域、DDR/PCIe

weixin_34226182的博客 413

tensorflow2.3训练自己的分类数据集

Keras和TensorFlow都是深度学习的框架,但它们具有一些主要的区别。首先,Keras是基于TensorFlow的高级API,用纯Python编写,使得其代码更加简洁,适合初学者使用。然而,由于Keras在TensorFlow的基础上进行了再次封装,可能在运行速度上不如TensorFlow快。(本文实际使用的框架是Keras,但面对小型数据集时速度差异不大)注意:本文当中的实验数据并无参考价值,在模型训练过程中存在较严重的过拟合问题,希望在过拟合问题上取的进展的兄弟可以和我一起探讨或者者不吝赐教。

m0_64096844的博客 2752

基于大疆TSDK与Pix4D的热红外数据工程化处理:从RJPG到温度正射影像的完整工作流

本文详细介绍了基于大疆TSDK与Pix4D的热红外数据工程化处理完整工作流。通过Python脚本自动化解析RJPG格式的热红外图像,提取并转换其中的原始辐射数据为包含真实温度信息的TIFF文件,再结合Pix4Dmapper进行批量拼接,最终生成可直接用于GIS分析的温度正射影像图。该流程解决了手动处理效率低下、参数校准复杂等难题,实现了从原始数据到定量分析成果的高效、准确、可重复生产。

weixin_29161785的博客 377

用EfficientNet训练数据集,对测试数据进行分类

用EfficientNet训练数据集,对测试数据进行分类使用EfficientNet数据集的准备数据集整理模型训练输出结果Accuracy其他 使用EfficientNet Google于2019年发表的EfficientNet,其独特的卷积结构令其在速度和精度上令人拍案叫绝。 *EfficientNet的优点及其与ResNet等网络的比较----->知乎 *github上EfficientNet官方代码EfficientNet-PyTorch *关于EfficientNet预训练模型的下载,请点击此

qq_46079933的博客 4786

ifix5.8连接ab plc的点-通过rslinx

以ifix连接ab plc的点为例 1.先在rslinx上把plc的点导出为opc server 2.使用opc power tool 作为opc client 去连接 3.保存到项目的PDB文件夹下面,并且以节点名命名。 也可以不以节点名命名,系统自动会生成一个以节点名命名的这种文件,就显得很乱。 同时,项目的PDB目录下面必须还得拷过来一个de...

中国智造2025 4114

详解卷积神经网络(CNN)

卷积神经网络(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。

qq_25762497的博客 25万+

coco数据集大小分类_pytorch训练自己图像分类数据集

2020年6月更新,调整代码的组成结构,使其更加通用,方便使用,更加整洁,添加模型蒸馏的方法。希望对初学者能有些帮助,欢迎starlxztju/pytorch_classification​github.com2020年4月26更新:cnn svm knn pytorch最近实现了利用cnn提取特征,然后利用svm或者knn,随机森林等分类器实现分类,在一些分类任务中效果会更好,代码已经在gith...

weixin_32538033的博客 1512

命令行驱动视频剪辑:cutcli与AI自动化工作流实战

在视频内容创作领域,自动化与批量化处理是提升生产效率的关键。传统图形界面工具在应对重复性任务时往往效率低下,而通过命令行接口(CLI)驱动视频生成,则能实现流程的程序化控制。其技术原理在于将视频结构抽象为可编程的指令序列,通过解析命令生成标准化的工程文件。这种模式的核心价值在于将视频制作从手动操作转变为代码驱动,特别适合与AI编程助手集成,实现自然语言到视频草稿的自动转换。应用场景广泛覆盖社交媒体内容批量生产、教育视频自动化生成、数据可视化视频组装等领域。本文以cutcli工具为例,深入解析如何通过命令行与

weixin_42520239的博客 576

【EfficientNet Mydataset】EfficientNet训练自定义分类数据集

文章目录1 分类数据集准备2 获取训练与验证图片路径及标签3 Dataset类与DataLoader类的理解3.1 Dataset类3.2 DataLoader类3.3 Dataset与DataLoader综合使用简单示例4 Efficientnet介绍5 训练总体流程6 推理一张图片7 所有内容下载8 感谢链接 1 分类数据集准备 期待的分类数据集样式如下,注意,验证集需要知道图片类别。 data ├── train │ ├── class_name_1 │ │ ├── 1.jpg │ │

计算机视觉方面的点点滴滴,欢迎一起讨论 2169

Arduino ESP32S3开发环境搭建 ------ 在线下载安装包Failed解决方案

本文介绍了Arduino ESP32 S3开发环境搭建的离线解决方案。

张一西的博客 1018

SAP会计凭证导入ABAP开发模板+注意点—附带源码

开发并不仅仅只要考虑实现的功能,只实现功能的是程序,考虑到使用场景的是工程。使用bapi校验创建会计凭证的数据,报错和参数和正式创建一致。用途,防止产生错误的凭证,即使财务凭证可以冲销。正式创建会计凭证。隐藏的坑。

小九啥也不会 1232

构建 Darknet 分类器 (Tiny Darknet) 训练数据集 (front_rear recognition 车头车尾识别/front_rear classification 车头车尾分类)

构建 Darknet 分类器 (Tiny Darknet) 训练数据集 (front_rear recognition 车头车尾识别/front_rear classification 车头车尾分类) 1. vehicle_source_data_20181015_autoparts 2. parser # # Created by foreverstrong on 12/31/2018 # import os import cv2 # classification_classes = ["fron

程永强 2548

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

使用vgg16训练自己的数据集进行图像分类

使用VGG16网络训练自己的图片分类网络

qq_41319665的博客 1万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

用小数据集训练分类器

仍旧是照着书敲程序出现超多问题的一天 还好慢慢都解决了 用小数据集训练猫狗分类器 1.首先是在kaggle上面下载数据集 链接就不放了,书里都有的,下载过程会遇到麻烦就是手机收不到验证码,后来解决办法是在手机号前面加上860就可以完美解决,验证码好像还是从浙江发过来的感觉蛮神奇。 2.下载之后的路径和书里的路径什么的不太一样要自己改一改,不要书里写的什么就无脑的照着敲上去,额,也可能只有我这么干...

max119xlx的博客 1584

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

使用自己的数据集训练MobileNet、ResNet实现图像分类(TensorFlow)

使用自己的数据集训练MobileNet、ResNet实现图像分类(TensorFlow) 之前鄙人写了一篇博客《使用自己的数据集训练GoogLenet InceptionNet V1 V2 V3模型(TensorFlow)》https://panjinquan.blog.youkuaiyun.com/article/details/81560537,本博客就是此博客的框架基础上,完成对MobileNet的图...

AI吃大瓜的博客 4万+

Efficientnet_pytorch训练自己的数据集,并对数据进行分类

准备训练的数据集 由于我原本的数据集是没有经过任何处理的,格式如图所示: data文件夹对应的图像集的标签在training.csv文件夹中,如图所示: 而输入的图像文件却需要满足ImageFolder的格式: class ImageFolder(DatasetFolder): """A generic data loader where the images are arranged in this way: :: root/dog/xxx.png root/d

Whisper_lg的博客 1万+
上一篇: YOLOv11训练自己的数据集
下一篇: 【机器学习算法】——线性回归
chairon
博客等级 码龄7年 964粉丝 172原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值