示例#1
0
    def __init__(self, args, dissectdir=None, device=None):
        self.cachedir = os.path.join(dissectdir, 'cache')
        self.device = device if device is not None else torch.device('cpu')
        self.dissectdir = dissectdir
        self.modellock = threading.Lock()

        # Load the generator from the pth file.
        args_copy = EasyDict(args)
        args_copy.edit = True
        model = create_instrumented_model(args_copy)
        model.eval()
        self.model = model

        # Get the set of layers of interest.
        # Default: all shallow children except last.
        self.layers = sorted(model.retained.keys())

        # Move it to CUDA if wanted.
        model.to(device)

        self.quantiles = {
            layer:
            load_quantile_if_present(os.path.join(self.dissectdir,
                                                  safe_dir_name(layer)),
                                     'quantiles.npz',
                                     device=torch.device('cpu'))
            for layer in self.layers
        }
示例#2
0
def run_command(args):
    verbose_progress(True)
    progress = default_progress()
    classname = args.classname # 'door'
    layer = args.layer # 'layer4'
    num_eval_units = 20

    assert os.path.isfile(os.path.join(args.outdir, 'dissect.json')), (
            "Should be a dissection directory")

    if args.variant is None:
        args.variant = 'ace'

    if args.l2_lambda != 0.005:
        args.variant = '%s_reg%g' % (args.variant, args.l2_lambda)

    cachedir = os.path.join(args.outdir, safe_dir_name(layer), args.variant,
            classname)

    if pidfile_taken(os.path.join(cachedir, 'lock.pid'), True):
        sys.exit(0)

    # Take defaults for model constructor etc from dissect.json settings.
    with open(os.path.join(args.outdir, 'dissect.json')) as f:
        dissection = EasyDict(json.load(f))
    if args.model is None:
        args.model = dissection.settings.model
    if args.pthfile is None:
        args.pthfile = dissection.settings.pthfile
    if args.segmenter is None:
        args.segmenter = dissection.settings.segmenter
    # Default segmenter class
    if args.segmenter is None:
        args.segmenter = ("netdissect.segmenter.UnifiedParsingSegmenter(" +
                "segsizes=[256], segdiv='quad')")

    if (not args.no_cache and
        os.path.isfile(os.path.join(cachedir, 'snapshots', 'epoch-%d.npy' % (
            args.train_epochs - 1))) and
        os.path.isfile(os.path.join(cachedir, 'report.json'))):
        print('%s already done' % cachedir)
        sys.exit(0)

    os.makedirs(cachedir, exist_ok=True)

    # Instantiate generator
    model = create_instrumented_model(args, gen=True, edit=True,
            layers=[args.layer])
    if model is None:
        print('No model specified')
        sys.exit(1)
    # Instantiate segmenter
    segmenter = autoimport_eval(args.segmenter)
    labelnames, catname = segmenter.get_label_and_category_names()
    classnum = [i for i, (n, c) in enumerate(labelnames) if n == classname][0]
    num_classes = len(labelnames)
    with open(os.path.join(cachedir, 'labelnames.json'), 'w') as f:
        json.dump(labelnames, f, indent=1)

    # Sample sets for training.
    full_sample = netdissect.zdataset.z_sample_for_model(model,
            args.search_size, seed=10)
    second_sample = netdissect.zdataset.z_sample_for_model(model,
            args.search_size, seed=11)
    # Load any cached data.
    cache_filename = os.path.join(cachedir, 'corpus.npz')
    corpus = EasyDict()
    try:
        if not args.no_cache:
            corpus = EasyDict({k: torch.from_numpy(v)
                for k, v in numpy.load(cache_filename).items()})
    except:
        pass

    # The steps for the computation.
    compute_present_locations(args, corpus, cache_filename,
            model, segmenter, classnum, full_sample)
    compute_mean_present_features(args, corpus, cache_filename, model)
    compute_feature_quantiles(args, corpus, cache_filename, model, full_sample)
    compute_candidate_locations(args, corpus, cache_filename, model, segmenter,
            classnum, second_sample)
    # visualize_training_locations(args, corpus, cachedir, model)
    init_ablation = initial_ablation(args, args.outdir)
    scores = train_ablation(args, corpus, cache_filename,
            model, segmenter, classnum, init_ablation)
    summarize_scores(args, corpus, cachedir, layer, classname,
            args.variant, scores)
    if args.variant == 'ace':
        add_ace_ranking_to_dissection(args.outdir, layer, classname, scores)