Пример #1
0
def batch_predict_rois(flist, tuned_clfs, params, path_audio_db='./'):
    """
    Predict the labels of rois in a list of audio files. 
    
    Parameters
    ----------
    flist: pandas DataFrame
        list of audio filenames to be analysed. Column name must be 'fname'
    tuned_clfs: dict
        data structure with tuned classifiers by grid search or random search
    params: dict
        data structure with the same parameters used to train the classifiers.
        Keys to be included: 'sample_rate_wav', 'flims', 'tlen', 'th', 
        'opt_spec', 'opt_shape_str'
    path_audio_db: str, default current directory
        path pointing to the directory where the audio files are located. 
        Note that all files in flist must be in the same directory
    
    Returns
    -------
    predictions: dict
        data structure with name of audio files as keys. Each element in the
        dictionary has a DataFrame with predictions for every region interest
        found. Predictions are given as probabilities for three different 
        classifiers, namely Random Forest ('rf'), Adaboost ('adb') and Support
        Vector Machines ('svm').
    
    """
    t_start = time.time() # compute processing time
    # Load params and variables
    clf_svm = tuned_clfs['svm'].best_estimator_
    clf_rf = tuned_clfs['rf'].best_estimator_
    clf_adb = tuned_clfs['adb'].best_estimator_
    flims = params['flims']
    tlen = params['tlen']
    th = params['th']
    opt_spec = params['opt_spec']
    opt_shape = opt_shape_presets(params['opt_shape_str'])
    sample_rate_std = params['sample_rate_wav']
    
    # Batch: compute rois, features and predict through files
    predictions = dict()
    for idx, fname in enumerate(flist['fname']):
        print(idx+1, '/', len(flist), fname)
        # fname = flist['fname'][0]
        s, fs = sound.load(path_audio_db+fname)
        # Check sampling frequency on file
        if fs==sample_rate_std:
            pass
        else:
            print('Warning: sample rate mismatch, resampling audio file to standard', 
                  sample_rate_std, 'Hz')
            s = resample(s, fs, sample_rate_std, res_type='kaiser_fast')
            fs = sample_rate_std
            
        rois = find_rois_cwt(s, fs, flims, tlen, th)    
        if rois.empty:
            #print('< No detection on file >')
            predictions[fname] = -1
        else:
            # filter rois shorter than 25% of tlen
            idx_rm = (rois.max_t - rois.min_t) < tlen*0.25
            rois.drop(index=np.where(idx_rm)[0], inplace=True)
            rois.reset_index(inplace=True, drop=True)
            if rois.empty:
                print('< No detection on file >')
                predictions[fname] = -1
            else:        
                # compute features
                rois_features = compute_rois_features(s, fs, rois, opt_spec, opt_shape, flims)
                # predict
                X = rois_features.loc[:,rois_features.columns.str.startswith('shp')]
                #X['frequency'] = preprocessing.scale(X['frequency'])  # new! scale frequency
                pred_rf = pd.DataFrame(data=clf_rf.predict_proba(X), 
                                       columns=[s + '_rf' for s in clf_rf.classes_.astype('str')])
                pred_adb = pd.DataFrame(data=clf_adb.predict_proba(X), 
                                        columns=[s + '_adb' for s in clf_adb.classes_.astype('str')])
                pred_svm = pd.DataFrame(data=clf_svm.predict_proba(X), 
                                        columns=[s + '_svm' for s in clf_svm.classes_.astype('str')])
                # save to variable
                pred_proba_file = pd.concat([rois, pred_rf, pred_adb, pred_svm], axis=1)
                predictions[fname] = pred_proba_file
    
    t_stop = time.time() # compute processing time
    print('Batch process completed. Processing time: ', np.round(t_stop - t_start,2),'s')
    return predictions
Пример #2
0
def batch_feature_rois_no_verb(rois_list, params_features, path_audio):
    """
    Computes features for a list of files
    
    Parameters:
    ----------
        params_features: dict
            Dictionary with the basic parameters to feed find_rois: 
            'flims', 'tlen', and 'th'.
        path_flist : str
            Path to a *.txt file with the list of audio filenames to process
        path_audio : str
            Path to the place were the dataset of audio files are stored
        path_save : str
            Path with the file name to save the csv

    Returns:
    -------
        info_features: dic
            Dictionary with features and all the parameters used to compute the features.
            Included keys: features, parameters_df, opt_shape, opt_spectro
            
    """    
    ## TODO: when the time limits are too short, the function has problems
    # load parameters
    flims = params_features['flims']
    opt_spec = params_features['opt_spec']
    opt_shape = opt_shape_presets(params_features['opt_shape_str'])

    # load detection data
    
    features = []
    for idx, file in enumerate(rois_list):   
        # unpack file values
        fname = file['fname']
        rois_tf = file['rois']
        #print(idx+1, '/', len(rois_list), fname)    
        
        if rois_tf.empty:
            #print('< No detection on file >')
            features.append({'fname':fname, 'features': pd.DataFrame()})
        else:
            # load materials: sound, spectrogram
            s, fs = sound.load(path_audio+fname)
            im, dt, df, ext = sound.spectrogram(s, fs, nperseg=opt_spec['nperseg'], 
                                                overlap=opt_spec['overlap'], fcrop=flims, 
                                                rescale=False, db_range=opt_spec['db_range'])
            
            # format rois to bbox
            ts = np.arange(ext[0], ext[1], dt)
            f = np.arange(ext[2],ext[3]+df,df)
            rois_bbox = format_rois(rois_tf, ts, f, fmt='bbox')
                
            # roi to image blob
            im_blobs = rois_to_imblobs(np.zeros(im.shape), rois_bbox)
            
            # get features: shape, center frequency
            im = normalize_2d(im, 0, 1)
            bbox, params, shape = shape_features(im, im_blobs, resolution='custom', 
                                                 opt_shape=opt_shape)
            _, cent = centroid(im, im_blobs)
            cent['frequency']= f[round(cent.y).astype(int)]  # y values to frequency
            
            # format rois to time-frequency
            rois_out = format_rois(bbox, ts, f, fmt='tf')
            
            # combine into a single df
            aux_df = pd.concat([rois_out, shape, cent.frequency], axis=1)
            #        aux_df['fname'] = fname
            features.append({'fname':fname, 'features': aux_df})
    
    
    # Arranges the data into a dictionary
    info_features = {'features': features,
                     'parameters_df': params,
                     'opt_shape': opt_shape,
                     'opt_spectro': opt_spec}
    return info_features