SSD训练数据集流程(学习记录)
關于理論部分我看的是b站“霹靂吧啦Wz”的SSD理論講解,作為入門小白表示能聽懂,需要的同學可以自行觀看
目錄
1.訓練環境
2.訓練步驟
1.訓練環境
我的環境是win11+anaconda+python3.6.13+pytorch1.10.2+cuda11.6
2.訓練步驟
(1)下載SSD源碼
可到github進行下載
GitHub - amdegroot/ssd.pytorch: A PyTorch Implementation of Single Shot MultiBox Detector
(2)下載模型文件
VGG16_reducedfc.pth預訓練模型下載地址:https://s3.amazonaws.com/amdegroot-models/vgg16_reducedfc.pth
將下載的模型文件放置于ssd源碼目錄中? wights/vgg16_reducedfc.pth
(3)數據集準備
與大多數訓練模型一樣,ssd支持的訓練格式為VOC和coco,這里采用voc2007作為演示,制作自己的數據集以及labimg的使用可自行觀看yolo數據集標注軟件安裝+使用流程_道人兄的博客-CSDN博客_yolo數據集標注工具
voc2007的具體下載方式我也不多贅述,網絡上百度也有,或者直接看我之前寫的也有提到使用Faster—RCNN訓練數據集流程(學習記錄)_道人兄的博客-CSDN博客
將下載后的voc2007數據集放置于./data/VOCdevkit/中
?然后到ssd.pytorch-master/data/中的voc0712.py進行修改其中的VOC_ROOT = osp.join(HOME, "data/VOCdevkit/"),他這里的HOME老是讀取我的C盤位置,所以一直報錯,我直接把數據集的絕對路徑寫上去了就沒報錯
將?voc0712.py文件中VOCDetection類的__init__函數,將image_sets修改為[('2007', 'train'), ('2007', 'val'),('2007','test')],修改后的結果如下。
def __init__(self, root,image_sets=[('2007', 'train'), ('2007', 'val'),('2007','test')],transform=None, target_transform=VOCAnnotationTransform(),dataset_name='VOC0712'):其中如果是訓練自己的數據集,記得修改voc0712.py文件中的VOC_CLASSES?變量。例如,將VOC_CLASSES修改為person類,注意如果只有一類則需要加方括號,修改后的結果如下。
VOC_CLASSES = [('person')如果訓練自己的數據集,還需要修改config.py文件中的voc字典變量。將其中的num_classes修改為2(以person為例)(背景類+你訓練集的種類個數),第一次調試時可以將max_iter調小至1000,修改后的結果如下。
voc = {'num_classes': 2,'lr_steps': (80000, 100000, 120000),'max_iter': 1000,'feature_maps': [38, 19, 10, 5, 3, 1],'min_dim': 300,'steps': [8, 16, 32, 64, 100, 300],'min_sizes': [30, 60, 111, 162, 213, 264],'max_sizes': [60, 111, 162, 213, 264, 315],'aspect_ratios': [[2], [2, 3], [2, 3], [2, 3], [2], [2]],'variance': [0.1, 0.2],'clip': True,'name': 'VOC', }最后一步,把coco_labels.txt放在ssd.pytorch-master/data/coco/目錄下,也可以通過修改coco.py文件中的COCO_ROOT = osp.join(HOME, 'data/coco/')來指定存放路徑。
(4)修改源碼
①修改ssd.py文件中SSD類的__init__函數和forward函數,修改后的結果如下。
if phase == 'test':self.softmax = nn.Softmax(dim=-1)self.detect = Detect(num_classes, 0, 200, 0.01, 0.45) 修改為: if phase == 'test':self.softmax = nn.Softmax()self.detect = Detect() if self.phase == "test":output = self.detect(loc.view(loc.size(0), -1, 4), # loc predsself.softmax(conf.view(conf.size(0), -1,self.num_classes)), # conf predsself.priors.type(type(x.data)) # default boxes) 修改為: if self.phase == "test":output = self.detect.apply(21, 0, 200, 0.01, 0.45,loc.view(loc.size(0), -1, 4), # loc predsself.softmax(conf.view(-1,21)), # conf predsself.priors.type(type(x.data)) # default boxes)②修改train.py中187至189行代碼,原因是.data[0]寫法適用于低版本Pytorch,否則會出現IndexError:invalid index of a 0-dim tensor...錯誤,修改后的結果如下。
loc_loss += loss_l.item() conf_loss += loss_c.item()if iteration % 10 == 0:print('timer: %.4f sec.' % (t1 - t0))print('iter ' + repr(iteration) + ' || Loss: %.4f ||' % (loss.item()), end=' ')③交換layers/modules/multibox_loss.py中97行和98代碼位置,否則會出現IndexError: The shape of the mask [14, 8732] at index 0does...錯誤,修改后的結果如下。
loss_c = loss_c.view(num, -1) loss_c[pos] = 0 # filter out pos boxes for now④根據自己的需要對train.py中預訓練模型、batch_size、學習率、模型名字和模型保存的次數等參數進行修改。建議學習率修改為1e-4(原因是原版使用1e-3可能會出現loss為nan情況),第一次調試時可以修改為每迭代100次保存,方便調試。
# 加載模型初始參數 parser = argparse.ArgumentParser(description='Single Shot MultiBox Detector Training With Pytorch') train_set = parser.add_mutually_exclusive_group() # 默認加載VOC數據集 parser.add_argument('--dataset', default='VOC', choices=['VOC', 'COCO'],type=str, help='VOC or COCO') # 設置VOC數據集根路徑 parser.add_argument('--dataset_root', default=VOC_ROOT,help='Dataset root directory path') # 設置預訓練模型vgg16_reducedfc.pth parser.add_argument('--basenet', default='vgg16_reducedfc.pth',help='Pretrained base model') # 設置批大小,根據自己顯卡能力設置,默認為32,此處我改為16 parser.add_argument('--batch_size', default=16, type=int,help='Batch size for training') # 是否恢復中斷的訓練,默認不恢復 parser.add_argument('--resume', default=None, type=str,help='Checkpoint state_dict file to resume training from') # 恢復訓練iter數,默認從第0次迭代開始 parser.add_argument('--start_iter', default=0, type=int,help='Resume training at this iter') # 數據加載線程數,根據自己CPU個數設置,默認為4 parser.add_argument('--num_workers', default=4, type=int,help='Number of workers used in dataloading') # 是否使用CUDA加速訓練,默認開啟,如果沒有GPU,可改成False直接用CPU訓練 parser.add_argument('--cuda', default=True, type=str2bool,help='Use CUDA to train model') # 學習率,默認0.001 parser.add_argument('--lr', '--learning-rate', default=1e-3, type=float,help='initial learning rate') # 最佳動量值,默認0.9(動量是梯度下降法中一種常用的加速技術,用于加速梯度下降,減少收斂耗時) parser.add_argument('--momentum', default=0.9, type=float,help='Momentum value for optim') # 權重衰減,即正則化項前面的系數,用于防止過擬合;SGD,即mini-batch梯度下降 parser.add_argument('--weight_decay', default=1e-4, type=float,help='Weight decay for SGD') # gamma更新,默認值0.1 parser.add_argument('--gamma', default=0.1, type=float,help='Gamma update for SGD') # 使用visdom將訓練過程loss圖像可視化 parser.add_argument('--visdom', default=False, type=str2bool,help='Use visdom for loss visualization') # 權重保存位置,默認存在weights/下 parser.add_argument('--save_folder', default='weights/',help='Directory for saving checkpoint models') args = parser.parse_args() if iteration != 0 and iteration % 100 == 0:print('Saving state, iter:', iteration)torch.save(ssd_net.state_dict(), 'weights/ssd300_VOC_' + repr(iteration) + '.pth')⑤因為pytorch1.9以上版本在這份源代碼中并不適用,一旦運行cuda方面會報錯如下:
RuntimeError: Expected a ‘cuda‘ device type for generator but found ‘cpu‘參考github上的解決方法,有兩種方法可成功運行:
第一種是重裝pytorch1.8版本,就可以正常運行,但我覺得太麻煩了
第二種是修改源碼:
在位于 anaconda 或任何地方的文件“site-packages/torch/utils/data/sampler.py”中。
[修改第 116 行]:generator = torch.Generator() 改成generator = torch.Generator(device='cuda') [修改第 126 行]:yield from torch.randperm(n, generator=generator).tolist() 改成yield from torch.randperm(n, generator=generator, device='cuda').tolist()在train.py文件中,data.DataLoader處進行添加generator
data_loader = data.DataLoader(dataset, args.batch_size,num_workers=args.num_workers,shuffle=True, collate_fn=detection_collate,pin_memory=True, generator=torch.Generator(device='cuda'))(5)運行train.py,如下圖
參考資料:
SSD訓練自己的數據集(pytorch版)_Kellenn的博客-CSDN博客_ssd訓練自己的數據集pytorch
【目標檢測實戰】Pytorch—SSD模型訓練(VOC數據集) - 知乎 (zhihu.com)
2.1SSD算法理論_嗶哩嗶哩_bilibili
總結
以上是生活随笔為你收集整理的SSD训练数据集流程(学习记录)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html语言语法骨架格式,0002 认识
- 下一篇: 【Unity Shader】Specia