Welcome to pymoth’s documentation!

The constructor for pymoth package.

class pymoth.modules.params.ModelParams(nF, goal)

This Python module contains the parameters for a sample moth, ie the template that is used to populate connection matrices and to control behavior.

Abbreviations:
  • n* : number of *
  • G : glomerulus (so eg nG : number of glomeruli)
  • R : response neuron (from antennae): this concept is not used. We use the stim-glomeruli, connections directly
  • P : excitatory projection neuron. note sometimes P’s stand in for gloms in indexing, since they are 1 to 1
  • PI : inhibitory projection neuron
  • L : lateral neuron (inhibitory)
  • K : kenyon cell (in MB)
  • F : feature (this is a change from the original moth/odor regime, where each stim/odor was identified with its own single feature)
  • S (not used in this function) : stimulus class
  • fr : fraction%
  • mu : mean
  • std : standard deviation
  • _2_ : synapse connection to, eg P2K_mu : mean synapse strength from PN to KC
  • octo : octopamine delivery neuron
Structure of synaptic strength matrices:
  • rows give the ‘from’ a synapse
  • cols give the ‘to’

So, M(i,j) is the strength from obj(i) to obj(j).

Glomeruli are not explicitly part of the equations, but the matrices for LN interconnections, PNs, and RNs are indexed according to the G.

create_connection_matrix()

Generates the various connection matrices, given a modelParams object, and appends them to model params object.

Parameters:None
Returns:connection matrices and other model info necessary to FR evolution and plotting
Return type:model_params (object)
>>> model_params.create_connection_matrix()
pymoth.modules.generate.average_image_stack(im_stack, indices_to_average)

Average a stack of images.

Parameters:
  • im_stack (numpy array) – 3-d stack (x, y, z) OR 2-d matrix (images-as-col-vecs, z)
  • indices_to_average (list) – which images in the stack to average
Returns:

average of image stack.

Return type:

average_image (numpy array)

>>> average_im = average_image_stack(dummy_feature_array[...,0], list(range(5)))
pymoth.modules.generate.crop_downsample_vectorize_images(im_stack, crop_val, downsample_ratio, downsample_method)

For each image in a stack of images; crop, downsample, then make into a vector.

Parameters:
  • im_stack (numpy array) – [numImages x width x height]
  • crop_val – number of pixels to shave off each side. (int) or (list) [top, bottom, left, right]
  • downsample_ratio (int) – image downsample ratio (n:1)
  • downsample_method (int) – method for downsampling image (0: sum square patches, 1: bicubic interpolation)
Returns:

[#pixels x #images] array, where #pixels refers to the number of pixels in the cropped and downsampled images.

Return type:

im_array (numpy array)

>>> crop_downsample_vectorize_images(dummy_image_array[...,0],2,2,1)
pymoth.modules.generate.extract_mnist_feature_array(mnist, labels, image_indices, phase_label)

Extracts a subset of the samples from each class, converts the images to doubles on [0 1], and returns a 4-D array.

Parameters:
  • mnist (dict) – loaded from MNIST_all.npy
  • labels (numpy array) – numeric classes (for MNIST, digits 0:9)
  • image_indices (range) – images you want from each class
  • phase_label (str) – Image set to draw from (‘train’ or ‘test’)
Returns:

4-D array [#images x image_height x image_width x #classes]

Return type:

im_array (numpy array)

>>> image_array = extract_mnist_feature_array(mnist, class_labels,      range(max_ind+1), 'train')
pymoth.modules.generate.generate_ds_mnist(max_ind, class_labels, crop, downsample_ratio, downsample_method, inds_to_ave, pixel_sum, inds_to_calc_RF, num_features, screen_size, save_results_folder, show_thumbnails, data_dir='/tmp', data_fname='MNIST_all')
Preprocessing:
  1. Load MNIST
  2. cropping and downsampling
  3. mean-subtract, make non-negative, normalize pixel sums
  4. select active pixels (receptive field)

Loads the MNIST dataset (from Yann LeCun’s website), then applies various preprocessing steps to reduce the number of pixels (each pixel will be a feature).

The ‘receptive field’ step destroys spatial relationships, so to reconstruct a 12 x 12 thumbnail (eg for viewing, or for CNN use) the active pixel indices can be embedded in a 144 x 1 col vector of zeros, then reshaped into a 12 x 12 image.

Parameters:
  • max_ind (int) – maximum number of samples to use
  • class_labels (numpy array) – numeric classes (for MNIST, digits 0:9)
  • crop (int) – image cropping parameter
  • downsample_ratio (int) – image downsample ratio (n:1)
  • downsample_method (int) – method for downsampling image
  • inds_to_ave (numpy array) – pixel indices
  • pixel_sum (int) – normalization factor
  • inds_to_calc_RF (numpy array) – pixel indices for receptive field
  • num_features (int) – number of pixels in the receptive field
  • screen_size (tuple) – screen size (width, height) for images
  • save_results_folder (str) – absolute path to where results will be saved
  • show_thumbnails (int) – number of thumbnails to show for each class (0 means none)
  • data_dir (str) – optional keyword arg specifying where to save data
  • data_fname (str) – optional keyword arg specifying filename of saved data
Returns:

  • feature_array (numpy array) – feature array [#active pixels x #samples x #classes]
  • active_pixel_inds (list) – pixel indices to allow thumbnail viewing
  • len_side (int) – allows reconstruction of thumbnails given from the feature vectors

>>> generate_ds_mnist(
                                  max_ind,
                                  class_labels,
                                  crop,
                                  downsample_ratio,
                                  downsample_method,
                                  [i for i in range(550,1000)],
                                  6,
                                  [i for i in range(550,1000)],
                                  85,
                                  screen_size,
                                  '',
                                  0,
                                 )
pymoth.modules.generate.select_active_pixels(feature_array, num_features, screen_size, save_image_folder=[], show_thumbnails=0)

Select the most active pixels, considering all class average images, to use as features.

Parameters:
  • feature_array (numpy array) – 3-D array # of features X # samples per class X # of classes, created by generate_ds_mnist().
  • num_features (int) – number of pixels in the receptive field
  • save_image_folder (str) – directory to save average thumbnail images (if empty, don’t save)
  • screen_size (tuple) – screen size (width, height) for images
  • show_thumbnails (int) – number of thumbnails to plot
Returns
active_pixel_inds (numpy array)
1 x nF vector of indices to use as features. Indices are relative to the vectorized thumbnails (so between 1 and 144).
>>> active_pixel_inds = select_active_pixels(feature_array, 85, (1920, 1080))
pymoth.modules.classify.classify_digits_log_likelihood(results)

Classify the test digits in a run using log likelihoods from the various EN responses.

Steps:
  1. for each test digit (ignore non-postTrain digits), for each EN, calculate the number of stds the test digit is from each class distribution. This makes a 10 x 10 matrix where each row corresponds to an EN, and each column corresponds to a class.
  2. Square this matrix by entry. Sum the columns. Select the col with the lowest value as the predicted class. Return the vector of sums in ‘likelihoods’.
  3. The rest is simple calculation.
Parameters:results (dict) – output from simulate(). i’th entry gives results for all classes, in the _i_th EN.
Returns:
  • true_classes (numpy array): shortened version of whichOdor (with only post-training, ie validation, entries)
  • targets (numpy array): one-hot-encoded target labels
  • roc_auc (dict): ROC curve and ROC area for each class
  • fpr (dict): false-positive rate for each class
  • tpr (dict): true-positive rate for each class
  • pred_classes (numpy array): predicted classes
  • likelihoods (numpy array): [n x 10] each row a post_training digit (entries are summed log likelihoods)
  • acc_perc (numpy array): [n x 10] class accuracies as percentages
  • total_acc (float): overall accuracy as percentage
  • conf_mat (numpy array): i,j’th entry is number of test digits with true label i that were predicted to be j
Return type:output (dict)
>>> classify_digits_log_likelihood( dummy_results )
pymoth.modules.classify.classify_digits_thresholding(results, home_advantage, home_thresh_sigmas, above_home_thresh_reward)

Classify the test digits using log likelihoods from the various EN responses, with the added option of rewarding high scores relative to an ENs home-class expected response distribution. One use of this function is to apply de-facto thresholding on discrete ENs, so that the predicted class corresponds to the EN that spiked most strongly (relative to its usual home-class response).

Steps:
  1. For each test digit (ignore non-postTrain digits), for each EN, calculate the # stds from the test digit is from each class distribution. This makes a 10 x 10 matrix where each row corresponds to an EN, and each column corresponds to a class.
  2. Square this matrix by entry. Sum the columns. Select the col with the lowest value as the predicted class. Return the vector of sums in ‘likelihoods’.
  3. The rest is simple calculation.
Parameters:
  • results (dict) – [1 x 10] dict produced by collect_stats().
  • home_advantage (int) – the emphasis given to the home EN. It multiplies the off-diagonal of dist. 1 -> no advantage (default). Very high means that a test digit will be classified according to the home EN it does best in, ie each EN acts on its own.
  • home_thresh_sigmas (int) – the number of stds below an EN’s home-class mean that we set a threshold, such that if a digit scores above this threshold in an EN, that EN will be rewarded by ‘above_home_thresh_reward’.
  • above_home_thresh_reward (int) – if a digit’s response scores above the EN’s mean home-class value, reward it by dividing by this value. This reduces the log likelihood score for that EN.
Returns:

  • true_classes (numpy array): shortened version of whichOdor (with only - post-training, ie validation, entries)
  • targets (numpy array): one-hot-encoded target labels
  • roc_auc (dict): ROC curve and ROC area for each class
  • fpr (dict): false-positive rate for each class
  • tpr (dict): true-positive rate for each class
  • pred_classes (numpy array): predicted classes
  • likelihoods (numpy array): [n x 10] each row a post_training digit (entries are summed log likelihoods)
  • acc_perc (numpy array): [n x 10] class accuracies as percentages
  • total_acc (float): overall accuracy as percentage
  • conf_mat (numpy array): i,j’th entry is number of test digits with true label i that were predicted to be j
  • home_advantage (int): the emphasis given to the home EN. It multiplies the off-diagonal of dist. 1 -> no advantage (default). Very high means that a test digit will be classified according to the home EN it does best in, ie each EN acts on its own.
  • home_thresh_sigmas (int): the number of stds below an EN’s home-class mean that we set a threshold, such that if a digit scores above this threshold in an EN, that EN will be rewarded by ‘above_home_thresh_reward’.

Return type:

output (dict)

>>> classify_digits_thresholding( dummy_results )
pymoth.modules.classify.roc_multi(true_classes, likelihoods)

Measure ROC AUC for multi-class classifiers.

Params:
true_classes (numpy array): class labels [observations,] likelihoods (numpy array): predicted likelihoods [observations x classes]
Returns:
  • targets (numpy array): one-hot-encoded target labels
  • roc_auc (dict): ROC curve and ROC area for each class
  • fpr (dict): false-positive rate for each class
  • tpr (dict): true-positive rate for each class
Return type:output (dict)
>>> roc_dict = roc_multi(true_classes, likelihoods)
pymoth.modules.sde.collect_stats(self, sim_results, exp_params, class_labels, show_time_plots, show_acc_plots, images_folder='', images_filename='', screen_size=(1920, 1080))

Collect stats on readout neurons (EN). Collect stats (median, mean, and std of FR) for each digit, pre- and post-training. Digits are referred to as odors, or as odor puffs.

Parameters:
  • sim_results (dict) – simulation results (output from sde_wrap())
  • exp_params (class) – timing info about experiment, eg when stimuli are given
  • class_labels (numpy array) – labels, eg 0:9 for MNIST
  • show_time_plots (bool) – show EN timecourses
  • show_acc_plots (bool) – show changes in accuracy
  • images_filename (str) – [optional] to generate image filenames when saving
  • images_folder (str) – [optional] directory to save results
  • screen_size (tuple) – [optional] screen size (width, height) for images
Returns:

pre_mean_resp (numpy array)

[numENs x numOdors] mean of EN responses pre-training

pre_std_resp (numpy array)

[numENs x numOdors] std of EN responses pre-training

post_mean_resp (numpy array)

[numENs x numOdors] mean of EN responses post-training

post_std_resp (numpy array)

[numENs x numOdors] std of EN responses post-training

percent_change_mean_resp (numpy array)

[1 x numOdors]

trained (list)

indices corresponding to the odor(s) that were trained

pre_spont_mean (float)

mean of pre_spont

pre_spont_std (float)

std of pre_spont

post_spont_mean (float)

mean of post_spont

post_spont_std (float)

std of post_spont

Return type:

results (dict)

pymoth.modules.sde.sde_evo_mnist(tspan, init_cond, time, class_mag_mat, feature_array, octo_hits, mP, exP, seed_val)

To include neural noise, evolve the differential equations using Euler-Maruyama, Milstein version (see Higham’s Algorithmic introduction to Numerical Simulation of SDE).

Called by sde_wrap(). For use with MNIST experiments.

The function uses the noise params to create a Wiener process, then evolves the FR equations with the added noise. Inside the difference equations we use a piecewise linear pseudo sigmoid, rather than a true sigmoid, for speed.

Regarding re-calculating added noise: We want noise to be proportional to the mean spontFR of each neuron. So we need to get an estimate of this mean spont FR first. Noise is not added while neurons settle to initial SpontFR values. Then noise is added, proportional to spontFR. After this noise begins, mean_spont_FRs converge to new values.

So, this is a ‘stepped’ system, that runs as follows:
  1. no noise, neurons converge to initial mean_spont_FRs = ms1
  2. noise proportional to ms1. neurons converge to new mean_spont_FRs = ms2
  3. noise is proportional to ms2. neurons may converge to new mean_spont_FRs = ms3, but noise is not changed. std_spont_FRs are calculated from ms3 time period.
This has the following effects on simulation results:
  1. In the heat maps and time-courses this will give a period of uniform FRs.
  2. The mean_spont_FR`s and `std_spont_FR`s are not ‘settled’ until after the `stopSpontMean3 timepoint.
Parameters:
  • tspan (tuple) – start and stop timepoints (seconds)
  • init_cond (numpy array) – [n x 1] starting FRs for all neurons, order-specific
  • time (numpy array) – [start:step:stop] vector of timepoints for stepping through the evolution. Note we assume that noise and FRs have the same step size (based on Milstein’s method).
  • class_mag_mat (numpy array) – [# of different classes X vector of time points] each entry is the strength of a digit presentation.
  • feature_array (numpy array) – [numFeatures x numStimsPerClass x numClasses]
  • octo_hits (numpy array) – [1 x length(t)] octopamine strengths at each timepoint.
  • mP (class) – model_params, including connection matrices, learning rates, etc.
  • exP (class) – experiment parameters with some timing info.
  • seed_val (int) – optional arg for random number generation.
Returns:

  • T: [m x 1] timepoints used in evolution (timepoints used in evolution)
  • Y: [m x K] where K contains all FRs for P, L, PI, KC, etc; and each row is the FR at a given timepoint
  • P2K: connection matrix
  • K2E: connection matrix

Return type:

this_run (dict)

pymoth.modules.sde.sde_wrap(model_params, exp_params, feature_array)

Runs the SDE time-stepped evolution of neural firing rates.

4 steps:
  1. load various params needed for pre-evolution prep
  2. specify stim and octo courses
  3. interaction equations and step through simulation
  4. unpack evolution output and export
Parameters:
  • model_params (class) – object with connection matrices, etc.
  • exp_params (class) – object with timing info about experiment, eg when stimuli are given.
  • feature_array (numpy array) – stimuli (numFeatures x numStimsPerClass x numClasses).
Returns:

EN timecourses and final P2K and K2E connection matrices.

Return type:

sim_results (dict)

pymoth.modules.show_figs.plot_roc_multi(ax, fpr, tpr, roc_auc, class_labels, title_str, y_axis_label=True, legend=True)
Parameters:
  • ax (object) – matplotlib axis (ie subplot)
  • tpr (dict) – true-positive rate for each class
  • fpr (dict) – false-positive rate for each class
  • roc_auc (dict) – ROC AUC for each class
  • class_labels (numpy array) – class labels (0:9 for MNIST)
  • title_str (str) – string to use in the title for this particular subplot
  • y_axis_label (str) – string to use in the y-axis label for this particular subplot
  • legend (bool) – toggle legend for figure
Returns:

Return type:

None

>>> plot_roc_multi(ax, fpr, tpr, roc_auc, class_labels, title_str,     y_axis_label='foo', legend=True)
pymoth.modules.show_figs.show_FA_thumbs(feature_array, show_per_class, normalize, title_string, screen_size, images_filename)

Show thumbnails of inputs used in the experiment.

Parameters:
  • feature_array (numpy array) – either 3-D (1 = cols of features, 2 = within class samples, 3 = class) or 2-D (1 = cols of features, 2 = within class samples, no 3)
  • show_per_class (int) – how many of the thumbnails from each class to show.
  • normalize (bool) – 1 to rescale thumbs to [0 1], 0 to not
  • title_string (str) – string for figure title
  • screen_size (tuple) – width, height
  • images_filename (str) – including absolute path
Returns:

Return type:

None

>>> show_FA_thumbs(_thumb_array, 1, 1, 'Input thumbnails', (1920,1080), 'foo/thumbnails')
pymoth.modules.show_figs.show_acc(pre_SA, post_SA, en_ind, pre_mean_resp, pre_median_resp, pre_std_resp, post_offset, post_mean_resp, post_median_resp, post_std_resp, class_labels, pre_heb_mean, pre_heb_std, post_heb_mean, post_heb_std, percent_change_mean_resp, screen_size)

Plot accuracy of MothNet for each class.

Parameters:
  • pre_SA (numpy array) – pre-sniff average,
  • post_SA (numpy array) – post-sniff average,
  • en_ind (int) – index of current EN,
  • pre_mean_resp (numpy array) – mean resp before training [#classes x 1],
  • pre_median_resp (numpy array) – median resp before training [#classes x 1],
  • pre_std_resp (numpy array) – std of resp before training [#classes x 1],
  • post_offset (numpy array) – pre-sniff average plus offset value,
  • post_mean_resp (numpy array) – mean resp after training [#classes x 1],
  • post_median_resp (numpy array) – median resp after training [#classes x 1],
  • post_std_resp (numpy array) – std of resp after training [#classes x 1],
  • class_labels (numpy array) – class labels (0:9 for MNIST),
  • pre_heb_mean – mean spontaneous activity before training [#classes x 1],
  • pre_heb_std – std of spontaneous activity before training [#classes x 1],
  • post_heb_mean – mean spontaneous activity after training [#classes x 1],
  • post_heb_std – std of spontaneous activity after training [#classes x 1],
  • percent_change_mean_resp – mean response converted to percent change [#classes x 1],
  • screen_size (tuple) – [optional] screen size (width, height) for images,
Returns:

matplotlib figure handle

Return type:

fig (object)

>>> show_acc(pre_SA, post_SA, en_ind, pre_mean_resp, pre_median_resp, pre_std_resp,         post_offset, post_mean_resp, post_median_resp, post_std_resp, class_labels,         pre_heb_mean, pre_heb_std, post_heb_mean, post_heb_std, percent_change_mean_resp,         screen_size)
pymoth.modules.show_figs.show_multi_roc(self, model_names, class_labels, images_filename='')

Show ROC plot for each model in a subplot of a single figure.

Parameters:
  • model_names (list) – names (strings) of models being plotted,
  • class_labels (numpy array) – label for each class of current stimuli,
  • images_filename (str) – [optional] name to use for image filename,
Returns:

Return type:

None

>>> show_multi_roc(model_names, class_labels, images_filename='foo')
pymoth.modules.show_figs.show_roc_curves(tpr, fpr, roc_auc, class_labels, title_str='', images_filename='')

Compute macro-average ROC curves and plot.

Parameters:
  • tpr (dict) – true-positive rate for each class
  • fpr (dict) – false-positive rate for each class
  • roc_auc (dict) – ROC AUC for each class
  • class_labels (numpy array) – class labels (0:9 for MNIST)
  • title_str (str) – string to use in the title for this particular subplot
  • images_filename (str) – directory to save figure output
Returns:

Return type:

None

>>> show_roc_curves(roc_knn['tpr'], roc_knn['fpr'], roc_knn['roc_auc'],     class_labels, title_str='KNN', images_filename='dirname/filename')
pymoth.modules.show_figs.show_timecourse(ax, en_ind, sim_results, octo_times, class_list, results, exp_params, stim_starts, which_class)

Plot the timecourse of EN responses of MothNet.

Parameters:
  • ax (object) – matplotlib axis,
  • en_ind (int) – index of current EN,
  • sim_results (dict) – simulation results (output from sde_wrap()),
  • octo_times (numpy array) – timing of octopamine,
  • class_labels (numpy array) – labels, eg 0:9 for MNIST,
  • results (list) – list of dicts containing simulation results (output from sde_wrap()),
  • exp_params (class) – timing info about experiment, eg when stimuli are given,
  • stim_starts (numpy array) – time-steps for current stimuli,
  • which_class (numpy array) – classes for current stimuli,
Returns:

matplotlib axis

Return type:

ax (object)

>>> show_timecourse(ax, en_ind, sim_results, octo_times, class_list, results,         exp_params, stim_starts, which_class )

Indices and tables