Skip to content
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

Chord Evaluation #309

Merged
merged 17 commits into from
Jul 24, 2017
Merged

Chord Evaluation #309

merged 17 commits into from
Jul 24, 2017

Conversation

fdlm
Copy link
Contributor

@fdlm fdlm commented Jul 11, 2017

Adds evaluation functionality for chord sequences.

TODO:

  • Add tests for the evaluation scores.
  • Change CHANGES.rst

Comments are welcome.

Copy link
Collaborator

@superbock superbock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can only give feedback regarding the formatting which is generally very nice. I added some comments regarding PEP 257. Also numpydoc usually ends descriptions of parameters with periods (which you sometimes use and sometimes not). I also find it nicer if there's a blank line before the closing """ of multi-line docstrings. But these are only minor details :)

(chords['intervals'] == _shorthands['7']).all(axis=1) |
(chords['intervals'] == _shorthands['min7']).all(axis=1) |
(chords['intervals'] == _shorthands['maj7']).all(axis=1) |
(chords['intervals'] == NO_CHORD[-1]).all(axis=1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could probably call select_majmin and only add the sevenths (7, min7, maj7).


def pitch(pitch_str):
"""
Converts a string representation of a pitch class (consisting of root
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP 257 suggests to use rather "do this" than "does..." style, i.e. "convert...".

"""
Converts a string representation of a musical interval into a semitone
integer (e.g. a minor seventh 'b7' into 10, because it is 10 semitones
above its base note).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above ('convert"). Additionally PEP 257 suggests that "multi-line docstrings consist of a summary line just like a one-line docstring, followed by a blank line, followed by a more elaborate description." However, I am not sure if it could be split like this. I don't mind if not.

def evaluation_pairs(det_chords, ann_chords):
"""
Matches detected with annotated chords and creates paired label segments
for evaluation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same again: match... create...

def segmentation(ann_starts, ann_ends, det_starts, det_ends):
"""
Compute the normalized Hamming divergence between chord
segmentations as defined in [1]_ (Eqs. 8.37 and 8.38).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you check if this links to the reference when docs are created?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes :)

@fdlm fdlm changed the title [WIP] Chord Evaluation Chord Evaluation Jul 24, 2017
@fdlm fdlm merged commit 852cfe8 into master Jul 24, 2017
@fdlm fdlm deleted the feature/chord_eval branch July 24, 2017 17:37
@@ -13,7 +13,7 @@ import argparse
import warnings

from madmom.utils import search_files, match_file
from madmom.evaluation import onsets, beats, notes, tempo, alignment
from madmom.evaluation import onsets, beats, notes, tempo, alignment, chords
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started re-arranging the imports alphabetically, because they are easier to read and searchable. Although not explicitly stated in PEP8, this is also recommended by various Python style guides. You could also do so when adding a final commit...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Since they were not sorted alphabetically until now, I did not care. I'm going to change that.

@@ -886,12 +886,13 @@ def evaluation_io(parser, ann_suffix, det_suffix, ann_dir=None, det_dir=None):


# finally import the submodules
from . import onsets, beats, notes, tempo, alignment
from . import onsets, beats, notes, tempo, alignment, chords
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup.


"""

import numpy as np
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor detail: most import style guides suggest an empty line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. ¯_(ツ)_/¯

----------
intervals_str : str
List of intervals as comma-separated string (e.g. 'b3, 5').

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary empty line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix this.

----------
det_chords : numpy structured array
Chord detections with 'start' and 'end' fields.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary empty line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be fixed.

('undersegmentation', 'UnderSegmentation'),
]

def __init__(self, detections, annotations, name, **kwargs):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if a name is really required. Most other evaluation classes don't do so. If you change it to name=None, please update the docstring accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll change it to name='' directly...

return seg / (ann_ends[-1] - ann_starts[0])


class ChordEvaluation(object):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this class can inherit from madmom.evaluation.EvaluationMixin. This mixin provides the metrics property, a dict containing all metrics defined in METRIC_NAMES.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm not sure what this MixIn is for:

  • Every evaluation implements its own to_string method.
  • The __len__ method is not used anywhere (in any case, it can only return an integer, so it is quite limited)
  • The metrics property is not used anywhere except for the AlignmentEvaluation
  • The formatters tocsv and totex only use METRIC_NAMES, which has to be defined for each evaluation class anyways.

So, what advantages does the Mixin give us?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not too much, but as said previously, it automatically provides a uniform way of accessing all metrics via a property...

Detected chords of evaluation segments.
durations : numpy array
Durations of evaluation segments.
"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor thing: I usually add an empty line before the closing """ -- as you did in many other places.
I just mention it here, it misses multiple times.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, fixed.

@superbock
Copy link
Collaborator

Ok, too late... maybe you can comment on my comments. Those are all things which can be incorporated in another commit, most of them bundled with other similar/related changes (e.g. reordering of imports).

@fdlm
Copy link
Contributor Author

fdlm commented Jul 24, 2017

Yes, I wanted to have this off my TODO list so I merged it quickly 😄

Anyways, #315 should address your comments, except the EvaluationMixin thing, which we should reconsider IMHO.

@superbock
Copy link
Collaborator

Fully understand this 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants