apmcleod / harmonic-inference Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Optimizing the beam search is an option, as well as running some of the models on GPU.
Now that repeats are removed, weird things happen when key changes interrupt identical chords.
Tried python annotate.py -h
after doing the indicated installation in a python=3.9.5
environment which left me with torch==1.9.0
and torchmetrics==0.11
. The result was
ImportError: cannot import name 'get_num_classes' from 'torchmetrics.utilities.data' (.../lib/python3.9/site-packages/torchmetrics/utilities/data.py)
Downgrading to torchmetrics==0.7
solved the issue as per pesser/stable-diffusion#13
Then the same command yielded
AttributeError: module 'distutils' has no attribute 'version'
which I managed to solve by installing setuptools==59.5.0
as per https://stackoverflow.com/questions/74684612/attributeerror-module-distutils-has-no-attribute-version
Sometimes, consecutive chords are the same, just with different inversions. In these cases, we want to allow the user to merge those into a single chord symbol (at least, with no change between the chords).
Relative to pitches of notes within some window of a chord, maybe 2 bars, maybe the chord duration?
The model should find "low" notes, even if they are only low locally, but not globally.
Maybe bag of pitches? Voice-based? bass and pitches?
This is possible since it's output is only used as a prior, not as output.
During the beam search, this seems to be giving incorrect results.
For example, when one note is held through the chord, but other non-chord notes are between that note and the chord onset.
The reduction should be able to be performed post creation for each dataset.
The minimum (octave, TPC) tuple is not necessarily the minimum pitch (and same for maximum)
Specifically, log any final unmatched tied_in_notes and any tied notes beginning with tied == 0.
Mozart K_279-2 (index 566), bar 46 has a C# chord. This is presumably being driven by the CSM, although the following key change makes no sense. This is also enharmonic to the correct chord (there is a Db)...:
Index = 712
ie, if someone wants to only use MAJOR, MINOR, AUGMENTED, DIMINISHED, each additional chord should map down to it. Perhaps also add an "OTHER" base chord type?
To use reductions, and remove inversions in ICM, this can be useful.
There is an off-by-one or off-by-margin error, particularly for the one-hot key/chord relative calculation in State.
Maybe as string "MAJOR", or int, e.g.: ChordType(int)
It is theoretically possible to go through a piece and finish with an empty Beam. What to do in such cases?
Per conversation with Johanes, probably best would be to add a new "Aug6" class with all of them, with the root at scale degree 2, #4, or b6.
Currently, they are just minor on 6 (or b6).
At first I tried to install in a Python 3.10 environment (which is also what you get when creating the conda environment with python=3
) but installation failed while a C subroutine was compiling numpy. Then I used an environment created with python=3.9
which lead to
INFO: pip is looking at multiple versions of harmonic-inference[dev] to determine which version is compatible with other requirements. This could take a while.
ERROR: Package 'harmonic-inference' requires a different Python: 3.9.16 not in '==3.9.5'
In a new environment created with python=3.9.5
the installation worked.
Decide how to handle these. (Probably by not ignoring tied notes). Another option: exclude chords with no notes.
Trying out annotating with forced labels, first attempt with a single piece. Here's the aggregated data: 146_wer.zip
Edit: It seems to be happening only in this special case where dealing with a single piece.
Steps to reproduce
Extract to corpus_data
and run
python annotate.py -i ../corpus_data/ -o output --label-type dcml --checkpoint checkpoints-beat-best -l annotate.log
Error
Occurred with the current 1.0.0
version on the output
branch:
Traceback (most recent call last):
File "~/harmonic-inference/annotate.py", line 376, in <module>
pieces = load_pieces(xml=ARGS.xml, input_path=ARGS.input, specific_id=ARGS.id)
File "~/harmonic-inference/harmonic_inference/utils/data_utils.py", line 125, in load_pieces
files_df, measures_df, chords_df, notes_df = load_clean_corpus_dfs(input_path)
File "~/harmonic-inference/harmonic_inference/data/corpus_reading.py", line 202, in load_clean_corpus_dfs
notes_df = cu.add_note_offsets(notes_df, measures_df)
File "~/harmonic-inference/harmonic_inference/utils/corpus_utils.py", line 291, in add_note_offsets
if isinstance(measures.iloc[0]["next"], list) or isinstance(measures.iloc[0]["next"], tuple):
File "~/miniconda3/envs/harmony/lib/python3.10/site-packages/pandas/core/indexing.py", line 1073, in __getitem__
return self._getitem_axis(maybe_callable, axis=axis)
File "~/miniconda3/envs/harmony/lib/python3.10/site-packages/pandas/core/indexing.py", line 1625, in _getitem_axis
self._validate_integer(key, axis)
File "~/miniconda3/envs/harmony/lib/python3.10/site-packages/pandas/core/indexing.py", line 1557, in _validate_integer
raise IndexError("single positional indexer is out-of-bounds")
IndexError: single positional indexer is out-of-bounds
Origin
I could trace back the error to corpus_reading.py#L140. After this call, measures_df
is empty.
Calling python annotate.py -i corpus_data -o corpus_data --label-type dcml --checkpoint checkpoints-beat-best -l annotate.log
on this corpus_data.zip works only if one removes chord.tsv
, otherwise it fails with
Traceback (most recent call last):
File "~/harmonic-inference/annotate.py", line 376, in <module>
pieces = load_pieces(xml=ARGS.xml, input_path=ARGS.input, specific_id=ARGS.id)
File "~/harmonic-inference/harmonic_inference/utils/data_utils.py", line 169, in load_pieces
pieces = [
File "~/harmonic-inference/harmonic_inference/utils/data_utils.py", line 170, in <listcomp>
get_score_piece_from_data_frames(
File "~/harmonic-inference/harmonic_inference/data/piece.py", line 970, in get_score_piece_from_data_frames
non_repeated_mask = get_reduction_mask(
File "~/harmonic-inference/harmonic_inference/data/piece.py", line 75, in get_reduction_mask
mask = np.full(len(inputs), True, dtype=bool)
TypeError: len() of unsized object
NB: chords.tsv
contains exactly one chord label per piece.
Pass it through from joint_model to get_note_vectors
In order to reproduce this bug, checkout #76 to fix an ms3
bug in the discovery of scores containing forces.
The error message occurs for this corpus_data.zip when executing python annotate.py --label-type dcml --checkpoint checkpoints-beat-best -l annotate.log -i ~/corpus_data -o ~/corpus_data --forces ~/corpus_data/MS3
.
Getting harmony for pieces: 0%| | 0/5 [00:00<?, ?it/s]
Traceback (most recent call last):
File "~/harmonic-inference/annotate.py", line 378, in <module>
annotate(
File "~/harmonic-inference/annotate.py", line 185, in annotate
state, estimated_piece = model.get_harmony(piece, **forces_dict)
File "~/harmonic-inference/harmonic_inference/models/joint_model.py", line 789, in get_harmony
self.kppm_post_processing(state)
File "~/harmonic-inference/harmonic_inference/models/joint_model.py", line 1605, in kppm_post_processing
piece = state.get_score_piece(
AttributeError: 'NoneType' object has no attribute 'get_score_piece'
Currently, it's priors_argosrt[0] == state.key
, but ksm returns are relative indexes, while state.key is absolute.
Convert to pitch_types library, for octave, MIDI -> TPC conversion, and min/max pitch.
DtypeWarning: Columns (18,19) have mixed types.Specify dtype option on import or set low_memory=False.
This is in regards to *_is_minor columns, which are nullable boolean-type.
The full range of relative chords is not always valid in absolute terms, similar to the key_change input vector. Think about whether this is an issue.
CTM may need these...
eg, to have different inversions usable, in some cases.
Presumably, this should be calculatable from root, chord_type, and inversion, but it isn't always correct.
Maybe it actually means "lowest note in the chord"?
Should allow for both musicxml and musescore3 (and DCML tsv format).
For example: "note 7 should be C:maj"
validation piece 1, chords 3 and 4 are the same:
pieces[1].get_chords()[3:5]:
Chord(root=21, bass=18, key_tonic=19, key_mode=KeyMode.MINOR, chord_type=ChordType.DIMINISHED, inversion=1, onset=(3, Fraction(3, 8)), onset_level=2, offset=(3, Fraction(5, 8)), offset_level=1, duration=1/4, pitch_type=PitchType.TPC),
Chord(root=21, bass=18, key_tonic=19, key_mode=KeyMode.MINOR, chord_type=ChordType.DIMINISHED, inversion=1, onset=(3, Fraction(5, 8)), onset_level=1, offset=(4, Fraction(0, 1)), offset_level=3, duration=1/8, pitch_type=PitchType.TPC)
Currently, duration information is not included in a chord vector.
Perhaps take some from mozart_loader.
At inference time
Running the pretrained model on an mxl
file with a single measure results in the following crash:
Loading pieces: 0%| | 0/1 [00:00<?, ?it/s]Traceback (most recent call last):
File "/home/napulen/harmonic-inference/annotate.py", line 327, in <module>
pieces = load_pieces(xml=ARGS.xml, input_path=ARGS.input, specific_id=ARGS.id)
File "/home/napulen/harmonic-inference/harmonic_inference/utils/data_utils.py", line 152, in load_pieces
pieces = [
File "/home/napulen/harmonic-inference/harmonic_inference/utils/data_utils.py", line 153, in <listcomp>
get_score_piece_from_music_xml(
File "/home/napulen/harmonic-inference/harmonic_inference/data/piece.py", line 943, in get_score_piece_from_music_xml
measures_df = get_measures_df_from_music21_score(m21_score)
File "/home/napulen/harmonic-inference/harmonic_inference/data/piece.py", line 779, in get_measures_df_from_music21_score
ts_epoch = Fraction(list(m21_score.measureOffsetMap().keys())[1] / 4)
IndexError: list index out of range
Loading pieces: 0%| | 0/1 [00:00<?, ?it/s]
Can confirm that the same input with an additional measure that repeats the last chord was successfully processed.
Since model args are already parsed from command line, this is the easiest way.
For example, could add a model.get_dataset_kwargs(self) -> Dict[str, Any]
function.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.