先看结果:第一层输入通道数已变成 1。
from n params module arguments
0 -1 1 176 ultralytics.nn.modules.conv.Conv [1, 16, 3, 2]
1 -1 1 4672 ultralytics.nn.modules.conv.Conv [16, 32, 3, 2]
2 -1 1 7360 ultralytics.nn.modules.block.C2f [32, 32, 1, True]
3 -1 1 18560 ultralytics.nn.modules.conv.Conv [32, 64, 3, 2]
4 -1 2 49664 ultralytics.nn.modules.block.C2f [64, 64, 2, True]
5 -1 1 73984 ultralytics.nn.modules.conv.Conv [64, 128, 3, 2]
6 -1 2 197632 ultralytics.nn.modules.block.C2f [128, 128, 2, True]
7 -1 1 295424 ultralytics.nn.modules.conv.Conv [128, 256, 3, 2]
8 -1 1 460288 ultralytics.nn.modules.block.C2f [256, 256, 1, True]
9 -1 1 164608 ultralytics.nn.modules.block.SPPF [256, 256, 5]
10 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
11 [-1, 6] 1 0 ultralytics.nn.modules.conv.Concat [1]
12 -1 1 148224 ultralytics.nn.modules.block.C2f [384, 128, 1]
13 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
14 [-1, 4] 1 0 ultralytics.nn.modules.conv.Concat [1]
15 -1 1 37248 ultralytics.nn.modules.block.C2f [192, 64, 1]
16 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
17 [-1, 2] 1 0 ultralytics.nn.modules.conv.Concat [1]
18 -1 1 9408 ultralytics.nn.modules.block.C2f [96, 32, 1]
19 -1 1 9280 ultralytics.nn.modules.conv.Conv [32, 32, 3, 2]
20 [-1, 15] 1 0 ultralytics.nn.modules.conv.Concat [1]
21 -1 1 31104 ultralytics.nn.modules.block.C2f [96, 64, 1]
22 -1 1 36992 ultralytics.nn.modules.conv.Conv [64, 64, 3, 2]
23 [-1, 12] 1 0 ultralytics.nn.modules.conv.Concat [1]
24 -1 1 123648 ultralytics.nn.modules.block.C2f [192, 128, 1]
25 -1 1 147712 ultralytics.nn.modules.conv.Conv [128, 128, 3, 2]
26 [-1, 9] 1 0 ultralytics.nn.modules.conv.Concat [1]
27 -1 1 493056 ultralytics.nn.modules.block.C2f [384, 256, 1]
28 [18, 21, 24, 27] 1 617364 ultralytics.nn.modules.head.Detect [1, [32, 64, 128, 256]]
YOLOv8 summary: 278 layers, 2926404 parameters, 2926388 gradients, 12.3 GFLOPs
方法:yolov8 github上@lxy5513 大神的方法,我只是搬运工。链接在这。另外避免val报错自己修改了一处。
内容:(也可直接看后文解释的内容。)
I've discovered a workaround that, regardless of how it's done, can run successfully. First, modify ./ultralytics/cfg/models/v8/yolov8.yaml by adding ch: 1. Then, make the following file modifications:
git diff ultralytics/utils/checks.py
diff --git a/ultralytics/utils/checks.py b/ultralytics/utils/checks.py
index 1ab031ba..c8fadcdc 100644
--- a/ultralytics/utils/checks.py
+++ b/ultralytics/utils/checks.py
@@ -648,7 +648,7 @@ def check_amp(model):
try:
from ultralytics import YOLO
- assert amp_allclose(YOLO("yolov8n.pt"), im)
+ # assert amp_allclose(YOLO("yolov8n.pt"), im)
LOGGER.info(f"{prefix}checks passed ✅")
except ConnectionError:
LOGGER.warning(f"{prefix}checks skipped ⚠️, offline and unable to download YOLOv8n. {warning_msg}")
diff --git a/ultralytics/nn/tasks.py b/ultralytics/nn/tasks.py
index 64ee7f50..c8f37677 100644
--- a/ultralytics/nn/tasks.py
+++ b/ultralytics/nn/tasks.py
@@ -263,6 +264,8 @@ class BaseModel(nn.Module):
if not hasattr(self, "criterion"):
self.criterion = self.init_criterion()
+ # import ipdb;ipdb.set_trace()
+ batch['img'] = batch['img'][:,:1,:,:]
preds = self.forward(batch["img"]) if preds is None else preds
return self.criterion(preds, batch)
diff --git a/ultralytics/nn/autobackend.py b/ultralytics/nn/autobackend.py
index 4d8c69c5..98469690 100644
--- a/ultralytics/nn/autobackend.py
+++ b/ultralytics/nn/autobackend.py
@@ -502,7 +502,7 @@ class AutoBackend(nn.Module):
"""
return torch.tensor(x).to(self.device) if isinstance(x, np.ndarray) else x
- def warmup(self, imgsz=(1, 3, 640, 640)):
+ def warmup(self, imgsz=(1, 1, 640, 640)):
"""
Warm up the model by running one forward pass with a dummy input.
diff --git a/ultralytics/engine/validator.py b/ultralytics/engine/validator.py
index 41be54c1..82ed2f03 100644
--- a/ultralytics/engine/validator.py
+++ b/ultralytics/engine/validator.py
@@ -154,7 +154,8 @@ class BaseValidator:
self.dataloader = self.dataloader or self.get_dataloader(self.data.get(self.args.split), self.args.batch)
model.eval()
- model.warmup(imgsz=(1 if pt else self.args.batch, 3, imgsz, imgsz)) # warmup
+ model.warmup(imgsz=(1 if pt else self.args.batch, 1, imgsz, imgsz)) # warmup gray image
+ # model.warmup(imgsz=(1 if pt else self.args.batch, 3, imgsz, imgsz)) # warmup
self.run_callbacks("on_val_start")
dt = (
@@ -175,6 +176,7 @@ class BaseValidator:
# Inference
with dt[1]:
+ batch["img"] = batch["img"][:,:1,:,:]
preds = model(batch["img"], augment=augment)
# Loss
diff --git a/ultralytics/engine/predictor.py b/ultralytics/engine/predictor.py
index e925902f..32745d6f 100644
--- a/ultralytics/engine/predictor.py
+++ b/ultralytics/engine/predictor.py
@@ -261,7 +261,8 @@ class BasePredictor:
# Warmup model
if not self.done_warmup:
- self.model.warmup(imgsz=(1 if self.model.pt or self.model.triton else self.dataset.bs, 3, *self.imgsz))
+ self.model.warmup(imgsz=(1 if self.model.pt or self.model.triton else self.dataset.bs, 1, *self.imgsz))
+ # self.model.warmup(imgsz=(1 if self.model.pt or self.model.triton else the dataset.bs, 3, *self.imgsz))
self.done_warmup = True
self.seen, self.windows, self.batch = 0, [], None
1. ./ultralytics/cfg/models/v8/yolov8.yaml(也可是你自己修改的yaml文件)文件加 ch:1.
像这样:
nc: 1 # number of classes
ch: 1
2. 修改 ultralytics/utils/checks.py 文件 (“-”表示删除;“+”表示添加 ;建议保留原代码注释后续方便改回。)
def check_amp(model): # ctrl+f 搜索定位到这
try:
from ultralytics import YOLO
- assert amp_allclose(YOLO("yolov8n.pt"), im)
+ # assert amp_allclose(YOLO("yolov8n.pt"), im)
LOGGER.info(f"{prefix}checks passed ✅")
except ConnectionError:
LOGGER.warning(f"{prefix}checks skipped ⚠️, offline and unable to download
YOLOv8n. {warning_msg}")
3. 修改 ultralytics/nn/tasks.py文件。
if not hasattr(self, "criterion"):
self.criterion = self.init_criterion()
+ # import ipdb;ipdb.set_trace()
+ batch['img'] = batch['img'][:,:1,:,:]
preds = self.forward(batch["img"]) if preds is None else preds
return self.criterion(preds, batch)
4. 修改 /ultralytics/nn/autobackend.py文件
class AutoBackend(nn.Module):
"""
return torch.tensor(x).to(self.device) if isinstance(x, np.ndarray) else x
- def warmup(self, imgsz=(1, 3, 640, 640)):
+ def warmup(self, imgsz=(1, 1, 640, 640)):
"""
Warm up the model by running one forward pass with a dummy input.
5. 修改 /ultralytics/engine/validator.py文件
class BaseValidator:
self.dataloader = self.dataloader or self.get_dataloader(self.data.get(self.args.split), self.args.batch)
model.eval()
- model.warmup(imgsz=(1 if pt else self.args.batch, 3, imgsz, imgsz)) # warmup
+ model.warmup(imgsz=(1 if pt else self.args.batch, 1, imgsz, imgsz)) # warmup gray image
+ # model.warmup(imgsz=(1 if pt else self.args.batch, 3, imgsz, imgsz)) # warmup
self.run_callbacks("on_val_start")
dt = (
class BaseValidator:
# Inference
with dt[1]:
+ batch["img"] = batch["img"][:,:1,:,:]
preds = model(batch["img"], augment=augment)
# Loss
6. 修改 /ultralytics/engine/predictor.py文件
class BasePredictor:
# Warmup model
if not self.done_warmup:
- self.model.warmup(imgsz=(1 if self.model.pt or self.model.triton else self.dataset.bs, 3, *self.imgsz))
+ self.model.warmup(imgsz=(1 if self.model.pt or self.model.triton else self.dataset.bs, 1, *self.imgsz))
+ # self.model.warmup(imgsz=(1 if self.model.pt or self.model.triton else the dataset.bs, 3, *self.imgsz))
self.done_warmup = True
self.seen, self.windows, self.batch = 0, [], None
7. (根据原题主继续补充避免val报错):修改ultralytics/models/yolo/detect/val.py文件
def preprocess(self, batch):
"""Preprocesses batch of images for YOLO training."""
batch["img"] = batch["img"].to(self.device, non_blocking=True)
batch["img"] = (batch["img"].half() if self.args.half else batch["img"].float()) / 255
+ batch['img'] = batch['img'][:, :1, :, :]
for k in ["batch_idx", "cls", "bboxes"]:
batch[k] = batch[k].to(self.device)
7.1 (防止predictor报错):修改ultralytics/engine/predictor.py
not_tensor = not isinstance(im, torch.Tensor)
if not_tensor:
im = np.stack(self.pre_transform(im))
im = im[..., ::-1].transpose((0, 3, 1, 2)) # BGR to RGB, BHWC to BCHW, (n, 3, h, w)
+ im = im[:, :1, :, :] ##################################
im = np.ascontiguousarray(im) # contiguous
im = torch.from_numpy(im)
8. 最后常规训练即可
from ultralytics import YOLO;model = YOLO('./ultralytics/cfg/models/v8/yolov8.yaml')
model.train(data="your_dataset.yaml", epochs=100, batch=16, model='./ultralytics/cfg/models/v8/yolov8.yaml')