Exemple #1
0
def parse_config_json(config_path, lastfm):
    ''' Parse a JSON configuration file into a handy Namespace.

    Parameters
    -----------
    config_path: str
        The path to the .json file, or the directory where it is saved.

    lastfm: str, LastFm, LastFm2Pandas
        Instance of the tags database. If a string is passed, try to instantiate the tags database from the (string as a) path.
        
    Returns
    -------
    config: argparse.Namespace
    '''

    if not isinstance(lastfm, (LastFm, LastFm2Pandas)):
        lastfm = LastFm(os.path.expanduser(lastfm))

    # if config_path is a folder, assume the folder contains a config.json
    if os.path.isdir(os.path.expanduser(config_path)):
        config_path = os.path.join(os.path.abspath(os.path.expanduser(config_path)), 'config.json')
    else:
        config_path = os.path.expanduser(config_path)

    # load json
    with open(config_path, 'r') as f:
        config_dict = json.loads(f.read())

    # create config namespace
    config = argparse.Namespace(**config_dict['model'], **config_dict['model-training'], **config_dict['tfrecords'])
    config.path = os.path.abspath(config_path)

    # update config (optimizer will be instantiated with tf.get_optimizer using {"class_name": config.optimizer_name, "config": config.optimizer})
    config.optimizer_name = config.optimizer.pop('name')

    # read tags from popularity dataframe
    top = config_dict['tags']['top']
    if (top is not None) and (top != config.n_tags):
        top_tags = lastfm.popularity()['tag'][:top].tolist()
        tags = set(top_tags)
    else:
        tags = None

    # update tags according to 'with' (to be added) and 'without' (to be discarded)
    if tags is not None:
        if config_dict['tags']['with']:
            tags.update(config_dict['tags']['with'])
        
        if config_dict['tags']['without']:
            tags.difference_update(config_dict['tags']['without'])

        tags = list(tags)
    else:
        raise ValueError("parameter 'with' is inconsistent to parameter 'top'")

    # write final tags
    config.tags = np.sort(lastfm.tag_to_tag_num(tags)) if tags is not None else None # sorting is necessary to aviod unexpected behaviour

    # write final tags to merge together
    config.tags_to_merge = lastfm.tag_to_tag_num(config_dict['tags']['merge']) if config_dict['tags']['merge'] is not None else None

    # count number of classes
    config.n_output_neurons = len(tags) if tags is not None else config.n_tags
    
    return config