Hierarchical optimization predicts plasticity in the macaque inferior temporal cortex following object training.
The 11 matches
- [1] § Methods › Simulation of monkey training using artificial neural networks › Base models ↔ analysis/paperFigures.py, lines 1514–1582 · score 0.80 · SimCLR, barlowTwins, MoCov2, ResNet18, VGG16, AlexNet
- [2] § Results › IT-like models best predict differences along untrained dimensions in IT ↔ analysis/paperFigures.py, lines 1692–1785 · score 0.72 · Horizontal position, Vertical position, mapped layers, rx, ry, rz
- [3] § Methods › Simulation of monkey training using artificial neural networks › Training strategies ↔ training/train_wandb_binaryTask.py, lines 382–522 · score 0.71 · cross entropy loss, learning rate scheduler, decay, epochs, validation, optimizing
- [4] § Methods › Simulation of monkey training using artificial neural networks › Training strategies ↔ training/train_wandb_v2.py, lines 18–145 · score 0.71 · cross entropy loss, learning rate scheduler, decay, epochs, validation, optimizing
- [5] § Methods › Neural and behavioral data analyses › Population-level object decoding ↔ analysis/categoryDecodes.py, lines 24–54 · score 0.61 · logistic regression, L2, stratified, fold, classifiers, splits
- [6] § Methods › Simulation of monkey training using artificial neural networks › Aligning base models to task-naïve IT responses ↔ analysis/paperFigures.py, lines 1216–1312 · score 0.59 · shifted log, 1–100, fit, accuracies, decodes, models
- [7] § Methods › Neural and behavioral data analyses › Neural recording quality metrics and pooling ↔ analysis/categoryDecodes.py, lines 638–740 · score 0.58 · spearman brown corrected, reliability criterion, split, repetition, stem, untrained
- [8] § Methods › Neural and behavioral data analyses › Behavioral metrics ↔ analysis/consistency.py, lines 15–81 · score 0.56 · Spearman Brown corrected, random splits, repetitions, reliability, behavioral, metric
- [9] § Results › Task-optimized ANNs reproduce IT’s task-training-induced differences ↔ analysis/paperFigures.py, lines 1788–1916 · score 0.55 · signal rotation, metrics matched, covariance, selectivity, models, training
- [10] § Methods › Simulation of monkey training using artificial neural networks › Aligning base models to task-naïve IT responses ↔ analysis/compute_modelFeatures.py, lines 79–195 · score 0.52 · brain score, mapped layer, cross, validated, predictivity, models
- [11] § Results › Task-optimized ANNs reproduce IT’s task-training-induced differences ↔ analysis/paperFigures.py, lines 1788–1916 · score 0.51 · Signal rotation, metrics matched, covariance, ratio, models, training
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
Python · 2,242 lines · 113 KB · MIT · 5 matches
- from pathlib import Path
- import joblib
- import matplotlib.pyplot as plt
- import numpy as np
- import pandas as pd
- import seaborn as sns
- from matplotlib_venn import venn3
- from pingouin import kruskal
- from scipy.optimize import curve_fit
- from scipy.stats import gaussian_kde
- from scipy.integrate import quad
- from analysis.categoryDecodes import load_ModelIT_categoryDecodes_allModels, load_MonkeyIT_Decodes_deltas
- from analysis.categoryDecodes import load_MonkeyIT_Decodes, get_ModelIT_categoryDecoding_UnitSiteScaling, \
- load_MonkeyIT_Decodes_permutation, load_MonkeyIT_subregion_Decodes, load_MonkeyIT_Decodes_novel500, \
- load_MonkeyIT_Decodes_novel500_HVMcontrol, load_MonkeyIT_Decodes_singleAnimal
- from analysis.consistency import get_consistency_modelIT_modelBehavior, get_consistency_behavior_ITneurons
- from analysis.orthogonalDecodes import load_ModelITorthogonalDecodes_selection, load_neuralITorthogonalDecodes,load_ModelLayer_orthogonalDecodes_selection
- from analysis.rsa import load_ModelRDMs_allModels, load_neuralRDMs_deltas
- from analysis.rsa import load_neuralRDMs, load_neuralRDMs_permutation, load_neuralRDMs_singleAnimal
- from analysis.selectivity import load_ModelSelectivity_allModels, load_neuralITselectivity_deltas
- from analysis.selectivity import load_neuralITselectivity, load_neuralITselectivity_permutation, load_neuralITselectivity_singleAnimal
- from analysis.trainingResults import loadTrainingResults
- from analysis.LFI import get_model_change_metrics
- from analysis.utils_behavioralData import load_MonkeyBehavior_individual, load_MonkeyBehavior_pooled, \
- getPerformanceThreshold, get_MonkeyBehavioralMetrics_draws, load_MonkeyTraining_dPrime, load_MonkeyTraining_individual
- from analysis.utils_neuralData import get_SiteReliability, load_MonkeyNeurons_pooled_rates, load_orthogonalFeatures
- from analysis.metrics import dPrime_monkey, computeDelta
- cm = 1 / 2.54
- pretraining_mapping = {'resnet18_v1': 'supervised',
- 'resnet34_v1': 'supervised',
- 'resnet50_v1': 'supervised',
- 'resnet50_MoCov2_200epochs': 'self-supervised',
- 'resnet50_barlowTwins_300epochs': 'self-supervised',
- 'resnet50_simclr_100epochs': 'self-supervised',
- 'resnet101_v1': 'supervised',
- 'resnet152_v1': 'supervised',
- 'alexnet': 'supervised',
- 'resnext101_32x8d_wsl': 'WSL-supervised',
- 'resnext101_32x16d_wsl': 'WSL-supervised',
- 'vgg16': 'supervised',
- 'vgg19': 'supervised'}
- def FigureS1_TrainTestSets(colors=None, figure_dir=None, source_file_dir=None):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- train_df = load_orthogonalFeatures(split='train')
- train_df['category'] = train_df['obj'].map({'bear': 'bear','ELEPHANT_M': 'elephant','face0001': 'person',
- 'alfa155': 'car','breed_pug': 'dog','Apple_Fruit_obj': 'apple',
- '001': 'chair','f16': 'plane'})
- train_df['xpos'] = train_df['ty'] * -1
- train_df['ypos'] = train_df['tz']
- train_df['ecc'] = np.sqrt(train_df['xpos']**2 + train_df['ypos']**2)
- train_df['filename'] = 'im'+ train_df['legacy_mkturk_image_num'].astype(str)
- train_df = train_df.rename(columns={'s':'objSize'})
- train_df['split'] = 'train'
- test_df = load_orthogonalFeatures(split='test')
- test_df['split'] = 'test'
- df = pd.concat([train_df, test_df], ignore_index=True)
- title_mapping={'xpos': 'Vertical position',
- 'ypos': 'Horizontal position',
- 'objSize': 'Object size',
- 'ecc': 'Eccentricity',
- 'ryz': 'Rotation (rx)',
- 'rxz': 'Rotation (ry)',
- 'rxy': 'Rotation (rz)',}
- g, ax = plt.subplots(2,4, sharex=False, sharey=True, figsize=(15*cm,10*cm), squeeze=False)
- ax = ax.flatten()
- for i, var in enumerate(['xpos', 'ypos', 'objSize','ecc', 'ryz', 'rxz', 'rxy']):
- sns.histplot(data=df, hue='split', kde=True, x=var, bins=100,ax=ax[i], legend=False)
- ax[i].set_xlabel(f"{title_mapping[var]}")
- ax[i].set_ylabel(' ')
- ax[0].set_ylabel('# images')
- plt.tight_layout()
- g.savefig(figure_dir + 'FigureS1_datasets_v0.png', dpi=300)
- g.savefig(figure_dir + 'FigureS1_datasets_v0.pdf', dpi=300, transparent=True)
- df.to_csv(source_file_dir + 'FigureS1_datasets.csv', index=False)
- def FigureS2_trainingCurves(figure_dir=None, source_file_dir = None):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- df_trials = load_MonkeyTraining_individual()
- num_trials_day = df_trials.groupby(['day', 'subject'], as_index=False)['trial'].nunique()
- g = sns.catplot(data=num_trials_day, x='day', hue='subject', y='trial', kind='bar',
- height=6 * cm, legend=False, aspect=1.6)
- g.set_xlabels('Training day')
- g.set_ylabels("# trials")
- g.savefig(figure_dir + 'FigureS2_LearningCurves_v2.png', dpi=300)
- g.savefig(figure_dir + 'FigureS2_LearningCurves_v2.pdf', dpi=300, transparent=True)
- num_trials_day.to_csv(source_file_dir + 'FigureS2_LearningCurves_v2.csv', index=False)
- # compute duration in number of days
- print(df_trials.groupby('subject')['date'].max() - df_trials.groupby('subject')['date'].min())
- df_dPrime = load_MonkeyTraining_dPrime()
- g = sns.relplot(data=df_dPrime, x= 'start_trial', y='dPrime', hue='subject', kind='line',
- height=6*cm, legend=False, aspect=1.2)
- g.set_xlabels('Trial')
- g.set_ylabels("Performance (d')")
- g.refline(x=0)
- g.refline(x=17400)
- g.savefig(figure_dir + 'FigureS2_LearningCurves_v0.png', dpi=300)
- g.savefig(figure_dir + 'FigureS2_LearningCurves_v0.pdf', dpi=300, transparent=True)
- df_dPrime.to_csv(source_file_dir + 'FigureS2_LearningCurves_v0.csv', index=False)
- g = sns.catplot(data=df_dPrime.loc[df_dPrime['start_trial'].isin([0, 17400])],
- x='start_trial', y='dPrime', hue='subject', kind='point',
- height=6 * cm, legend=False, aspect=0.8, dodge=0.2, join=False)
- g.set_ylabels("Performance (d')")
- g.set_xlabels("Training phase")
- g.set(ylim=[0, 4.5])
- g.set_xticklabels(['Early', 'Late'])
- g.savefig(figure_dir + 'FigureS2_LearningCurves_v1.png', dpi=300)
- g.savefig(figure_dir + 'FigureS2_LearningCurves_v1.pdf', dpi=300, transparent=True)
- df_dPrime.loc[df_dPrime['start_trial'].isin([0, 17400])].to_csv(source_file_dir + 'FigureS2_LearningCurves_v1.csv', index=False)
- def Figure1_monkeyPerformance(colors=None, figure_dir=None, data_dir=None, source_file_dir = None):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- monkey_performance = load_MonkeyBehavior_individual(data_dir=data_dir)
- performance_subject = monkey_performance.groupby('subject').mean()
- performance_subject['trained?'] = 'yes'
- order = ['no', 'yes']
- g = sns.catplot(data=performance_subject, x='trained?', y='i1', hue='trained?', kind='point', errorbar=("ci", 95),
- order=order,
- palette={'no': colors[0], 'yes': sns.xkcd_palette(['raspberry'])[0]}, height=4.5 * cm, aspect=0.85,
- legend=False)
- g.refline(y=0)
- g.set_ylabels("Performance (d')")
- g.set(ylim=[-1, 3.5])
- g.savefig(figure_dir + 'Figure1_performance_i1.png', dpi=300)
- g.savefig(figure_dir + 'Figure1_performance_i1.pdf', dpi=300, transparent=True)
- performance_subject.to_csv(source_file_dir + 'Figure1_performance_i1.csv')
- def Figure1_trainingCurves(figure_dir = None, source_file_dir = None):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- df_dPrime = load_MonkeyTraining_dPrime()
- df_dPrime_mean = df_dPrime.groupby(['class', 'start_trial'], as_index=False)['dPrime'].mean()
- g = sns.relplot(data=df_dPrime_mean.loc[df_dPrime_mean['start_trial'] <= 17400], x='start_trial', y='dPrime', kind='line',
- legend=False, height=4.5*cm, aspect=1.2, color=sns.xkcd_palette(['raspberry'])[0])
- g.set_xlabels('Trial')
- g.set_ylabels("Performance (d')")
- g.refline(y=0)
- g.savefig(figure_dir + 'Figure1_LearningCurves.png', dpi=300)
- g.savefig(figure_dir + 'Figure1_LearningCurves.pdf', dpi=300, transparent=True)
- df_dPrime_mean.loc[df_dPrime_mean['start_trial'] <= 17400].to_csv(source_file_dir + 'Figure1_LearningCurves.csv', index=False)
- def FigureS4_SiteReliability(figure_dir=None, source_file_dir=None, colors=None, recompute=False, criterion=0.3, n_sites_per_sub=53,
- draws=1000, version='v0',
- mode='empirical_conditioned_v2'):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- if version in ['v1', 'v2']:
- rates = load_MonkeyNeurons_pooled_rates(subsampled_neurons=n_sites_per_sub, draws=draws,
- mode=mode, recompute=recompute, reliability_criterion=criterion)
- if version == 'v0':
- reliabilities = get_SiteReliability(recompute=recompute)
- df = []
- for state in ['trained', 'untrained']:
- subs = reliabilities[state].keys()
- for sub in subs:
- df.append(pd.DataFrame({'reliabilities': np.mean(reliabilities[state][sub], axis=1),
- 'state': state,
- 'subject': sub}))
- df = pd.concat(df, ignore_index=True)
- g = sns.displot(data=df, x='reliabilities', hue='state', palette={'trained': colors[1], 'untrained': colors[0]},
- height=5 * cm, aspect=1.2,
- bins=30)
- g.set_ylabels("# sites")
- g.refline(x=criterion)
- g.savefig(figure_dir + 'FigureS4_reliability.png', dpi=300)
- g.savefig(figure_dir + 'FigureS4_reliability.pdf', dpi=300, transparent=True)
- df.to_csv(source_file_dir + 'FigureS4_reliability.csv', index=False)
- elif version == 'v1':
- d = np.random.randint(draws)
- df = []
- for state in ['trained', 'untrained']:
- df.append(pd.DataFrame({'reliabilities': rates[f'reliability_{state}'][d],
- 'state': state,
- }))
- df = pd.concat(df, ignore_index=True)
- g = sns.displot(data=df, x='reliabilities', hue='state', palette={'trained': colors[1], 'untrained': colors[0]},
- height=5 * cm, aspect=1.2,
- bins=30)
- g.refline(x=criterion)
- g.savefig(figure_dir + 'FigureS4_reliability_v1.png', dpi=300)
- g.savefig(figure_dir + 'FigureS4_reliability_v1.pdf', dpi=300, transparent=True)
- elif version == 'v2':
- diff_dist = np.median(rates[f'reliability_trained'], axis=1) - np.median(rates[f'reliability_untrained'],
- axis=1)
- g = sns.displot(x=diff_dist,
- height=4.5 * cm, aspect=1.2,
- bins=30)
- g.refline(x=0, c='white')
- g.set_ylabels("# draws")
- g.set_xlabels("reliability differences\n(median in pools)")
- g.savefig(figure_dir + 'FigureS4_reliability_v2.png', dpi=300)
- g.savefig(figure_dir + 'FigureS4_reliability_v2.pdf', dpi=300, transparent=True)
- elif version == 'v3':
- df = []
- for hemi in ['LH', 'RH']:
- reliabilities = get_SiteReliability(recompute=recompute, area='IT', hemisphere=hemi)
- for state in ['trained', 'untrained']:
- subs = reliabilities[state].keys()
- for sub in subs:
- df.append(pd.DataFrame({'reliabilities': np.mean(reliabilities[state][sub], axis=1),
- 'state': state,
- 'hemisphere': hemi,
- 'subject': sub}))
- df = pd.concat(df, ignore_index=True)
- g = sns.displot(data=df.loc[df['state'] == 'untrained'], x='reliabilities', col='hemisphere', row='subject',
- height=3.5 * cm, aspect=1.2,
- bins=30, col_order=['LH', 'RH'], row_order=['monkeyT', 'monkeyC', 'monkeyS'])
- g.set_titles(' ')
- g.set(ylim=[0, 40])
- for condition in g.axes_dict:
- subject, hemi = condition[0], condition[1]
- site_yield = (df.loc[(df['state'] == 'untrained') & (df['subject'] == subject) & (df['hemisphere'] == hemi), 'reliabilities'] > criterion).sum()
- total = len(df.loc[(df['state'] == 'untrained') & (df['subject'] == subject) & (df['hemisphere'] == hemi), 'reliabilities'])
- g.axes_dict[condition].text(-0.2, 35, f"{site_yield}/{total}", size=8)
- g.set_ylabels("# sites")
- g.refline(x=criterion)
- g.savefig(figure_dir + 'FigureS3_reliability_naive_v3.png', dpi=300)
- g.savefig(figure_dir + 'FigureS3_reliability_naive_v3.pdf', dpi=300, transparent=True)
- df.loc[df['state'] == 'untrained'].to_csv(source_file_dir + 'FigureS3_reliability_naive_v3.csv', index=False)
- g = sns.displot(data=df.loc[df['state'] == 'trained'], x='reliabilities', col='hemisphere', row='subject',
- height=3.5 * cm, aspect=1.2,
- col_order=['LH', 'RH'], row_order=['monkeyN', 'monkeyM', 'monkeyB'],
- bins=30)
- g.set_titles(' ')
- g.set(ylim=[0, 40])
- for condition in g.axes_dict:
- subject, hemi = condition[0], condition[1]
- site_yield = (df.loc[(df['state'] == 'trained') & (df['subject'] == subject) & (
- df['hemisphere'] == hemi), 'reliabilities'] > criterion).sum()
- total = len(df.loc[(df['state'] == 'trained') & (df['subject'] == subject) & (
- df['hemisphere'] == hemi), 'reliabilities'])
- g.axes_dict[condition].text(-0.2, 35, f"{site_yield}/{total}", size=8)
- g.set_ylabels("# sites")
- g.refline(x=criterion)
- g.savefig(figure_dir + 'FigureS3_reliability_trained_v3.png', dpi=300)
- g.savefig(figure_dir + 'FigureS3_reliability_trained_v3.pdf', dpi=300, transparent=True)
- df.loc[df['state'] == 'trained'].to_csv(source_file_dir + 'FigureS3_reliability_trained_v3.csv', index=False)
- def Figure2_selectivity(figure_dir=None, source_file_dir=None, colors=None,
- recompute=False, num_sites=159,
- num_subs=3, draws=1000,
- mode='empirical_conditioned_v2',
- version='v0', n_jobs=-1):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- if version == 'v0':
- neural_df = load_neuralITselectivity(recompute=recompute, draws=1, n_jobs=n_jobs, include='combinedCategories',
- mode='empirical_all')
- df_units = []
- for state in ['untrained', 'trained']:
- df_units.append(
- pd.DataFrame({'state': state, 'category_selectivity': np.array(neural_df[state]).flatten()}))
- df_units = pd.concat(df_units, ignore_index=True)
- print(df_units.groupby('state').size())
- g = sns.displot(data=df_units, x='category_selectivity', hue='state', stat='percent', common_norm=False,
- kde=True, palette=colors, height=5 * cm, aspect=1.25, legend=False)
- g.refline(x=0, ls='--', color='white')
- g.set(xticks=[0, 0.1, 0.2], yticks=[0, 10, 20])
- g.set_xlabels('Category selectivity')
- g.set_ylabels('% neural sites')
- g.savefig(figure_dir + 'Figure2_selectivity_v0.png', dpi=300)
- g.savefig(figure_dir + 'Figure2_selectivity_v0.pdf', dpi=300, transparent=True)
- df_units.index.name = 'unit'
- df_units.to_csv(source_file_dir + 'Figure2_selectivity_v0.csv')
- elif version == 'v1':
- neural_df_draws = load_neuralITselectivity(recompute=recompute, draws=draws, n_jobs=n_jobs,
- include='combinedCategories',
- mode=mode, neural_sites_perSubject=num_sites // num_subs)
- draws = len(neural_df_draws['trained'])
- df = []
- for state in ['untrained', 'trained']:
- for d in range(draws):
- df.append(
- {'state': state, 'draw': d, 'selectivity': np.median(neural_df_draws[f'{state}'][d])})
- df = pd.DataFrame(df)
- g = sns.catplot(data=df, x='state', y='selectivity', hue='state', kind='point', errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=1,
- legend=False)
- g.set(ylim=[0.02, 0.06], yticks=[0.02, 0.04, 0.06])
- g.set_xticklabels(["naive", "trained"])
- g.set_xlabels(f'IT neuron pool\n({num_sites} sites)')
- g.set_ylabels("Selectivity")
- g.savefig(figure_dir + 'Figure2_selectivity_v1.png', dpi=300)
- g.savefig(figure_dir + 'Figure2_selectivity_v1.pdf', dpi=300, transparent=True)
- print('Medians:')
- print(df.groupby('state').median())
- print(
- f"{((df.groupby('state').median().loc['trained', 'selectivity'] / df.groupby('state').median().loc['untrained', 'selectivity']) - 1) * 100}% increase")
- print(
- f"CI (95%): {((df.loc[df['state'] == 'trained', 'selectivity'].reset_index() - df.loc[df['state'] == 'untrained', 'selectivity'].reset_index())['selectivity']).quantile(0.025)} - {((df.loc[df['state'] == 'trained', 'selectivity'].reset_index() - df.loc[df['state'] == 'untrained', 'selectivity'].reset_index())['selectivity']).quantile(0.975)}")
- df.to_csv(source_file_dir + 'Figure2_selectivity_v1.csv', index=False)
- def Figure2_rsa(figure_dir=None, source_file_dir=None,
- neural_sites_perSubject=53, draws=1000,
- colors=None, recompute=False,
- version='v0', mode='empirical_conditioned_v2'):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- n_sites = np.unique(np.geomspace(1, neural_sites_perSubject, num=12, dtype='int'))
- print(n_sites)
- neural_df = load_neuralRDMs(recompute=recompute, draws=draws, mode=mode,
- neural_sites_perSubject=n_sites)
- if version == 'v0':
- df = []
- for state in ['untrained', 'trained']:
- for d in range(draws):
- df.append(
- {'state': state, 'draw': d,
- 'tau': np.mean(neural_df[f'{neural_sites_perSubject * 3}_sites'][f'{state}_category'][d])})
- df = pd.DataFrame(df)
- g = sns.catplot(data=df, x='state', y='tau', hue='state', kind='point', errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=1,
- legend=False)
- g.set(ylim=[0.065, 0.13], yticks=[0.08, 0.1, 0.12])
- g.set_xlabels('IT neuron pool')
- g.set_ylabels("Object-level\ncorrelation (τ)")
- g.savefig(figure_dir + 'Figure2_rsa_v0.png', dpi=300)
- g.savefig(figure_dir + 'Figure2_rsa_v0.pdf', dpi=300, transparent=True)
- print('Means:')
- print(df.groupby('state').mean())
- print('SD:')
- print(df.groupby('state').std())
- print(
- f"{((df.groupby('state').median().loc['trained', 'tau'] / df.groupby('state').median().loc['untrained', 'tau']) - 1) * 100}% increase")
- print(
- f"CI (95%): {((df.loc[df['state'] == 'trained', 'tau'].reset_index() - df.loc[df['state'] == 'untrained', 'tau'].reset_index())['tau']).quantile(0.025)} - {((df.loc[df['state'] == 'trained', 'tau'].reset_index() - df.loc[df['state'] == 'untrained', 'tau'].reset_index())['tau']).quantile(0.975)}")
- print(
- f"Mean difference: {((df.loc[df['state'] == 'trained', 'tau'].reset_index() - df.loc[df['state'] == 'untrained', 'tau'].reset_index())['tau']).mean()}")
- print(
- f"SD (diff): {((df.loc[df['state'] == 'trained', 'tau'].reset_index() - df.loc[df['state'] == 'untrained', 'tau'].reset_index())['tau']).std()}")
- df.to_csv(source_file_dir + 'Figure2_rsa_v0.csv', index=False)
- elif version == 'v1':
- df = []
- for n in n_sites:
- for state in ['untrained', 'trained']:
- for d in range(draws):
- df.append(
- {'sites': 3 * n, 'state': state, 'draw': d,
- 'tau': np.mean(neural_df[f'{n * 3}_sites'][f'{state}_category'][d])})
- df = pd.DataFrame(df)
- g = sns.relplot(data=df, x='sites', y='tau', hue='state', kind='line', errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=1.3,
- legend=False)
- g.set(xlim=[-5, 200], xticks=[0, 100, 200], ylim=[0, 0.15])
- g.set_ylabels("Object-level\ncorrelation (τ)")
- g.set_xlabels("IT neuron pool size")
- g.savefig(figure_dir + 'Figure2_rsa_v1.png', dpi=300)
- g.savefig(figure_dir + 'Figure2_rsa_v1.pdf', dpi=300, transparent=True)
- df.to_csv(source_file_dir + 'Figure2_rsa_v1.csv', index=False)
- def Figure2_decoding(figure_dir=None, source_file_dir=None, colors=None, version='v1', recompute=False,
- performance_threshold=None, num_sites=159, mode='empirical_conditioned_v2', draws=1000):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- if version == 'v0':
- IT_neurons = load_MonkeyIT_Decodes(num_neurons=np.array([num_sites]), includeReliability=False,
- recompute=recompute,
- mode=mode, draws=draws)
- df = []
- for state in ['untrained', 'trained']:
- for d in range(draws):
- df.append(
- {'state': state, 'draw': d, 'i1': np.mean(IT_neurons[f'{num_sites}_neurons'][state]['dprimes'][d])})
- df = pd.DataFrame(df)
- g = sns.catplot(data=df, x='state', y='i1', hue='state', kind='point', errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=1,
- legend=False)
- g.set(ylim=[2.5, 3.5], yticks=[2.5, 3, 3.5])
- g.set_titles('Image-by-image\ndecoding')
- g.set_xticklabels(["naive", "trained"])
- g.set_ylabels("Performance (d')")
- g.set_xlabels("IT neuron pool\n(159 sites)")
- g.savefig(figure_dir + 'Figure2_decoding_v0.png', dpi=300)
- g.savefig(figure_dir + 'Figure2_decoding_v0.pdf', dpi=300, transparent=True)
- print('Means:')
- print(df.groupby('state').mean())
- print('SD:')
- print(df.groupby('state').std())
- print(
- f"{((df.groupby('state').median().loc['trained', 'i1'] / df.groupby('state').median().loc['untrained', 'i1']) - 1) * 100}% increase")
- print(
- f"CI (95%): {((df.loc[df['state'] == 'trained', 'i1'].reset_index() - df.loc[df['state'] == 'untrained', 'i1'].reset_index())['i1']).quantile(0.025)} - {((df.loc[df['state'] == 'trained', 'i1'].reset_index() - df.loc[df['state'] == 'untrained', 'i1'].reset_index())['i1']).quantile(0.975)}")
- print(
- f"Mean difference: {((df.loc[df['state'] == 'trained', 'i1'].reset_index() - df.loc[df['state'] == 'untrained', 'i1'].reset_index())['i1']).mean()}")
- print(
- f"SD (diff): {((df.loc[df['state'] == 'trained', 'i1'].reset_index() - df.loc[df['state'] == 'untrained', 'i1'].reset_index())['i1']).std()}")
- df.to_csv(source_file_dir + 'Figure2_decoding_v0.csv', index=False)
- elif version == 'v1':
- mean_performance = getPerformanceThreshold('test_d-prime', kind=('mean', None))
- n_sites = np.unique((np.geomspace(3, num_sites, num=12, dtype='int') // 3) * 3)
- dPrimes = load_MonkeyIT_Decodes(resultFile_stem='CategoryDecodes_ITneurons_manySizes_', num_neurons=n_sites,
- includeReliability=False,
- recompute=recompute, mode=mode, draws=draws)
- df = []
- for n in n_sites:
- for state in ['untrained', 'trained']:
- for d in range(draws):
- df.append(
- {'state': state, 'draw': d, 'sites': n,
- 'i1': np.mean(dPrimes[f'{n}_neurons'][state]['dprimes'][d])})
- df = pd.DataFrame(df)
- def func(x, a, b, c): # x-shifted log
- return a * np.log(x + b) + c
- fitting_df_trained = df[df['state'] == 'trained'].groupby('sites', as_index=False)['i1'].mean()
- fitting_df_untrained = df[df['state'] == 'untrained'].groupby('sites', as_index=False)['i1'].mean()
- popt_t, pcov_t = curve_fit(func, fitting_df_trained.sites.values, fitting_df_trained.i1.values)
- popt_u, pcov_u = curve_fit(func, fitting_df_untrained.sites.values, fitting_df_untrained.i1.values)
- fitting_df_trained['predicted_i1'] = func(fitting_df_trained.sites.values, *popt_t)
- fitting_df_untrained['predicted_i1'] = func(fitting_df_untrained.sites.values, *popt_u)
- extrapolation_df_trained = pd.DataFrame(
- {'sites': np.arange(1, 200), 'i1_predicted': func(np.arange(1, 200), *popt_t)})
- extrapolation_df_untrained = pd.DataFrame(
- {'sites': np.arange(1, 200), 'i1_predicted': func(np.arange(1, 200), *popt_u)})
- g = sns.relplot(data=df, x='sites', y='i1', hue='state', kind='line', errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=1.2,
- legend=False)
- g.ax.plot(extrapolation_df_trained.sites.values, extrapolation_df_trained['i1_predicted'].values, ls=':',
- color=sns.xkcd_palette(['jade'])[0])
- g.ax.plot(extrapolation_df_untrained.sites.values, extrapolation_df_untrained['i1_predicted'].values, ls=':',
- color=sns.xkcd_palette(['slate grey'])[0])
- g.refline(y=mean_performance['min_value'], color='grey', zorder=1)
- g.map(plt.axhspan, ymin=performance_threshold['min_value'], ymax=performance_threshold['max_value'], zorder=0,
- color='grey', alpha=0.4)
- print(
- f"Untrained: {extrapolation_df_untrained.loc[extrapolation_df_untrained['i1_predicted'] >= performance_threshold['min_value'], 'sites'].min()}")
- print(
- f"Trained: {extrapolation_df_trained.loc[extrapolation_df_trained['i1_predicted'] >= performance_threshold['min_value'], 'sites'].min()}")
- g.set(xlim=[-5, 200])
- g.set_titles('Image-by-image\ndecoding')
- g.set_ylabels("Performance (d')")
- g.set_xlabels("IT neuron pool")
- g.savefig(figure_dir + 'Figure2_decoding_v1.png', dpi=300)
- g.savefig(figure_dir + 'Figure2_decoding_v1.pdf', dpi=300, transparent=True)
- df.to_csv(source_file_dir + 'Figure2_decoding_v1.csv', index=False)
- elif version == 'v2':
- monkey_behavior = get_MonkeyBehavioralMetrics_draws(recompute=recompute, draws=draws)
- monkey_behavior = monkey_behavior.rename(columns={'test_d-prime': 'delta_i1'})
- monkey_behavior.drop(columns=['test_acc_binary', 'test_d-prime_o1'], inplace=True)
- monkey_behavior['data'] = 'Behavior'
- IT_neurons = load_MonkeyIT_Decodes(num_neurons=np.array([num_sites]), includeReliability=False,
- recompute=recompute,
- mode=mode, draws=draws)
- df = []
- for d in range(draws):
- df.append(
- {'data': 'IT', 'draw': d,
- 'delta_i1': np.mean(IT_neurons[f'{num_sites}_neurons']['trained']['dprimes'][d]) - np.mean(
- IT_neurons[f'{num_sites}_neurons']['untrained']['dprimes'][d])})
- df = pd.DataFrame(df)
- df = pd.concat([df, monkey_behavior])
- g = sns.catplot(data=df, x='data', y='delta_i1', kind='point', errorbar=("pi", 95),
- palette={'Behavior': sns.xkcd_palette(['raspberry'])[0],
- 'IT': sns.xkcd_palette(['royal blue'])[0]}, height=5 * cm, aspect=0.6, hue='data',
- legend=False, dodge=False)
- g.set(ylim=[0, 4], yticks=[0, 2, 4])
- g.set_xticklabels(rotation=90)
- g.set_ylabels("Δ performance (d')")
- g.savefig(figure_dir + 'Figure2_decoding_v2.png', dpi=300)
- g.savefig(figure_dir + 'Figure2_decoding_v2.pdf', dpi=300, transparent=True)
- df.to_csv(source_file_dir + 'Figure2_decoding_v2.csv', index=False)
- def FigureS5_decoding_reliability(reliabilities=[0.3, 0.5, 0.7], num_sites_all=[159, 147, 102],
- figure_dir=None, source_file_dir=None, colors=None, recompute=False,
- mode='empirical_conditioned_v2', draws=1000):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- df = []
- for reliability, num_sites in zip(reliabilities, num_sites_all):
- if reliability == 0.3:
- IT_neurons = load_MonkeyIT_Decodes(num_neurons=np.array([num_sites]), includeReliability=False,
- recompute=recompute,
- mode=mode, draws=draws)
- else:
- IT_neurons = load_MonkeyIT_Decodes(num_neurons=np.array([num_sites]), includeReliability=False,
- recompute=recompute,
- mode=mode, draws=draws, reliability_criterion=reliability)
- for state in ['untrained', 'trained']:
- for d in range(draws):
- df.append(
- {'state': state, 'draw': d, 'i1': np.mean(IT_neurons[f'{num_sites}_neurons'][state]['dprimes'][d]),
- 'reliability criterion': reliability})
- df = pd.DataFrame(df)
- g = sns.catplot(data=df, x='state', y='i1', hue='state', kind='point', errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=1, col= 'reliability criterion',
- legend=False)
- g.set_titles('{col_name}')
- g.set_xticklabels(["naive", "trained"])
- g.set_ylabels("Performance (d')")
- g.set_xlabels("IT neuron pool")
- g.savefig(figure_dir + 'FigureS5_decoding_reliabilityCriterion.png', dpi=300)
- g.savefig(figure_dir + 'FigureS5_decoding_reliabilityCriterion.pdf', dpi=300, transparent=True)
- df.to_csv(source_file_dir + 'FigureS5_decoding_reliabilityCriterion.csv', index=False)
- def FigureS6_singleSubject_analyses(figure_dir=None, source_file_dir=None, colors=None, recompute=False, reliability_criterion=0.3):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- IT_decoding = load_MonkeyIT_Decodes_singleAnimal(recompute=recompute,reliability_criterion=reliability_criterion)
- IT_selectivity = load_neuralITselectivity_singleAnimal(recompute=recompute,reliability_criterion=reliability_criterion)
- IT_rsa = load_neuralRDMs_singleAnimal(recompute=recompute,reliability_criterion=reliability_criterion)
- df = []
- for state in ['untrained', 'trained']:
- subs = list(IT_decoding[state].keys())
- for sub in subs:
- df.append(
- {'state': state, 'subject': sub[-1:],
- 'i1': np.mean(IT_decoding[state][sub]['i1']),
- 'selectivity': np.median(IT_selectivity[state][sub]),
- 'tau': float(np.squeeze(IT_rsa[state][sub])),
- 'num_sites': np.mean(IT_decoding[state][sub]['n_sites'])})
- df = pd.DataFrame(df)
- g = sns.catplot(data=df, x='subject', y='i1', hue='state', kind='point',
- errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=1,
- legend=False, join=False)
- g.set(ylim=[1, 4])
- g.set_ylabels("Performance (d')\n ")
- g.refline(y=df.loc[df['state'] == 'trained']['i1'].mean(), color=colors[1])
- g.refline(y=df.loc[df['state'] == 'untrained']['i1'].mean(), color=colors[0])
- g.set_xlabels("Subject")
- g.savefig(figure_dir + 'FigureS6_singleSubject_decoding_i1.png', dpi=300)
- g.savefig(figure_dir + 'FigureS6_singleSubject_decoding_i1.pdf', dpi=300, transparent=True)
- g = sns.catplot(data=df, x='subject', y='selectivity', hue='state', kind='point',
- errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=1,
- legend=False, join=False)
- g.set(ylim=[0, 0.08])
- g.refline(y=df.loc[df['state'] == 'trained']['selectivity'].mean(), color=colors[1])
- g.refline(y=df.loc[df['state'] == 'untrained']['selectivity'].mean(), color=colors[0])
- g.set_ylabels("Selectivity")
- g.set_xlabels("Subject")
- g.savefig(figure_dir + 'FigureS6_singleSubject_selectivity.png', dpi=300)
- g.savefig(figure_dir + 'FigureS6_singleSubject_selectivity.pdf', dpi=300, transparent=True)
- g = sns.catplot(data=df, x='subject', y='tau', hue='state', kind='point',
- errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=1,
- legend=False, join=False)
- g.set(ylim=[0.04, 0.12])
- g.set_ylabels("Correlation (τ)")
- g.set_xlabels("Subject")
- g.refline(y=df.loc[df['state'] == 'trained']['tau'].mean(), color=colors[1])
- g.refline(y=df.loc[df['state'] == 'untrained']['tau'].mean(), color=colors[0])
- g.savefig(figure_dir + 'FigureS6_singleSubject_rsa.png', dpi=300)
- g.savefig(figure_dir + 'FigureS6_singleSubject_rsa.pdf', dpi=300, transparent=True)
- df.to_csv(source_file_dir + 'FigureS6_singleSubject.csv', index=False)
- def FigureS7_selectivity(figure_dir=None, source_file_dir=None, recompute=False, n_jobs=-1,
- num_sites=159, mode='empirical_conditioned_v2', draws=200):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- IT_neurons_null = load_neuralITselectivity_permutation(neural_sites_perSubject=num_sites // 3,
- include='combinedCategories',
- recompute=recompute, mode=mode, draws=draws, n_jobs=n_jobs)
- IT_neurons_observed = load_neuralITselectivity(recompute=False, n_jobs=n_jobs,
- include='combinedCategories',
- mode=mode, neural_sites_perSubject=num_sites // 3)
- deltas = pd.DataFrame()
- for permutation in IT_neurons_null.keys():
- if permutation == 'sites':
- pass
- else:
- deltas = pd.concat([deltas,
- pd.DataFrame({'permutation': str(permutation),
- 'delta': np.median(IT_neurons_null[permutation]['group1'],
- axis=1) - np.median(
- IT_neurons_null[permutation]['group2'], axis=1), 'kind': 'null'})],
- ignore_index=True)
- deltas = pd.concat([deltas, pd.DataFrame({'permutation': 'None',
- 'delta': np.median(IT_neurons_observed['trained'], axis=1)[
- :draws] - np.median(IT_neurons_observed['untrained'], axis=1)[
- :draws], 'kind': 'empirical'})], ignore_index=True)
- g = sns.displot(data=deltas[deltas['kind'] == 'null'], x='delta', hue='kind', palette='colorblind', height=5 * cm,
- aspect=1.2)
- g.refline(x=deltas.groupby('kind')['delta'].mean()['empirical'], c='red')
- g.set_xlabels("differences (Δ)")
- print(
- f"p-value (two-sided): {(deltas.groupby('kind')['delta'].mean().loc['empirical'] <= deltas.loc[deltas['kind'] == 'null', 'delta']).mean()}")
- g.savefig(figure_dir + 'FigureS7_permutation_selectivity.png', dpi=300)
- g.savefig(figure_dir + 'FigureS7_permutation_selectivity.pdf', dpi=300, transparent=True)
- deltas.to_csv(source_file_dir + 'FigureS7_permutation_selectivity.csv', index=False)
- def FigureS7_rsa(figure_dir=None, source_file_dir=None, recompute=False, subs=3,
- neural_sites_perSubject=53, mode='empirical_conditioned_v2', draws=200):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- IT_neurons_null = load_neuralRDMs_permutation(neural_sites_perSubject=np.array([neural_sites_perSubject]),
- recompute=recompute,
- mode=mode, draws=draws)
- IT_neurons_observed = load_neuralRDMs(recompute=False, mode=mode,
- neural_sites_perSubject=np.array([neural_sites_perSubject]))
- num_sites = neural_sites_perSubject * subs
- deltas = pd.DataFrame()
- for permutation in IT_neurons_null[f'{num_sites}_sites'].keys():
- if permutation == 'sites':
- pass
- else:
- deltas = pd.concat([deltas,
- pd.DataFrame(
- {'delta': IT_neurons_null[f'{num_sites}_sites'][permutation]['group1_category']
- - IT_neurons_null[f'{num_sites}_sites'][permutation]['group2_category'],
- 'kind': 'null'})], ignore_index=True)
- deltas = pd.concat(
- [deltas, pd.DataFrame({'delta': IT_neurons_observed[f'{num_sites}_sites']['trained_category'][:draws] -
- IT_neurons_observed[f'{num_sites}_sites']['untrained_category'][:draws],
- 'kind': 'empirical'})], ignore_index=True)
- g = sns.displot(data=deltas[deltas['kind'] == 'null'], x='delta', hue='kind', palette='colorblind', height=5 * cm,
- aspect=1.2)
- g.refline(x=deltas.groupby('kind')['delta'].mean()['empirical'], c='red')
- g.set_xlabels("differences (Δ)")
- print(
- f"p-value (two-sided): {(deltas.groupby('kind')['delta'].mean().loc['empirical'] <= deltas.loc[deltas['kind'] == 'null', 'delta']).mean()}")
- g.savefig(figure_dir + 'FigureS7_permutation_rsa.png', dpi=300)
- g.savefig(figure_dir + 'FigureS7_permutation_rsa.pdf', dpi=300, transparent=True)
- deltas.to_csv(source_file_dir + 'FigureS7_permutation_rsa.csv', index=False)
- def FigureS7_decoding(figure_dir=None, source_file_dir=None,
- recompute=False,
- num_sites=159, mode='empirical_conditioned_v2', draws=200):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- IT_neurons_null = load_MonkeyIT_Decodes_permutation(num_neurons=np.array([num_sites]),
- recompute=recompute, mode=mode, draws=draws)
- IT_neurons_observed = load_MonkeyIT_Decodes(num_neurons=np.array([num_sites]), includeReliability=False,
- recompute=False, mode=mode)
- deltas = pd.DataFrame()
- for permutation in IT_neurons_null[f'{num_sites}_neurons'].keys():
- if permutation == 'sites':
- pass
- else:
- deltas = pd.concat([deltas,
- pd.DataFrame({'delta': np.mean(
- IT_neurons_null[f'{num_sites}_neurons'][permutation]['group1']['dprimes'],
- axis=1) - np.mean(
- IT_neurons_null[f'{num_sites}_neurons'][permutation]['group2']['dprimes'], axis=1)
- , 'kind': 'null'})], ignore_index=True)
- deltas = pd.concat(
- [deltas, pd.DataFrame({'delta': np.mean(IT_neurons_observed[f'{num_sites}_neurons']['trained']['dprimes'],
- axis=1)[:draws] - np.mean(
- IT_neurons_observed[f'{num_sites}_neurons']['untrained']['dprimes'], axis=1)[:draws]
- , 'kind': 'empirical'})], ignore_index=True)
- g = sns.displot(data=deltas[deltas['kind'] == 'null'], x='delta', hue='kind', palette='colorblind', height=5 * cm,
- aspect=1.2)
- g.refline(x=deltas.groupby('kind')['delta'].mean()['empirical'], c='red')
- g.set_xlabels("differences (Δ)")
- g.savefig(figure_dir + 'FigureS7_permutation_decoding.png', dpi=300)
- g.savefig(figure_dir + 'FigureS7_permutation_decoding.pdf', dpi=300, transparent=True)
- deltas.to_csv(source_file_dir + 'FigureS7_permutation_decoding.csv', index=False)
- print(
- f"p-value (two-sided): {(deltas.groupby('kind')['delta'].mean().loc['empirical'] <= deltas.loc[deltas['kind'] == 'null', 'delta']).mean()}")
- def Figure3_decoding_anatomy(mode='empirical_conditioned_v2', draws=300, num_sites=159, recompute=False,
- figure_dir=None, source_file_dir=None, colors=None):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- IT_decodes_AIT = load_MonkeyIT_subregion_Decodes('AIT', mode=mode, draws=draws, num_neurons=np.array([32]),
- includeReliability=False, recompute=recompute)
- IT_decodes_AIT['num_subs'] = 1
- IT_decodes_CIT = load_MonkeyIT_subregion_Decodes('CIT', mode=mode, draws=draws, num_neurons=np.array([19]),
- includeReliability=False, recompute=recompute)
- IT_decodes_CIT['num_subs'] = 3
- IT_decodes_PIT = load_MonkeyIT_subregion_Decodes('PIT', mode=mode, draws=draws, num_neurons=np.array([17]), includeReliability=False, recompute=recompute)
- IT_decodes_PIT['num_subs'] = 2
- df = []
- for area in ['AIT', 'CIT', 'PIT']:
- for state in ['untrained', 'trained']:
- for d in range(draws):
- num_sites = np.squeeze(eval(f'IT_decodes_{area}')['num_subs'] * eval(f'IT_decodes_{area}')['num_neurons'])
- df.append(
- {'area': area, 'sites': num_sites, 'subs':eval(f'IT_decodes_{area}')['num_subs'], 'state': state, 'draw': d, 'i1': np.mean(eval(f'IT_decodes_{area}')[f'{num_sites}_neurons'][state]['dprimes'][d])})
- df = pd.DataFrame(df)
- g = sns.catplot(data=df, col='area', x='state', y='i1', hue='state', kind='point', errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=0.75,
- legend=False, sharey=False)
- g.set_titles('{col_name}')
- g.set_xticklabels(["naïve", "trained"])
- g.set_ylabels("Performance (d')")
- g.set_xlabels('IT neuron pool')
- g.savefig(figure_dir + 'Figure3_subregions_decoding_i1.png', dpi=300)
- g.savefig(figure_dir + 'Figure3_subregions_decoding_i1.pdf', dpi=300, transparent=True)
- df.to_csv(source_file_dir + 'Figure3_subregions_decoding_i1.csv', index=False)
- print('Means:')
- print(df.groupby(['area', 'state']).mean())
- print('SD:')
- print(df.groupby(['area', 'state']).std())
- for area in ['AIT', 'CIT', 'PIT']:
- print(area)
- print(
- f"{((df.loc[df['area'] == area].groupby(['state'])['i1'].mean()['trained'] / df.loc[df['area'] == area].groupby(['state'])['i1'].mean()['untrained']) - 1) * 100}% increase")
- df_dist = ((df.loc[(df['area'] == area) & (df['state'] == 'trained'), 'i1'].reset_index() - df.loc[
- (df['area'] == area) & (df['state'] == 'untrained'), 'i1'].reset_index())['i1'])
- print(
- f"CI (95%): {df_dist.quantile(0.025)} - {df_dist.quantile(0.975)}")
- print(
- f"p-val: {np.min([(df_dist < 0).mean(), (df_dist > 0).mean()]) * 2}")
- print(
- f"Mean diff: {((df.loc[(df['state'] == 'trained') & (df['area'] == area), 'i1'].reset_index() - df.loc[(df['state'] == 'untrained') & (df['area'] == area), 'i1'].reset_index())['i1']).mean()}")
- print(
- f"Mean SD: {((df.loc[(df['state'] == 'trained') & (df['area'] == area), 'i1'].reset_index() - df.loc[(df['state'] == 'untrained') & (df['area'] == area), 'i1'].reset_index())['i1']).std()}")
- IT_decodes_LH = load_MonkeyIT_subregion_Decodes('IT', hemisphere='LH', mode=mode, draws=draws,
- num_neurons=np.array([89]), # n_jobs=1,
- includeReliability=False, recompute=False)
- IT_decodes_LH['num_subs'] = 2
- area = 'LH'
- df_LH = []
- for state in ['untrained', 'trained']:
- for d in range(draws):
- num_sites = np.squeeze(
- eval(f'IT_decodes_{area}')['num_subs'] * eval(f'IT_decodes_{area}')['num_neurons'])
- df_LH.append(
- {'area': area, 'sites': num_sites, 'subs': eval(f'IT_decodes_{area}')['num_subs'], 'state': state,
- 'draw': d, 'i1': np.mean(eval(f'IT_decodes_{area}')[f'{num_sites}_neurons'][state]['dprimes'][d])})
- df_LH = pd.DataFrame(df_LH)
- g = sns.catplot(data=df_LH, col='area', x='state', y='i1', hue='state', kind='point',
- errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=0.9,
- legend=False, sharey=False)
- g.set_titles('Left hemisphere')
- g.set_xticklabels(["naïve", "trained"])
- g.set_ylabels("Performance (d')")
- g.set_xlabels('IT neuron pool')
- g.savefig(figure_dir + 'Figure3_hemisphere-LH_decoding_i1.png', dpi=300)
- g.savefig(figure_dir + 'Figure3_hemisphere-LH_decoding_i1.pdf', dpi=300, transparent=True)
- df_LH.to_csv(source_file_dir + 'Figure3_hemisphere-LH_decoding_i1.csv', index=False)
- print('Means:')
- print(df_LH.groupby(['state'])['i1'].mean())
- print('SD:')
- print(df_LH.groupby(['state'])['i1'].std())
- print(f"{((df_LH.groupby(['state'])['i1'].mean()['trained'] / df_LH.groupby(['state'])['i1'].mean()['untrained']) - 1) * 100}% increase")
- df_dist = ((df_LH.loc[(df_LH['state'] == 'trained'), 'i1'].reset_index() - df_LH.loc[
- (df['state'] == 'untrained'), 'i1'].reset_index())['i1'])
- print(
- f"CI (95%): {df_dist.quantile(0.025)} - {df_dist.quantile(0.975)}")
- print(
- f"p-val: {np.min([(df_dist < 0).mean(), (df_dist > 0).mean()]) * 2}")
- print(
- f"Mean diff: {df_dist.mean()}")
- print(
- f"SD diff: {df_dist.std()}")
- n_sites = np.unique((np.geomspace(3, num_sites, num=12, dtype='int') // 3) * 3)
- dPrimes = load_MonkeyIT_Decodes(resultFile_stem='CategoryDecodes_ITneurons_manySizes_', num_neurons=n_sites,
- includeReliability=False,
- recompute=recompute, mode=mode, draws=draws)
- n_sites = dPrimes['num_neurons']
- df_multi = []
- for n in n_sites:
- for state in ['untrained', 'trained']:
- for d in range(draws):
- df_multi.append(
- {'state': state, 'draw': d, 'sites': n,
- 'i1': np.mean(dPrimes[f'{n}_neurons'][state]['dprimes'][d])})
- df_multi = pd.DataFrame(df_multi)
- def func(x, a, b, c): # x-shifted log
- return a * np.log(x + b) + c
- fitting_df_trained = df_multi[df_multi['state'] == 'trained'].groupby('sites')['i1'].mean()
- fitting_df_untrained = df_multi[df_multi['state'] == 'untrained'].groupby('sites')['i1'].mean()
- popt_t, pcov_t = curve_fit(func, fitting_df_trained.index.values, fitting_df_trained.values)
- popt_u, pcov_u = curve_fit(func, fitting_df_untrained.index.values, fitting_df_untrained.values)
- fitting_df_trained['predicted_i1'] = func(fitting_df_trained.index.values, *popt_t)
- fitting_df_untrained['predicted_i1'] = func(fitting_df_untrained.index.values, *popt_u)
- extrapolation_df_trained = pd.DataFrame(
- {'sites': np.arange(1, 200), 'i1_predicted': func(np.arange(1, 200), *popt_t)})
- extrapolation_df_untrained = pd.DataFrame(
- {'sites': np.arange(1, 200), 'i1_predicted': func(np.arange(1, 200), *popt_u)})
- g = sns.relplot(data=df_multi, x='sites', y='i1', hue='state', kind='line', errorbar=("pi", 95),
- palette=colors, height=5 * cm, aspect=1.2,
- legend=False)
- g.ax.plot(extrapolation_df_trained.sites.values, extrapolation_df_trained['i1_predicted'].values, ls=':',
- color=sns.xkcd_palette(['jade'])[0])
- g.ax.plot(extrapolation_df_untrained.sites.values, extrapolation_df_untrained['i1_predicted'].values, ls=':',
- color=sns.xkcd_palette(['slate grey'])[0])
- for area in ['AIT', 'CIT', 'PIT']:
- num_sites = df.loc[(df['area'] == area), 'sites'].values[0]
- for s, state in enumerate(['untrained', 'trained']):
- g.ax.scatter(num_sites,df.loc[(df['area'] == area) & (df['state'] == state), 'i1'].mean(),
- color=colors[s])
- for s, state in enumerate(['untrained', 'trained']):
- g.ax.scatter(df_LH['sites'].values[0], df_LH.loc[(df['state'] == state), 'i1'].mean(),
- color=colors[s])
- g.set(xlim=[-5, 200])
- g.set_titles('Image-by-image\ndecoding')
- g.set_ylabels("Performance (d')")
- g.set_xlabels("IT neuron pool")
- g.savefig(figure_dir + 'Figure3_anatomyScaling_decoding_i1.png', dpi=300)
- g.savefig(figure_dir + 'Figure3_anatomyScaling_decoding_i1.pdf', dpi=300, transparent=True)
- def Figure4_novel500_decoding(draws=1000, mode='empirical_conditioned_v2', figure_dir=None, source_file_dir=None,
- colors=None, recompute=False, num_sites=55):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- n_sites = np.unique(np.geomspace(3, num_sites, num=12, dtype='int'))
- IT_neurons_hvm = load_MonkeyIT_Decodes_novel500_HVMcontrol(num_neurons=n_sites, includeReliability=False,
- recompute=recompute,
- mode=mode, draws=draws)
- IT_neurons_novel500 = load_MonkeyIT_Decodes_novel500(num_neurons=n_sites, includeReliability=False,
- recompute=recompute,
- mode=mode, draws=draws)
- df = []
- for state in ['untrained', 'trained']:
- for site in n_sites:
- for d in range(draws):
- df.append(
- {'dataset': 'Novel500', 'state': state, 'pool size': site, 'draw': d,
- 'i1': np.mean(IT_neurons_novel500[f'{site}_neurons'][state]['dprimes'][d])})
- df.append(
- {'dataset': 'HVM', 'state': state, 'pool size': site, 'draw': d,
- 'i1': np.mean(IT_neurons_hvm[f'{site}_neurons'][state]['dprimes'][d])})
- df = pd.DataFrame(df)
- # DIFFICULTY-CONTROLLED DATASETS
- # sample images such that HVM has the same untrained difficulty
- np.random.seed(2)
- novel500_kde = gaussian_kde(np.mean(IT_neurons_novel500[f'{num_sites}_neurons']['untrained']['dprimes'], axis=0))
- hvm_kde = gaussian_kde(np.mean(IT_neurons_hvm[f'{num_sites}_neurons']['untrained']['dprimes'], axis=0))
- # Function to find the minimum of two KDE evaluations
- shared_kde = lambda x: np.min([novel500_kde(x), hvm_kde(x)], axis=0)
- overlap_area, _ = quad(shared_kde, -1, 4)
- maximum_sample = int(500 * overlap_area)
- # map this to the images
- naive_img_hvm = pd.DataFrame({'dataset': 'HVM', 'img': np.arange(640),
- 'i1': np.mean(IT_neurons_hvm[f'{num_sites}_neurons']['untrained']['dprimes'],
- axis=0)})
- naive_img_hvm['pdf'] = novel500_kde(naive_img_hvm['i1']) / hvm_kde(naive_img_hvm['i1'])
- naive_img_novel500 = pd.DataFrame({'dataset': 'novel500', 'img': np.arange(500), 'i1': np.mean(
- IT_neurons_novel500[f'{num_sites}_neurons']['untrained']['dprimes'], axis=0)})
- naive_img_novel500['pdf'] = hvm_kde(naive_img_novel500['i1']) / novel500_kde(naive_img_novel500['i1'])
- hvm_mean = 0
- novel500_mean = 1
- while np.round(abs(hvm_mean - novel500_mean), 1) != 0:
- sampled_hvm = naive_img_hvm.sample(maximum_sample, weights='pdf')
- sampled_novel500 = naive_img_novel500.sample(maximum_sample, weights='pdf')
- hvm_mean = sampled_hvm['i1'].mean()
- novel500_mean = sampled_novel500['i1'].mean()
- print(hvm_mean)
- print(novel500_mean)
- g, ax = plt.subplots(1, 2, figsize=(4.5 * cm * 0.9 * 2, 4.5 * cm), sharey=True, sharex=True)
- sns.histplot(np.mean(IT_neurons_hvm[f'{num_sites}_neurons']['untrained']['dprimes'], axis=0), ax=ax[0],
- color=sns.xkcd_palette(['dull yellow'])[0], kde=True)
- sns.histplot(np.mean(IT_neurons_novel500[f'{num_sites}_neurons']['untrained']['dprimes'], axis=0), ax=ax[0],
- color=sns.xkcd_palette(['pale lavender'])[0], kde=True)
- sns.lineplot(x=np.arange(-1, 4, 0.1), y=shared_kde(np.arange(-1, 4, 0.1)) * 100,
- color=sns.xkcd_palette(['blush'])[0], ax=ax[0])
- ax[0].set_xlabel("Task-naive accuracy (d')")
- ax[0].set_ylabel("# images")
- sns.histplot(sampled_hvm['i1'], ax=ax[1], color=sns.xkcd_palette(['dull yellow'])[0])
- sns.histplot(sampled_novel500['i1'], ax=ax[1], color=sns.xkcd_palette(['pale lavender'])[0])
- sns.lineplot(x=np.arange(-1, 4, 0.1), y=shared_kde(np.arange(-1, 4, 0.1)) * 100,
- color=sns.xkcd_palette(['blush'])[0], ax=ax[1])
- ax[1].set_xlabel(" ")
- plt.tight_layout()
- g.savefig(figure_dir + 'Figure4_novel500_decoding_naiveDists.png', dpi=300)
- g.savefig(figure_dir + 'Figure4_novel500_decoding_naiveDists.pdf', dpi=300, transparent=True)
- # apply sampling to the whole dataset
- df_matched = []
- for state in ['untrained', 'trained']:
- for d in range(draws):
- df_matched.append(
- {'dataset': 'Novel500', 'state': state, 'pool size': num_sites, 'draw': d,
- 'i1': np.mean(
- IT_neurons_novel500[f'{num_sites}_neurons'][state]['dprimes'][d, sampled_novel500['img'].values])})
- df_matched.append(
- {'dataset': 'HVM', 'state': state, 'pool size': num_sites, 'draw': d,
- 'i1': np.mean(IT_neurons_hvm[f'{num_sites}_neurons'][state]['dprimes'][d, sampled_hvm['img'].values])})
- df_matched = pd.DataFrame(df_matched)
- g = sns.catplot(data=df_matched, x='state', y='i1', hue='state', kind='point',
- errorbar=("pi", 95), col='dataset',
- palette=colors, height=5 * cm, aspect=0.7,
- legend=False)
- g.set(ylim=[0.5, 2.5])
- g.set_titles(' ')
- g.set_xticklabels(["naïve", "trained"])
- g.set_ylabels("Performance (d')")
- g.set_xlabels("IT neuron pool")
- g.refline(y=(sampled_hvm['i1'].mean() + sampled_novel500['i1'].mean()) / 2, color=sns.xkcd_palette(['blush'])[0], zorder=0)
- g.savefig(figure_dir + 'Figure4_novel500_decoding_i1_naiveMatched.png', dpi=300)
- g.savefig(figure_dir + 'Figure4_novel500_decoding_i1_naiveMatched.pdf', dpi=300, transparent=True)
- df_matched.to_csv(source_file_dir + 'Figure4_novel500_decoding_i1_naiveMatched.csv', index=False)
- print('Means:')
- print(df_matched.loc[df_matched['pool size'] == num_sites].groupby(['dataset', 'state']).mean())
- print('SD:')
- print(df_matched.loc[df_matched['pool size'] == num_sites].groupby(['dataset', 'state']).std())
- for dataset in ['HVM', 'Novel500']:
- print(dataset)
- print(
- f"{((df_matched.loc[(df_matched['dataset'] == dataset) & (df_matched['pool size'] == num_sites)].groupby(['state'])['i1'].mean()['trained'] / df_matched.loc[(df_matched['dataset'] == dataset) & (df_matched['pool size'] == num_sites)].groupby(['state'])['i1'].mean()['untrained']) - 1) * 100}% increase")
- df_dist = ((df_matched.loc[(df_matched['dataset'] == dataset) & (df_matched['pool size'] == num_sites) & (
- df_matched['state'] == 'trained'), 'i1'].reset_index() - df_matched.loc[
- (df_matched['dataset'] == dataset) & (df_matched['pool size'] == num_sites) & (
- df_matched['state'] == 'untrained'), 'i1'].reset_index())['i1'])
- print(
- f"CI (95%): {df_dist.quantile(0.025)} - {df_dist.quantile(0.975)}")
- print(
- f"p-val: {np.min([(df_dist < 0).mean(), (df_dist > 0).mean()]) * 2}")
- print(
- f"Mean diff: {df_dist.mean()}")
- print(
- f"SD diff: {df_dist.std()}")
- def FigureS9_BrainScoreLayerMapping(base_models, figure_dir=None, source_file_dir=None,
- result_file=None
- ):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if result_file == None:
- result_file = f'{Path(__file__).parent.parent}/Results/meta/BrainScore_ITmappings.pkl'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- df_all = pd.read_pickle(result_file)
- col_order = [' ']
- col_order.extend(base_models)
- g = sns.FacetGrid(data=df_all, col='baseModel', col_wrap=3, col_order=col_order, height=5 * cm, aspect=1.3,
- sharex=False, sharey=False)
- g.map(plt.errorbar, 'layer', 'scores_x', 'scores_y', color='grey', zorder=0)
- for i, ax in enumerate(g.axes[1:]):
- ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
- xs, ys = ax.lines[-1].get_data()
- ax.scatter(xs[np.argmax(ys)], np.max(ys), color=sns.xkcd_palette(['royal blue'])[0], s=20)
- ax.axvline(xs[np.argmax(ys)], color=sns.xkcd_palette(['royal blue'])[0], ls='--')
- ax.set_title(base_models[i])
- g.set_xlabels('Model layer')
- g.set_ylabels('IT encoding\nscore')
- plt.subplots_adjust(hspace=1.75, wspace=0.2)
- g.savefig(f'{figure_dir}FigureS9_ITMappings.png', dpi=300)
- g.savefig(f'{figure_dir}FigureS9_ITMappings.pdf', transparent=True, dpi=300)
- df_all.to_csv(source_file_dir + 'FigureS9_ITMappings.csv', index=False)
- def FigureS10_UnitSiteScaling_IT(base_models, num_sites=159,
- recompute=False,
- reestimate_predictions=False,
- draws=1000,
- maximum_scaling=101,
- resultFile=None,
- figure_dir=None,
- source_file_dir=None,
- mode='empirical_conditioned_v2'):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if resultFile == None:
- resultFile = f'{Path(__file__).parent.parent}/Results/meta/UnitSiteScaling.pkl'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- IT_neurons = load_MonkeyIT_Decodes(num_neurons=np.array([num_sites]), includeReliability=False, mode=mode,
- recompute=recompute, draws=draws)
- dfs = get_ModelIT_categoryDecoding_UnitSiteScaling(base_models, reestimate_predictions=reestimate_predictions,
- recompute=recompute, num_sites=num_sites)
- target_value = IT_neurons[f'{num_sites}_neurons']['untrained']['dprimes'].mean()
- dfs['siteScaling'] = dfs['units'] / num_sites
- def func(x, a, b, c): # x-shifted log
- return a * np.log(x + b) + c
- fitting_df = dfs[dfs['siteScaling'] < maximum_scaling].groupby(['base_model', 'siteScaling']).mean()
- sigma_df = dfs[dfs['siteScaling'] < maximum_scaling].groupby(['base_model', 'siteScaling']).std()
- sigma_df.loc[sigma_df['i1'] == 0] = 1
- g = sns.relplot(data=dfs, x='siteScaling', y='i1', kind='line', errorbar=("pi", 95),
- color='seagreen', height=5 * cm, aspect=1.2, style='base_model',
- dashes=False, col='base_model', col_wrap=3,
- markers=['o' for _ in base_models], legend=False)
- g.set_titles("{col_name}")
- g.refline(y=target_value, color='grey', ls='-')
- unit_scaling = []
- for model, ax in zip(base_models, g.axes):
- # print(model)
- popt, pcov = curve_fit(func, fitting_df.loc[model].index.values, fitting_df.loc[model, 'i1'].values,
- sigma=sigma_df.loc[model, 'i1'].values,
- )
- # print(popt)
- fitting_df.loc[model, 'predicted_i1'] = func(fitting_df.loc[model].index.values, *popt)
- interpolation_df = pd.DataFrame(
- {'base_model': model, 'sitesScaling': np.arange(1, 100), 'i1_predicted': func(np.arange(1, 100), *popt)})
- ax.plot(interpolation_df.sitesScaling.values, interpolation_df['i1_predicted'].values, ls=':', color='m')
- required_sites = interpolation_df.loc[interpolation_df['i1_predicted'] >= target_value, 'sitesScaling'].min()
- # Identify the adjacent actual datapoints
- required_sites_empirical_upper = fitting_df.loc[model, 'i1'][
- fitting_df.loc[model, 'i1'] >= target_value].index.min()
- required_sites_empirical_lower = fitting_df.loc[model, 'i1'][
- fitting_df.loc[model, 'i1'] <= target_value].index.max()
- if pd.isna(required_sites_empirical_upper) | pd.isna(required_sites_empirical_lower):
- required_sites_empirical_estimated = np.nan
- else:
- lower_val = fitting_df.loc[model].loc[required_sites_empirical_lower]['i1']
- upper_val = fitting_df.loc[model].loc[required_sites_empirical_upper]['i1']
- linearFit = np.polyfit([required_sites_empirical_lower, required_sites_empirical_upper],
- [lower_val, upper_val], 1)
- required_sites_empirical_estimated = (target_value - linearFit[1]) / linearFit[0]
- # ax.axvline(x=required_sites_empirical_estimated, color='orange')
- if required_sites != np.nan:
- ax.axvline(x=required_sites, color='m')
- print(f'{model}: {required_sites} / {required_sites_empirical_estimated}')
- unit_scaling.append(
- {'base_model': model, 'siteUnitScaling': required_sites, 'units': required_sites * num_sites})
- g.set(xlim=[0, maximum_scaling])
- g.set_ylabels("Accuracy (d')")
- g.set_xlabels("Unit/site ratio")
- g.savefig(figure_dir + 'FigureS10_siteUnitScaling.png', dpi=300)
- g.savefig(figure_dir + 'FigureS10_siteUnitScaling.pdf', dpi=300, transparent=True)
- dfs.to_csv(source_file_dir + 'FigureS10_siteUnitScaling.csv', index=False)
- unit_scaling = pd.DataFrame(unit_scaling)
- if recompute:
- unit_scaling.to_pickle(resultFile)
- return unit_scaling.loc[unit_scaling['siteUnitScaling'].isna() == False, 'base_model'].tolist()
- def Figure6_performance(training_groups, base_models, model_suffix='best', metric='test_d-prime', recompute=False,
- performance_threshold=None, figure_dir=None, source_file_dir=None,
- version='v0', dataset='hvm_modelTest'):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- df = pd.DataFrame()
- for f in training_groups:
- trained_feature_dir = training_groups[f]['feature_dir'] + f'{dataset}/{model_suffix}/'
- if (recompute == True) or (
- not Path(f'{training_groups[f]["feature_dir"]}/TrainingMetrics.pkl').exists()):
- ### This requires retraining. Wandb meta-files not included.
- tmp = loadTrainingResults(base_models, training_groups[f]['feature_dir'],
- project=training_groups[f]['project'], entity=training_groups[f]['entity'],
- sweep_suffix=training_groups[f]['sweep_suffix'],
- model_suffix=model_suffix, recompute=recompute)
- ###
- else:
- tmp = joblib.load(
- f'{training_groups[f]["feature_dir"]}/TrainingMetrics.pkl')
- tmp['Training'] = f
- df = pd.concat([df, tmp], ignore_index=True)
- df = df.loc[df['base_model'].isin(base_models)]
- if version == 'v0':
- g = sns.FacetGrid(df, col="Training", sharex=True, sharey=False, col_wrap=3, aspect=1.25, height=1.7)
- g.map(sns.histplot, metric, binwidth=0.2,
- clip_on=False,
- fill=True, alpha=0.5, linewidth=0.5, color='white')
- g.figure.subplots_adjust(hspace=-0.5)
- df['selected'] = False
- if 'max_value' not in performance_threshold:
- g.refline(x=performance_threshold['min_value'], color=sns.xkcd_palette(['raspberry'])[0], linestyle='--')
- df.loc[df[metric] >= performance_threshold['min_value'], 'selected'] = True
- else:
- g.map(plt.axvspan, xmin=performance_threshold['min_value'], xmax=performance_threshold['max_value'],
- zorder=0, color=sns.xkcd_palette(['raspberry'])[0],
- alpha=0.2)
- df.loc[(df[metric] >= performance_threshold['min_value']) & (
- df[metric] <= performance_threshold['max_value']), 'selected'] = True
- g.set_titles("")
- g.set(xlabel="Performance (d')", ylabel="# models")
- g.savefig(figure_dir + 'FigureS12_performance.png', dpi=300)
- g.savefig(figure_dir + 'FigureS12_performance.pdf', dpi=300, transparent=True)
- print(df.groupby('Training')['selected'].sum())
- df.to_csv(source_file_dir + 'FigureS12_performance.csv', index=False)
- elif version == 'v1':
- g = sns.displot(data=df, x=metric,
- color='white', height=3.75 * cm, aspect=1.25, clip_on=False, fill=True, alpha=0.5,
- linewidth=0.5,
- facet_kws={'sharex': False, 'sharey': False}, common_bins=False, bins=30)
- g.figure.subplots_adjust(hspace=-0.5)
- df['selected'] = False
- if 'max_value' not in performance_threshold:
- g.refline(x=performance_threshold['min_value'], color=sns.xkcd_palette(['raspberry'])[0], linestyle='--')
- df.loc[df[metric] >= performance_threshold['min_value'], 'selected'] = True
- else:
- g.map(plt.axvspan, xmin=performance_threshold['min_value'], xmax=performance_threshold['max_value'],
- zorder=0, color=sns.xkcd_palette(['raspberry'])[0], alpha=0.2,
- )
- df.loc[(df[metric] >= performance_threshold['min_value']) & (
- df[metric] <= performance_threshold['max_value']), 'selected'] = True
- g.set_titles("")
- g.set(xlabel="Performance (d')", ylabel="# models")
- g.savefig(figure_dir + 'Figure6_performance.png', dpi=300)
- g.savefig(figure_dir + 'Figure6_performance.pdf', dpi=300, transparent=True)
- print(df['selected'].sum())
- df.to_csv(source_file_dir + 'Figure6_performance.csv', index=False)
- return df
- def Figure6_modelITComparison_means(base_models, training_groups, performance_threshold, model_draws=100,
- num_sites=159, draws=1000, mode='empirical_conditioned_v2', recompute=False,
- delta='proportion',
- figure_dir=None,
- meta_dir=None,
- source_file_dir=None,
- version='v0'
- ):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if meta_dir == None:
- meta_dir = f'{Path(__file__).parent.parent}/Results/meta/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- df_selectivity = load_ModelSelectivity_allModels(base_models, training_groups, performance_threshold, delta=delta,
- model_draws=model_draws, recompute=recompute)
- df_rsa = load_ModelRDMs_allModels(base_models, training_groups, performance_threshold, delta=delta,
- model_draws=model_draws, recompute=recompute)
- df_decoding = load_ModelIT_categoryDecodes_allModels(base_models, training_groups, performance_threshold,
- delta=delta,
- model_draws=model_draws, recompute=recompute)
- # Already computed in the neural analyses
- neural_selectivity = load_neuralITselectivity_deltas(recompute=False, draws=draws, mode=mode, delta=delta)
- neural_rsa = load_neuralRDMs_deltas(recompute=False, draws=draws, mode=mode, num_sites=num_sites, delta=delta)
- neural_decoding = load_MonkeyIT_Decodes_deltas(num_sites=num_sites, includeReliability=False, recompute=False,
- mode=mode, draws=draws, delta=delta)
- df_combined = pd.DataFrame()
- df_combined['delta'] = df_selectivity.groupby('model_ID')['delta (selectivity)'].median()
- df_combined['metric'] = 'selectivity'
- df_combined = df_combined.reset_index()
- df_tmp = pd.DataFrame()
- df_tmp['delta'] = df_rsa.groupby('model_ID')['delta (tau)'].mean()
- df_tmp['metric'] = 'rsa'
- df_tmp = df_tmp.reset_index()
- df_combined = pd.concat([df_combined, df_tmp])
- df_tmp = pd.DataFrame()
- df_tmp['delta'] = df_decoding.groupby('model_ID')['delta (i1)'].mean()
- df_tmp['metric'] = 'decoding'
- df_tmp = df_tmp.reset_index()
- df_combined = pd.concat([df_combined, df_tmp])
- # Define subsets
- set_decoding = set(df_combined.loc[(df_combined.loc[
- df_combined['metric'] == 'decoding', 'delta'] >= np.quantile(
- eval(f'neural_decoding'), 0.025)) & (
- df_combined.loc[
- df_combined['metric'] == 'decoding', 'delta'] <= np.quantile(
- eval(f'neural_decoding'), 0.975)), 'model_ID'])
- set_rsa = set(df_combined.loc[(df_combined.loc[df_combined['metric'] == 'rsa', 'delta'] >= np.quantile(
- eval(f'neural_rsa'), 0.025)) & (
- df_combined.loc[df_combined['metric'] == 'rsa', 'delta'] <= np.quantile(
- eval(f'neural_rsa'), 0.975)), 'model_ID'])
- set_selectivity = set(df_combined.loc[(df_combined.loc[
- df_combined['metric'] == 'selectivity', 'delta'] >= np.quantile(
- eval(f'neural_selectivity'), 0.025)) & (
- df_combined.loc[df_combined[
- 'metric'] == 'selectivity', 'delta'] <= np.quantile(
- eval(f'neural_selectivity'), 0.975)), 'model_ID'])
- models_pt3 = pd.DataFrame({'model_ID': df_combined.model_ID.unique()})
- models_pt3['match_selectivity'] = models_pt3['model_ID'].isin(set_selectivity)
- models_pt3['match_rsa'] = models_pt3['model_ID'].isin(set_rsa)
- models_pt3['match_decoding'] = models_pt3['model_ID'].isin(set_decoding)
- models_pt3['match_all'] = models_pt3['match_selectivity'] & models_pt3['match_rsa'] & models_pt3['match_decoding']
- models_pt3['match_none'] = (models_pt3['match_selectivity'] == False) & (models_pt3['match_rsa'] == False) & (
- models_pt3['match_decoding'] == False)
- models_pt3['match_one'] = (models_pt3['match_decoding'].astype(int) + models_pt3['match_selectivity'].astype(int) +
- models_pt3['match_rsa'].astype(int)) == 1
- models_pt3['match_two'] = (models_pt3['match_decoding'].astype(int) + models_pt3['match_selectivity'].astype(
- int) + models_pt3['match_rsa'].astype(int)) == 2
- for feature in ['base_model', 'Training', 'base_model_type']:
- models_pt3[feature] = models_pt3['model_ID'].map(dict(zip(df_decoding['model_ID'], df_decoding[feature])))
- if recompute:
- models_pt3.to_pickle(meta_dir + f'SelectedModels_pt3_means.pkl')
- plotting_titles = {'rsa': 'Representational\nstrength',
- 'selectivity': 'Selectivity',
- 'decoding': 'Linear decodability'}
- if version == 'v0':
- g = sns.displot(data=df_combined, x='delta', row='metric',
- color=sns.xkcd_palette(['raspberry'])[0], height=3.75 * cm, aspect=1.25, clip_on=False,
- fill=True, alpha=0.2, linewidth=0.5,
- facet_kws={'sharex': False, 'sharey': False}, common_bins=False, bins=30)
- for title, ax in g.axes_dict.items():
- print(title)
- ax.axvspan(np.quantile(eval(f'neural_{title}'), 0.025),
- np.quantile(eval(f'neural_{title}'), 0.975),
- color=sns.xkcd_palette(['royal blue'])[0], zorder=0, alpha=0.2)
- ax.set_title(plotting_titles[title], fontweight='bold', fontsize=10)
- print(
- f"# models falling below neural CI: {(df_combined.loc[df_combined['metric'] == title, 'delta'] < np.quantile(eval(f'neural_{title}'), 0.025)).sum()}")
- print(
- f"# models falling above neural CI: {(df_combined.loc[df_combined['metric'] == title, 'delta'] > np.quantile(eval(f'neural_{title}'), 0.975)).sum()}")
- print(
- f"# models within neural CI: {((df_combined.loc[df_combined['metric'] == title, 'delta'] >= np.quantile(eval(f'neural_{title}'), 0.025)) & (df_combined.loc[df_combined['metric'] == title, 'delta'] <= np.quantile(eval(f'neural_{title}'), 0.975))).sum()}")
- g.set_ylabels('# models')
- g.set_xlabels('Δ%')
- g.savefig(figure_dir + f'Figure6_modelITComparison_means_v0.png', dpi=300)
- g.savefig(figure_dir + f'Figure6_modelITComparison_means_v0.pdf', dpi=300, transparent=True)
- df_combined.to_csv(source_file_dir + 'Figure6_modelITComparison_means_v0.csv', index=False)
- elif version == 'v1':
- # make a venn diagram
- fig, ax = plt.subplots()
- venn3([set_selectivity, set_decoding, set_rsa], ('Selectivity', 'Decoding', 'RSA'),
- ax=ax)
- fig.savefig(figure_dir + f'Figure6_modelITComparison_means_v1.png', dpi=300)
- fig.savefig(figure_dir + f'Figure6_modelITComparison_means_v1.pdf', dpi=300, transparent=True)
- elif version == 'v2':
- df_plot = models_pt3.groupby('Training', as_index=False)['match_all'].mean()
- df_plot['match_all_%'] = df_plot['match_all'] * 100
- df_plot['dummy'] = 100
- g = sns.catplot(data=df_plot, x='Training', y='match_all_%',
- kind='bar', color=sns.xkcd_palette(['royal blue'])[0],
- height=3.75 * cm, aspect=0.9, order=['FT', '2stepFT', 'binary'],
- edgecolor=".5", linewidth=0.5,
- )
- g.map(sns.barplot, 'Training', 'dummy', order=['FT', '2stepFT', 'binary'], zorder=0, color='white',
- linewidth=0.5, edgecolor=".5")
- g.set_xticklabels(['Standard', 'Step-wise', 'Binary choice'], rotation=90)
- g.set(ylim=[0, 100])
- g.set_ylabels('% models')
- g.savefig(figure_dir + f'FigureS12_modelITComparison_means_Training.png')
- g.savefig(figure_dir + f'FigureS12_modelITComparison_means_Training.pdf', dpi=300, transparent=True)
- df_plot.to_csv(source_file_dir + 'FigureS12_modelITComparison_means_Training.csv', index=False)
- df_plot = models_pt3.groupby('base_model', as_index=False)['match_all'].mean()
- df_plot['match_all_%'] = df_plot['match_all'] * 100
- df_plot['dummy'] = 100
- model_order = ['resnet18_v1', 'resnet34_v1', 'resnet50_v1', 'resnet101_v1', 'resnet152_v1',
- 'alexnet', 'vgg16', 'vgg19', ' ',
- 'resnet50_MoCov2_200epochs', 'resnet50_simclr_100epochs', 'resnet50_barlowTwins_300epochs',
- ]
- model_titles = ['18', '34', '50', '101', '152',
- 'alexnet', 'vgg16', 'vgg19', ' ',
- 'MoCov2', 'SimCLR', 'barlowTwins']
- g = sns.catplot(data=df_plot, x='base_model', y='match_all_%',
- kind='bar', color=sns.xkcd_palette(['royal blue'])[0],
- height=3.75 * cm, aspect=2.4,
- order=model_order,
- edgecolor=".5", linewidth=0.5,
- )
- g.map(sns.barplot, 'base_model', 'dummy', order=model_order,
- zorder=0, color='white',
- linewidth=0.5, edgecolor=".5")
- g.set_xticklabels(model_titles, rotation=90)
- g.set(ylim=[0, 100])
- g.set_ylabels('% models')
- g.savefig(figure_dir + f'FigureS12_modelITComparison_means_baseModel.png')
- g.savefig(figure_dir + f'FigureS12_modelITComparison_means_baseModel.pdf', dpi=300, transparent=True)
- df_plot.to_csv(source_file_dir + 'FigureS12_modelITComparison_means_baseModel.csv', index=False)
- def FigureS11_modelITComparison_controlLayers(layers, base_models, training_groups, performance_threshold, model_draws=100,
- num_sites=159, draws=1000, mode='empirical_conditioned_v2', recompute=False,
- delta='proportion', figure_dir=None, source_file_dir=None,):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- df_combined_all = []
- for layer in layers:
- print(layer)
- area = f'Layer-{layer}'
- df_selectivity = load_ModelSelectivity_allModels(base_models, training_groups, performance_threshold,
- delta=delta, area=area, model_draws=model_draws,
- recompute=recompute)
- df_rsa = load_ModelRDMs_allModels(base_models, training_groups, performance_threshold, delta=delta, area=area,
- model_draws=model_draws, recompute=recompute)
- df_decoding = load_ModelIT_categoryDecodes_allModels(base_models, training_groups, performance_threshold,
- delta=delta, area=area, model_draws=model_draws,
- recompute=recompute)
- df_combined = pd.DataFrame()
- df_combined['delta'] = df_selectivity.groupby('model_ID')['delta (selectivity)'].median()
- df_combined['metric'] = 'selectivity'
- df_combined = df_combined.reset_index()
- df_tmp = pd.DataFrame()
- df_tmp['delta'] = df_rsa.groupby('model_ID')['delta (tau)'].mean()
- df_tmp['metric'] = 'rsa'
- df_tmp = df_tmp.reset_index()
- df_combined = pd.concat([df_combined, df_tmp])
- df_tmp = pd.DataFrame()
- df_tmp['delta'] = df_decoding.groupby('model_ID')['delta (i1)'].mean()
- df_tmp['metric'] = 'decoding'
- df_tmp = df_tmp.reset_index()
- df_combined = pd.concat([df_combined, df_tmp])
- df_combined['area'] = area
- df_combined['layer'] = layer
- df_combined_all.append(df_combined)
- df_combined_all = pd.concat(df_combined_all, ignore_index=True)
- neural_selectivity = load_neuralITselectivity_deltas(recompute=False, draws=draws, mode=mode, delta=delta)
- neural_decoding = load_MonkeyIT_Decodes_deltas(num_sites=num_sites, includeReliability=False, recompute=False,
- mode=mode, draws=draws, delta=delta)
- neural_rsa = load_neuralRDMs_deltas(recompute=False, draws=draws, mode=mode, num_sites=num_sites, delta=delta)
- plotting_titles = {'rsa': 'Representational\nstrength',
- 'selectivity': 'Selectivity',
- 'decoding': 'Linear decodability'}
- #model_IDs = df_combined_all.loc[df_combined_all['area'] == 'EarlyLayerControl', 'model_ID'].unique()
- df_combined_plotting = df_combined_all.loc[
- df_combined_all['layer'].isin(['layer2[0].relu', 'layer4[0].relu', 'avgpool'])]
- df_combined_plotting.loc[df_combined_plotting['layer'] == 'layer4[0].relu', 'area'] = 'IT-mapped layer'
- df_combined_plotting.loc[df_combined_plotting['layer'] == 'layer2[0].relu', 'area'] = 'Early control layer'
- df_combined_plotting.loc[df_combined_plotting['layer'] == 'avgpool', 'area'] = 'Late control layer'
- g = sns.displot(data=df_combined_plotting, x='delta', col='metric',
- hue='area', height=5 * cm, aspect=1, clip_on=False, fill=True, alpha=0.2, linewidth=0.5,
- facet_kws={'sharex': False, 'sharey': False}, common_bins=False, kde=True,
- palette=sns.xkcd_palette(['tangerine', 'raspberry', 'pastel purple']))
- for title, ax in g.axes_dict.items():
- print(title)
- ax.axvspan(np.quantile(eval(f'neural_{title}'), 0.025),
- np.quantile(eval(f'neural_{title}'), 0.975),
- color=sns.xkcd_palette(['grey'])[0], zorder=0, alpha=0.3)
- ax.set_title(plotting_titles[title])
- g.set_ylabels('# models')
- g.set_xlabels('Δ%')
- #plt.show()
- g.savefig(figure_dir + f'FigureS11_modelITComparison_controlLayers.png', dpi=300)
- g.savefig(figure_dir + f'FigureS11_modelITComparison_controlLayers.pdf', dpi=300, transparent=True)
- df_combined_plotting.to_csv(source_file_dir + 'FigureS11_modelITComparison_controlLayers.csv', index=False)
- g = sns.catplot(data=df_combined_all, x='layer', y='delta', col='metric', kind='point', order=layers,
- color=sns.xkcd_palette(['eggplant'])[0],
- col_order=['selectivity', 'rsa', 'decoding'], errorbar=('pi', 95), height=5.5 * cm, aspect=1.3,
- sharey=False)
- for title, ax in g.axes_dict.items():
- ax.axhspan(np.quantile(eval(f'neural_{title}'), 0.025),
- np.quantile(eval(f'neural_{title}'), 0.975),
- color=sns.xkcd_palette(['grey'])[0], zorder=0, alpha=0.3)
- ax.set_title(plotting_titles[title])
- g.refline(x=layers.index('layer4[0].relu'), c=sns.xkcd_palette(['raspberry'])[0], ls='-', zorder=0)
- g.refline(x=layers.index('layer2[0].relu'), c=sns.xkcd_palette(['tangerine'])[0], ls='-', zorder=0)
- g.refline(x=layers.index('avgpool'), c=sns.xkcd_palette(['pastel purple'])[0], ls='-', zorder=0)
- g.refline(y=0)
- g.set_xticklabels([])
- g.set_ylabels('Δ%')
- g.set_xlabels('Model layer')
- g.savefig(figure_dir + f'FigureS11_modelITComparison_controlLayers_v1.png', dpi=300)
- g.savefig(figure_dir + f'FigureS11_modelITComparison_controlLayers_v1.pdf', dpi=300, transparent=True)
- df_combined_all.to_csv(
- source_file_dir + 'FigureS11_modelITComparison_controlLayers_v1.csv', index=False)
- def FigureS11_modelITcomparison_controlLayers_orthogonalDecoding(training_groups, layers=None, seed=6,
- recompute=False, metric='corrs', model_draws=100, draws=1000,
- delta='proportion', mode='empirical_conditioned',reestimate_predictions=False,
- figure_dir=None, meta_dir=None, source_file_dir=None):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if meta_dir == None:
- meta_dir = f'{Path(__file__).parent.parent}/Results/meta/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- if layers == None:
- layers = ['layer2[0].relu', 'layer4[0].relu', 'avgpool']
- np.random.seed(seed)
- models_pt3 = pd.read_pickle(meta_dir + f'SelectedModels_pt3_means.pkl')
- models_pt3['match_one'] = (models_pt3['match_decoding'].astype(int) + models_pt3['match_selectivity'].astype(int) + models_pt3['match_rsa'].astype(int)) == 1
- models_pt3['match_two'] = (models_pt3['match_decoding'].astype(int) + models_pt3['match_selectivity'].astype(
- int) + models_pt3['match_rsa'].astype(int)) == 2
- # Only include IT-like models and vary the layer...
- models_pt3 = models_pt3.loc[(models_pt3['base_model'] == 'resnet152_v1') & (models_pt3['match_all'])]
- df = []
- for layer in layers:
- print(layer)
- area = f'Layer-{layer}'
- df.append(load_ModelLayer_orthogonalDecodes_selection(models_pt3, training_groups,area=area, draws=model_draws, recompute=recompute,
- reestimate_predictions=reestimate_predictions))
- df[-1]['layer'] = layer
- df = pd.concat(df, ignore_index=True)
- df.loc[df['layer'] == 'layer4[0].relu', 'area'] = 'IT-mapped layer'
- df.loc[df['layer'] == 'layer2[0].relu', 'area'] = 'Early control layer'
- df.loc[df['layer'] == 'avgpool', 'area'] = 'Late control layer'
- neural_df = load_neuralITorthogonalDecodes(recompute=recompute, draws=draws, mode=mode, metric=metric)
- neural_df = neural_df.reset_index()
- neural_df['delta'] = computeDelta(neural_df['corrs', 'untrained'], neural_df['corrs', 'trained'], kind=delta)
- neural_df_plot = neural_df.copy()
- neural_df_plot.columns = ["_".join(a) for a in neural_df_plot.columns.to_flat_index()]
- neural_df_plot = neural_df_plot.melt(value_vars=['corrs_trained', 'corrs_untrained'], id_vars=['draws_', 'targetFeature_'])
- df['delta'] = computeDelta(df['corrs_pre'], df['corrs_post'])
- df['# matched IT-category metrics'] = None
- df.loc[df['model_ID'].isin(models_pt3.loc[models_pt3['match_all'], 'model_ID']), '# matched IT-category metrics'] = '3/3'
- df.loc[df['model_ID'].isin(models_pt3.loc[models_pt3['match_one'], 'model_ID']), '# matched IT-category metrics'] = '1/3'
- df.loc[df['model_ID'].isin(models_pt3.loc[models_pt3['match_two'], 'model_ID']), '# matched IT-category metrics'] = '2/3'
- df.loc[df['model_ID'].isin(models_pt3.loc[models_pt3['match_none'], 'model_ID']), '# matched IT-category metrics'] = '0/3'
- df_means = df.groupby(['model_ID', 'targetFeature', 'base_model', 'base_model_type', '# matched IT-category metrics', 'area'], as_index=False)['delta'].mean()
- df_means['targetFeature'] = df_means['targetFeature'].str.split('_', expand=True)[2]
- col_order = ['xpos', 'ypos', 'objSize', 'ecc', 'ryz', 'rxz', 'rxy']
- title_mapping = {'xpos': 'Vertical position',
- 'ypos': 'Horizontal position',
- 'objSize': 'Object size',
- 'ecc': 'Eccentricity',
- 'rxz': 'Rotation (ry)',
- 'ryz': 'Rotation (rx)',
- 'rxy': 'Rotation (rz)'}
- colors = sns.xkcd_palette(['tangerine', 'raspberry', 'pastel purple'])
- g = sns.catplot(df_means, col='targetFeature', height=4.5 * cm, aspect=0.8,
- y='delta', x='area', kind='strip', order=['Early control layer', 'IT-mapped layer', 'Late control layer'],
- palette=colors,
- sharey=False, sharex=False, col_order=col_order, alpha=0.5, zorder=1)
- g.refline(y=0)
- for title, ax in g.axes_dict.items():
- ax.axhspan(np.quantile(neural_df.loc[neural_df['targetFeature'] == title, 'delta'], 0.025),
- np.quantile(neural_df.loc[neural_df['targetFeature'] == title, 'delta'], 0.975),
- color=sns.xkcd_palette(['grey'])[0], zorder=0, alpha=.4)
- ax.set_title(title_mapping[title], fontsize=10)
- g.set_ylabels('%Δ performance')
- g.set_xlabels('Layer')
- g.set_xticklabels('')
- plt.tight_layout()
- #plt.show()
- g.savefig(figure_dir + f'FigureS11_orthogonalDecodes_change_controlLayers.pdf', dpi=300, transparent=True)
- g.savefig(figure_dir + f'FigureS11_orthogonalDecodes_change_controlLayers.png', dpi=300)
- df_means.to_csv(
- source_file_dir + 'FigureS11_orthogonalDecodes_change_controlLayers.csv', index=False)
- def Figure7_LFI_models(training_groups, recompute=False, meta_dir = None, figure_dir= None, source_file_dir=None, max_dim = 250):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if meta_dir == None:
- meta_dir = f'{Path(__file__).parent.parent}/Results/meta/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- models_pt3 = pd.read_pickle(meta_dir + f'SelectedModels_pt3_means.pkl')
- models_pt3['# metrics matched'] = models_pt3['match_selectivity'].astype(int) + models_pt3['match_rsa'].astype(
- int) + models_pt3['match_decoding'].astype(int)
- df_model = get_model_change_metrics(models_pt3, training_groups, recompute=recompute)
- categories = np.arange(8)
- plot_df = []
- pca_df = []
- for model_ID in df_model:
- for c in categories:
- plot_df.append({'model_ID': model_ID,
- '# metrics matched': models_pt3.loc[models_pt3['model_ID'] == model_ID, '# metrics matched'].item(),
- 'base_model': df_model[model_ID]['base_model'],
- 'training': df_model[model_ID]['Training'],
- 'category': c,
- 'state': 'naive',
- 'N_units': int(df_model[model_ID][c]['N_units']),
- 'Signal strength': df_model[model_ID][c]['df_abs_pre'],
- 'Response variance': df_model[model_ID][c]['variance_median_pre'],
- 'Noise correlations': df_model[model_ID][c]['NoiseCorrelation_median_pre'],
- 'Fano Factor': df_model[model_ID][c]['FanoFactor_median_pre'],
- 'aLFI': float(df_model[model_ID][c]['LFI_pre']),
- })
- pca_df.append(pd.DataFrame({'model_ID': model_ID,
- '# metrics matched': models_pt3.loc[
- models_pt3['model_ID'] == model_ID, '# metrics matched'].item(),
- 'base_model': df_model[model_ID]['base_model'],
- 'training': df_model[model_ID]['Training'],
- 'category': c,
- 'N_units': int(df_model[model_ID][c]['N_units']),
- 'N_components': np.arange(len(df_model[model_ID][c]['PCA_rotation']))[:max_dim],
- 'PCA rotation': np.array(df_model[model_ID][c]['PCA_rotation'])[:max_dim],
- 'PC absolute (naive)': df_model[model_ID][c]['PC_abs_pre'][:max_dim],
- 'PC relative (naive)': df_model[model_ID][c]['PC_abs_pre'][:max_dim]/ np.array(df_model[model_ID][c]['PC_abs_pre']).sum(),
- 'PC absolute (trained)': df_model[model_ID][c]['PC_abs_post'][:max_dim],
- 'PC relative (trained)': df_model[model_ID][c]['PC_abs_post'][:max_dim] / np.array(
- df_model[model_ID][c]['PC_abs_post'][:max_dim]).sum(),
- 'PC ratio': (df_model[model_ID][c]['PC_abs_post'][:max_dim] / np.array(
- df_model[model_ID][c]['PC_abs_post'][:max_dim]).sum())/(df_model[model_ID][c]['PC_abs_pre'][:max_dim]/ np.array(df_model[model_ID][c]['PC_abs_pre'][:max_dim]).sum())
- }))
- plot_df.append({'model_ID': model_ID,
- '# metrics matched': models_pt3.loc[
- models_pt3['model_ID'] == model_ID, '# metrics matched'].item(),
- 'base_model': df_model[model_ID]['base_model'],
- 'training': df_model[model_ID]['Training'],
- 'category': c,
- 'state': 'trained',
- 'N_units': int(df_model[model_ID][c]['N_units']),
- 'Signal strength': df_model[model_ID][c]['df_abs_post'],
- 'Response variance': df_model[model_ID][c]['variance_median_post'],
- 'Noise correlations': df_model[model_ID][c]['NoiseCorrelation_median_post'],
- 'Fano Factor': df_model[model_ID][c]['FanoFactor_median_post'],
- 'aLFI': float(df_model[model_ID][c]['LFI_post']),
- 'rotation_pre_post': float(df_model[model_ID][c]['rotation_pre_post']),
- 'gain_LFI': np.log10(df_model[model_ID][c]['LFI_post']) - np.log10(df_model[model_ID][c]['LFI_pre']),
- 'ratio_Signal strength': float(df_model[model_ID][c]['df_abs_post']) / float(
- df_model[model_ID][c]['df_abs_pre']),
- 'ratio_Response variance': float(df_model[model_ID][c]['variance_median_post']) / float(
- df_model[model_ID][c]['variance_median_pre']),
- 'ratio_FanoFactor': df_model[model_ID][c]['FanoFactor_median_post'] / df_model[model_ID][c]['FanoFactor_median_pre'],
- 'ratio_NC': df_model[model_ID][c]['NoiseCorrelation_median_post'] / df_model[model_ID][c][
- 'NoiseCorrelation_median_pre']
- })
- plot_df = pd.DataFrame(plot_df)
- pca_df = pd.concat(pca_df, ignore_index=True)
- plot_df_mean = plot_df.groupby(['model_ID', 'state', 'base_model', 'training'], as_index=False).mean()
- palette = sns.color_palette(['#e9d2de', '#c0bcde', '#5369B0', '#4a3f99'])
- # Plot signal separation
- g = sns.catplot(data=plot_df_mean, x='# metrics matched', y='ratio_Signal strength',
- aspect=0.9, height=6 * cm, kind='point', legend=False,
- hue='# metrics matched', palette=palette)
- g.set_xticklabels([0, 1, 2, 3])
- g.set_ylabels('Signal strength ratio\n(trained/naive)')
- g.refline(y=1)
- g.savefig(figure_dir + f'Figure7_InfoMetrics_Signal.png', dpi=300)
- g.savefig(figure_dir + f'Figure7_InfoMetrics_Signal.pdf', dpi=300, transparent=True)
- plot_df_mean.to_csv(
- source_file_dir + 'Figure7_InfoMetrics.csv', index=False)
- g = sns.catplot(data=plot_df_mean, x='# metrics matched', y='ratio_Response variance',
- aspect=0.9, height=6 * cm, kind='point', legend=False,
- hue='# metrics matched', palette=palette)
- g.set_xticklabels([0, 1, 2, 3])
- g.set_ylabels('Response variance\nratio (trained/naive)')
- g.refline(y=1)
- g.savefig(figure_dir + f'Figure7_InfoMetrics_Var.png', dpi=300)
- g.savefig(figure_dir + f'Figure7_InfoMetrics_Var.pdf', dpi=300, transparent=True)
- g = sns.catplot(data=plot_df_mean, x='# metrics matched', y='rotation_pre_post',
- aspect=0.9, height=6 * cm, kind='point', legend=False,
- hue='# metrics matched', palette=palette)
- g.set_xticklabels([0, 1, 2, 3])
- g.refline(y=0)
- g.set_ylabels('Signal rotation angle\n(trained/naive)')
- g.savefig(figure_dir + f'Figure7_InfoMetrics_Rot.png', dpi=300)
- g.savefig(figure_dir + f'Figure7_InfoMetrics_Rot.pdf', dpi=300, transparent=True)
- g = sns.relplot(data=pca_df, x='N_components', y='PCA rotation', kind='line',
- hue='# metrics matched', palette=palette, height=6 * cm, aspect=0.9, legend=False)
- g.set(xlim=[0, 25])
- g.set_xlabels('Principal components')
- g.set_ylabels('Covariance rotation\nangle (trained/naive)')
- g.savefig(figure_dir + f'Figure7_InfoMetrics_PCsRot.png', dpi=300)
- g.savefig(figure_dir + f'Figure7_InfoMetrics_PCsRot.pdf', dpi=300, transparent=True)
- plot_df_mean.to_csv(
- source_file_dir + 'Figure7_InfoMetrics_PCsRot.csv', index=False)
- def Figure8_orthogonalDecoding_means(training_groups,
- recompute=False, metric='corrs', model_draws=100, draws=1000,
- delta='proportion', mode='empirical_conditioned_v2',
- reestimate_predictions=False,
- figure_dir=None,
- meta_dir=None,
- source_file_dir=None,
- version='v0'):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if meta_dir == None:
- meta_dir = f'{Path(__file__).parent.parent}/Results/meta/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- models_pt3 = pd.read_pickle(meta_dir + f'SelectedModels_pt3_means.pkl')
- models_pt3['match_one'] = (models_pt3['match_decoding'].astype(int) + models_pt3['match_selectivity'].astype(int) +
- models_pt3['match_rsa'].astype(int)) == 1
- models_pt3['match_two'] = (models_pt3['match_decoding'].astype(int) + models_pt3['match_selectivity'].astype(
- int) + models_pt3['match_rsa'].astype(int)) == 2
- df = load_ModelITorthogonalDecodes_selection(models_pt3, training_groups, draws=model_draws, recompute=recompute,
- reestimate_predictions=reestimate_predictions)
- neural_df = load_neuralITorthogonalDecodes(recompute=recompute, draws=draws, mode=mode, metric=metric)
- neural_df = neural_df.reset_index()
- neural_df['delta'] = computeDelta(neural_df['corrs', 'untrained'], neural_df['corrs', 'trained'], kind=delta)
- if version == 'v0':
- print('Medians:')
- print(neural_df.groupby(['targetFeature']).median())
- for target in neural_df['targetFeature'].unique():
- print(target)
- print(
- f"{((neural_df.loc[neural_df['targetFeature'] == target, 'corrs']['trained'].mean() / neural_df.loc[neural_df['targetFeature'] == target, 'corrs']['untrained'].mean()) - 1) * 100}% increase")
- difference_dist = neural_df.loc[neural_df['targetFeature'] == target, 'corrs']['trained'] - \
- neural_df.loc[neural_df['targetFeature'] == target, 'corrs']['untrained']
- lower_CI = difference_dist.quantile(0.025)
- upper_CI = difference_dist.quantile(0.975)
- p_val = np.min([(difference_dist < 0).mean(), (difference_dist > 0).mean()]) * 2
- print(f'mean diff {difference_dist.mean()}')
- print(f'mean SD {difference_dist.std()}')
- print(
- f"CI (95%): {lower_CI} - {upper_CI}")
- print(f"p-val: {p_val}")
- neural_df_plot = neural_df.copy()
- neural_df_plot.columns = ["_".join(a) for a in neural_df_plot.columns.to_flat_index()]
- neural_df_plot = neural_df_plot.melt(value_vars=['corrs_trained', 'corrs_untrained'],
- id_vars=['draws_', 'targetFeature_'])
- g = sns.catplot(data=neural_df_plot, x='targetFeature_', y='value', hue='variable', kind='point',
- errorbar=("pi", 95),
- palette={'corrs_untrained': sns.xkcd_palette(['slate grey'])[0],
- 'corrs_trained': sns.xkcd_palette(['jade'])[0]}, height=4.5 * cm, aspect=2,
- legend=False, order=['xpos', 'ypos', 'ecc', 'objSize', 'ryz', 'rxz', 'rxy'], join=False,
- dodge=0.25)
- g.refline(y=0)
- g.set_xticklabels(["x-pos.", "y-pos.", 'ecc.', 'size', 'rx', 'ry', 'rz'])
- g.set_ylabels("Correlation")
- g.set_xlabels("Category-orthogonal property")
- g.savefig(figure_dir + 'FigureS13_orthogonal_neuralDecodes.png', dpi=300)
- g.savefig(figure_dir + 'FigureS13_orthogonal_neuralDecodes.pdf', dpi=300, transparent=True)
- neural_df_plot.to_csv(
- source_file_dir + 'FigureS13_orthogonal_neuralDecodes.csv', index=False)
- elif version == 'v1':
- df['delta'] = computeDelta(df['corrs_pre'], df['corrs_post'])
- df['# matched IT-category metrics'] = None
- df.loc[df['model_ID'].isin(
- models_pt3.loc[models_pt3['match_all'], 'model_ID']), '# matched IT-category metrics'] = '3/3'
- df.loc[df['model_ID'].isin(
- models_pt3.loc[models_pt3['match_one'], 'model_ID']), '# matched IT-category metrics'] = '1/3'
- df.loc[df['model_ID'].isin(
- models_pt3.loc[models_pt3['match_two'], 'model_ID']), '# matched IT-category metrics'] = '2/3'
- df.loc[df['model_ID'].isin(
- models_pt3.loc[models_pt3['match_none'], 'model_ID']), '# matched IT-category metrics'] = '0/3'
- df_means = df.groupby(
- ['model_ID', 'targetFeature', 'base_model', 'base_model_type', '# matched IT-category metrics'],
- as_index=False).mean()
- df_means['targetFeature'] = df_means['targetFeature'].str[14:]
- col_order = ['xpos', 'ypos', 'objSize', 'ecc', 'ryz', 'rxz', 'rxy']
- title_mapping = {'xpos': 'Vertical position',
- 'ypos': 'Horizontal position',
- 'objSize': 'Object size',
- 'ecc': 'Eccentricity',
- 'rxz': 'Rotation (ry)',
- 'ryz': 'Rotation (rx)',
- 'rxy': 'Rotation (rz)'}
- g = sns.catplot(df_means, col='targetFeature', col_wrap=4, height=4 * cm, aspect=1,
- y='delta', x='# matched IT-category metrics', kind='strip', order=['0/3', '1/3', '2/3', '3/3'],
- color=sns.xkcd_palette(['cerulean'])[0],
- sharey=False, sharex=False, col_order=col_order, alpha=0.1, zorder=1)
- g.refline(y=0)
- for title, ax in g.axes_dict.items():
- ax.axhspan(np.quantile(neural_df.loc[neural_df['targetFeature'] == title, 'delta'], 0.025),
- np.quantile(neural_df.loc[neural_df['targetFeature'] == title, 'delta'], 0.975),
- color=sns.xkcd_palette(['grey'])[0], zorder=0, alpha=.5)
- ax.set_title(title_mapping[title], fontsize=10)
- sns.pointplot(
- data=df_means.loc[df_means['targetFeature'] == title], x='# matched IT-category metrics', y='delta',
- join=False,
- order=['0/3', '1/3', '2/3', '3/3'],
- errorbar=None, estimator=np.median, color=sns.xkcd_palette(['cerulean'])[0],
- markers="_", scale=2, ax=ax,
- )
- g.set_ylabels('%Δ accuracy')
- g.set_xlabels('# IT-aligned\ncategory metrics')
- g.savefig(figure_dir + f'Figure8_orthogonalDecodes.pdf', dpi=300, transparent=True)
- g.savefig(figure_dir + f'Figure8_orthogonalDecodes.png', dpi=300)
- df_means.to_csv(
- source_file_dir + 'Figure8_orthogonalDecodes.csv', index=False)
- k = df_means['# matched IT-category metrics'].nunique() # four model groups
- n = df_means['model_ID'].nunique()
- for target in col_order:
- print(target)
- stats = kruskal(data=df_means.loc[df_means['targetFeature'] == target], dv='delta',
- between='# matched IT-category metrics')
- print(stats)
- epsilon_sq = (stats['H'].item() - k + 1) / (n - k)
- print('Effect size (epsilon_sq):', epsilon_sq)
- def Figure8_performanceStripes(figure_dir=None,
- recompute=False, num_sites=159,
- ):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- IT_neurons = load_MonkeyIT_Decodes(num_neurons=np.array([num_sites]), includeReliability=False, recompute=recompute)
- IT_image_trained = np.mean(IT_neurons[f'{num_sites}_neurons']['trained']['dprimes'], axis=0)
- g = sns.FacetGrid(data=pd.DataFrame(np.zeros((2, 1))), height=10 * cm, aspect=0.3)
- sns.heatmap(IT_image_trained[:, None], cmap='Spectral', ax=g.ax, cbar=False,
- vmin=np.percentile(IT_image_trained, 5), vmax=np.percentile(IT_image_trained, 95))
- g.ax.set(xlabel="", ylabel="", yticks=np.arange(1, 8) * 80, xticks=[])
- plt.savefig(figure_dir + 'Figure6_performanceStripes_ITtrained.png', dpi=300)
- plt.savefig(figure_dir + 'Figure6_performanceStripes_ITtrained.pdf', dpi=300, transparent=True)
- IT_image_naive = np.mean(IT_neurons[f'{num_sites}_neurons']['untrained']['dprimes'], axis=0)
- g = sns.FacetGrid(data=pd.DataFrame(np.zeros((2, 1))), height=10 * cm, aspect=0.3)
- sns.heatmap(IT_image_naive[:, None], cmap='Spectral', ax=g.ax, cbar=False,
- vmin=np.percentile(IT_image_naive, 5), vmax=np.percentile(IT_image_naive, 95))
- g.ax.set(xlabel="", ylabel="", yticks=np.arange(1, 8) * 80, xticks=[])
- plt.savefig(figure_dir + 'Figure6_performanceStripes_ITnaive.png', dpi=300)
- plt.savefig(figure_dir + 'Figure6_performanceStripes_ITnaive.pdf', dpi=300, transparent=True)
- pooled_behavior = load_MonkeyBehavior_pooled()
- dPrimes, _ = dPrime_monkey(pooled_behavior)
- g = sns.FacetGrid(data=pd.DataFrame(np.zeros((2, 1))), height=10 * cm, aspect=0.3)
- sns.heatmap(dPrimes['i1'][:, None], cmap='Spectral', ax=g.ax, cbar=False,
- vmin=np.percentile(dPrimes['i1'], 5), vmax=np.percentile(dPrimes['i1'], 95))
- g.ax.set(xlabel="", ylabel="", yticks=np.arange(1, 8) * 80, xticks=[])
- plt.savefig(figure_dir + 'Figure6_performanceStripes_behavior.png', dpi=300)
- plt.savefig(figure_dir + 'Figure6_performanceStripes_behavior.pdf', dpi=300, transparent=True)
- def Figure8_ITbehavioralConsistency_means(training_groups, seed=6,
- recompute=False, metric='i1', model_draws=100, draws=1000, num_sites=159,
- delta='proportion', mode='empirical_conditioned_v2',
- source_file_dir=None,
- figure_dir=None,
- meta_dir=None, version='v1'):
- if figure_dir == None:
- figure_dir = f'{Path(__file__).parent.parent}/Figures/'
- if meta_dir == None:
- meta_dir = f'{Path(__file__).parent.parent}/Results/meta/'
- if source_file_dir == None:
- source_file_dir = f'{Path(__file__).parent.parent}/SourceDataFiles/'
- np.random.seed(seed)
- models_pt3 = pd.read_pickle(meta_dir + f'SelectedModels_pt3_means.pkl')
- models_pt3['match_one'] = (models_pt3['match_decoding'].astype(int) + models_pt3['match_selectivity'].astype(int) +
- models_pt3['match_rsa'].astype(int)) == 1
- models_pt3['match_two'] = (models_pt3['match_decoding'].astype(int) + models_pt3['match_selectivity'].astype(
- int) + models_pt3['match_rsa'].astype(int)) == 2
- neural_df = get_consistency_behavior_ITneurons(consistency_metric=metric, recompute=recompute, num_sites=num_sites,
- mode=mode, draws=draws)
- neural_df = neural_df.reset_index()
- neural_df['delta'] = computeDelta(neural_df['consistency_i1_untrained'], neural_df['consistency_i1_trained'],
- kind=delta)
- if version == 'v0':
- print('Medians:')
- print(neural_df.median())
- print('Means:')
- print(neural_df.mean())
- print('SD:')
- print(neural_df.std())
- print(
- f"{((neural_df['consistency_i1_trained'].mean() / neural_df['consistency_i1_untrained'].mean()) - 1) * 100}% increase")
- difference_dist = neural_df['consistency_i1_trained'] - \
- neural_df['consistency_i1_untrained']
- lower_CI = difference_dist.quantile(0.025)
- upper_CI = difference_dist.quantile(0.975)
- p_val = np.min([(difference_dist < 0).mean(), (difference_dist > 0).mean()]) * 2
- print(
- f"Behavioral consistency CI (95%): {lower_CI} - {upper_CI}")
- print(f"p-val: {p_val}")
- neural_df_plot = neural_df.copy()
- neural_df_plot = neural_df_plot.melt(value_vars=['consistency_i1_untrained', 'consistency_i1_trained'],
- id_vars='draw')
- g = sns.catplot(data=neural_df_plot, x='variable', y='value', hue='variable', kind='point',
- errorbar=("pi", 95),
- palette={'consistency_i1_untrained': sns.xkcd_palette(['slate grey'])[0],
- 'consistency_i1_trained': sns.xkcd_palette(['jade'])[0]}, height=4.5 * cm, aspect=1.05,
- legend=False, join=False, dodge=0.25)
- g.refline(y=0)
- g.set_ylabels("IT-behavior\nconsistency")
- g.set_xlabels("IT neuron pools")
- g.set_xticklabels(['naïve', 'trained'])
- g.savefig(figure_dir + 'FigureS13_consistency_neuralDecodes.png', dpi=300)
- g.savefig(figure_dir + 'FigureS13_consistency_neuralDecodes.pdf', dpi=300, transparent=True)
- neural_df_plot.to_csv(
- source_file_dir + 'FigureS13_consistency_neuralDecodes.csv', index=False)
- elif version == 'v1':
- df = get_consistency_modelIT_modelBehavior(models_pt3, training_groups, recompute=recompute)
- df['delta'] = computeDelta(df['consistency_i1_pre'], df['consistency_i1_post'])
- df['Training'] = df['model_ID'].map(dict(zip(models_pt3['model_ID'], models_pt3['Training'])))
- df['# matched IT-category metrics'] = None
- df.loc[df['model_ID'].isin(
- models_pt3.loc[models_pt3['match_all'], 'model_ID']), '# matched IT-category metrics'] = '3/3'
- df.loc[df['model_ID'].isin(
- models_pt3.loc[models_pt3['match_one'], 'model_ID']), '# matched IT-category metrics'] = '1/3'
- df.loc[df['model_ID'].isin(
- models_pt3.loc[models_pt3['match_two'], 'model_ID']), '# matched IT-category metrics'] = '2/3'
- df.loc[df['model_ID'].isin(
- models_pt3.loc[models_pt3['match_none'], 'model_ID']), '# matched IT-category metrics'] = '0/3'
- df_means = df.groupby(['model_ID', '# matched IT-category metrics', 'Training'], as_index=False).mean()
- print(kruskal(data=df_means, dv='delta', between='# matched IT-category metrics'))
- g = sns.catplot(df_means, height=4 * cm, aspect=1.15,
- y='delta', x='# matched IT-category metrics', kind='strip', order=['0/3', '1/3', '2/3', '3/3'],
- color=sns.xkcd_palette(['cerulean'])[0],
- sharey=False, sharex=False, zorder=1, alpha=0.1, dodge=True)
- g.refline(y=0)
- g.ax.axhspan(np.quantile(neural_df['delta'], 0.025),
- np.quantile(neural_df['delta'], 0.975),
- color=sns.xkcd_palette(['grey'])[0], zorder=0, alpha=.5)
- sns.pointplot(
- data=df_means, x='# matched IT-category metrics', y='delta', join=False,
- order=['0/3', '1/3', '2/3', '3/3'],
- errorbar=None, estimator=np.median, color=sns.xkcd_palette(['cerulean'])[0],
- markers="_", scale=2, ax=g.ax,
- )
- g.set_ylabels('%Δ consistency')
- g.set_xlabels('# IT-aligned\ncategory metrics')
- g.savefig(figure_dir + f'Figure8_behavioralConsistency_v1.pdf', dpi=300, transparent=True)
- g.savefig(figure_dir + f'Figure8_behavioralConsistency_v1.png', dpi=300)
- df_means.to_csv(
- source_file_dir + 'Figure8_behavioralConsistency_v1.csv', index=False)
- g = sns.catplot(df_means, height=4 * cm, aspect=1.15,
- y='delta', x='# matched IT-category metrics', kind='strip', order=['0/3', '1/3', '2/3', '3/3'],
- color=sns.xkcd_palette(['cerulean'])[0],
- sharey=False, sharex=False, zorder=1, alpha=0.1,
- dodge=True)
- g.refline(y=0)
- g.ax.axhspan(np.quantile(neural_df['delta'], 0.025),
- np.quantile(neural_df['delta'], 0.975),
- color=sns.xkcd_palette(['grey'])[0], zorder=0, alpha=.5)
- sns.pointplot(
- data=df_means, x='# matched IT-category metrics', y='delta', join=False,
- order=['0/3', '1/3', '2/3', '3/3'],
- errorbar=None, estimator=np.median, color=sns.xkcd_palette(['cerulean'])[0],
- markers="_", scale=2, ax=g.ax,
- )
- g.set_ylabels('%Δ consistency')
- g.set_xlabels('# IT-aligned\ncategory metrics')
- g.set(ylim=[-20, 105])
- g.savefig(figure_dir + f'Figure8_behavioralConsistency_v1_zoom.pdf', dpi=300, transparent=True)
- g.savefig(figure_dir + f'Figure8_behavioralConsistency_v1_zoom.png', dpi=300)
paperFigures.py at commit 85fe071, under MIT · at the source
Overview
- McGovern Institute for Brain Research, Dept. of Brain and Cognitive Sciences, Massachusetts Institute of Technology, Cambridge, USA
- Center for Brains, Minds and Machines, Massachusetts Institute of Technology, Cambridge, USA
- MIT Quest for Intelligence, Cambridge, USA
- Centre for Integrative and Applied Neuroscience, York University, Toronto, Canada
- Department of Biology, Centre for Vision Research, York University, Toronto, Canada
Abstract
How does the primate brain coordinate plasticity when learning to discriminate new objects? We measured consequences of object learning on inferior temporal (IT) cortex, a key waypoint supporting object recognition in the ventral visual stream, in male macaques. Neural activity in task-trained monkeys’ IT showed increased object selectivity, enhanced linear separability across objects, and more object-invariant representations compared to task-naïve monkeys. To model these differences, we developed a computational framework using anatomically-mapped artificial neural network (ANN) models of the ventral stream with various learning algorithms. Simulations revealed that gradient-based, performance-optimizing updates of ANN internal representations accurately approximated observed IT cortex changes. These models predict novel training-induced phenomena in the IT cortex, including changes independent of object identity and IT’s alignment with behavior. This convergence between empirical measurements and model predictions suggests ventral stream plasticity follows task optimization principles well-approximated by gradient descent, enabling accurate predictions about visual plasticity and generalization to test images.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repositories
Its files are read in the Code ↔ Paper reader above, with 11 matches between paragraphs and lines of code.
dicarlolab/mkturk
4bdfaca7d1caa02115fb16c97b158dca1e620595, 1 September 2018Availability: 1 check, the latest on 27 September 2026: the link answers
- 27 September 2026: the link answers
15 files
- exampleinstall/
mkturk_installsettings.j , JavaScript, 20 liness - public/
liveplot_googlecharts.js , JavaScript, 110 lines - public/
liveplot_utils.js , JavaScript, 123 lines - public/
mkturk_ImageBuffer.js , JavaScript, 105 lines - public/
mkturk_TrialQueue.js , JavaScript, 298 lines - public/
mkturk_automator.js , JavaScript, 246 lines - public/
mkturk_bluetooth.js , JavaScript, 309 lines - public/
mkturk_dropbox.js , JavaScript, 506 lines - public/
mkturk_eventlisteners.js , JavaScript, 229 lines - public/
mkturk_globalvariables.j , JavaScript, 196 liness - public/
mkturk_installsettings0. , JavaScript, 25 linesjs - public/
mkturk_screenfunctions.j , JavaScript, 561 liness - public/
mkturk_usb.js , JavaScript, 248 lines - public/
mkturk_utils.js , JavaScript, 357 lines - README.md, Text, 98 lines
OSF dcgze
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
- 27 September 2026: the link answers (HTTP 200)
21 files
- Images/
utils.py , Python, 39 lines - analysis/
LFI.py , Python, 277 lines - analysis/
anatomy.py , Python, 289 lines - analysis/
categoryDecodes.py , Python, 976 lines - analysis/
compute_modelFeatures.py , Python, 425 lines - analysis/
consistency.py , Python, 171 lines - analysis/
metrics.py , Python, 142 lines - analysis/
orthogonalDecodes.py , Python, 330 lines - analysis/
paperFigures.py , Python, 2,242 lines - analysis/
rsa.py , Python, 370 lines - analysis/
selectivity.py , Python, 380 lines - analysis/
trainingResults.py , Python, 152 lines - analysis/
utils_behavioralData.py , Python, 197 lines - analysis/
utils_neuralData.py , Python, 524 lines - baseModels/
layersSpecs.py , Python, 69 lines - baseModels/
models.py , Python, 140 lines - baseModels/
transforms.py , Python, 35 lines - baseModels/
utils.py , Python, 133 lines - main_figures.py, Python, 197 lines
- LICENSE, License, 21 lines
- README.md, Text, 60 lines
lynnsoerensen/ObjectTraining_IT_ANNs
85fe071926ac2f44f8ac27428a33ca4a4fd1d4c4, 1 May 2026Availability: 1 check, the latest on 27 September 2026: the link answers
- 27 September 2026: the link answers
25 files
- Images/
utils.py , Python, 39 lines - analysis/
LFI.py , Python, 277 lines - analysis/
anatomy.py , Python, 289 lines - analysis/
categoryDecodes.py , Python, 976 lines, 2 matches - analysis/
compute_modelFeatures.py , Python, 425 lines, 1 match - analysis/
consistency.py , Python, 171 lines, 1 match - analysis/
metrics.py , Python, 142 lines - analysis/
orthogonalDecodes.py , Python, 330 lines - analysis/
paperFigures.py , Python, 2,242 lines, 5 matches - analysis/
rsa.py , Python, 370 lines - analysis/
selectivity.py , Python, 380 lines - analysis/
trainingResults.py , Python, 152 lines - analysis/
utils_behavioralData.py , Python, 197 lines - analysis/
utils_neuralData.py , Python, 524 lines - baseModels/
layersSpecs.py , Python, 69 lines - baseModels/
models.py , Python, 140 lines - baseModels/
transforms.py , Python, 35 lines - baseModels/
utils.py , Python, 133 lines - main_figures.py, Python, 197 lines
- training/
train_wandb_2stepFT.py , Python, 261 lines - training/
train_wandb_binaryTask.p , Python, 575 lines, 1 matchy - training/
train_wandb_v2.py , Python, 200 lines, 1 match - training/
training_utils.py , Python, 197 lines - LICENSE, License, 21 lines
- README.md, Text, 60 lines
Zenodo 19955396
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
- 27 September 2026: the link answers (HTTP 200)
Code availability
All code can be accessed on the Open Science Framework repository (https://
Reproduced under the paper's license (CC BY), from the paper cited above.
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 4 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 56 scripts, each with its path and the digest of its content;
- 11 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Data availability
All data has been deposited in the following Open Science Framework repository (https://
Reproduced under the paper's license (CC BY), from the paper cited above.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 27 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 3 authors, 2 keywords, 12 MeSH terms, 7 funders, 116 references.
Cite
This paper
Sörensen, L. K. A., DiCarlo, J. J., & Kar, K. (2026). Hierarchical optimization predicts plasticity in the macaque inferior temporal cortex following object training. Nature communications, 17(1), 8434. https://
BibTeX
@article{sorensen2026hie
author = {Sörensen, Lynn K A and DiCarlo, James J and Kar, Kohitij},
title = {{Hierarchical optimization predicts plasticity in the macaque inferior temporal cortex following object training}},
journal = {Nature communications},
year = {2026},
month = jul,
volume = {17},
number = {1},
pages = {8434},
publisher = {Nature Publishing Group},
issn = {2041-1723},
doi = {10.1038/
url = {https://
pmid = {42420264},
pmcid = {PMC13478300}
}
RIS
TY - JOUR
AU - Sörensen, Lynn K A
AU - DiCarlo, James J
AU - Kar, Kohitij
TI - Hierarchical optimization predicts plasticity in the macaque inferior temporal cortex following object training
T2 - Nature communications
J2 - Nat Commun
PY - 2026
DA - 2026/
VL - 17
IS - 1
SP - 8434
SN - 2041-1723
PB - Nature Publishing Group
DO - 10.1038/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1038/
"type": "article-journal",
"title": "Hierarchical optimization predicts plasticity in the macaque inferior temporal cortex following object training",
"container-title": "Nature communications",
"author": [
{
"family": "Sörensen",
"given": "Lynn K A"
},
{
"family": "DiCarlo",
"given": "James J"
},
{
"family": "Kar",
"given": "Kohitij"
}
],
"container-title-short":
"volume": "17",
"issue": "1",
"page": "8434",
"DOI": "10.1038/
"PMID": "42420264",
"PMCID": "PMC13478300",
"ISSN": "2041-1723",
"publisher": "Nature Publishing Group",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
8
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1038/s41467-026-76106-1 [code]
- Facial expression discrimination emerges from partially overlapping neural subspaces of detection and identity.Journal: Nature communicationsIn common: h5py, seaborn, scikit-learn, 4 other tools, non-human primate, 12 references, author Kohitij Kar
- [2] doi:10.1038/s41467-026-76098-y [code]
- A single computational objective can produce specialization of streams in visual cortex.Journal: Nature communicationsIn common: h5py, PyTorch, seaborn, 5 other tools, 6 references
- [3] doi:10.1038/s41593-026-02207-1 [code]
- Neuronal tuning aligns dynamically with object and texture manifolds across the visual hierarchy.Journal: Nature neuroscienceIn common: PyTorch, seaborn, scikit-learn, 4 other tools, non-human primate, 6 references
- [4] doi:10.1038/s41467-026-72146-9 [code]
- Modeling attention and binding in the brain through bidirectional recurrent gating.Journal: Nature communicationsIn common: PyTorch, seaborn, SciPy, 2 other tools, 8 references
- [5] doi:10.1038/s42003-026-10169-0 [code]
- Shared representations in brains and models reveal a two-route cortical organization during scene perception.Journal: Communications biologyIn common: h5py, PyTorch, seaborn, 5 other tools, 6 references
- [6] doi:10.1038/s41598-026-43946-2
- Human lateral occipital complex is invariant for position and size transformations at the single-neuron level.Journal: Scientific reportsIn common: 8 references
- [7] doi:10.1371/journal.pone.0347992 [code]
- Rotation-tolerant representations elucidate the time-course of high-level object processing.Journal: PloS oneIn common: pandas, NumPy, 7 references
- [8] doi:10.1038/s41562-026-02414-7 [code]
- Optimized feature gains explain and predict successes and failures of human selective listening.Journal: Nature human behaviourIn common: Pingouin, h5py, PyTorch, 6 other tools, 2 references
- [9] doi:10.1038/s41467-026-74460-8 [code]
- Spike-based alignment learning solves the weight transport problem.Journal: Nature communicationsIn common: PyTorch, seaborn, scikit-learn, 4 other tools, 4 references
- [10] doi:10.7554/elife.105968 [code]
- Modeling the hallucinatory effects of classical psychedelics in terms of replay-dependent plasticity mechanisms.Journal: eLifeIn common: PyTorch, scikit-learn, Matplotlib, 1 other tool, 5 references
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 4 repositories of the authors' code, each at its verified commit and with its license, 56 scripts, and 11 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:17caeb5f69420490…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
