-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add temporal metrics; add temporal versions of MajajHong2015 #1109
Merged
Merged
Changes from all commits
Commits
Show all changes
121 commits
Select commit
Hold shift + click to select a range
d97d452
feature: support temporal models for neural alignment by chaning Temp…
2a32f46
Merge branch 'brain-score:master' into master
YingtianDt c372d12
add example temporal submission
YingtianDt 40d2d2b
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt c0827b3
Merge branch 'brain-score:master' into master
YingtianDt 92cede9
complete new framework
YingtianDt e74015d
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt 088b9af
new module: temporal model helpers
YingtianDt c5b9097
change the arch of temporal; add tutorials
YingtianDt 8f301a3
improve: better naming
YingtianDt 3c3e475
update: wrapper tutorial on brain model
YingtianDt 34fbc08
add feature: inferencer identifier tracked by extractor for result ca…
YingtianDt f6c2fe4
fix: video fps sampling; need more tests!
YingtianDt 7e948ed
fix bugs: video sampling based on fps was wrong.
YingtianDt 3998027
Merge branch 'brain-score:master' into master
YingtianDt 17ecc5d
add mmaction2 models; add more features to the inferencers
YingtianDt 5fac41c
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt 20941fe
Merge branch 'brain-score:master' into master
YingtianDt 89bf58c
PR: temporal model helpers
YingtianDt 1433635
PR fix: not including gitmodules for now
YingtianDt b678e95
Update brainscore_vision/model_helpers/brain_transformation/temporal.py
YingtianDt 905c964
Update brainscore_vision/model_helpers/brain_transformation/temporal.py
YingtianDt e1e77ca
Update brainscore_vision/model_helpers/brain_transformation/temporal.py
YingtianDt 817b448
Update brainscore_vision/models/temporal_models/test.py
YingtianDt ad8cf5a
add mae_st; add ding2012
YingtianDt 749c371
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt 95e413e
try new arch
YingtianDt d020363
merge
YingtianDt d6960fc
init ding2012
YingtianDt 227e801
add tests for temporal model helpers; add block inferencer
YingtianDt 7906ddd
Delete tests/test_model_helpers/temporal/test___init__.py
YingtianDt 9316398
add benchmark ding2012
YingtianDt e0ba781
merge pr version
YingtianDt 6151364
resolve merge conflict
YingtianDt 8fcb49f
add mutliple libs for temporal models
YingtianDt f6b6554
change executor output format; add more inference tests; init load_we…
YingtianDt bf82677
add openstl
YingtianDt 4d2b669
merge
YingtianDt 66dafe0
update backend for executor
YingtianDt c7b2a84
feat:load_weight_file and corresponding test
YingtianDt 4b77eab
change:resize strategy changed from bilinear to pooling
YingtianDt d56f164
change:resize strategy changed from bilinear to pooling
YingtianDt 70fdb9e
fix mae_st submission
YingtianDt e7c37fc
minor
YingtianDt beba210
fix:dtype in assembly time align
YingtianDt 83585a1
minor
YingtianDt d2d2673
update model submissions
YingtianDt 8e84c09
Merge branch 'brain-score:master' into master
YingtianDt 0b0d598
fix dependency
YingtianDt 89d5424
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt df51aea
refactor: simplify the inferencer methods
YingtianDt f6f3105
fix:block inferencer, neuroid coord while merging
YingtianDt 323eb8a
fix:inferencer identifier
YingtianDt 244d38d
fix:weigh download
YingtianDt 657996f
Merge branch 'brain-score:master' into master
YingtianDt bfbb470
change tests to have max_workers=1
YingtianDt a062a07
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt af3cbbb
revert screen.py
YingtianDt 01fb289
not submit region_layer_map
YingtianDt cb18a88
remove torch dependency
YingtianDt 3e47774
make fake modules in tests
YingtianDt 64f2ec4
add torch to requirements; avoid torch in tests
YingtianDt 20aca51
minor
YingtianDt 2f7a3d8
minor
YingtianDt 2d411de
Merge branch 'brain-score:master' into master
YingtianDt 0dbf122
np.object changed to object
YingtianDt d19a633
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt 4ac951c
remove return in tests
YingtianDt f0c6e39
fix insertion position bug
YingtianDt e2a2ce3
Merge branch 'master' into master
mschrimpf 64079b8
Apply suggestions from code review
YingtianDt 465fb07
add: more type hints and comments
YingtianDt d430141
minor
YingtianDt effb0f8
pr:only commit temporal model helpers
YingtianDt 20e1b0a
pr: add one model for example
YingtianDt c0e7b13
Merge branch 'master' into master
mschrimpf 95065a5
undo whole_brain in Brainodel.RecordingTarget
YingtianDt 61737bd
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt 0febc8e
Merge branch 'master' into master
mschrimpf 28a5f40
use logger and fix newlines
mschrimpf b560af3
fix: video fps with copy was wrong
YingtianDt bea3d26
feat:fractional max_spatial_size
YingtianDt 70b2370
downsample layers in VideoMAE
YingtianDt 8b7a733
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt bd6f436
fix:video sampling wrong duration
YingtianDt 2ed5123
add more tests
YingtianDt 0ae615c
merge upstream
YingtianDt 05fd380
fix merge
YingtianDt e4b11bb
fix merge
YingtianDt ebd3c0a
module refactor; add more input test
YingtianDt 85f5217
add more temporal models
YingtianDt faf7fdd
Merge branch 'master' of https://github.com/brain-score/vision
YingtianDt 3e14419
fix videomaev2 sha
YingtianDt 427ae93
fix:temporal_modelmae_st
YingtianDt f3bd1fe
change:video conservative loading; rename:image to pil image
YingtianDt e204c66
fix:video last frame sampling; fix_time_naming
YingtianDt 4343a73
Merge branch 'master' of https://github.com/brain-score/vision
YingtianDt 7c7a23b
ignore pytest_cache
YingtianDt ccfdf87
Merge branch 'master' into master
mschrimpf a6ba086
Merge branch 'master' into master
YingtianDt 7164de4
gerge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt 94bb305
re-trigger tests
YingtianDt 342779c
Merge branch 'brain-score:master' into master
YingtianDt 6acb243
add joblib pool error management; fix video/image path recognizer
YingtianDt ea732d7
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt 96bc38b
Merge branch 'master' into master
YingtianDt fab8741
Merge branch 'master' into master
deirdre-k c39233b
Merge branch 'master' into master
YingtianDt 91505cb
update: naming of failed to pickle func in joblibmapper
YingtianDt 516492a
Merge branch 'master' into master
YingtianDt f87d9ac
Merge branch 'brain-score:master' into master
YingtianDt 0f8fee4
add temporal metric helpers
YingtianDt e06853e
add temporal version of mamjajhong2015
YingtianDt b1dcaf7
Merge branch 'master' of https://github.com/YingtianDt/brain-score
YingtianDt 57ce832
Merge branch 'master' into master
mike-ferguson e7dd0ef
Merge branch 'master' into master
YingtianDt f0243a0
Update benchmark.py
YingtianDt 5542996
Update benchmark.py
YingtianDt 149a6b0
Update brainscore_vision/metric_helpers/temporal.py
YingtianDt 9cdebde
Update brainscore_vision/metrics/internal_consistency/__init__.py
YingtianDt 790851b
Update benchmark.py
YingtianDt File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import xarray as xr | ||
import numpy as np | ||
|
||
from brainscore_vision.benchmark_helpers.neural_common import Score | ||
from brainscore_vision.metric_helpers.transformations import standard_error_of_the_mean | ||
|
||
from .xarray_utils import apply_over_dims, recursive_op | ||
|
||
|
||
# take the mean of scores (medians of single neuron scores) over time | ||
|
||
|
||
def average_over_presentation(score: Score) -> Score: | ||
raw = score | ||
score = raw.mean('presentation') | ||
score.attrs['raw'] = raw | ||
return score | ||
|
||
|
||
# PerOps is applied to every slice/chunk of the xarray along the specified dimensions | ||
class PerOps: | ||
def __init__(self, callable, dims, check_coords=[]): | ||
# for coordinate checking, they are supposed to be the same across assemblies | ||
self.dims = dims | ||
self.callable = callable | ||
self.check_coords = check_coords | ||
|
||
def __call__(self, *asms): | ||
for check_coord in self.check_coords: | ||
asms = [asm.sortby(check_coord) for asm in asms] | ||
for asm in asms[1:]: | ||
assert (asm[check_coord].values == asms[0][check_coord].values).all() | ||
ret = apply_over_dims(self.callable, *asms, dims=self.dims) | ||
return ret | ||
|
||
|
||
# SpanOps aggregates specified dimensions to one dimension | ||
class SpanOps: | ||
def __init__(self, callable, source_dims, aggregated_dim, resample=False): | ||
# if resample, randomly choose samples from the aggregated dimension, | ||
# whose size is the same as the assembly.sizes[aggregated_dim] | ||
self.source_dims = source_dims | ||
self.aggregated_dim = aggregated_dim | ||
self.callable = callable | ||
self.resample = resample | ||
|
||
def __call__(self, *asms): | ||
asms = [self._stack(asm) for asm in asms] | ||
return self.callable(*asms) | ||
|
||
def _stack(self, assembly): | ||
assembly_type = type(assembly) | ||
size = assembly.sizes[self.aggregated_dim] | ||
assembly = xr.DataArray(assembly) # xarray cannot deal with stacking MultiIndex (pydata/xarray#1554) | ||
assembly = assembly.reset_index(self.source_dims) | ||
assembly = assembly.rename({dim:dim+"_" for dim in self.source_dims}) # we'll call stacked timebins "presentation" | ||
assembly = assembly.stack({self.aggregated_dim : [dim+"_" for dim in self.source_dims]}) | ||
if self.resample: | ||
indices = np.random.randint(0, assembly.sizes[self.aggregated_dim], size) | ||
assembly = assembly.isel({self.aggregated_dim: indices}) | ||
return assembly_type(assembly) | ||
|
||
class PerTime(PerOps): | ||
def __init__(self, callable, time_dim="time_bin", check_coord="time_bin_start", **kwargs): | ||
self.time_bin = time_dim | ||
super().__init__(callable, dims=[time_dim], check_coords=[check_coord], **kwargs) | ||
|
||
class PerPresentation(PerOps): | ||
def __init__(self, callable, presentation_dim="presentation", check_coord="stimulus_id", **kwargs): | ||
self.presentation_dim = presentation_dim | ||
super().__init__(callable, dims=[presentation_dim], check_coords=[check_coord], **kwargs) | ||
|
||
class PerNeuroid(PerOps): | ||
def __init__(self, callable, neuroid_dim="neuroid", check_coord="neuroid_id", **kwargs): | ||
self.neuroid_dim = neuroid_dim | ||
super().__init__(callable, dims=[neuroid_dim], check_coords=[check_coord], **kwargs) | ||
|
||
class SpanTime(SpanOps): | ||
def __init__(self, callable, time_dim="time_bin", presentation_dim="presentation", resample=False): | ||
self.time_dim = time_dim | ||
self.presentation_dim = presentation_dim | ||
source_dims = [self.time_dim, self.presentation_dim] | ||
aggregated_dim = self.presentation_dim | ||
super().__init__(callable, source_dims, aggregated_dim, resample=resample) | ||
|
||
class SpanTimeRegression: | ||
""" | ||
Fits a regression with weights shared across the time bins. | ||
""" | ||
|
||
def __init__(self, regression): | ||
self._regression = regression | ||
|
||
def fit(self, source, target): | ||
assert (source['time_bin'].values == target['time_bin'].values).all() | ||
SpanTime(self._regression.fit)(source, target) | ||
|
||
def predict(self, source): | ||
return PerTime(self._regression.predict)(source) | ||
|
||
class PerTimeRegression: | ||
""" | ||
Fits a regression with different weights for each time bins. | ||
""" | ||
|
||
def __init__(self, regression): | ||
self._regression = regression | ||
|
||
def fit(self, source, target): | ||
# Lazy fit until predict | ||
assert (source['time_bin'].values == target['time_bin'].values).all() | ||
self._train_source = source | ||
self._train_target = target | ||
|
||
def predict(self, source): | ||
def fit_predict(train_source, train_target, test_source): | ||
self._regression.fit(train_source, train_target) | ||
return self._regression.predict(test_source) | ||
return PerTime(fit_predict)(self._train_source, self._train_target, source) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
from brainscore_vision import metric_registry | ||
from .ceiling import InternalConsistency | ||
|
||
from brainscore_vision.metric_helpers.temporal import PerTime | ||
|
||
|
||
metric_registry['internal_consistency'] = InternalConsistency | ||
metric_registry['internal_consistency_temporal'] = lambda *args, **kwargs: PerTime(InternalConsistency(*args, **kwargs)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import numpy as np | ||
import scipy.stats | ||
from pytest import approx | ||
from sklearn.linear_model import LinearRegression | ||
|
||
from brainio.assemblies import NeuroidAssembly | ||
from brainscore_vision.metric_helpers.xarray_utils import XarrayRegression, XarrayCorrelation | ||
from brainscore_vision.metric_helpers.temporal import PerTime, SpanTime, PerTimeRegression, SpanTimeRegression | ||
|
||
|
||
class TestMetricHelpers: | ||
def test_pertime_ops(self): | ||
jumbled_source = NeuroidAssembly(np.random.rand(500, 10, 20), | ||
coords={'stimulus_id': ('presentation', list(reversed(range(500)))), | ||
'image_meta': ('presentation', [0] * 500), | ||
'neuroid_id': ('neuroid', list(reversed(range(10)))), | ||
'neuroid_meta': ('neuroid', [0] * 10), | ||
'time_bin_start': ('time_bin', np.arange(0, 400, 20)), | ||
'time_bin_end': ('time_bin', np.arange(20, 420, 20))}, | ||
dims=['presentation', 'neuroid', 'time_bin']) | ||
mean_neuroid = lambda arr: arr.mean('neuroid') | ||
pertime_mean_neuroid = PerTime(mean_neuroid) | ||
output = pertime_mean_neuroid(jumbled_source) | ||
output = output.transpose('presentation', 'time_bin') | ||
target = jumbled_source.transpose('presentation', 'time_bin', 'neuroid').mean('neuroid') | ||
assert (output == approx(target)).all().item() | ||
|
||
def test_spantime_ops(self): | ||
jumbled_source = NeuroidAssembly(np.random.rand(500, 10, 20), | ||
coords={'stimulus_id': ('presentation', list(reversed(range(500)))), | ||
'image_meta': ('presentation', [0] * 500), | ||
'neuroid_id': ('neuroid', list(reversed(range(10)))), | ||
'neuroid_meta': ('neuroid', [0] * 10), | ||
'time_bin_start': ('time_bin', np.arange(0, 400, 20)), | ||
'time_bin_end': ('time_bin', np.arange(20, 420, 20))}, | ||
dims=['presentation', 'neuroid', 'time_bin']) | ||
mean_presentation = lambda arr: arr.mean("presentation") | ||
spantime_mean_presentation = SpanTime(mean_presentation) | ||
output = spantime_mean_presentation(jumbled_source) | ||
output = output.transpose('neuroid') | ||
target = jumbled_source.transpose('presentation', 'time_bin', 'neuroid').mean('presentation').mean('time_bin') | ||
assert (output == approx(target)).all().item() | ||
|
||
def test_pertime_regression(self): | ||
jumbled_source = NeuroidAssembly(np.random.rand(500, 10, 20), | ||
coords={'stimulus_id': ('presentation', list(reversed(range(500)))), | ||
'image_meta': ('presentation', [0] * 500), | ||
'neuroid_id': ('neuroid', list(reversed(range(10)))), | ||
'neuroid_meta': ('neuroid', [0] * 10), | ||
'time_bin_start': ('time_bin', np.arange(0, 400, 20)), | ||
'time_bin_end': ('time_bin', np.arange(20, 420, 20))}, | ||
dims=['presentation', 'neuroid', 'time_bin']) | ||
target = jumbled_source.sortby(['stimulus_id', 'neuroid_id']) | ||
pertime_regression = PerTimeRegression(XarrayRegression(LinearRegression())) | ||
pertime_regression.fit(jumbled_source, target) | ||
prediction = pertime_regression.predict(jumbled_source) | ||
prediction = prediction.transpose(*target.dims) | ||
# do not test for alignment of metadata - it is only important that the data is well-aligned with the metadata. | ||
np.testing.assert_array_almost_equal(prediction.sortby(['stimulus_id', 'neuroid_id', 'time_bin']).values, | ||
target.sortby(['stimulus_id', 'neuroid_id', 'time_bin']).values) | ||
|
||
|
||
def test_spantime_regression(self): | ||
jumbled_source = NeuroidAssembly(np.random.rand(500, 10, 20), | ||
coords={'stimulus_id': ('presentation', list(reversed(range(500)))), | ||
'image_meta': ('presentation', [0] * 500), | ||
'neuroid_id': ('neuroid', list(reversed(range(10)))), | ||
'neuroid_meta': ('neuroid', [0] * 10), | ||
'time_bin_start': ('time_bin', np.arange(0, 400, 20)), | ||
'time_bin_end': ('time_bin', np.arange(20, 420, 20))}, | ||
dims=['presentation', 'neuroid', 'time_bin']) | ||
target = jumbled_source.sortby(['stimulus_id', 'neuroid_id']) | ||
spantime_regression = SpanTimeRegression(XarrayRegression(LinearRegression())) | ||
spantime_regression.fit(jumbled_source, target) | ||
prediction = spantime_regression.predict(jumbled_source) | ||
prediction = prediction.transpose(*target.dims) | ||
# do not test for alignment of metadata - it is only important that the data is well-aligned with the metadata. | ||
np.testing.assert_array_almost_equal(prediction.sortby(['stimulus_id', 'neuroid_id', 'time_bin']).values, | ||
target.sortby(['stimulus_id', 'neuroid_id', 'time_bin']).values) | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not just
temporal_ridge
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because "spantime" and "pertime" are essentially different: the former shares the weights across time and the latter train separate weights for each time bin.