Giter VIP home page Giter VIP logo

Comments (7)

jongwook avatar jongwook commented on June 8, 2024

Hi Tristan, thanks for your interest.

I'm in the process of rewriting the repo to make it easier to reuse/extend, so please stay tuned for updates!

Meanwhile, the code that I used to convert the pitch values to the 360-D vectors is:

import mir_eval
import numpy as np
from scipy.stats import norm

classifier_lowest_hz = 31.70
classifier_lowest_cent = mir_eval.melody.hz2cents(np.array([classifier_lowest_hz]))[0]
classifier_cents_per_bin = 20
classifier_octaves = 6
classifier_total_bins = int((1200 / classifier_cents_per_bin) * classifier_octaves)
classifier_cents = np.linspace(0, (classifier_total_bins - 1) * classifier_cents_per_bin, classifier_total_bins) + classifier_lowest_cent
classifier_cents_2d = np.expand_dims(classifier_cents, axis=1)
classifier_norm_stdev = 25
classifier_pdf_normalizer = norm.pdf(0)

def to_classifier_label(pitch, crossentropy=False):
    """
    Converts pitch labels in cents, to a vector representing the classification label
    Uses the normal distribution centered at the pitch and the standard deviation of 25 cents,
    normalized so that the exact prediction has the value 1.0.
    :param pitch: a number of ndarray of dimension 1
    pitch values in cents, as returned by hz2cents with base_frequency = 10 (default)
    :return: ndarray
    """
    if np.isscalar(pitch):
        vec = norm.pdf((classifier_cents - pitch) / classifier_norm_stdev)
        vec /= crossentropy and classifier_pdf_normalizer or np.sum(vec)
        return vec
    else:
        result = np.zeros((classifier_total_bins, len(pitch)))
        for i, p in enumerate(pitch):
            vec = norm.pdf((classifier_cents - p) / classifier_norm_stdev)
            vec /= crossentropy and classifier_pdf_normalizer or np.sum(vec)
            result[:, i] = vec
        return result

def to_weighted_average_cents(label):
    if label.ndim == 1:
        productsum = np.sum(classifier_cents * label)
        weightsum = np.sum(label)
        return productsum / weightsum
    if label.ndim == 2:
        productsum = np.sum(classifier_cents_2d * label, axis=0)
        weightsum = np.sum(label, axis=0)
        return productsum / weightsum
    raise Exception("label should be either 1d or 2d ndarray")

from crepe.

tbehrensprivate avatar tbehrensprivate commented on June 8, 2024

You are the best!

Meanwhile I implemented this:

frequency_reference = 10
    c_true = 1200 * math.log(frequency / frequency_reference, 2)

    cents_mapping = np.linspace(0, 7180, 360) + 1997.3794084376191
    target = np.exp(-(cents_mapping - c_true)**2 / (2 * 25**2))

Seems to produce the same. What do you think?

from crepe.

jongwook avatar jongwook commented on June 8, 2024

yeah, it seems right! mine got a bit complex to work with either 1D / 2D dimensions, and to deal with an alternative training setup where it uses a different normalization scheme.

from crepe.

tbazin avatar tbazin commented on June 8, 2024

Hi! Quick question on this discussion:
The CREPE paper states that:

The bin corresponding to the ground truth fundamental frequency is given a magnitude of one.

But, with the final implementation discussed here, the bin is given a magnitude of one only if the target pitch happens to fall exactly on one of the values of the cents_mapping matrix, otherwise it's slightly lower.
Is that the actual behavior that was implemented for training the model, or should the target frequencies be rounded to the nearest bin value in order to properly assign magnitudes on the bin level?

from crepe.

jongwook avatar jongwook commented on June 8, 2024

Hi! You're correct that it is not given a magnitude of one unless the target pitch falls exactly on the center value, when I trained the model as well. Maybe I should have described it more accurately in the paper.

This is a repo that contains the code I used for training (not so well maintained or documented), and the code I commented above is actually from this training code.

IMO this behavior is advantageous for the post-processing step that takes weighted average to find more precise predictions than the frequency bin resolution (details in README.md):

image

from crepe.

symbiosdotwiki avatar symbiosdotwiki commented on June 8, 2024

Hi I just wanted to leave a comment noting that C1 should be 32.7Hz (correctly stated in the pdf paper) but it implemented as 31.7Hz in the code leading to incorrect translation of bin to Hz if you are using information from the paper.

from crepe.

jongwook avatar jongwook commented on June 8, 2024

Oops... thanks for letting me know.

I found that the training was also done assuming C1 is 32.7 Hz, so while the overall range is about half semitone lower than the paper, the predictions in Hz from the code should be accurate.

from crepe.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.