Skip to content

Tuning Analyses

Methods for characterizing neural response properties through gradient-based analyses.

Response Gradient Analysis

get_gradient_grid

get_gradient_grid(
    stim: Tensor,
    model_neuron: IncreaseObjective,
    n_channels: int = 2,
    start: float = -1,
    stop: float = 1,
    step_size: float = 0.1,
) -> tuple

Generate a grid of response gradients for a given stimulus and model neuron.

PARAMETER DESCRIPTION
stim

The MEI stimulus.

TYPE: torchTensor, 1 x n_channels x time x height x width

model_neuron

The model neuron objective.

TYPE: IncreaseObjective

n_channels

The number of channels. Defaults to 2.

TYPE: int DEFAULT: 2

start

The starting value for the contrast range. Defaults to -1.

TYPE: float DEFAULT: -1

stop

The ending value for the contrast range. Defaults to 1.

TYPE: float DEFAULT: 1

step_size

The step size for the contrast range. Defaults to 0.1.

TYPE: float DEFAULT: 0.1

RETURNS DESCRIPTION
tuple

A tuple containing the following elements: - grid (ndarray): A grid of gradient values with shape (n_channels, len(green_contrast_values), len(uv_contrast_values)). - resp_grid (ndarray): A grid of loss values with shape (len(green_contrast_values), len(uv_contrast_values)). - norm_grid (ndarray): A grid of norm values with shape (len(green_contrast_values), len(uv_contrast_values)). - green_contrast_values (ndarray): An array of green contrast values. - uv_contrast_values (ndarray): An array of UV contrast values.

TYPE: tuple

Source code in openretina/insilico/tuning_analyses/response_gradient.py
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
def get_gradient_grid(
    stim: torch.Tensor,
    model_neuron: IncreaseObjective,
    n_channels: int = 2,
    start: float = -1,
    stop: float = 1,
    step_size: float = 0.1,
) -> tuple:
    """
    Generate a grid of response gradients for a given stimulus and model neuron.

    Args:
        stim (torchTensor, 1 x n_channels x time x height x width): The MEI stimulus.
        model_neuron (IncreaseObjective): The model neuron objective.
        n_channels (int, optional): The number of channels. Defaults to 2.
        start (float, optional): The starting value for the contrast range. Defaults to -1.
        stop (float, optional): The ending value for the contrast range. Defaults to 1.
        step_size (float, optional): The step size for the contrast range. Defaults to 0.1.

    Returns:
        tuple: A tuple containing the following elements:
            - grid (ndarray): A grid of gradient values with shape (n_channels, len(green_contrast_values),
            len(uv_contrast_values)).
            - resp_grid (ndarray): A grid of loss values with shape (len(green_contrast_values),
            len(uv_contrast_values)).
            - norm_grid (ndarray): A grid of norm values with shape (len(green_contrast_values),
            len(uv_contrast_values)).
            - green_contrast_values (ndarray): An array of green contrast values.
            - uv_contrast_values (ndarray): An array of UV contrast values.
    """
    green_contrast_values = np.arange(start, stop + step_size, step_size)
    uv_contrast_values = np.arange(start, stop + step_size, step_size)
    grid = np.zeros((n_channels, len(green_contrast_values), len(uv_contrast_values)))
    resp_grid = np.zeros((len(green_contrast_values), len(uv_contrast_values)))
    norm_grid = np.zeros((len(green_contrast_values), len(uv_contrast_values)))

    for i, contrast_green in enumerate(np.arange(-1, 1 + step_size, step_size)):
        for j, contrast_uv in enumerate(np.arange(-1, 1 + step_size, step_size)):
            mei_contrast_gen = MeiAcrossContrasts(torch.Tensor([contrast_green, contrast_uv]), stim)
            response_gradient, response = trainer_fn(mei_contrast_gen, model_neuron, lr=0.1)
            grid[0, i, j] = response_gradient[0]
            grid[1, i, j] = response_gradient[1]
            resp_grid[i, j] = response
            norm_grid[i, j] = np.linalg.norm(grid[:, i, j])
    return grid, resp_grid, norm_grid, green_contrast_values, uv_contrast_values

equalize_channels

equalize_channels(
    stim: Tensor, flip_green: bool = False
) -> Tensor

Scale the channels of a stimulus to have equal norm, preserving total norm. Optionally flips green channel.

PARAMETER DESCRIPTION
stim

Stimulus tensor of shape (1, 2, 50, 18, 16).

TYPE: Tensor

flip_green

Whether to flip the sign of the green channel.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
Tensor

Equalized stimulus tensor of the same shape.

Source code in openretina/insilico/tuning_analyses/response_gradient.py
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
def equalize_channels(stim: torch.Tensor, flip_green: bool = False) -> torch.Tensor:
    """Scale the channels of a stimulus to have equal norm, preserving total norm. Optionally flips green channel.

    Args:
        stim: Stimulus tensor of shape (1, 2, 50, 18, 16).
        flip_green: Whether to flip the sign of the green channel.

    Returns:
        Equalized stimulus tensor of the same shape.
    """
    green_chan = stim[0, 0]
    uv_chan = stim[0, 1]
    green_norm = torch.norm(green_chan)
    uv_norm = torch.norm(uv_chan)
    total_norm = torch.norm(stim)
    green_factor = (total_norm / 2) / green_norm
    uv_factor = (total_norm / 2) / uv_norm
    equalized_stim = torch.zeros_like(stim, device=stim.device)
    equalized_stim[0, 0] = green_factor * stim[0, 0]
    if flip_green:
        equalized_stim[0, 0] = -1 * equalized_stim[0, 0]
    equalized_stim[0, 1] = uv_factor * stim[0, 1]
    total_factor = total_norm / torch.norm(equalized_stim)
    equalized_stim = total_factor * equalized_stim
    return equalized_stim