OSCR

Plasticity and language in the anaesthetized human hippocampus.

A correction to this paper has been published: the notice, 42277412, from Europe PMC.

A correction to this paper has been published: the notice, 42680833, from Europe PMC.

Code ↔ Paper

9 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 9 matches · 3 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
  1. [1] § Methods › Continuous-rate RNN model ↔ code/rate/model.py, lines 446–567 · score 0.86 · synaptic decay, sigmoid function, inhibitory units, rate RNN, firing rate, sum
  2. [2] § Methods › Continuous-rate RNN model ↔ code/rate/fnc_eval_model.m, the whole file · a weak match · score 0.80 · recurrent connectivity matrix, synaptic decay, firing rate, sigmoid, excitatory, variable
  3. [3] § Methods › Neuropixels data acquisition set-up and intraoperative recordings ↔ notebook/ap_chronic_demo.ipynb, lines 77–118 · score 0.65 · SpikeGLX, Neuropixels probe, shank, AP, filtered, channels
  4. [4] § Plasticity in the unconscious state ↔ code/rate/model.py, lines 22–26 · score 0.61 · recurrent connection, inhibitory neurons, RNN model, excitatory
  5. [5] § Methods › Continuous-rate RNN model ↔ code/rate/model.py, lines 27–64 · score 0.60 · readout weights, recurrent connectivity, classifier, network, model
  6. [6] § Methods › Continuous-rate RNN model ↔ code/rate/fnc_eval_model.m, the whole file · a weak match · score 0.59 · synaptic decay, recurrent connectivity, weights, model, RNN, trained
  7. [7] § Auditory monitoring during anaesthesia ↔ code/rate/svm_decoding_per_neuron.m, lines 281–354 · score 0.58 · SVM decoding, tone accuracy, tone identity, encoding
  8. [8] § Methods › Neuronal data processing › Motion correction ↔ matlab/dredge.m, the whole file · a weak match · score 0.55 · Decentralized Registration, Motion correction, DREDge, raw
  9. [9] § Methods › Neuronal data processing › LFP data ↔ notebook/lfp_registration_and_interpolation_demo.ipynb, lines 201–252 · score 0.55 · bandpass filtered, LFP band, raw, signal, channels

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 · 701 lines · 22 KB · Apache-2.0 · 3 matches

  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # vim:fenc=utf-8
  4. #
  5. # Name: Robert Kim
  6. # Date: October 11, 2019
  7. # Email: [email hidden]
  8. # Description: Implementation of the continuous rate RNN model
  9. import os, sys
  10. import numpy as np
  11. import tensorflow as tf
  12. if tf.__version__[0] == '2':
  13. import tensorflow.compat.v1 as tf
  14. tf.disable_v2_behavior()
  15. import scipy.io
  16. '''
  17. CONTINUOUS FIRING-RATE RNN CLASS
  18. '''
  19. class FR_RNN_dale:
  20. """
  21. Firing-rate RNN model for excitatory and inhibitory neurons
  22. Initialization of the firing-rate model with recurrent connections
  23. """
  24. def __init__(self, N, P_inh, P_rec, w_in, som_N, w_dist, gain, apply_dale, w_out):
  25. """
  26. Network initialization method
  27. N: number of units (neurons)
  28. P_inh: probability of a neuron being inhibitory
  29. P_rec: recurrent connection probability
  30. w_in: NxN weight matrix for the input stimuli
  31. som_N: number of SOM neurons (set to 0 for no SOM neurons)
  32. w_dist: recurrent weight distribution ('gaus' or 'gamma')
  33. apply_dale: apply Dale's principle ('True' or 'False')
  34. w_out: Nx1 readout weights
  35. Based on the probability (P_inh) provided above,
  36. the units in the network are classified into
  37. either excitatory or inhibitory. Next, the
  38. weight matrix is initialized based on the connectivity
  39. probability (P_rec) provided above.
  40. """
  41. self.N = N
  42. self.P_inh = P_inh
  43. self.P_rec = P_rec
  44. self.w_in = w_in
  45. self.som_N = som_N
  46. self.w_dist = w_dist
  47. self.gain = gain
  48. self.apply_dale = apply_dale
  49. self.w_out = w_out
  50. # Assign each unit as excitatory or inhibitory
  51. inh, exc, NI, NE, som_inh = self.assign_exc_inh()
  52. self.inh = inh
  53. self.som_inh = som_inh
  54. self.exc = exc
  55. self.NI = NI
  56. self.NE = NE
  57. # Initialize the weight matrix
  58. self.W, self.mask, self.som_mask = self.initialize_W()
  59. def assign_exc_inh(self):
  60. """
  61. Method to randomly assign units as excitatory or inhibitory (Dale's principle)
  62. Returns
  63. inh: bool array marking which units are inhibitory
  64. exc: bool array marking which units are excitatory
  65. NI: number of inhibitory units
  66. NE: number of excitatory units
  67. som_inh: indices of "inh" for SOM neurons
  68. """
  69. # Apply Dale's principle
  70. if self.apply_dale == True:
  71. inh = np.random.rand(self.N, 1) < self.P_inh
  72. exc = ~inh
  73. NI = len(np.where(inh == True)[0])
  74. NE = self.N - NI
  75. # Do NOT apply Dale's principle
  76. else:
  77. inh = np.random.rand(self.N, 1) < 0 # no separate inhibitory units
  78. exc = ~inh
  79. NI = len(np.where(inh == True)[0])
  80. NE = self.N - NI
  81. if self.som_N > 0:
  82. som_inh = np.where(inh==True)[0][:self.som_N]
  83. else:
  84. som_inh = 0
  85. return inh, exc, NI, NE, som_inh
  86. def initialize_W(self):
  87. """
  88. Method to generate and initialize the connectivity weight matrix, W
  89. The weights are drawn from either gaussian or gamma distribution.
  90. Returns
  91. w: NxN weights (all positive)
  92. mask: NxN matrix of 1's (excitatory units)
  93. and -1's (for inhibitory units)
  94. NOTE: To compute the "full" weight matrix, simply
  95. multiply w and mask (i.e. w*mask)
  96. """
  97. # Weight matrix
  98. w = np.zeros((self.N, self.N), dtype = np.float32)
  99. idx = np.where(np.random.rand(self.N, self.N) < self.P_rec)
  100. if self.w_dist.lower() == 'gamma':
  101. w[idx[0], idx[1]] = np.random.gamma(2, 0.003, len(idx[0]))
  102. elif self.w_dist.lower() == 'gaus':
  103. w[idx[0], idx[1]] = np.random.normal(0, 1.0, len(idx[0]))
  104. w = w/np.sqrt(self.N*self.P_rec)*self.gain # scale by a gain to make it chaotic
  105. if self.apply_dale == True:
  106. w = np.abs(w)
  107. # Mask matrix
  108. mask = np.eye(self.N, dtype=np.float32)
  109. mask[np.where(self.inh==True)[0], np.where(self.inh==True)[0]] = -1
  110. # SOM mask matrix
  111. som_mask = np.ones((self.N, self.N), dtype=np.float32)
  112. if self.som_N > 0:
  113. for i in self.som_inh:
  114. som_mask[i, np.where(self.inh==True)[0]] = 0
  115. return w, mask, som_mask
  116. def load_net(self, model_dir):
  117. """
  118. Method to load pre-configured network settings
  119. """
  120. settings = scipy.io.loadmat(model_dir)
  121. self.N = settings['N'][0][0]
  122. self.som_N = settings['som_N'][0][0]
  123. self.inh = settings['inh']
  124. self.exc = settings['exc']
  125. self.inh = self.inh == 1
  126. self.exc = self.exc == 1
  127. self.NI = len(np.where(settings['inh'] == True)[0])
  128. self.NE = len(np.where(settings['exc'] == True)[0])
  129. self.mask = settings['m']
  130. self.som_mask = settings['som_m']
  131. self.W = settings['w']
  132. self.w_in = settings['w_in']
  133. self.b_out = settings['b_out']
  134. self.w_out = settings['w_out']
  135. return self
  136. def display(self):
  137. """
  138. Method to print the network setup
  139. """
  140. print('Network Settings')
  141. print('====================================')
  142. print('Number of Units: ', self.N)
  143. print('\t Number of Excitatory Units: ', self.NE)
  144. print('\t Number of Inhibitory Units: ', self.NI)
  145. print('Weight Matrix, W')
  146. full_w = self.W*self.mask
  147. zero_w = len(np.where(full_w == 0)[0])
  148. pos_w = len(np.where(full_w > 0)[0])
  149. neg_w = len(np.where(full_w < 0)[0])
  150. print('\t Zero Weights: %2.2f %%' % (zero_w/(self.N*self.N)*100))
  151. print('\t Positive Weights: %2.2f %%' % (pos_w/(self.N*self.N)*100))
  152. print('\t Negative Weights: %2.2f %%' % (neg_w/(self.N*self.N)*100))
  153. '''
  154. Task-specific input signals
  155. '''
  156. def generate_input_stim_go_nogo(settings):
  157. """
  158. Method to generate the input stimulus matrix for the
  159. Go-NoGo task
  160. INPUT
  161. settings: dict containing the following keys
  162. T: duration of a single trial (in steps)
  163. stim_on: stimulus starting time (in steps)
  164. stim_dur: stimulus duration (in steps)
  165. prob: probability for GO trials
  166. taus: time-constants (in steps)
  167. DeltaT: sampling rate
  168. OUTPUT
  169. u: 1xT stimulus matrix
  170. label: either +1 (Go trial) or 0 (NoGo trial)
  171. """
  172. T = settings['T']
  173. stim_on = settings['stim_on']
  174. stim_dur = settings['stim_dur']
  175. prob = settings['prob']
  176. u = np.zeros((1, T)) #+ np.random.randn(1, T)
  177. u_lab = np.zeros((2, 1))
  178. if np.random.rand() <= prob:
  179. u[0, stim_on:stim_on+stim_dur] = 1
  180. label = 1
  181. else:
  182. u[0, stim_on:stim_on+stim_dur] = -1
  183. label = 0
  184. return u, label
  185. def generate_input_stim_go_nogo2(settings):
  186. """
  187. Method to generate the input stimulus matrix for the
  188. Go-NoGo task
  189. Modified to include two input channels
  190. INPUT
  191. settings: dict containing the following keys
  192. T: duration of a single trial (in steps)
  193. stim_on: stimulus starting time (in steps)
  194. stim_dur: stimulus duration (in steps)
  195. prob: probability for GO trials
  196. taus: time-constants (in steps)
  197. DeltaT: sampling rate
  198. OUTPUT
  199. u: 1xT stimulus matrix
  200. label: either +1 (Go trial) or 0 (NoGo trial)
  201. """
  202. T = settings['T']
  203. stim_on = settings['stim_on']
  204. stim_dur = settings['stim_dur']
  205. prob = settings['prob']
  206. u = np.zeros((2, T)) #+ np.random.randn(1, T)
  207. u = u + np.random.randn(np.shape(u)[0], np.shape(u)[1])
  208. u_lab = np.zeros((2, 1))
  209. if np.random.rand() <= prob:
  210. u[1, stim_on:stim_on+stim_dur] = u[1, stim_on:stim_on+stim_dur] + 1
  211. label = 1
  212. else:
  213. u[0, stim_on:stim_on+stim_dur] = u[0, stim_on:stim_on+stim_dur] + 1
  214. label = 0
  215. return u, label
  216. def generate_input_stim_xor(settings):
  217. """
  218. Method to generate the input stimulus matrix (u)
  219. for the XOR task
  220. INPUT
  221. settings: dict containing the following keys
  222. T: duration of a single trial (in steps)
  223. stim_on: stimulus starting time (in steps)
  224. stim_dur: stimulus duration (in steps)
  225. delay: delay b/w two stimuli (in steps)
  226. taus: time-constants (in steps)
  227. DeltaT: sampling rate
  228. OUTPUT
  229. u: 2xT stimulus matrix
  230. label: 'same' or 'diff'
  231. """
  232. T = settings['T']
  233. stim_on = settings['stim_on']
  234. stim_dur = settings['stim_dur']
  235. delay = settings['delay']
  236. # Initialize u
  237. u = np.zeros((2, T))
  238. # XOR task
  239. labs = []
  240. if np.random.rand() < 0.50:
  241. u[0, stim_on:stim_on+stim_dur] = 1
  242. labs.append(1)
  243. else:
  244. u[0, stim_on:stim_on+stim_dur] = -1
  245. labs.append(-1)
  246. if np.random.rand() < 0.50:
  247. u[1, stim_on+stim_dur+delay:stim_on+2*stim_dur+delay] = 1
  248. labs.append(1)
  249. else:
  250. u[1, stim_on+stim_dur+delay:stim_on+2*stim_dur+delay] = -1
  251. labs.append(-1)
  252. if np.prod(labs) == 1:
  253. label = 'same'
  254. else:
  255. label = 'diff'
  256. return u, label
  257. def generate_input_stim_mante(settings):
  258. """
  259. Method to generate the input stimulus matrix for the
  260. mante task
  261. INPUT
  262. settings: dict containing the following keys
  263. T: duration of a single trial (in steps)
  264. stim_on: stimulus starting time (in steps)
  265. stim_dur: stimulus duration (in steps)
  266. taus: time-constants (in steps)
  267. DeltaT: sampling rate
  268. OUTPUT
  269. u: 4xT stimulus matrix (first 2 rows for motion/color and the second
  270. 2 rows for context
  271. label: either +1 or -1
  272. """
  273. T = settings['T']
  274. stim_on = settings['stim_on']
  275. stim_dur = settings['stim_dur']
  276. # Color/motion sensory inputs
  277. u = np.zeros((2, T))
  278. u_lab = np.zeros((2, 1))
  279. if np.random.rand() <= 0.50:
  280. u[0, stim_on:stim_on+stim_dur] = np.random.randn(1, stim_dur) + 0.5
  281. u_lab[0, 0] = 1
  282. else:
  283. u[0, stim_on:stim_on+stim_dur] = np.random.randn(1, stim_dur) - 0.5
  284. u_lab[0, 0] = -1
  285. if np.random.rand() <= 0.50:
  286. u[1, stim_on:stim_on+stim_dur] = np.random.randn(1, stim_dur) + 0.5
  287. u_lab[1, 0] = 1
  288. else:
  289. u[1, stim_on:stim_on+stim_dur] = np.random.randn(1, stim_dur) - 0.5
  290. u_lab[1, 0] = -1
  291. # Context input
  292. c = np.zeros((2, T))
  293. label = 0
  294. if np.random.rand() <= 0.50:
  295. c[0, :] = 1
  296. if u_lab[0, 0] == 1:
  297. label = 1
  298. elif u_lab[0, 0] == -1:
  299. label = -1
  300. else:
  301. c[1, :] = 1
  302. if u_lab[1, 0] == 1:
  303. label = 1
  304. elif u_lab[1, 0] == -1:
  305. label = -1
  306. return np.vstack((u, c)), label
  307. '''
  308. Task-specific target signals
  309. '''
  310. def generate_target_continuous_go_nogo(settings, label):
  311. """
  312. Method to generate a continuous target signal (z)
  313. for the Go-NoGo task
  314. INPUT
  315. settings: dict containing the following keys
  316. T: duration of a single trial (in steps)
  317. stim_on: stimulus starting time (in steps)
  318. stim_dur: stimulus duration (in steps)
  319. taus: time-constants (in steps)
  320. DeltaT: sampling rate
  321. label: either +1 or -1
  322. OUTPUT
  323. z: 1xT target signal
  324. """
  325. T = settings['T']
  326. stim_on = settings['stim_on']
  327. stim_dur = settings['stim_dur']
  328. z = np.zeros((1, T))
  329. if label == 1:
  330. z[0, stim_on+stim_dur:] = 1
  331. elif label == 0:
  332. z[0, stim_on+stim_dur:] = -1
  333. return np.squeeze(z)
  334. def generate_target_continuous_xor(settings, label):
  335. """
  336. Method to generate a continuous target signal (z)
  337. for the XOR task
  338. INPUT
  339. settings: dict containing the following keys
  340. T: duration of a single trial (in steps)
  341. stim_on: stimulus starting time (in steps)
  342. stim_dur: stimulus duration (in steps)
  343. delay: delay b/w two stimuli (in steps)
  344. taus: time-constants (in steps)
  345. DeltaT: sampling rate
  346. label: string value (either 'same' or 'diff')
  347. OUTPUT
  348. z: 1xT target signal
  349. """
  350. T = settings['T']
  351. stim_on = settings['stim_on']
  352. stim_dur = settings['stim_dur']
  353. delay = settings['delay']
  354. task_end_T = stim_on+2*stim_dur + delay
  355. z = np.zeros((1, T))
  356. if label == 'same':
  357. z[0, 10+task_end_T:10+task_end_T+100] = 1
  358. elif label == 'diff':
  359. z[0, 10+task_end_T:10+task_end_T+100] = -1
  360. return np.squeeze(z)
  361. def generate_target_continuous_mante(settings, label):
  362. """
  363. Method to generate a continuous target signal (z)
  364. for the MANTE task
  365. INPUT
  366. settings: dict containing the following keys
  367. T: duration of a single trial (in steps)
  368. stim_on: stimulus starting time (in steps)
  369. stim_dur: stimulus duration (in steps)
  370. taus: time-constants (in steps)
  371. DeltaT: sampling rate
  372. label: either +1 or -1
  373. OUTPUT
  374. z: 1xT target signal
  375. """
  376. T = settings['T']
  377. stim_on = settings['stim_on']
  378. stim_dur = settings['stim_dur']
  379. z = np.zeros((1, T))
  380. if label == 1:
  381. z[0, stim_on+stim_dur:] = 1
  382. else:
  383. z[0, stim_on+stim_dur:] = -1
  384. return np.squeeze(z)
  385. '''
  386. CONSTRUCT TF GRAPH FOR TRAINING
  387. '''
  388. def construct_tf(fr_rnn, settings, training_params):
  389. """
  390. Method to construct a TF graph and return nodes with
  391. Dale's principle
  392. INPUT
  393. fr_rnn: firing-rate RNN class
  394. settings: dict containing the following keys
  395. T: duration of a single trial (in steps)
  396. stim_on: stimulus starting time (in steps)
  397. stim_dur: stimulus duration (in steps)
  398. delay: delay b/w two stimuli (in steps)
  399. taus: time-constants (in steps)
  400. DeltaT: sampling rate
  401. training_params: dictionary containing training parameters
  402. learning_rate: learning rate
  403. OUTPUT
  404. TF graph
  405. """
  406. # Task params
  407. T = settings['T']
  408. taus = settings['taus']
  409. DeltaT = settings['DeltaT']
  410. task = settings['task']
  411. # Training params
  412. learning_rate = training_params['learning_rate']
  413. # Excitatory units
  414. exc_idx_tf = tf.constant(np.where(fr_rnn.exc == True)[0], name='exc_idx')
  415. # Inhibitory units
  416. inh_idx_tf = tf.constant(np.where(fr_rnn.inh == True)[0], name='inh_idx')
  417. som_inh_idx_tf = tf.constant(fr_rnn.som_inh, name='som_inh_idx')
  418. # Input node
  419. # XOR task
  420. if task == 'xor':
  421. stim = tf.placeholder(tf.float32, [2, T], name='u')
  422. # Sensory integration task
  423. elif task == 'mante':
  424. stim = tf.placeholder(tf.float32, [4, T], name='u')
  425. # Go-NoGo task
  426. elif task == 'go-nogo':
  427. stim = tf.placeholder(tf.float32, [1, T], name='u')
  428. elif task == 'go-nogo2':
  429. stim = tf.placeholder(tf.float32, [2, T], name='u')
  430. # Target node
  431. z = tf.placeholder(tf.float32, [T,], name='target')
  432. # Initialize the decay synaptic time-constants (gaussian random).
  433. # This vector will go through the sigmoid transfer function.
  434. if len(taus) > 1:
  435. taus_gaus = tf.Variable(tf.random_normal([fr_rnn.N, 1]), dtype=tf.float32,
  436. name='taus_gaus', trainable=True)
  437. elif len(taus) == 1:
  438. taus_gaus = tf.Variable(tf.random_normal([fr_rnn.N, 1]), dtype=tf.float32,
  439. name='taus_gaus', trainable=False)
  440. print('Synaptic decay time-constants will not get updated!')
  441. # Synaptic currents and firing-rates
  442. x = [] # synaptic currents
  443. r = [] # firing-rates
  444. x.append(tf.random_normal([fr_rnn.N, 1], dtype=tf.float32)/100)
  445. # Transfer function options
  446. if training_params['activation'] == 'sigmoid':
  447. r.append(tf.sigmoid(x[0]))
  448. elif training_params['activation'] == 'clipped_relu':
  449. r.append(tf.clip_by_value(tf.nn.relu(x[0]), 0, 20))
  450. elif training_params['activation'] == 'softplus':
  451. r.append(tf.clip_by_value(tf.nn.softplus(x[0]), 0, 20))
  452. # Initialize recurrent weight matrix, mask, input & output weight matrices
  453. w = tf.get_variable('w', initializer = fr_rnn.W, dtype=tf.float32, trainable=True)
  454. m = tf.get_variable('m', initializer = fr_rnn.mask, dtype=tf.float32, trainable=False)
  455. som_m = tf.get_variable('som_m', initializer = fr_rnn.som_mask, dtype=tf.float32,
  456. trainable=False)
  457. w_in = tf.get_variable('w_in', initializer = fr_rnn.w_in, dtype=tf.float32, trainable=False)
  458. w_out = tf.get_variable('w_out', initializer = fr_rnn.w_out, dtype=tf.float32,
  459. trainable=True)
  460. b_out = tf.Variable(0, dtype=tf.float32, name='b_out', trainable=True)
  461. # Forward pass
  462. o = [] # output (i.e. weighted linear sum of rates, r)
  463. for t in range(1, T):
  464. if fr_rnn.apply_dale == True:
  465. # Parametrize the weight matrix to enforce exc/inh synaptic currents
  466. w = tf.nn.relu(w)
  467. # next_x is [N x 1]
  468. ww = tf.matmul(w, m)
  469. ww = tf.multiply(ww, som_m)
  470. # Pass the synaptic time constants thru the sigmoid function
  471. if len(taus) > 1:
  472. taus_sig = tf.sigmoid(taus_gaus)*(taus[1] - taus[0]) + taus[0]
  473. elif len(taus) == 1: # one scalar synaptic decay time-constant
  474. taus_sig = taus[0]
  475. next_x = tf.multiply((1 - DeltaT/taus_sig), x[t-1]) + \
  476. tf.multiply((DeltaT/taus_sig), ((tf.matmul(ww, r[t-1]))\
  477. + tf.matmul(w_in, tf.expand_dims(stim[:, t-1], 1)))) +\
  478. tf.random_normal([fr_rnn.N, 1], dtype=tf.float32)/10
  479. x.append(next_x)
  480. if training_params['activation'] == 'sigmoid':
  481. r.append(tf.sigmoid(next_x))
  482. elif training_params['activation'] == 'clipped_relu':
  483. r.append(tf.clip_by_value(tf.nn.relu(next_x), 0, 20))
  484. elif training_params['activation'] == 'softplus':
  485. r.append(tf.clip_by_value(tf.nn.softplus(next_x), 0, 20))
  486. next_o = tf.matmul(w_out, r[t]) + b_out
  487. o.append(next_o)
  488. return stim, z, x, r, o, w, w_in, m, som_m, w_out, b_out, taus_gaus
  489. '''
  490. DEFINE LOSS AND OPTIMIZER
  491. '''
  492. def loss_op(o, z, training_params):
  493. """
  494. Method to define loss and optimizer for ONLY ONE target signal
  495. INPUT
  496. o: list of output values
  497. z: target values
  498. training_params: dictionary containing training parameters
  499. learning_rate: learning rate
  500. OUTPUT
  501. loss: loss function
  502. training_op: optimizer
  503. """
  504. # Loss function
  505. loss = tf.zeros(1)
  506. loss_fn = training_params['loss_fn']
  507. for i in range(0, len(o)):
  508. if loss_fn.lower() == 'l1':
  509. loss += tf.norm(o[i] - z[i])
  510. elif loss_fn.lower() == 'l2':
  511. loss += tf.square(o[i] - z[i])
  512. if loss_fn.lower() == 'l2':
  513. loss = tf.sqrt(loss)
  514. # Optimizer function
  515. with tf.name_scope('ADAM'):
  516. optimizer = tf.train.AdamOptimizer(learning_rate = training_params['learning_rate'])
  517. training_op = optimizer.minimize(loss)
  518. return loss, training_op
  519. '''
  520. EVALUATE THE TRAINED MODEL
  521. NOTE: NEED TO BE UPDATED!!
  522. '''
  523. def eval_tf(model_dir, settings, u):
  524. """
  525. Method to evaluate a trained TF graph
  526. INPUT
  527. model_dir: full path to the saved model .mat file
  528. stim_params: dictionary containig the following keys
  529. u: 12xT stimulus matrix
  530. NOTE: There are 12 rows (one per dot pattern): 6 cues and 6 probes.
  531. OUTPUT
  532. o: 1xT output vector
  533. """
  534. T = settings['T']
  535. stim_on = settings['stim_on']
  536. stim_dur = settings['stim_dur']
  537. delay = settings['delay']
  538. DeltaT = settings['DeltaT']
  539. # Load the trained mat file
  540. var = scipy.io.loadmat(model_dir)
  541. # Get some additional params
  542. N = var['N'][0][0]
  543. exc_ind = [np.bool(i) for i in var['exc']]
  544. # Get the delays
  545. taus_gaus = var['taus_gaus']
  546. taus = var['taus'][0] # tau [min, max]
  547. taus_sig = (1/(1+np.exp(-taus_gaus))*(taus[1] - taus[0])) + taus[0]
  548. # Synaptic currents and firing-rates
  549. x = np.zeros((N, T)) # synaptic currents
  550. r = np.zeros((N, T)) # firing-rates
  551. x[:, 0] = np.random.randn(N, )/100
  552. r[:, 0] = 1/(1 + np.exp(-x[:, 0]))
  553. # r[:, 0] = np.minimum(np.maximum(x[:, 0], 0), 1) #clipped relu
  554. # r[:, 0] = np.clip(np.minimum(np.maximum(x[:, 0], 0), 1), None, 10) #clipped relu
  555. # r[:, 0] = np.clip(np.log(np.exp(x[:, 0])+1), None, 10) # softplus
  556. # r[:, 0] = np.minimum(np.maximum(x[:, 0], 0), 6)/6 #clipped relu6
  557. # Output
  558. o = np.zeros((T, ))
  559. o_counter = 0
  560. # Recurrent weights and masks
  561. # w = var['w0'] #!!!!!!!!!!!!
  562. w = var['w']
  563. m = var['m']
  564. som_m = var['som_m']
  565. som_N = var['som_N'][0][0]
  566. # Identify excitatory/inhibitory neurons
  567. exc = var['exc']
  568. exc_ind = np.where(exc == 1)[0]
  569. inh = var['inh']
  570. inh_ind = np.where(inh == 1)[0]
  571. som_inh_ind = inh_ind[:som_N]
  572. for t in range(1, T):
  573. # next_x is [N x 1]
  574. ww = np.matmul(w, m)
  575. ww = np.multiply(ww, som_m)
  576. # next_x = (1 - DeltaT/tau)*x[:, t-1] + \
  577. # (DeltaT/tau)*(np.matmul(ww, r[:, t-1]) + \
  578. # np.matmul(var['w_in'], u[:, t-1])) + \
  579. # np.random.randn(N, )/10
  580. next_x = np.multiply((1 - DeltaT/taus_sig), np.expand_dims(x[:, t-1], 1)) + \
  581. np.multiply((DeltaT/taus_sig), ((np.matmul(ww, np.expand_dims(r[:, t-1], 1)))\
  582. + np.matmul(var['w_in'], np.expand_dims(u[:, t-1], 1)))) +\
  583. np.random.randn(N, 1)/10
  584. x[:, t] = np.squeeze(next_x)
  585. r[:, t] = 1/(1 + np.exp(-x[:, t]))
  586. # r[:, t] = np.minimum(np.maximum(x[:, t], 0), 1)
  587. # r[:, t] = np.clip(np.minimum(np.maximum(x[:, t], 0), 1), None, 10)
  588. # r[:, t] = np.clip(np.log(np.exp(x[:, t])+1), None, 10) # softplus
  589. # r[:, t] = np.minimum(np.maximum(x[:, t], 0), 6)/6
  590. wout = var['w_out']
  591. wout_exc = wout[0, exc_ind]
  592. wout_inh = wout[0, inh_ind]
  593. r_exc = r[exc_ind, :]
  594. r_inh = r[inh_ind, :]
  595. o[o_counter] = np.matmul(wout, r[:, t]) + var['b_out']
  596. # o[o_counter] = np.matmul(wout_exc, r[exc_ind, t]) + var['b_out'] # excitatory output
  597. # o[o_counter] = np.matmul(wout_inh, r[inh_ind, t]) + var['b_out'] # inhibitory output
  598. o_counter += 1
  599. return x, r, o

model.py at commit c8937f9, under Apache-2.0 · at the source

Overview

Authors: Kalman A. Katlowitz1, Eric R. Cole1, Elizabeth A. Mickiewicz1, Shraddha Shah1, Melissa Franch1, Joshua A. Adkinson1, James L. Belanger1, Raissa K. Mathura1, Domokos Meszéna2,3,4, Matthew McGinley5, William Muñoz6, Garrett P. Banks1, Sydney S. Cash2,4, Chih-Wei Hsu7, Angelique C. Paulk2,4, Nicole R. Provenza1,8,9,10, Andrew J. Watrous1, Ziv Williams6, Alica M. Goldman11, Vaishnav Krishnan5,8,11
and 6 other authorsAtul Maheshwari11, Sarah R. Heilbronner1,5,10, Robert Kim12, Nuttida Rungratsameetaweemana13, Benjamin Y. Hayden1,5,8,10, Sameer A. Sheth1,5,8,10,14,15
15 affiliations
  1. Department of Neurosurgery, Baylor College of Medicine,Houston, TX USA
  2. Department of Neurology, Massachusetts General Hospital, Harvard Medical School,Boston, MA USA
  3. HUN-REN Research Centre for Natural Sciences, Budapest, Hungary PPCU Faculty of Information Technology and Bionics,Budapest, Hungary
  4. Center for Neurotechnology and Neurorecovery, Department of Neurology, Mass General Brigham,Boston, MA USA
  5. Department of Neuroscience, Baylor College of Medicine,Houston, TX USA
  6. Department of Neurosurgery, Massachusetts General Hospital, Harvard Medical School,Boston, MA USA
  7. Department of Integrative Physiology, Baylor College of Medicine,Houston, TX USA
  8. Department of Electrical & Computer Engineering, Rice University,Houston, TX USA
  9. Department of Bioengineering, Rice University,Houston, TX USA
  10. Neuroengineering Initiative, Rice University,Houston, TX USA
  11. Department of Neurology, Baylor College of Medicine,Houston, TX USA
  12. Department of Neurology, Cedars-Sinai Medical Center,Los Angeles, CA USA
  13. Department of Biomedical Engineering, Columbia University,New York, NY USA
  14. Department of Psychiatry and Behavioral Sciences, Baylor College of Medicine,Houston, TX USA
  15. Cain Laboratories, Duncan Neurological Research Institute, Texas Children’s Hospital,Houston, TX USA
Institutions: Baylor College of Medicine (United States); Massachusetts General Hospital (United States); Pázmány Péter Catholic University (Hungary); Mass General Brigham (United States); Rice University (United States); Cedars-Sinai Medical Center (United States); Columbia University (United States); Texas Children's Hospital (United States)
Journal: Nature, volume 654, issue 8119, pages 714-723
Dates: received 9 April 2025; accepted 25 March 2026; published online 6 May 2026; in print 2026
Type: Research article · Language: English
License: CC BY-NC-ND
Identifiers: DOI 10.1038/s41586-026-10448-0 · PMID 42092132 · PMCID PMC13275293 · OpenAlex W7160451128
Open access: hybrid, a free copy (OpenAlex)
Status: code verified
Categories: extracellular electrophysiology (units, LFP) (modality), human (organism), cognitive (subfield)
Methods: Spectral & time-frequency, Connectivity, Statistics, Smoothing, state filtering, decompositions, Machine learning, Preprocessing, Evoked potentials, fMRI & imaging, Single-unit activity, calcium imaging
Keywords: Perception, Language, Hippocampus, Sensory processing, Consciousness
MeSH: Anesthesia, General*, Hippocampus*, Language*, Neuronal Plasticity*, Acoustic Stimulation, Adult, Consciousness, Discrimination, Psychological, Female, Humans, Local Field Potential Measurement, Male, Models, Neurological, Neurons, Semantics, Unconsciousness, Young Adult (* major topic)
Topic: Neural dynamics and brain function (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: NINDS NIH HHS (U01 NS121472)
Citations: cited by 6 papers (Europe PMC); 68 references in the paper
Notices: A correction to this paper has been published (42277412, from Europe PMC); A correction to this paper has been published (42680833, from Europe PMC)

Abstract

The abstract is not reproduced here: the paper's license (CC BY-NC-ND) does not allow it. Read it in the paper, at the publisher or on Europe PMC.

Repositories

Its files are read in the Code ↔ Paper reader above, with 9 matches between paragraphs and lines of code.

evarol/DREDge

License: MIT
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: ed236113a0b6c29b376065440174da6341a1d875, 21 March 2026
Languages: MATLAB (23), Python (5), Jupyter (4)
Size: 44 files, 32 scripts
Software Heritage: not archived
Found in: the text, “Motion correction”
Holds: README, license file, environment (pyproject.toml), continuous integration, 4 notebooks
Not found: CITATION.cff, tests, documentation
Tools: NumPy (8 files), Image Processing Toolbox (5 files), Matplotlib (4 files), SpikeInterface (4 files), Statistics and Machine Learning Toolbox (3 files), SciPy (3 files), Signal Processing Toolbox (1 file), PyTorch (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
34 files

NuttidaLab/rnn_oddball

License: Apache-2.0
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: c8937f93abb5c4dc14b747ae3b5b95028b07fc65, 10 February 2026
Languages: MATLAB (14), Python (5), Shell (2)
Size: 28 files, 21 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Statistics and Machine Learning Toolbox (8 files), TensorFlow (5 files), NumPy (4 files), SciPy (4 files), Parallel Computing Toolbox (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
23 files

Code availability statement

The paper has a code availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

Read it in the paper: doi.org/10.1038/s41586-026-10448-0.

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:

  • 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 53 scripts, each with its path and the digest of its content;
  • 9 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 statement

The paper has a data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

  • no repository, dataset or request procedure was recognized in it

Read it in the paper: doi.org/10.1038/s41586-026-10448-0.

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 2, 28 September 2026

  • Publisher: n/a → Nature Portfolio

Version 1, 28 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 26 authors, 5 keywords, 17 MeSH terms, 1 funder, 62 references, 2 integrity notices.

Cite

This paper

Katlowitz, K. A., Cole, E. R., Mickiewicz, E. A., Shah, S., Franch, M., Adkinson, J. A., Belanger, J. L., Mathura, R. K., Meszéna, D., McGinley, M., Muñoz, W., Banks, G. P., Cash, S. S., Hsu, C.-W., Paulk, A. C., Provenza, N. R., Watrous, A. J., Williams, Z., Goldman, A. M., . . . Sheth, S. A. (2026). Plasticity and language in the anaesthetized human hippocampus. Nature, 654(8119), 714-723. https://doi.org/10.1038/s41586-026-10448-0

BibTeX

@article{katlowitz2026plasticity,
author = {Katlowitz, Kalman A. and Cole, Eric R. and Mickiewicz, Elizabeth A. and Shah, Shraddha and Franch, Melissa and Adkinson, Joshua A. and Belanger, James L. and Mathura, Raissa K. and Meszéna, Domokos and McGinley, Matthew and Muñoz, William and Banks, Garrett P. and Cash, Sydney S. and Hsu, Chih-Wei and Paulk, Angelique C. and Provenza, Nicole R. and Watrous, Andrew J. and Williams, Ziv and Goldman, Alica M. and Krishnan, Vaishnav and Maheshwari, Atul and Heilbronner, Sarah R. and Kim, Robert and Rungratsameetaweemana, Nuttida and Hayden, Benjamin Y. and Sheth, Sameer A.},
title = {{Plasticity and language in the anaesthetized human hippocampus}},
journal = {Nature},
year = {2026},
month = may,
volume = {654},
number = {8119},
pages = {714--723},
publisher = {Nature Portfolio},
issn = {0028-0836},
doi = {10.1038/s41586-026-10448-0},
url = {https://doi.org/10.1038/s41586-026-10448-0},
pmid = {42092132},
pmcid = {PMC13275293}
}

RIS

TY - JOUR
AU - Katlowitz, Kalman A.
AU - Cole, Eric R.
AU - Mickiewicz, Elizabeth A.
AU - Shah, Shraddha
AU - Franch, Melissa
AU - Adkinson, Joshua A.
AU - Belanger, James L.
AU - Mathura, Raissa K.
AU - Meszéna, Domokos
AU - McGinley, Matthew
AU - Muñoz, William
AU - Banks, Garrett P.
AU - Cash, Sydney S.
AU - Hsu, Chih-Wei
AU - Paulk, Angelique C.
AU - Provenza, Nicole R.
AU - Watrous, Andrew J.
AU - Williams, Ziv
AU - Goldman, Alica M.
AU - Krishnan, Vaishnav
AU - Maheshwari, Atul
AU - Heilbronner, Sarah R.
AU - Kim, Robert
AU - Rungratsameetaweemana, Nuttida
AU - Hayden, Benjamin Y.
AU - Sheth, Sameer A.
TI - Plasticity and language in the anaesthetized human hippocampus
T2 - Nature
J2 - Nature
PY - 2026
DA - 2026/05/06
VL - 654
IS - 8119
SP - 714
EP - 723
SN - 0028-0836
PB - Nature Portfolio
DO - 10.1038/s41586-026-10448-0
UR - https://doi.org/10.1038/s41586-026-10448-0
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41586-026-10448-0",
"type": "article-journal",
"title": "Plasticity and language in the anaesthetized human hippocampus",
"container-title": "Nature",
"author": [
{
"family": "Katlowitz",
"given": "Kalman A."
},
{
"family": "Cole",
"given": "Eric R."
},
{
"family": "Mickiewicz",
"given": "Elizabeth A."
},
{
"family": "Shah",
"given": "Shraddha"
},
{
"family": "Franch",
"given": "Melissa"
},
{
"family": "Adkinson",
"given": "Joshua A."
},
{
"family": "Belanger",
"given": "James L."
},
{
"family": "Mathura",
"given": "Raissa K."
},
{
"family": "Meszéna",
"given": "Domokos"
},
{
"family": "McGinley",
"given": "Matthew"
},
{
"family": "Muñoz",
"given": "William"
},
{
"family": "Banks",
"given": "Garrett P."
},
{
"family": "Cash",
"given": "Sydney S."
},
{
"family": "Hsu",
"given": "Chih-Wei"
},
{
"family": "Paulk",
"given": "Angelique C."
},
{
"family": "Provenza",
"given": "Nicole R."
},
{
"family": "Watrous",
"given": "Andrew J."
},
{
"family": "Williams",
"given": "Ziv"
},
{
"family": "Goldman",
"given": "Alica M."
},
{
"family": "Krishnan",
"given": "Vaishnav"
},
{
"family": "Maheshwari",
"given": "Atul"
},
{
"family": "Heilbronner",
"given": "Sarah R."
},
{
"family": "Kim",
"given": "Robert"
},
{
"family": "Rungratsameetaweemana",
"given": "Nuttida"
},
{
"family": "Hayden",
"given": "Benjamin Y."
},
{
"family": "Sheth",
"given": "Sameer A."
}
],
"container-title-short": "Nature",
"volume": "654",
"issue": "8119",
"page": "714-723",
"DOI": "10.1038/s41586-026-10448-0",
"PMID": "42092132",
"PMCID": "PMC13275293",
"ISSN": "0028-0836",
"publisher": "Nature Portfolio",
"URL": "https://doi.org/10.1038/s41586-026-10448-0",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
6
]
]
}
}

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/s41586-026-10691-5 [code]
Mapping the neuronal building blocks of human language with language models.
Journal: Nature
In common: SciPy, Matplotlib, NumPy, cognitive, 3 references, 2 authors
[2] doi:10.1016/j.patter.2026.101590 [code]
Density-based longitudinal neuron tracking in high-density electrophysiological recordings.
Journal: Patterns (New York, N.Y.)
In common: SpikeInterface, Parallel Computing Toolbox, Signal Processing Toolbox, 5 other tools, extracellular electrophysiology (units, LFP), 3 references
[3] doi:10.1038/s41586-026-10653-x [code]
A mosaic of whole-body representations on the human precentral gyrus.
Journal: Nature
In common: PyTorch, Statistics and Machine Learning Toolbox, SciPy, 2 other tools, 2 authors
[4] doi:10.1371/journal.pbio.3003831 [code]
Disinhibitory signaling enables flexible coding of top-down information in cortical networks.
Journal: PLoS biology
In common: TensorFlow, Image Processing Toolbox, PyTorch, 4 other tools, 1 reference, author Robert Kim
[5] doi:10.7554/elife.110588 [code]
Opening the black box toward a modular approach to spike sorting.
Journal: eLife
In common: SpikeInterface, TensorFlow, PyTorch, 3 other tools, extracellular electrophysiology (units, LFP), 4 references
[6] doi:10.1038/s41467-026-71443-7 [code]
Large-scale single-neuron recording in the human cortex using an ultra-flexible electrode array.
Journal: Nature communications
In common: Signal Processing Toolbox, Statistics and Machine Learning Toolbox, extracellular electrophysiology (units, LFP), 6 references
[7] doi:10.1038/s41593-026-02205-3 [code]
Competitive interactions shape mammalian brain network dynamics and computation.
Journal: Nature neuroscience
In common: Parallel Computing Toolbox, Image Processing Toolbox, Signal Processing Toolbox, 5 other tools, 2 references
[8] doi:10.1038/s41593-026-02258-4 [code]
Laminar organization of cellular microcircuits modulating human interictal epileptiform discharges.
Journal: Nature neuroscience
In common: Parallel Computing Toolbox, Image Processing Toolbox, Signal Processing Toolbox, 4 other tools, 2 references
[9] doi:10.1038/s41593-026-02357-2 [code]
Experience reorganizes content-specific memory traces in macaques.
Journal: Nature neuroscience
In common: Parallel Computing Toolbox, Image Processing Toolbox, Signal Processing Toolbox, 4 other tools, 2 references
[10] doi:10.1038/s41467-026-73106-z [code]
Respiratory pauses highlight sleep architecture in mice.
Journal: Nature communications
In common: Parallel Computing Toolbox, TensorFlow, Image Processing Toolbox, 5 other tools, extracellular electrophysiology (units, LFP)

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.

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.