Example #1
0
    def _cent_pitch_to_feature(self, pitch_cent, ref_freq):
        feature = PitchDistribution.from_cent_pitch(
            pitch_cent, ref_freq=ref_freq, kernel_width=self.kernel_width,
            step_size=self.step_size)
        if self.feature_type == 'pcd':
            feature.to_pcd()

        return feature
Example #2
0
    def _cent_pitch_to_feature(self, pitch_cent, ref_freq):
        feature = PitchDistribution.from_cent_pitch(
            pitch_cent,
            ref_freq=ref_freq,
            kernel_width=self.kernel_width,
            step_size=self.step_size)
        if self.feature_type == 'pcd':
            feature.to_pcd()

        return feature
    def _compute_seyir_features_per_interval(self, pp, tt, t_intervals,
                                             t_center):
        seyir_features = []
        maxdur = max(ti[1] - ti[0] for ti in t_intervals)

        for ti, tc in zip(t_intervals, t_center):
            p_cent, p_sliced = self._slice_pitch(pp, ti, tt)

            if p_cent.size == 0:  # silence
                seyir_features.append(
                    {'pitch_distribution': [], 'average_pitch': np.nan,
                     'stable_pitches': [], 'time_interval': ti,
                     'time_center': tc})
            else:
                pd = PitchDistribution.from_cent_pitch(
                    p_cent, ref_freq=self._dummy_ref_freq,
                    kernel_width=self.kernel_width, step_size=self.step_size)

                # reconvert to Hz
                pd.cent_to_hz()

                # normalize to 1 (instead of the area under the curve)
                maxval = max(pd.vals)
                num_ratio = float(len(p_cent)) / len(p_sliced)  # ratio of
                # number of samples
                time_ratio = (ti[1] - ti[0]) / maxdur
                pd.vals = pd.vals * num_ratio * time_ratio / maxval

                # get the stable pitches, i.e. peaks
                peak_idx, peak_vals = pd.detect_peaks()
                stable_pitches = [{'frequency': float(pd.bins[idx]),
                                   'value': float(val)}
                                  for idx, val in zip(peak_idx, peak_vals)]

                # get the average pitch
                avpitch = Converter.cent_to_hz(np.mean(p_cent),
                                               self._dummy_ref_freq)

                seyir_features.append(
                    {'pitch_distribution': pd, 'average_pitch': avpitch,
                     'stable_pitches': stable_pitches, 'time_interval': ti,
                     'time_center': tc})

        return seyir_features
def evaluate(step_size, kernel_width, distribution_type, model_type,
             experiment_type, dis_measure, k_neighbor, min_peak_ratio,
             result_folder):
    test_folder = os.path.abspath(os.path.join(io.get_folder(
        os.path.join(result_folder, 'testing', experiment_type), model_type,
        distribution_type, step_size, kernel_width, dis_measure,
        k_neighbor, min_peak_ratio)))
    result_files = get_filenames_in_dir(test_folder,
                                        keyword='*results.json')[0]

    anno_file = './data/ottoman_turkish_makam_recognition_dataset' \
                '/annotations.json'
    annotations = json.load(open(anno_file))
    makam_labels = np.unique([a['makam'] for a in annotations]).tolist()
    evaluator = Evaluator()

    tmp_bins = np.arange(0, 1200, step_size)
    if experiment_type == 'tonic':
        eval_folds = {'num_correct_tonic': 0, 'tonic_accuracy': 0,
                      'tonic_deviation_distribution': PitchDistribution(
                          tmp_bins, np.zeros(np.shape(tmp_bins)),
                          kernel_width=0, ref_freq=None)}
    elif experiment_type == 'mode':
        eval_folds = {'num_correct_mode': 0, 'mode_accuracy': 0,
                      'confusion_matrix': {
                          'matrix': np.zeros((len(makam_labels),
                                              len(makam_labels))),
                          'labels': makam_labels}
                      }
    else:
        eval_folds = {'num_correct_tonic': 0, 'tonic_accuracy': 0,
                      'num_correct_mode': 0, 'mode_accuracy': 0,
                      'num_correct_joint': 0, 'joint_accuracy': 0,
                      'tonic_deviation_distribution': PitchDistribution(
                          tmp_bins, np.zeros(np.shape(tmp_bins)),
                          kernel_width=0, ref_freq=None),
                      'confusion_matrix': {
                          'matrix': np.zeros((len(makam_labels),
                                              len(makam_labels))),
                          'labels': makam_labels}
                      }

    for rf in result_files:
        res = json.load(open(rf))
        eval_file = os.path.join(os.path.dirname(rf), 'evaluation.json')

        rec_ev = []
        for aa in annotations:
            mbid = os.path.split(aa['mbid'])[-1]

            if mbid in res.keys():  # in testing data
                if experiment_type == 'tonic':
                    rec_ev.append(evaluator.evaluate_tonic(res[mbid][0][0],
                                                           aa['tonic'], mbid))
                    rec_ev[-1]['tonic_eval'] = rec_ev[-1]['tonic_eval'].\
                        tolist()
                    rec_ev[-1]['same_octave'] = rec_ev[-1]['same_octave'].\
                        tolist()

                elif experiment_type == 'mode':
                    rec_ev.append(evaluator.evaluate_mode(res[mbid][0][0],
                                                          aa['makam'], mbid))

                else:
                    rec_ev.append(evaluator.evaluate_joint(
                        [res[mbid][0][0][0], aa['tonic']],
                        [res[mbid][0][0][1], aa['makam']], mbid))

                    rec_ev[-1]['tonic_eval'] = rec_ev[-1]['tonic_eval'].\
                        tolist()
                    rec_ev[-1]['same_octave'] = rec_ev[-1]['same_octave'].\
                        tolist()
                    try:
                        rec_ev[-1]['joint_eval'] = rec_ev[-1]['joint_eval'].\
                            tolist()
                    except AttributeError:
                        # TODO: find out why i've put an exception here
                        pass

        ev = {'per_recording': rec_ev, 'overall': {}}
        try:
            ev['overall']['num_correct_tonic'] = sum(re['tonic_eval']
                                                     for re in rec_ev)
            ev['overall']['tonic_accuracy'] = (
                ev['overall']['num_correct_tonic'] / len(rec_ev))

            ev['overall']['tonic_deviation_distribution'] = \
                PitchDistribution.from_cent_pitch(
                    [re['cent_diff'] for re in rec_ev], ref_freq=None,
                    step_size=step_size, kernel_width=0)

            try:  # force to pcd
                ev['overall']['tonic_deviation_distribution'].to_pcd()
            except AssertionError:
                pass

            eval_folds['num_correct_tonic'] += ev['overall'][
                'num_correct_tonic']
            eval_folds['tonic_deviation_distribution'].vals +=\
                ev['overall']['tonic_deviation_distribution'].vals

            ev['overall']['tonic_deviation_distribution'] = \
                ev['overall']['tonic_deviation_distribution'].to_dict()
        except KeyError:
            pass
        try:
            ev['overall']['num_correct_mode'] = sum(re['mode_eval']
                                                    for re in rec_ev)
            ev['overall']['mode_accuracy'] = (
                ev['overall']['num_correct_mode'] / len(rec_ev))

            ev['overall']['confusion_matrix'] = {
                'matrix': confusion_matrix(
                    [re['annotated_mode'] for re in rec_ev],
                    [re['estimated_mode'] for re in rec_ev],
                    labels=makam_labels),
                'labels': makam_labels}

            eval_folds['num_correct_mode'] += ev['overall'][
                'num_correct_mode']

            eval_folds['confusion_matrix']['matrix'] +=\
                ev['overall']['confusion_matrix']['matrix']

            ev['overall']['confusion_matrix']['matrix'] = \
                ev['overall']['confusion_matrix']['matrix'].astype(int).tolist()

        except KeyError:
            pass
        try:
            ev['overall']['num_correct_joint'] = sum(re['joint_eval']
                                                     for re in rec_ev)
            ev['overall']['joint_accuracy'] = (
                ev['overall']['num_correct_joint'] / len(rec_ev))

            eval_folds['num_correct_joint'] += ev['overall'][
                'num_correct_joint']
        except KeyError:
            pass

        json.dump(ev, open(eval_file, 'w'))

    if experiment_type == 'tonic':
        eval_folds['tonic_accuracy'] = eval_folds['num_correct_tonic'] / 10
        eval_folds['tonic_deviation_distribution'] = \
            eval_folds['tonic_deviation_distribution'].to_dict()
    elif experiment_type == 'mode':
        eval_folds['mode_accuracy'] = eval_folds['num_correct_mode'] / 10
        eval_folds['confusion_matrix']['matrix'] = \
            eval_folds['confusion_matrix']['matrix'].astype(int).tolist()
    else:
        eval_folds['tonic_accuracy'] = eval_folds['num_correct_tonic'] / 10
        eval_folds['mode_accuracy'] = eval_folds['num_correct_mode'] / 10
        eval_folds['joint_accuracy'] = eval_folds['num_correct_joint'] / 10

        eval_folds['tonic_deviation_distribution'] = \
            eval_folds['tonic_deviation_distribution'].to_dict()
        eval_folds['confusion_matrix']['matrix'] = \
            eval_folds['confusion_matrix']['matrix'].tolist()

    json.dump(eval_folds,
              open(os.path.join(test_folder, 'overall_eval.json'), 'w'))

    return u'{0:s} done'.format(test_folder)