add resnet
This commit is contained in:
parent
cbb64b4949
commit
21c1778a4a
1
.gitignore
vendored
1
.gitignore
vendored
@ -167,3 +167,4 @@ pnnx*
|
|||||||
|
|
||||||
# dataset cache
|
# dataset cache
|
||||||
*.cache
|
*.cache
|
||||||
|
.conda
|
||||||
|
17
test_yaml.py
17
test_yaml.py
@ -5,25 +5,14 @@ from ultralytics import YOLO
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
error_result = []
|
error_result = []
|
||||||
for yaml_path in tqdm.tqdm(os.listdir('ultralytics/cfg/models/v8')):
|
|
||||||
if 'rtdetr' not in yaml_path and 'cls' not in yaml_path and 'world' not in yaml_path:
|
|
||||||
try:
|
|
||||||
model = YOLO(f'ultralytics/cfg/models/v8/{yaml_path}')
|
|
||||||
model.info(detailed=True)
|
|
||||||
model.profile([640, 640])
|
|
||||||
model.fuse()
|
|
||||||
except Exception as e:
|
|
||||||
error_result.append(f'{yaml_path} {e}')
|
|
||||||
|
|
||||||
for yaml_path in tqdm.tqdm(os.listdir('ultralytics/cfg/models/v10')):
|
|
||||||
if 'rtdetr' not in yaml_path and 'cls' not in yaml_path and 'world' not in yaml_path:
|
|
||||||
try:
|
try:
|
||||||
model = YOLO(f'ultralytics/cfg/models/v10/{yaml_path}')
|
model = YOLO(f'ultralytics/cfg/models/mtl/yolov8-cls.yaml')
|
||||||
model.info(detailed=True)
|
model.info(detailed=True)
|
||||||
model.profile([640, 640])
|
model.profile([224, 224])
|
||||||
model.fuse()
|
model.fuse()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_result.append(f'{yaml_path} {e}')
|
print(e)
|
||||||
|
|
||||||
for i in error_result:
|
for i in error_result:
|
||||||
print(i)
|
print(i)
|
44
train.py
44
train.py
@ -5,50 +5,10 @@ import warnings, os
|
|||||||
warnings.filterwarnings('ignore')
|
warnings.filterwarnings('ignore')
|
||||||
from ultralytics import YOLO
|
from ultralytics import YOLO
|
||||||
|
|
||||||
# BILIBILI UP 魔傀面具
|
|
||||||
# 训练参数官方详解链接:https://docs.ultralytics.com/modes/train/#resuming-interrupted-trainings:~:text=a%20training%20run.-,Train%20Settings,-The%20training%20settings
|
|
||||||
|
|
||||||
# 指定显卡和多卡训练问题 统一都在<YOLOV8V10配置文件.md>下方常见错误和解决方案。
|
|
||||||
# 训练过程中loss出现nan,可以尝试关闭AMP,就是把下方amp=False的注释去掉。
|
|
||||||
# 训练时候输出的AMP Check使用的YOLOv8n的权重不是代表载入了预训练权重的意思,只是用于测试AMP,正常的不需要理会。
|
|
||||||
# 整合多个创新点的B站视频链接:https://www.bilibili.com/video/BV15H4y1Y7a2/
|
|
||||||
# 更多问题解答请看使用说明.md下方<常见疑问>
|
|
||||||
|
|
||||||
# YOLOV8源码常见疑问解答小课堂
|
|
||||||
# 1. [关于配置文件中Optimizer参数为auto的时候,究竟Optimizer会怎么选用呢?](https://www.bilibili.com/video/BV1K34y1w7cZ/)
|
|
||||||
# 2. [best.pt究竟是根据什么指标来保存的?](https://www.bilibili.com/video/BV1jN411M7MA/)
|
|
||||||
# 3. [数据增强在yolov8中的应用](https://www.bilibili.com/video/BV1aQ4y1g7ah/)
|
|
||||||
# 4. [如何添加FPS计算代码和FPS的相关的一些疑问](https://www.bilibili.com/video/BV1Sw411g7DD/)
|
|
||||||
# 5. [预测框粗细颜色修改与精度小数位修改](https://www.bilibili.com/video/BV12K421a7rH/)
|
|
||||||
# 6. [导出改进/剪枝的onnx模型和讲解onnx-opset和onnxsim的作用](https://www.bilibili.com/video/BV1CK421e7Y3/)
|
|
||||||
# 7. [YOLOV8模型详细讲解(包含该如何改进YOLOV8)(刚入门小白,需要改进YOLOV8的同学必看!)](https://www.bilibili.com/video/BV1Ms421u7VH/)
|
|
||||||
# 8. [学习率变化问题](https://www.bilibili.com/video/BV1frnferEL1/)
|
|
||||||
|
|
||||||
# 一些非常推荐小白看的视频链接
|
|
||||||
# 1. [YOLOV8模型详细讲解(包含该如何改进YOLOV8)(刚入门小白,需要改进YOLOV8的同学必看!)](https://www.bilibili.com/video/BV1Ms421u7VH/)
|
|
||||||
# 2. [提升多少才能发paper?轻量化需要看什么指标?需要轻量化到什么程度才能发paper?这期给大家一一解答!](https://www.bilibili.com/video/BV1QZ421M7gu/)
|
|
||||||
# 3. [深度学习实验部分常见疑问解答!(小白刚入门必看!少走弯路!少自我内耗!)](https://www.bilibili.com/video/BV1Bz421B7pC/)
|
|
||||||
# ```
|
|
||||||
# 1. 如何衡量自己的所做的工作量够不够?
|
|
||||||
# 2. 为什么别人的论文说这个模块对xxx有作用,但是我自己用的时候还掉点了?
|
|
||||||
# 3. 提升是和什么模型相比呢 比如和yolov8这种基础模型比还是和别人提出的目前最好的模型比
|
|
||||||
# 4. 对比不同的模型的时候,输入尺寸,学习率,学习次数这些是否需要一致?
|
|
||||||
# ```
|
|
||||||
# 4. [深度学习实验部分常见疑问解答二!(小白刚入门必看!少走弯路!少自我内耗!)](https://www.bilibili.com/video/BV1ZM4m1m785/)
|
|
||||||
# ```
|
|
||||||
# 1. 为什么我用yolov8自带的coco8、coco128训练出来的效果很差?
|
|
||||||
# 2. 我的数据集很大,机器跑得慢,我是否可以用数据集的百分之10的数据去测试这个改进点是否有效?有效再跑整个数据集?
|
|
||||||
# ```
|
|
||||||
# 5. [深度学习实验部分常见疑问解答三!(怎么判断模型是否收敛?模型过拟合怎么办?)](https://www.bilibili.com/video/BV11S421d76P/)
|
|
||||||
# 6. [YOLO系列模型训练结果详细解答!(训练过程的一些疑问,该放哪个文件运行出来的结果、参数量计算量在哪里看..等等问题)](https://www.bilibili.com/video/BV11b421J7Vx/)
|
|
||||||
# 7. [深度学习论文实验中新手非常容易陷入的一个误区:抱着解决xxx问题的心态去做实验](https://www.bilibili.com/video/BV1kkkvYJEHG/)
|
|
||||||
# 8. [深度学习实验准备-数据集怎么选?有哪些需要注意的点?](https://www.bilibili.com/video/BV11zySYvEhs/)
|
|
||||||
# 9. [深度学习炼丹必备必看必须知道的小技巧!](https://www.bilibili.com/video/BV1q3SZYsExc/)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
model = YOLO('ultralytics/cfg/models/v8/yolov8n.yaml')
|
model = YOLO('ultralytics/cfg/models/v8/yolov8n-cls.yaml')
|
||||||
# model.load('yolov8n.pt') # loading pretrain weights
|
# model.load('yolov8n.pt') # loading pretrain weights
|
||||||
model.train(data='/root/code/dataset/dataset_visdrone/data.yaml',
|
model.train(data='G:/skin-cancer-detection',
|
||||||
cache=False,
|
cache=False,
|
||||||
imgsz=640,
|
imgsz=640,
|
||||||
epochs=300,
|
epochs=300,
|
||||||
|
14
ultralytics/cfg/models/mtl/yolov8-cls.yaml
Normal file
14
ultralytics/cfg/models/mtl/yolov8-cls.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
||||||
|
# YOLOv8-cls image classification model. For Usage examples see https://docs.ultralytics.com/tasks/classify
|
||||||
|
|
||||||
|
# Parameters
|
||||||
|
nc: 38 # number of classes
|
||||||
|
|
||||||
|
# YOLOv8.0n backbone
|
||||||
|
backbone:
|
||||||
|
# [from, repeats, module, args]
|
||||||
|
- [-1, 1, ResNet18, []] # 0-P1/2
|
||||||
|
|
||||||
|
# YOLOv8.0n head
|
||||||
|
head:
|
||||||
|
- [-1, 1, Classify, [nc]] # Classify
|
182
ultralytics/nn/backbone/resnet.py
Normal file
182
ultralytics/nn/backbone/resnet.py
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
import torch
|
||||||
|
import torch.nn as nn
|
||||||
|
import torch.nn.functional as F
|
||||||
|
|
||||||
|
__all__ = [ 'ResNet18','ResNet34','ResNet50']
|
||||||
|
|
||||||
|
'''-------------一、BasicBlock模块-----------------------------'''
|
||||||
|
# 用于ResNet18和ResNet34基本残差结构块
|
||||||
|
class BasicBlock(nn.Module):
|
||||||
|
def __init__(self, inchannel, outchannel, stride=1):
|
||||||
|
super(BasicBlock, self).__init__()
|
||||||
|
self.left = nn.Sequential(
|
||||||
|
nn.Conv2d(inchannel, outchannel, kernel_size=3, stride=stride, padding=1, bias=False),
|
||||||
|
nn.BatchNorm2d(outchannel),
|
||||||
|
nn.ReLU(inplace=True), #inplace=True表示进行原地操作,一般默认为False,表示新建一个变量存储操作
|
||||||
|
nn.Conv2d(outchannel, outchannel, kernel_size=3, stride=1, padding=1, bias=False),
|
||||||
|
nn.BatchNorm2d(outchannel)
|
||||||
|
)
|
||||||
|
self.shortcut = nn.Sequential()
|
||||||
|
#论文中模型架构的虚线部分,需要下采样
|
||||||
|
if stride != 1 or inchannel != outchannel:
|
||||||
|
self.shortcut = nn.Sequential(
|
||||||
|
nn.Conv2d(inchannel, outchannel, kernel_size=1, stride=stride, bias=False),
|
||||||
|
nn.BatchNorm2d(outchannel)
|
||||||
|
)
|
||||||
|
|
||||||
|
def forward(self, x):
|
||||||
|
out = self.left(x) #这是由于残差块需要保留原始输入
|
||||||
|
out += self.shortcut(x)#这是ResNet的核心,在输出上叠加了输入x
|
||||||
|
out = F.relu(out)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
'''-------------二、Bottleneck模块-----------------------------'''
|
||||||
|
# 用于ResNet50及以上的残差结构块
|
||||||
|
class Bottleneck(nn.Module):
|
||||||
|
def __init__(self, inchannel, outchannel, stride=1):
|
||||||
|
super(Bottleneck, self).__init__()
|
||||||
|
self.left = nn.Sequential(
|
||||||
|
nn.Conv2d(inchannel, int(outchannel / 4), kernel_size=1, stride=stride, padding=0, bias=False),
|
||||||
|
nn.BatchNorm2d(int(outchannel / 4)),
|
||||||
|
nn.ReLU(inplace=True),
|
||||||
|
nn.Conv2d(int(outchannel / 4), int(outchannel / 4), kernel_size=3, stride=1, padding=1, bias=False),
|
||||||
|
nn.BatchNorm2d(int(outchannel / 4)),
|
||||||
|
nn.ReLU(inplace=True),
|
||||||
|
nn.Conv2d(int(outchannel / 4), outchannel, kernel_size=1, stride=1, padding=0, bias=False),
|
||||||
|
nn.BatchNorm2d(outchannel),
|
||||||
|
)
|
||||||
|
self.shortcut = nn.Sequential()
|
||||||
|
if stride != 1 or inchannel != outchannel:
|
||||||
|
self.shortcut = nn.Sequential(
|
||||||
|
nn.Conv2d(inchannel, outchannel, kernel_size=1, stride=stride, bias=False),
|
||||||
|
nn.BatchNorm2d(outchannel)
|
||||||
|
)
|
||||||
|
|
||||||
|
def forward(self, x):
|
||||||
|
out = self.left(x)
|
||||||
|
y = self.shortcut(x)
|
||||||
|
out += self.shortcut(x)
|
||||||
|
out = F.relu(out)
|
||||||
|
return out
|
||||||
|
|
||||||
|
'''-------------ResNet18---------------'''
|
||||||
|
class ResNet_18(nn.Module):
|
||||||
|
def __init__(self, ResidualBlock, num_classes=10):
|
||||||
|
super(ResNet_18, self).__init__()
|
||||||
|
self.inchannel = 64
|
||||||
|
self.conv1 = nn.Sequential(
|
||||||
|
nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False),
|
||||||
|
nn.BatchNorm2d(64),
|
||||||
|
nn.ReLU(),
|
||||||
|
)
|
||||||
|
self.layer1 = self.make_layer(ResidualBlock, 64, 2, stride=1)
|
||||||
|
self.layer2 = self.make_layer(ResidualBlock, 128, 2, stride=2)
|
||||||
|
self.layer3 = self.make_layer(ResidualBlock, 256, 2, stride=2)
|
||||||
|
self.layer4 = self.make_layer(ResidualBlock, 512, 2, stride=2)
|
||||||
|
self.channel = [i.size(1) for i in self.forward(torch.randn(1, 3, 224, 224))]
|
||||||
|
|
||||||
|
def make_layer(self, block, channels, num_blocks, stride):
|
||||||
|
strides = [stride] + [1] * (num_blocks - 1) # strides=[1,1]
|
||||||
|
layers = []
|
||||||
|
for stride in strides:
|
||||||
|
layers.append(block(self.inchannel, channels, stride))
|
||||||
|
self.inchannel = channels
|
||||||
|
return nn.Sequential(*layers)
|
||||||
|
|
||||||
|
def forward(self, x): # 3*32*32
|
||||||
|
out = self.conv1(x) # 64*32*32
|
||||||
|
out = self.layer1(out) # 64*32*32
|
||||||
|
out = self.layer2(out) # 128*16*16
|
||||||
|
out = self.layer3(out) # 256*8*8
|
||||||
|
out = self.layer4(out) # 512*4*4
|
||||||
|
out = F.avg_pool2d(out, 4) # 512*1*1
|
||||||
|
return out
|
||||||
|
|
||||||
|
'''-------------ResNet34---------------'''
|
||||||
|
class ResNet_34(nn.Module):
|
||||||
|
def __init__(self, ResidualBlock, num_classes=10):
|
||||||
|
super(ResNet_34, self).__init__()
|
||||||
|
self.inchannel = 64
|
||||||
|
self.conv1 = nn.Sequential(
|
||||||
|
nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False),
|
||||||
|
nn.BatchNorm2d(64),
|
||||||
|
nn.ReLU(),
|
||||||
|
)
|
||||||
|
self.layer1 = self.make_layer(ResidualBlock, 64, 3, stride=1)
|
||||||
|
self.layer2 = self.make_layer(ResidualBlock, 128, 4, stride=2)
|
||||||
|
self.layer3 = self.make_layer(ResidualBlock, 256, 6, stride=2)
|
||||||
|
self.layer4 = self.make_layer(ResidualBlock, 512, 3, stride=2)
|
||||||
|
self.channel = [i.size(1) for i in self.forward(torch.randn(1, 3, 224, 224))]
|
||||||
|
|
||||||
|
def make_layer(self, block, channels, num_blocks, stride):
|
||||||
|
strides = [stride] + [1] * (num_blocks - 1) # strides=[1,1]
|
||||||
|
layers = []
|
||||||
|
for stride in strides:
|
||||||
|
layers.append(block(self.inchannel, channels, stride))
|
||||||
|
self.inchannel = channels
|
||||||
|
return nn.Sequential(*layers)
|
||||||
|
|
||||||
|
def forward(self, x): # 3*32*32
|
||||||
|
out = self.conv1(x) # 64*32*32
|
||||||
|
out = self.layer1(out) # 64*32*32
|
||||||
|
out = self.layer2(out) # 128*16*16
|
||||||
|
out = self.layer3(out) # 256*8*8
|
||||||
|
out = self.layer4(out) # 512*4*4
|
||||||
|
out = F.avg_pool2d(out, 4) # 512*1*1
|
||||||
|
out = out.view(out.size(0), -1) # 512
|
||||||
|
return out
|
||||||
|
|
||||||
|
'''-------------ResNet50---------------'''
|
||||||
|
class ResNet_50(nn.Module):
|
||||||
|
def __init__(self, ResidualBlock, num_classes=10):
|
||||||
|
super(ResNet_50, self).__init__()
|
||||||
|
self.inchannel = 64
|
||||||
|
self.conv1 = nn.Sequential(
|
||||||
|
nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False),
|
||||||
|
nn.BatchNorm2d(64),
|
||||||
|
nn.ReLU(),
|
||||||
|
)
|
||||||
|
self.layer1 = self.make_layer(ResidualBlock, 256, 3, stride=1)
|
||||||
|
self.layer2 = self.make_layer(ResidualBlock, 512, 4, stride=2)
|
||||||
|
self.layer3 = self.make_layer(ResidualBlock, 1024, 6, stride=2)
|
||||||
|
self.layer4 = self.make_layer(ResidualBlock, 2048, 3, stride=2)
|
||||||
|
self.channel = [i.size(1) for i in self.forward(torch.randn(1, 3, 224, 224))]
|
||||||
|
# **************************
|
||||||
|
|
||||||
|
def make_layer(self, block, channels, num_blocks, stride):
|
||||||
|
strides = [stride] + [1] * (num_blocks - 1) # strides=[1,1]
|
||||||
|
layers = []
|
||||||
|
for stride in strides:
|
||||||
|
layers.append(block(self.inchannel, channels, stride))
|
||||||
|
self.inchannel = channels
|
||||||
|
return nn.Sequential(*layers)
|
||||||
|
|
||||||
|
def forward(self, x): # 3*32*32
|
||||||
|
out = self.conv1(x) # 64*32*32
|
||||||
|
out = self.layer1(out) # 64*32*32
|
||||||
|
out = self.layer2(out) # 128*16*16
|
||||||
|
out = self.layer3(out) # 256*8*8
|
||||||
|
out = self.layer4(out) # 512*4*4
|
||||||
|
out = F.avg_pool2d(out, 4) # 512*1*1
|
||||||
|
# print(out.size())
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def ResNet18():
|
||||||
|
return ResNet_18(BasicBlock)
|
||||||
|
|
||||||
|
|
||||||
|
def ResNet34():
|
||||||
|
return ResNet_34(BasicBlock)
|
||||||
|
|
||||||
|
|
||||||
|
def ResNet50():
|
||||||
|
return ResNet_50(Bottleneck)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
model = ResNet18()
|
||||||
|
inputs = torch.randn((1, 3, 224, 224))
|
||||||
|
res = model(inputs)
|
||||||
|
for i in res:
|
||||||
|
print(i.size())
|
@ -93,6 +93,7 @@ from ultralytics.nn.backbone.revcol import *
|
|||||||
from ultralytics.nn.backbone.lsknet import *
|
from ultralytics.nn.backbone.lsknet import *
|
||||||
from ultralytics.nn.backbone.SwinTransformer import *
|
from ultralytics.nn.backbone.SwinTransformer import *
|
||||||
from ultralytics.nn.backbone.repvit import *
|
from ultralytics.nn.backbone.repvit import *
|
||||||
|
from ultralytics.nn.backbone.resnet import *
|
||||||
from ultralytics.nn.backbone.CSwomTramsformer import *
|
from ultralytics.nn.backbone.CSwomTramsformer import *
|
||||||
from ultralytics.nn.backbone.UniRepLKNet import *
|
from ultralytics.nn.backbone.UniRepLKNet import *
|
||||||
from ultralytics.nn.backbone.TransNext import *
|
from ultralytics.nn.backbone.TransNext import *
|
||||||
@ -871,7 +872,7 @@ def torch_safe_load(weight):
|
|||||||
"ultralytics.nn.tasks.YOLOv10DetectionModel": "ultralytics.nn.tasks.DetectionModel", # YOLOv10
|
"ultralytics.nn.tasks.YOLOv10DetectionModel": "ultralytics.nn.tasks.DetectionModel", # YOLOv10
|
||||||
},
|
},
|
||||||
):
|
):
|
||||||
ckpt = torch.load(file, map_location="cpu")
|
ckpt = torch.load(file, map_location="cpu",weights_only=False)
|
||||||
|
|
||||||
except ModuleNotFoundError as e: # e.name is missing module name
|
except ModuleNotFoundError as e: # e.name is missing module name
|
||||||
if e.name == "models":
|
if e.name == "models":
|
||||||
@ -1150,7 +1151,8 @@ def parse_model(d, ch, verbose=True, warehouse_manager=None): # model_dict, inp
|
|||||||
RMT_T, RMT_S, RMT_B, RMT_L,
|
RMT_T, RMT_S, RMT_B, RMT_L,
|
||||||
PKINET_T, PKINET_S, PKINET_B,
|
PKINET_T, PKINET_S, PKINET_B,
|
||||||
MobileNetV4ConvSmall, MobileNetV4ConvMedium, MobileNetV4ConvLarge, MobileNetV4HybridMedium, MobileNetV4HybridLarge,
|
MobileNetV4ConvSmall, MobileNetV4ConvMedium, MobileNetV4ConvLarge, MobileNetV4HybridMedium, MobileNetV4HybridLarge,
|
||||||
starnet_s050, starnet_s100, starnet_s150, starnet_s1, starnet_s2, starnet_s3, starnet_s4
|
starnet_s050, starnet_s100, starnet_s150, starnet_s1, starnet_s2, starnet_s3, starnet_s4,
|
||||||
|
ResNet18,ResNet34,ResNet50,
|
||||||
}:
|
}:
|
||||||
if m is RevCol:
|
if m is RevCol:
|
||||||
args[1] = [make_divisible(min(k, max_channels) * width, 8) for k in args[1]]
|
args[1] = [make_divisible(min(k, max_channels) * width, 8) for k in args[1]]
|
||||||
|
Loading…
Reference in New Issue
Block a user