-
Notifications
You must be signed in to change notification settings - Fork 258
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
mostly_tracked, partially_tracked, mostly_lost not granular enough #118
Comments
Hey Pavel! I believe these categories have been introduced in the following paper
and have been reported in many follow-up papers. While I believe its useful to add fine-grained steps for inspection, for publications we still need those exact categories. Anyways, the code is in py-motmetrics/motmetrics/metrics.py Line 465 in 411f4e5
Each category is implemented as a separate metric that can be selected for computation. |
So you don't want to add more to the master branch? If I want to implement a version for myself that gets more granular, it's a matter of just |
Sorry, I didn't mean to say that. I just wanted to mention that the current behavior should persist.
Yes, basically that's it. The name of the arguments of the function is relevant. I.e they refer to dependencies of other functions. |
Okay, I went and added the metrics I want (didn't realize I needed to change |
Okay, no no no no. I've spent some time playing with the I found where it lives on disk so I can make additions. I'm importing If I try adding
If I try calling the Why is this so hard? Why is the code written in such a way that I can't actually access a variable that according to the table in the readme is exposed? How do I actually get my hands on the |
Slight progress: If I add |
Okay, I've gone spelunking and found that this is the line where the
The Series with the name I had to go about 12 misdirections deep to figure this out. Clearly the repetitious
The idea is all this stuff is found for me with calls to the |
I'm seeing now that all that registration is so that you can check for those dependencies. But in order for that to work dependent functions have to be specified with a name identical to the param name. Why not enforce that all function dependencies are made explicit and skip the confusing and verbose inference logic, function registration, and subtle 'this has to have the same name as that' rule? "Explicit is better than implicit" - I'm beginning to get inspired to refactor this code. How open are you to supporting me in such an undertaking? |
Hey Pavel, sorry for the inconvenience. It's true that the registration is implicit through argument names. That's for historic reasons. I'm open to refactoring this part of the code basis iff the following constraints apply
Best, |
Sorry, I get kind of snarky when I'm frustrated. I tried some refactoring for a few hours myself but ran in to several things where I just had no idea what the intention was, so I had to stop. I definitely need buy-in and help from you guys if I'm to make headway. And this code definitely needs help. It's too long, there are too many functions that seem to be doing the same thing, and there's some crazy local()/global() implicit weirdness going on. In essence, it seems pretty easy to add single-number metrics now in a targeted fashion (if your metric depends on an already-defined datastructure/function), but defining new ones or surfacing more complex ones is pretty confusing. Seems like you have been the leaders at MOT metics for years, so we can salve a lot of pain at once if this is addressed. Otherwise someone else will eventually come along and usurp you. |
well, i'm going to have a look.
|
If one want to add a new metric, firstly, a function name and function instance should be registered in 'def create' in metrics.py; secondly, to accelerate calculation, another function instance with same name + '_m' suffix should be defined, in this function the per video results will be provided, so we can make some easy combination instead of compute something from the beginning, for example, we don't need to re-calculate IDF1 for the combination for the all videos (this is time-consuming in an early version), but just do some simple add operations for the results of each video. |
Why is there this '_m' suffix business? It's not easy to understand. |
simple_add_func is actually a default definition of MetricName_m, because a lot of basic metrics can be combined through a weighted sum way, and it is not beautiful to repeat the same things for a dozen times. In fact, each metric should be viewed as a sub-class which inheriting a common parent-class, it will be a more reasonable framework, however, it is also largely change the current code so I did not doing so then. |
for example, in the original design, when we compute the overall IDF1 score, we combine 7 videos into one very large video, and recaculate the IDF1 for this large fake video. actually we have the IDF1 score computed for each of the 7 video, a more efficient way is to find out the relationship of the overall IDF1 and the IDF1-s for each video. so we need to defined another metric function, for a fast merging. '_m' means merge. |
I still don't fully understand. And having to push all these functions in to a list, iterate the list to create closures, shove those closures in |
doing this is to automatically infer the dependency graph. some python tricks are used. i was just following and extending the idea. of course turning all into classes will make it easier to understand (if i was the initial designer, i definitly will use class strure) . but now it will be a big change and will take time to rebuild the framework.
|
Can it be undertaken anyway? I spent a whole day trying to access a series that is supposed to be exposed only to realize I can't. |
From my point of view refactoring that part of the code would make a good investment into the future of py-motmetrics. I know of several metrics to be published in the short term that eventually should make it into py-motmetrics. Maybe we can trace the current way the metrics are computed. @Helicopt would you mind giving us a head-start? Its quite a long time for me that I actually worked on the part of the code :( |
I'm not convinced making dependent metrics subclasses of the ones they depend on is the right way to encode that relationship. Making each one a class seems like a recipe for really verbose code to me. It will be clearer, but still hard to understand. Maybe a dictionary that encodes who depends on whom is sufficient? It's no more annoying to know you have to add an entry to a dictionary than to know you have to inherit from certain things, and it's maybe even more explicit than subclassing because you can see all dependency relationships in one, short place. For a large enough project with enough metrics, though, subclassing may be better, because then each piece of code can be smaller, and new contributors can just ignore almost all metrics because they're just analogous to whichever example they choose to look at. I'm sure an elegant way to evaluate parents first and pass results exists. |
0-20%, 20-80%, and 80+% are useful, but for complicated scenes, most everything falls in the "mostly tracked" bucket. Can we get a few more buckets? Maybe one for each 10% or 20% increment? I can't imagine this would be difficult in the code, so if you point the way, I'm willing to implement it and submit a PR myself.
The text was updated successfully, but these errors were encountered: