-
-
Notifications
You must be signed in to change notification settings - Fork 16.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Put feature map visualizations in the same "exp" directory #3902
Comments
@adrianholovaty ya maybe that's a good idea, though the model of course has no concept of what it's doing really beyond being in .train() mode or .eval() mode, so it doesn't know if it's being called by train, test, detect, or as a hub model, or even less what directories those processes may log to. I'll go take a look. |
@glenn-jocher Yeah, it smells like some tight coupling for sure. :-/ Is there an object that contains state for the current train/test/detect run? Like, runtime params. That would be a good place to put this data, rather than on the model (which, yeah, seems inappropriate). |
@adrianholovaty can you try this variant of def feature_visualization(x, module_type, stage, n=64):
"""
x: Features to be visualized
module_type: Module type
stage: Module stage within model
n: Maximum number of feature maps to plot
"""
batch, channels, height, width = x.shape # batch, channels, height, width
if height > 1 and width > 1:
f = f"stage_{stage}_{module_type.split('.')[-1]}_features.png" # filename
project, name = Path('runs/features'), 'exp'
save_dir = increment_path(project / name, exist_ok=not (project / name / f).exists()) # increment run
save_dir.mkdir(parents=True, exist_ok=True) # make dir
plt.figure(tight_layout=True)
blocks = torch.chunk(x, channels, dim=1) # block by channel dimension
n = min(n, len(blocks))
for i in range(n):
feature = transforms.ToPILImage()(blocks[i].squeeze())
ax = plt.subplot(int(math.sqrt(n)), int(math.sqrt(n)), i + 1)
ax.axis('off')
plt.imshow(feature) # cmap='gray'
print(f'Saving {save_dir / f}...')
plt.savefig(save_dir / f, dpi=300) |
@adrianholovaty good news 😃! Your original issue may now be fixed ✅ in PR #3920. This is a complete revamp of feature visualization with many fixes and improvements. To receive this update:
Thank you for spotting this issue and informing us of the problem. Please let us know if this update resolves the issue for you, and feel free to inform us of any other issues you discover or feature requests that come to mind. Happy trainings with YOLOv5 🚀! |
@glenn-jocher Looks good — that fixes the issue I raised here. Nice one! |
Hi sir, i have a question in your picture. In picture hava 32 images, what mean in it's image ? tks sir !!! |
I was excited to check out the new feature map functionality! One thing came up in my testing, which seems like an opportunity for improvement.
At the moment, each distinct feature map image gets put in a new (incremented)
exp
directory —exp2
,exp3
,exp4
, etc. It looks as though the feature map image files will always have distinct names within the context of a single run, so it would be safe (and more intuitive) to put them in a single directory together.So, instead of this resulting directory structure:
...it would be:
The downside of the current approach is: When you run inference, the system will generate several
exp
directories in thefeatures
directory — e.g.,features/exp2
,features/exp3
,features/exp4
— while only using a singledetect/exp
directory for the inference results. This makes it difficult to cross-reference whichfeatures/*
directories go with whichdetect/*
directories, because the numbers are out of sync.To see what I mean, change
forward_once()
inmodels/yolo.py
to something like this:I believe this is what @Zigars was referring to in this comment, but I'm not 100% sure.
The root of this issue is that the new
feature_visualization()
function always increments a newexp
directory, for every image it creates. A solution could be:feature_visualization()
to take anoutput_dir
parameter and use that, instead of callingincrement_path()
.feature_visualization()
to pass theoutput_dir
.X
to be used indetect/expX
andfeatures/expX
), but I'm not comfortable enough with the YOLOv5 code to know where to put this.The text was updated successfully, but these errors were encountered: