yolo5_train.py
- Pytorch中named_children()和named_modules()的区别:
named_children( ):返回包含子模块的迭代器,同时产生模块的名称及模块本身
named_modules( ):返回网络中所有模块的所有迭代器
例如:
import torch
import torch.nn as nn
class TestModule(nn.Module):
def __init__(self):
super(TestModule,self).__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(16,32,3,1),
nn.ReLU(inplace=True)
)
self.layer2 = nn.Sequential(
nn.Linear(32,10)
)
def forward(self,x):
x = self.layer1(x)
x = self.layer2(x)
model = TestModule()
for name, module in model.named_children():
print('children module:', name)
for name, module in model.named_modules():
print('modules:', name)
>>out:
children module: layer1
children module: layer2
modules:
modules: layer1
modules: layer1.0
modules: layer1.1
modules: layer2
modules: layer2.0
if hasattr(v, 'bias') and isinstance(v.bias, nn.Parameter):
pg2.append(v.bias) # biases
hasattr(对象,属性):判断对象是否包含属性;
isinstance(对象, 已知类型):判断对象是否是已知类型;
list.append(object):将object添加到列表队尾
3.round():返回浮点数的四舍五入值;
4.
# parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')
#添加default=‘True’,开启adam优化,否则为SGD优化
parser.add_argument('--adam', default='True', action='store_true', help='use torch.optim.Adam() optimizer')
action = ‘store_true’ ->默认为True
# test.py
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("--test_action", action='store_true')
args = parser.parse_args()
action_val = args.test_action
print(action_val)
5.
parser = argparse.ArgumentParser()
parser.add_argument('--weights', type=str, default='weights/yolov5x.pt', help='initial weights path')
/*...省略....*/
parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')
opt = parser.parse_args()
parse_args()模块解析:https://blog.csdn.net/yy_diego/article/details/82851661
1.import argparse
2.建立解析对象:parser = argparse.ArgumentParser()
3.增加属性:parser.add_argument('--x',....)
4.属性给与args实例,把parser中设置的所有add_argument返回到args子类实例中,那么parser中增加的属性内容都会在args实例中,使用即可;
5.属性前添加--为可选参数;
#设置cosine调度器,定义学习率衰减
lf = lambda x: ((1 + math.cos(x * math.pi / epochs)) / 2) * (1 - hyp['lrf']) + hyp['lrf'] # cosine
scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lf)
lambda:匿名函数,即函数没有具体名称,可以使程序更加精简;
7.pytorch中学习率调整的方法:
#设置cosine调度器,定义学习率衰减
lf = lambda x: ((1 + math.cos(x * math.pi / epochs)) / 2) * (1 - hyp['lrf']) + hyp['lrf'] # cosine
scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lf)
主要两种调整方法:
一、直接修改optimizer中的lr学习率的值;
model = net()
LR = 0.01
optimizer = Adam(model.parameters(),lr = LR)
lr_list = []
for epoch in range(100):
if epoch % 5 == 0:
for p in optimizer.param_groups:
p['lr'] *= 0.9
lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(100),lr_list,color = 'r')
二、利用lr_scheduler()提供的几种方法自动调整;
主要有:
1.torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1):lr_lambda 会接收到一个int参数:epoch,然后根据epoch计算出对应的lr。如果设置多个lambda函数的话,会分别作用于Optimizer中的不同的params_group
import numpy as np
lr_list = []
model = net()
LR = 0.01
optimizer = Adam(model.parameters(),lr = LR)
lambda1 = lambda epoch:np.sin(epoch) / epoch
scheduler = lr_scheduler.LambdaLR(optimizer,lr_lambda = lambda1)
for epoch in range(100):
scheduler.step()
lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(100),lr_list,color = 'r')
2.torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1):每个一定的epoch,lr会自动乘以gamma
lr_list = []
model = net()
LR = 0.01
optimizer = Adam(model.parameters(),lr = LR)
scheduler = lr_scheduler.StepLR(optimizer,step_size=5,gamma = 0.8)
for epoch in range(100):
scheduler.step()
lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(100),lr_list,color = 'r')
3.torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=-1):三段式lr,epoch进入milestones范围内即乘以gamma,离开milestones范围之后再乘以gamma这种衰减方式也是在学术论文中最常见的方式,一般手动调整也会采用这种方法。
lr_list = []
model = net()
LR = 0.01
optimizer = Adam(model.parameters(),lr = LR)
scheduler = lr_scheduler.MultiStepLR(optimizer,milestones=[20,80],gamma = 0.9)
for epoch in range(100):
scheduler.step()
lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(100),lr_list,color = 'r')
4.torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma, last_epoch=-1):每个epoch中lr都乘以gamma
lr_list = []
model = net()
LR = 0.01
optimizer = Adam(model.parameters(),lr = LR)
scheduler = lr_scheduler.ExponentialLR(optimizer, gamma=0.9)
for epoch in range(100):
scheduler.step()
lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(100),lr_list,color = 'r')
5.torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0, last_epoch=-1):T_max 对应1/2个cos周期所对应的epoch数值
eta_min 为最小的lr值,默认为0
lr_list = []
model = net()
LR = 0.01
optimizer = Adam(model.parameters(),lr = LR)
scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max = 20)
for epoch in range(100):
scheduler.step()
lr_list.append(optimizer.state_dict()['param_groups'][0]['lr'])
plt.plot(range(100),lr_list,color = 'r')
6.torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode=‘min’, factor=0.1, patience=10, verbose=False, threshold=0.0001, threshold_mode=‘rel’, cooldown=0, min_lr=0, eps=1e-08):
在发现loss不再降低或者acc不再提高之后,降低学习率。各参数意义如下:
mode:'min’模式检测metric是否不再减小,'max’模式检测metric是否不再增大;
factor: 触发条件后lr*=factor;
patience:不再减小(或增大)的累计次数;
verbose:触发条件后print;
threshold:只关注超过阈值的显著变化;
threshold_mode:有rel和abs两种阈值计算模式,rel规则:max模式下如果超过best(1+threshold)为显著,min模式下如果低于best(1-threshold)为显著;abs规则:max模式下如果超过best+threshold为显著,min模式下如果低于best-threshold为显著;
cooldown:触发一次条件后,等待一定epoch再进行检测,避免lr下降过速;
min_lr:最小的允许lr;
eps:如果新旧lr之间的差异小与1e-8,则忽略此次更新。
-------------
# 加载预训练模型和权重,并写入训练结果到results.txt
if wandb and wandb.run is None:
id = ckpt.get('wandb_id') if 'ckpt' in locals() else None
wandb_run = wandb.init(config=opt, resume="allow", project="YOLOv5", name=log_dir.stem, id=id)
yolov5更新了wandb,可实时可视化训练过程,需要配置。
------
pretrained = weights.endswith('.pt') # endswitch判断是否以.pt结尾,是则返回true
endswith()判断是否以…结尾,是则返回True,因此有if pretrained:为True,即以加入预训练;
locals()函数返回所有局部变量
例如:c = torch.tensor(labels[:, 0]) # classes
x[:,n]表示在全部数组(维)中取第n个数据,直观来说,x[:,n]就是取所有集合的第n个数据:
maps = np.zeros(nc) # mAP per class
IMG_PATH = os.path.join(os.getcwd(), 'input', 'images-optional')
``fppi_tmp = np.insert(fppi, 0, -1.0)
np.insert(arr, obj, values, axis)
#arr原始数组,可一可多,obj插入元素位置,values是插入内容,axis是按行按列插入。
ref = np.logspace(-2.0, 0.0, num = 9)
np.logspace() 对数等比数列–常用参数及示例
np.logspace(start=开始值,stop=结束值,num=元素个数,base=指定对数的底, endpoint=是否包含结束值)
plt.barh(range(n_classes), sorted_values, color=plot_color)
# 绘图 x x轴, height 高度, 默认:color="blue", width=0.2 线条的宽度 默认0.8 p1 = plt.bar(x, height=y, width=0.5)
gt_classes = sorted(gt_classes)
gt_classes = list(gt_counter_per_class.keys())
list() 方法用于将元组转换为列表。
注:元组与列表是非常类似的,区别在于元组的元素值不能修改,元组是放在括号中,列表是放于方括号中。
file_id = os.path.basename(os.path.normpath(file_id))