Skip to content

Commit 66446fa

Browse files
committed
ReadMe corrected
1 parent 904e884 commit 66446fa

1 file changed

Lines changed: 40 additions & 60 deletions

File tree

README.md

Lines changed: 40 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,24 @@ For some samples last midi note onsets are slightly beyond the duration of the c
2929
# Not used datasets
3030
## Not used: MAPS (from Fichiers - Aix-Marseille Université)
3131
https://amubox.univ-amu.fr/index.php/s/iNG0xc5Td1Nv4rR
32+
3233
### Issue 1 (small dataset and not as natural)
3334
From https://arxiv.org/pdf/1810.12247.pdf, Page 4, Section 3 "Dataset":
35+
3436
`MAPS ... “performances” are not as natural as the MAESTRO performances captured from live performances. In addition, synthesized audio makes up a large fraction of the MAPS dataset.`
37+
3538
### Issue 2 (skipped notes)
3639
From https://arxiv.org/pdf/1710.11153.pdf, Page 6, Section 6 "Need for more data, more rigorous evaluation":
40+
3741
`In addition to the small number of the MAPS Disklavier recordings, we have also noticed several cases where the Disklavier appears to skip some notes played at low velocity. For example, at the beginning of the Beethoven Sonata No. 9, 2nd movement, several Ab notes played with MIDI velocities in the mid-20s are clearly missing from the audio...`
42+
3843
### Issue 3 (two chords instead of one)
3944
There is an issue with datasets __*"ENSTDkAm"*__ & __*"ENSTDkCl"*__, subtypes __*"RAND"*__ & __*"UCHO"*__. They are assumed to have only one chord per one WAV-file. But sometimes the chord is split into two onset times in corresponding MIDI and TXT-files, and those two onset times fall into two consecutive time-frames of cqt-transform (or mel-transform).
4045
## Not used: MusicNET (from University of Washington Computer Science & Engineering)
4146
https://homes.cs.washington.edu/~thickstn/musicnet.html
4247

4348
From https://arxiv.org/pdf/1810.12247.pdf, Page 4, Section 3 "Dataset":
49+
4450
`As discussed in Hawthorne et al. (2018), the alignment between audio and score is not fully accurate. One advantage of MusicNet is that it contains instruments other than piano` ... `and a wider variety of recording environments.`
4551

4652

@@ -62,10 +68,8 @@ From https://arxiv.org/pdf/1810.12247.pdf, Page 5, Section 4 "Piano Transcriptio
6268
`switched to HTK frequency spacing (Young et al., 2006) for the mel-frequency spectrogram input.`
6369

6470
Mel-frequency values are strange:
65-
66-
$f_{min} = 30 Hz$, but the first "A" note of 1st octave is *27.5 Hz*
67-
68-
$f_{max} = 8 000 Hz$ (librosa default), and it is much higher than the last "C" note of 8th octave (*4 186 Hz*). So, mel-spectrogram will contain lots of high harmonics, and maybe, it will help the CNN-model correctly identify notes in the last octaves.
71+
- fmin = 30 Hz, but the first "A" note of 1st octave is *27.5 Hz*
72+
- fmax = 8 000 Hz (librosa default), and it is much higher than the last "C" note of 8th octave (*4 186 Hz*). So, mel-spectrogram will contain lots of high harmonics, and maybe, it will help the CNN-model correctly identify notes in the last octaves.
6973

7074
Maybe (don't know) Mel-scaled spectrogram is used instead of Constant-Q transform, because CQT-transform produces equal number of bins for each note, while mel-frequencies are located such that there are more nearby frequencies for higher notes. So, mel-spectrogram provides more input data for higher octaves, and the CNN-model can transcribe higher notes with better accuracy. It can help solve the issue with lots of annoying false-positive notes in high octaves.
7175

@@ -74,18 +78,24 @@ librosa.power_to_db, ref=1 (default) --> mels decibels are approximately in rang
7478

7579
## Note message durations: 2 consecutive frames
7680
From https://arxiv.org/pdf/1710.11153.pdf:
81+
7782
Page 2, Section 2 "Dataset and Metrics":
83+
7884
`... we first translate “sustain pedal” control changes into longer note durations. If a note is active when sustain goes on, that note will be extended until either sustain goes off or the same note is played again.`
85+
7986
Page 3, Section 3, "Model Configuration":
87+
8088
`... all onsets will end up spanning exactly two frames. Labeling only the frame that contains the exact beginning of the onset does not work as well because of possible mis-alignments of the audio and labels. We experimented with requiring a minimum amount of time a note had to be present in a frame before it was labeled, but found that the optimum value was to include any presence.`
8189

8290
## Number of time-frames: 625 + 1 (20 seconds at sample rate of 16 kHz)
8391
From https://arxiv.org/pdf/1710.11153.pdf, Page 2, Section 3 "Model Configuration":
92+
8493
`... we split the training audio into smaller files. However, when we do this splitting we do not want to cut the audio during notes because the onset detector would miss an onset while the frame detector would still need to predict the note’s presence. We found that 20 second splits allowed us to achieve a reasonable batch size during training of at least 8, while also forcing splits in only a small number of places where notes are active.`
8594

8695

8796
# 2 Training and Validation
8897
My previous model performed well on __*MAPS*__ dataset, but resulted in much lower accuracy on new larger, more natural, and more complicated __*MAESTRO*__ dataset. It turned out, that just simple fully-connected network produced similar result. It probably makes sense, as it is written in https://arxiv.org/pdf/1810.12247.pdf, Page 5, Section 4 "Piano Transcription":
98+
8999
`In general, we found that the best ways to get higher performance with the larger dataset were to make the model larger and simpler.`
90100

91101
So, I based my model on Google "Onsets and Frames: Dual-Objective Piano Transcription".<br>From https://arxiv.org/pdf/1710.11153.pdf, Page 3, Figure 1 "Diagram of Network Architecture":
@@ -99,91 +109,53 @@ I blindly copied those model parameters, except:
99109

100110
## Onsets CNN subnetwork
101111
From https://arxiv.org/pdf/1710.11153.pdf, Page 2, Section 3 "Model Configuration":
112+
102113
`The onset detector is composed of the acoustic model, followed by a bidirectional LSTM ... with 128 units in both the forward and backward directions, followed by a fully connected sigmoid layer with 88 outputs for representing the probability of an onset for each of the 88 piano keys.`
103114

104-
Acoustic convolutional stack is taken from https://arxiv.org/pdf/1612.05153.pdf<br>Page 5, Section 5 "State of the Art Models", Table 4 "Model Architectures":
105-
_ | DNN | ConvNet | AllConv
106-
:-------------|:------------:|:-------------:|:-----------:
107-
- | Input 229 | Input 5x229 | Input 5x229
108-
- | Dropout 0.1 | Conv 32x3x3 | Conv 32x3x3
109-
- | Dense 512 | Conv 32x3x3 | Conv 32x3x3
110-
- | BatchNorm | BatchNorm | BatchNorm
111-
- | Dropout 0.25 | MaxPool 1x2 | MaxPool 1x2
112-
- | Dense 512 | Dropout 0.25 | Dropout 0.25
113-
- | BatchNorm | Conv 64x3x3 | Conv 32x1x3
114-
- | Dropout 0.25 | MaxPool 1x2 | BatchNorm
115-
- | Dense 512 | Dropout 0.25 | Conv 32x1x3
116-
- | BatchNorm | Dense 512 | BatchNorm
117-
- | Dropout 0.25 | Dropout 0.5 | MaxPool 1x2
118-
- | Dense 88 | Dense 88 | Dropout 0.25
119-
- | _ | _ | Conv 64x1x25
120-
- | _ | _ | BatchNorm
121-
- | _ | _ | Conv 128x1x25
122-
- | _ | _ | BatchNorm
123-
- | _ | _ | Dropout 0.5
124-
- | _ | _ | Conv 88x1x1
125-
- | _ | _ | BatchNorm
126-
- | _ | _ | AvgPool 1x6
127-
- | _ | _ | Sigmoid
128-
__*# Params*__| __*691288*__ | __*1877880*__ | __*284544*__
129-
130-
We are interested in ConvNet, which is:
131-
-|-|-|-|-|-|-| \# Params
132-
---|---|---|---|---|---|---|---
133-
- | Input 5x229 | Conv 32x3x3 | Conv 32x3x3 | BatchNorm | MaxPool 1x2 | Dropout 0.25 | -->
134-
--> | Conv 64x3x3 | MaxPool 1x2 | Dropout 0.25 | Dense 512 | Dropout 0.5 | Dense 88 | __*1877880*__
135-
In our case there are 625 + 1 frames (20 seconds), there is bidirectional __*LSTM*__ layer in between the last two fully-connected layers, batch normalization is heavily used, dropout is not required, and remaining parameters are from https://arxiv.org/pdf/1810.12247.pdf (also, from https://github.com/tensorflow/magenta/blob/master/magenta/models/onsets_frames_transcription/model.py ):
115+
Acoustic convolutional stack is taken from https://arxiv.org/pdf/1612.05153.pdf, Page 5, Section 5 "State of the Art Models", Table 4 "Model Architectures", ConvNet column. In our case there are 625 + 1 frames (20 seconds), there is bidirectional __*LSTM*__ layer in between the last two fully-connected layers, batch normalization is heavily used, dropout is not required, and remaining parameters are from https://arxiv.org/pdf/1810.12247.pdf (also, from https://github.com/tensorflow/magenta/blob/master/magenta/models/onsets_frames_transcription/model.py ):
136116

137117
Page 5, Section 4 "Piano Transcription":
138118
1. `... increased the size of the bidirectional LSTM layers from 128 to 256 units,`
139119
2. `changed the number of filters in the convolutional layers from 32/32/64 to 48/48/96,`
140120
3. `and increased the units in the fully connected layer from 512 to 768.`
141121

142-
So, ConvNet simplifies to:
143-
-|-|-|-|-|-|-|-|-|-|-|-|-
144-
---|---|---|---|---|---|---|---|---|---|---|---|---
145-
Input 626x229 | --> | Conv 48x3x3 | --> | BatchNorm | --> | Conv 48x3x3 | --> | BatchNorm | --> | MaxPool 1x2 | -->
146-
Conv 96x3x3 | --> | BatchNorm | --> | MaxPool 1x2 | --> | Dense 768 | --> | BatchNorm | --> | Bidir LSTM 256 | --> | Dense 88
147-
148122
## Offsets RNN subnetwork
149123
From https://arxiv.org/pdf/1810.12247.pdf, Page 5, Section 4 "Piano Transcription":
124+
150125
`... adding an offset detection head, inspired by Kelz et al. (2018). The offset head feeds into the frame detector but is not directly used during decoding. The offset labels are defined to be the 32ms following the end of each note.`
151126

152127
## Frames RNN combined network
153128
From https://arxiv.org/pdf/1710.11153.pdf, Page 2, Section 3 "Model Configuration":
129+
154130
`The frame activation detector is composed of a separate acoustic model, followed by a fully connected sigmoid layer with 88 outputs. Its output is concatenated together with the output of the onset detector and followed by a bidirectional LSTM with 128 units in both the forward and backward directions. Finally, the output of that LSTM is followed by a fully connected sigmoid layer with 88 outputs. During inference, we use a threshold of 0.5 to determine whether the onset detector or frame detector is active.`
155-
Page 3:
156-
`Our loss function is the sum of two cross-entropy losses: one from the onset side and one from the note side.`
157-
$$L_{total} = L_{onset} + L_{frame}$$
131+
158132
From https://arxiv.org/pdf/1810.12247.pdf, Page 5, Section 4 "Piano Transcription":
133+
159134
`We also stopped gradient propagation into the onset subnetwork from the frame network...`
160135

161136
## Frame-Based Accuracy Metric (stricter than F1-score)
162-
Standard accuracy is not representative, it would be almost 50% immediately at the beginning, and would obviously rise up to 99% very quickly. F1-score is better, but there is stricter accuracy metric, taken from http://c4dm.eecs.qmul.ac.uk/ismir15-amt-tutorial/AMT_tutorial_ISMIR_2015.pdf<br>Page 50, Slide 100, Evaluation Metric 3 [Dixon, 2000]:
163-
$$Acc = \frac{\sum_{n}Ntp[n]}{\sum_{n}Nfp[n] + \sum_{n}Nfn[n] + \sum_{n}Ntp[n]} =$$$$= \frac{tp}{fp + fn + tp} = \frac{tp}{(pp-tp) + (rp-tp) + tp} = \frac{tp}{pp + rp - tp}$$
137+
Standard accuracy is not representative, it would be almost 50% immediately at the beginning, and would obviously rise up to 99% very quickly. F1-score is better, but there is stricter accuracy metric, taken from<br>http://c4dm.eecs.qmul.ac.uk/ismir15-amt-tutorial/AMT_tutorial_ISMIR_2015.pdf<br>Page 50, Slide 100, Evaluation Metric 3 [Dixon, 2000]:
138+
139+
Acc = tp / (fp + fn + tp) = tp / ((pp - tp) + (rp - tp) + tp) = tp / (pp + rp - tp)
164140

165141
## Volumes CNN - separate network
166142
From https://arxiv.org/pdf/1710.11153.pdf, Page 3, Section 3.1 "Velocity Estimation":
167-
`We further extend the model by adding another stack to also predict velocities for each onset. This stack is similar to the others and consists of the same layers of convolutions. This stack does not connect to the other two. The velocity labels are generated by dividing all the velocities by the maximum velocity present in the piece. The smallest velocity does not go to zero, but rather to` $v_{min}$ __**...**__ $v_{max}$` . The stack is trained with the following loss averaged across a batch:`
168-
$$L_{vel} = \sum_{p=p_{min}}^{p_{max}}\sum_{t=0}^{T}I_{onset}(p, t)(v_{label}^{p, t} - v_{predicted}^{p, t})^2$$
169-
`At inference time the output is clipped to [0, 1] and then transformed to a midi velocity by the following mapping:`
170-
$$v_{midi} = 80v_{predicted} + 10$$
171-
### Volumes Accuracy Metric
172-
From https://arxiv.org/pdf/1710.11153.pdf, Page 3, Section 3.1 "Velocity Estimation":
173-
`... we first re-scale all of the ground-truth velocities in a transcription to be in the range [0, 1]. After notes are matched according to their pitch and onset/offset timing, we assemble pairs of the reference (ground-truth) and estimated velocities for matched notes, referred to as` $v_r$ `and` $v_e$ `respectively. We then perform a linear regression to estimate a global scale and offset parameter such that the squared difference between pairs of reference and estimated velocities is minimized:`
174143

175-
Page 4:
176-
$$m, b = \underset{m, b}{argmin}\sum_{i=1}^{M}||v_r(i)-(mv_e(i) + b)||^2$$
177-
`where` __**M**__ `is the number of matches (i.e. number of entries in` $v_r$ `and` $v_e$ `). These scalar parameters are used to re-scale the entries of` $v_e$ `to obtain`
178-
$$\hat{v_e} = \{mv_e(i) + b, i ∈ 1,...,M\}$$
179-
`Finally, a match` __*i*__ `is now only considered correct if, in addition to having its pitch and timing match, it also satisfies` $|v_e(i) − v_r(i)| < τ$ `for some threshold` __**τ**__ `. We used` __**τ**__ ` = 0.1 in all of our evaluations. The precision, recall, and F1 scores are then recomputed as normal based on this newly filtered list of matches.`
144+
`We further extend the model by adding another stack to also predict velocities for each onset. This stack is similar to the others and consists of the same layers of convolutions. This stack does not connect to the other two. The velocity labels are generated by dividing all the velocities by the maximum velocity present in the piece. The smallest velocity does not go to zero, but rather to Vmin ... Vmax.`
180145

146+
`At inference time the output is clipped to [0, 1] and then transformed to a midi velocity by the following mapping:`
147+
148+
Vmidi = 80 * Vpredicted + 10
181149

182150
## 2.1. Training & Validation
183151
From https://arxiv.org/pdf/1710.11153.pdf (also from https://github.com/tensorflow/magenta/blob/master/magenta/models/onsets_frames_transcription/model.py ):
152+
184153
Page 4, Section 4 "Experiments":
154+
185155
`... batch size of 8 ...` __*In our case it is 4 for onsets, offsets, and frames subnetworks, and 8 for volumes CNN*__
156+
186157
`... Adam optimizer ...`
158+
187159
### Keras Backend
188160
We use __*CuDNNLSTM*__ as recurrent layer, and it supports only __*Tensorflow*__ backend, so, it is impossible to use __*CNTK*__.
189161

@@ -195,27 +167,35 @@ From https://arxiv.org/pdf/1710.11153.pdf, Page 2, Section 2 "Dataset and Metric
195167
4. `Poor quality transcriptions can still result in high frame scores due to short spurious notes and repeated notes that should be held.`
196168

197169
Page 4, Section 4 "Experiments":
170+
198171
`To our ears, the decrease in transcription quality is best reflected by the note-with-offset scores.`
199172

200173
From https://arxiv.org/pdf/1810.12247.pdf, Page 5, Section 4 "Piano Transcription", Table 4:
174+
201175
`Note-based scores calculated by the mir eval library, frame-based scores as defined in Bay et al. (2009). Final metric is the mean of scores calculated per piece.`
202176

203177

204178
# 3 Magenta to Keras
205179

206180
In the third IPython template, instead of training my own model, I just copied the weights from the Google's pre-trained tensorflow checkpoint:
207181
https://storage.googleapis.com/magentadata/models/onsets_frames_transcription/maestro_checkpoint.zip
208-
(or look for the link here: https://github.com/tensorflow/magenta/tree/master/magenta/models/onsets_frames_transcription)
182+
183+
Or look for the link here:
184+
https://github.com/tensorflow/magenta/tree/master/magenta/models/onsets_frames_transcription)
209185

210186

211187
# 4 Piano Audio to Midi
212188

213189
No instrument information is extracted, and all transcribed notes get combined into one part.
214190

215191
From https://arxiv.org/pdf/1710.11153.pdf:
192+
216193
Page 1 "Abstract":
194+
217195
`During inference, we restrict the predictions from the framewise detector by not allowing a new note to start unless the onset detector also agrees that an onset for that pitch is present in the frame.`
196+
218197
Page 2, Section 3 "Model Configuration":
198+
219199
`An activation from the frame detector is only allowed to start a note if the onset detector agrees that an onset is present in that frame.`
220200

221201
There could be lots of noticeable false-positive notes in high octaves where they absolutely surely should not be. If it is too annoying, then I cannot think of any better solution than to use much higher threshold for higher octaves :disappointed:

0 commit comments

Comments
 (0)