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)