yolov8 训练单通道灰度图片

先看结果:第一层输入通道数已变成 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')

  • 16
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 29
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值