Random object detection results

Alberto500: <p>Random results in object detection when using a custom trained model(yolov8s as well yolo11s)</p>
<p>YAML data file:</p>
<pre data-code-wrap="ini"><code class="lang-ini">path: (…folder path)
test: test\imagestrain:
train\images
val: validation\imagesnc: 1
names: [“Apple”]
</code></pre>
<p>All folders(test, train, validate) contain “images” and “labels” folders, all images all unique(no repeating images in any of the folders).<br>
I run the training with this command “yolo detect train data=data.yaml model=yolov8s.pt epochs=90 imgsz=640 profile = True”.</p>
<p>Once the training is done, i copy the file “best.pt” from Data-&gt;runs-&gt;detect-&gt;train-&gt;weights, then i convert it with a script to .onnx since i am using it in OpenCV.<br>
I am converting as well the trained models, so the conversion to .onnx isn’t the issue.</p>
<p>Correct results rectangle output: (Link to image: <a href="https://freeimage.host/i/KjGoVv2" class="inline-onebox" rel="noopener nofollow ugc">good result — Freeimage.host</a>)</p>
<pre><code class="lang-auto">x 139.614 y 117.224 w 180.547 h 177.173 class_id 47 class_score 0.959822
x 319.697 y 323.333 w 636.135 h 627.457 class_id 60 class_score 0.26418
x 493.684 y 249.387 w 236.908 h 206.874 class_id 46 class_score 0.924733
</code></pre>
<p>BAD results rectangle output: (Link to image: <a href="https://freeimage.host/i/KjGoWpS" class="inline-onebox" rel="noopener nofollow ugc">bad result — Freeimage.host</a>)</p>
<pre><code class="lang-auto">x 132.563 y 616.468 w 266.61 h 47.1793 class_id 12 class_score 621.335
x 144.472 y 617.792 w 283.971 h 44.7845 class_id 7 class_score 621.335
x 166.978 y 620.281 w 331.142 h 40.2383 class_id 2 class_score 621.335
x 192.263 y 621.335 w 379.946 h 38.3646 class_id 2 class_score 620.519
x 212.024 y 620.519 w 434.511 h 40.2094 class_id 2 class_score 618.833
x 234.077 y 618.833 w 470.669 h 43.7068 class_id 2 class_score 617.004
x 263.682 y 617.004 w 470.693 h 47.3287 class_id 2 class_score 614.085
x 297.421 y 614.085 w 470.935 h 53.1138 class_id 2 class_score 610.107
x 331.886 y 610.107 w 474.087 h 61.0482 class_id 2 class_score 607.41
x 361.037 y 607.41 w 480.529 h 66.4008 class_id 27 class_score 607.363
x 387.238 y 606.562 w 482.929 h 67.9863 class_id 22 class_score 607.363
x 414.299 y 605.055 w 474.496 h 70.7969 class_id 17 class_score 607.363
x 425.989 y 600.909 w 436.541 h 78.6324 class_id 12 class_score 607.363
</code></pre>
<p>You can clearly see, that the max “class_score” is equal to the next rectangle Y pos… Which obviously produces broken results, as well as a decreasing value pattern.</p>
<p>This model has been trained with only one class (id 0) but the class ids 12, 7, 2, 27, 22, 17 are as well either random results or something else.<br>
There are 8400 rectangles detected, some are reduced by NMSBoxes(opencv), the same value as the output in rows. Since the class_score is random, all the rectangles predictions are random as well.</p>
<p>I tried to load the custom model into pytorch directly with python and no c++ OpenCV, but i get some weird error when i try load the model, it says:</p>
<pre><code class="lang-auto">  File "&lt;frozen runpy&gt;", line 198, in _run_module_as_main
  File "&lt;frozen runpy&gt;", line 88, in _run_code
  File "......py_detect.py", line 21, in &lt;module&gt;
  pred = model([img])
  TypeError: 'dict' object is not callable
</code></pre>
<p>I don’t use python, i don’t know what it is, and i didn’t find any specific solution for this, and i have no more time, so i am unable to test if by chance it works correctly this way.</p>
<p>The last thing, in this video (put this code “3XmjyBE8xVA“ in youtube’s  watch?v= since i can put only 2 links) at time 13:29, the dude uses this code:</p>
<p>He multiplies the x and w by the with and height in pixels, which suggests that the X/Y values MUST be in 0-1 range, meaning that to get 320x320 pixels, the value must be (0.5, 0.5) which as well he suggested, then the rectangle is adjusted by it’s center</p>
<pre data-code-wrap="cpp"><code class="lang-cpp">float x = data[0], y = data[1], w = data[2], h = data[3];
int left = x * modelInput.cols - w * modelInput.cols / 2;
int top = y * modelInput.rows - h * modelInput.rows / 2;
int width = w * modelInput.cols;
int height = h * modelInput.rows;

</code></pre>
<p>However i am getting the values in pixels in both cases(custom broken model and the working downloaded ones), if i use his suggestions then i will get values like 40000x50000 which is obviously out of boundary</p>
<pre data-code-wrap="cpp"><code class="lang-cpp">int left = x - w/2;
int top = y - h/2;
int width = w;
int height = h;
</code></pre>
<p>I tried to do everything i could, but nothing seems to work. I include as well the full training config</p>
<blockquote>
<p>task: detect<br>
mode: train<br>
model: yolov8s.pt<br>
data: data.yaml<br>
epochs: 90<br>
time: null<br>
patience: 100<br>
batch: 16<br>
imgsz: 640<br>
save: true<br>
save_period: -1<br>
cache: false<br>
device: null<br>
workers: 8<br>
project: null<br>
name: train2<br>
exist_ok: false<br>
pretrained: true<br>
optimizer: auto<br>
verbose: true<br>
seed: 0<br>
deterministic: true<br>
single_cls: false<br>
rect: false<br>
cos_lr: false<br>
close_mosaic: 10<br>
resume: false<br>
amp: true<br>
fraction: 1.0<br>
profile: true<br>
freeze: null<br>
multi_scale: false<br>
compile: false<br>
overlap_mask: true<br>
mask_ratio: 4<br>
dropout: 0.0<br>
val: true<br>
split: val<br>
save_json: false<br>
conf: null<br>
iou: 0.7<br>
max_det: 300<br>
half: false<br>
dnn: false<br>
plots: true<br>
source: null<br>
vid_stride: 1<br>
stream_buffer: false<br>
visualize: false<br>
augment: false<br>
agnostic_nms: false<br>
classes: null<br>
retina_masks: false<br>
embed: null<br>
show: false<br>
save_frames: false<br>
save_txt: false<br>
save_conf: false<br>
save_crop: false<br>
show_labels: true<br>
show_conf: true<br>
show_boxes: true<br>
line_width: null<br>
format: torchscript<br>
keras: false<br>
optimize: false<br>
int8: false<br>
dynamic: false<br>
simplify: true<br>
opset: null<br>
workspace: null<br>
nms: false<br>
lr0: 0.01<br>
lrf: 0.01<br>
momentum: 0.937<br>
weight_decay: 0.0005<br>
warmup_epochs: 3.0<br>
warmup_momentum: 0.8<br>
warmup_bias_lr: 0.1<br>
box: 7.5<br>
cls: 0.5<br>
dfl: 1.5<br>
pose: 12.0<br>
kobj: 1.0<br>
nbs: 64<br>
hsv_h: 0.015<br>
hsv_s: 0.7<br>
hsv_v: 0.4<br>
degrees: 0.0<br>
translate: 0.1<br>
scale: 0.5<br>
shear: 0.0<br>
perspective: 0.0<br>
flipud: 0.0<br>
fliplr: 0.5<br>
bgr: 0.0<br>
mosaic: 1.0<br>
mixup: 0.0<br>
cutmix: 0.0<br>
copy_paste: 0.0<br>
copy_paste_mode: flip<br>
auto_augment: randaugment<br>
erasing: 0.4<br>
cfg: null<br>
tracker: botsort.yaml</p>
</blockquote>

Alberto500: <p>No one knows anything?</p>

ptrblck: <aside class="quote no-group" data-username="Alberto500" data-post="1" data-topic="223524">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/a/e9bcb4/48.png" class="avatar"> Alberto500:</div>
<blockquote>
<pre><code class="lang-auto">TypeError: 'dict' object is not callable
</code></pre>
</blockquote>
</aside>
<p>This error is often raised of you only loaded the <code>state_dict</code> and try to call it instead of loading it into a model instance via <code>model.load_state_dict</code>.</p>
<p>I’m not familiar with your code so don’t know why outputs seems to be mixed up.</p>

Alberto500: <p>The errors were caused by wrong class number, it was set by default to 80 from one place i borrowed the code to load the bytes, but since i had 1 class only, the results were random. It would load some other values, and because the trained models i downloaded had exactly 80 classes, it would pass.</p>
<p>I thought it had something to do with my trained models, but it didn’t.</p>