Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Open In Colab   Open in Kaggle

Tutorial 1: Consciousness

Week 2, Day 5: Mysteries

By Neuromatch Academy

Content creators: Steve Fleming, Guillaume Dumas, Samuele Bolotta, Juan David Vargas, Hakwan Lau, Anil Seth, Claire Sergent, Megan Peters

Content reviewers: Samuele Bolotta, Lily Chamakura, RyeongKyung Yoon, Yizhou Chen, Ruiyi Zhang, Patrick Mineault, Alex Murphy

Production editors: Konstantine Tsafatinos, Ella Batty, Spiros Chavlis, Samuele Bolotta, Hlib Solodzhuk, Patrick Mineault, Alex Murphy


Tutorial Objectives

Estimated timing of tutorial: 120 minutes

By the end of this tutorial, participants will be able to:

  1. Understand and distinguish various aspects of consciousness including the hard problem of consciousness, the difference between phenomenal consciousness and access consciousness, as well as the distinctions between consciousness and sentience or intelligence.

  2. Explore core frameworks for analyzing consciousness, including diagnostic criteria, and will compare objective probabilities with subjective credences.

  3. Explore reductionist theories of consciousness, such as Global Workspace Theory (GWT), theories of metacognition, and Higher-Order Thought (HOT) theories.

The topic of consciousness and what it means to be conscious is a long-standing open question in neuroscience and recently has drawn a lot of attention in machine learning in the context of large language models and foundation models. People have claimed that these models exhibits sparks of consciousness and a strong debate in the community continues to rage on. It’s therefore likely a big issue that will continue to gain a lot of traction in the space of NeuroAI and we hope you can start to build some familiarity with the tools use to quantify and study this fascinating topic.


Setup

Install and import feedback gadget

Source
WARNING: typer 0.29.1 does not provide the extra 'all'

Import dependencies

Figure settings

Source

Helper functions

Source
/opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/_reduction.py:42: UserWarning: size_average and reduce args will be deprecated, please use reduction='sum' instead.
  warnings.warn(warning.format(ret))

Plotting functions

Source

Set device (GPU or CPU)

Source
GPU is not enabled in this notebook. 
If you want to enable it, in the menu under `Runtime` -> 
`Hardware accelerator.` and select `GPU` from the dropdown menu

Section 1: Global Neuronal Workspace

Before we get started, we will hear from Claire and Guillaume, who will talk a bit about the neural correlates of consciousness, their research using the global workspace model, and its implications for distinguishing conscious from non-conscious processing.

Video 1: Global Neuronal Workspace

Youtube
Bilibili

Video 2: Global Neuronal Workspace

Youtube
Bilibili

Section 1a: Modularity Of The Mind

Video 3: Modularity Of The Mind

Youtube
Bilibili

In this section, we are exploring an important concept in machine learning: the idea that the complexity we observe in the physical world often arises from simpler, independently functioning parts. Think of the world as being made up of different modules or units that usually operate on their own but sometimes interact with each other. This is similar to how different apps on your phone work independently but can share information when needed.


Modularity Recap

Remember in W2D1, our day entitled Macrocircuits? In Tutorial 3 of that day, the focus was on neural network modularity and we showed you that, compared to a single holistic architecture, having separable modular approaches, each with their own inductive biases, provided a much more efficient mechanism to model complex data. Not only that, but these sub-modules had stronger inductive biases and were easily generalizable to novel inputs. Today, we’re also shining a spotlight on the similar idea, but from a much more integrative perspective applied to the grand idea of modeling consciousness. Those of you who are interested should review this tutorial and the ideas on modularity and how it can support complex systems more efficiently than holistic unitary mechanisms.


This idea is closely linked to the field of causal inference, which studies how these separate units or mechanisms cause and influence each other. The goal is to understand and model how these mechanisms work both individually and together. Importantly, these mechanisms often interact only minimally, which means they can keep working properly even if changes occur in other parts. This characteristic makes them very robust, or capable of handling disturbances well.

A specific example from machine learning that uses this idea is called Recurrent Independent Mechanisms (RIMs). In RIMs, different parts of the model mostly work independently, but they can also communicate or “pay attention” to each other when it’s necessary. This setup allows for efficient and dynamic processing of information. The research paper available here (https://arxiv.org/pdf/1909.10893) discusses this approach in detail.

Recurrent Independent Mechanisms (RIMs)

RIM networks are a type of recurrent neural network that process temporal sequences. Inputs are processed one element at a time, the different units of the network process the inputs, a hidden state is updated and propagated through time. RIM networks can thus be used as a drop-in replacement for RNNs like LSTMs or GRUs. The key differences are that:

  1. The RIM cells are sparsely activated, meaning that only a subset of the RIM units are active at each time step.

  2. The RIM units are mostly independent, meaning that they do not share weights or hidden states.

  3. The RIM units can communicate with each other through an attention mechanism.

Selecting the input

Recall in W1D5 (Microcircuits) we had a tutorial on Attention (Tutorial 3), where we covered how modern Transformer-based neural networks implement attention via the Query matrix, the Key matrix and the Value matrix? If not, you might benefit from reviewing the tutorial videos from that day as these concepts are used in the RIM networks we will look at today. Each RIM unit is activated and updated when the input is attended using the attention mechanism. Using key-value attention (KV matrices), the queries (Q matrix) originate from the RIMs, while the keys and values are derived from the current input. In standard deep learning terminology, this is very closely related to the concept of cross-attention. The key-value attention mechanisms enable dynamic selection of which variable instance (i.e., which entity or object) will serve as input to each RIM mechanism:

Attention(Q,K,V)=softmax(QKTd)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{Q K^T}{\sqrt{d}}\right) V

Linear transformations are used to construct keys K=XWkK = XW^k , values V=XWv V = XW^v and queries Q=htWiqQ = h_t W^q_i.

Here:

  • Wk W^k is a weight matrix which maps the input to the keys (Key matrix)

  • Wv W^v is a matrix mapping from an input element to the corresponding value vector for the weighted attention (Value matrix)

  • Wiq W^q_i is a per-RIM weight matrix which maps from the RIM’s hidden state to its queries (Query matrix)

  • hth_t is the hidden state for a RIM mechanism.

⊕\oplus refers to the row-level concatenation operator. The attention thus is:

Ai(in)=softmax(htWiq(XWk)Tde)XWv, where θi(in)=(Wiq,Wk,Wv)A^{(\text{in})}_i = \text{softmax}\left(\frac{h_t W^q_i (XW^k)^T}{\sqrt{d_e}}\right) XW^v, \text{ where } \theta^{(\text{in})}_i = (W^q_i, W^k, W^v)

At each step, the top-k RIMs are selected based on their attention scores for the actual input. Essentially, the RIMs compete at each step to read from the input, and only the RIMs that prevail in this competition are allowed to read from the input and update their state.

Picture which shows how RIMs work over two steps.

This figure shows how RIMs work over two steps.

  • Query generation: each RIM starts by creating a query. This query helps each RIM pull out the necessary information from the data it receives at that moment.

  • Attention-based selection: on the right side of the figure, you can see that some RIMs are chosen to be active (colored in blue) and others stay inactive (colored in white). This selection is made using a special scoring system called attention, which picks RIMs based on how relevant they are to the current visual inputs.

  • State transition for active RIMs: the RIMs that get activated update their internal states according to their specific rules, using the information they’ve gathered. The RIMs that aren’t activated don’t change and keep their previous states.

  • Communication between RIMs: finally, the active RIMs share information with each other, but this communication is limited. They use a system similar to key-value pairing, which helps them share only the most important information needed for the next step.

To make this more concrete, consider the example of modeling the motion of two balls. We can think of each ball as an independent mechanism. Although both balls are affected by Earth’s gravity, and very slightly from each other, they generally move independently. The only interaction that is significant occurs when they collide. This model captures the essence of independent mechanisms interacting sparsely, a key idea in developing more effective and generalizable AI systems (see W1D5 - Tutorial 1 for the tutorial devoted entirely to sparsity and its benefits).

Now, let’s download the RIM model!

Data retrieval

Source

Training RIMs

RIMs are motivated by the hypothesis that generalization performance can benefit from modules that only activate on relevant parts of the sequence. To measure RIMs’ ability to perform tasks out-of-distribution, we consider the task of classifying MNIST digits as sequences of pixels (Sequential MNIST) and assess generalization to images of resolutions different from those seen during training. The intuition is that the RIMs model should have distinct subsets of the RIMs activated for pixels containing the digit and for empty pixels. RIMs should generalize better to higher resolutions by keeping dormant those RIMs that store pixel information over empty regions of the image.

This is the test setup:

  1. Train on 14x14 images of MNIST digits

  2. Test on:

    • 16x16 images (validation set 1)

    • 19x19 images (validation set 2)

    • 24x24 images (validation set 3)

This approach helps to understand whether the model can still recognize the digits accurately even when they appear at different scales or resolutions than those on which it was originally trained. By testing the model on various image sizes, we can determine how flexible and effective the model is at dealing with variations in input data.

Note: if you train the model locally, it will take around 10 minutes to complete.

  0%|          | 0/20 [00:00<?, ?it/s]
  5%|▌         | 1/20 [00:09<03:00,  9.52s/it]
 10%|█         | 2/20 [00:18<02:48,  9.37s/it]
 15%|█▌        | 3/20 [00:29<02:49,  9.97s/it]
 20%|██        | 4/20 [00:40<02:44, 10.28s/it]
 25%|██▌       | 5/20 [00:50<02:36, 10.46s/it]
 30%|███       | 6/20 [01:01<02:28, 10.59s/it]
 35%|███▌      | 7/20 [01:12<02:19, 10.77s/it]
 40%|████      | 8/20 [01:23<02:09, 10.81s/it]
 45%|████▌     | 9/20 [01:34<01:58, 10.80s/it]
 50%|█████     | 10/20 [01:45<01:47, 10.76s/it]
 55%|█████▌    | 11/20 [01:56<01:36, 10.77s/it]
 60%|██████    | 12/20 [02:07<01:26, 10.85s/it]
 65%|██████▌   | 13/20 [02:17<01:15, 10.81s/it]
 70%|███████   | 14/20 [02:28<01:04, 10.79s/it]
 75%|███████▌  | 15/20 [02:39<00:53, 10.74s/it]
 80%|████████  | 16/20 [02:49<00:42, 10.73s/it]
 85%|████████▌ | 17/20 [03:00<00:32, 10.72s/it]
 90%|█████████ | 18/20 [03:11<00:21, 10.78s/it]
 95%|█████████▌| 19/20 [03:22<00:10, 10.77s/it]
100%|██████████| 20/20 [03:26<00:00,  8.82s/it]
100%|██████████| 20/20 [03:26<00:00, 10.33s/it]

  0%|          | 0/20 [00:00<?, ?it/s]
  5%|▌         | 1/20 [00:06<02:08,  6.78s/it]
 10%|█         | 2/20 [00:13<02:01,  6.75s/it]
 15%|█▌        | 3/20 [00:20<01:54,  6.75s/it]
 20%|██        | 4/20 [00:26<01:47,  6.73s/it]
 25%|██▌       | 5/20 [00:33<01:41,  6.74s/it]
 30%|███       | 6/20 [00:40<01:35,  6.85s/it]
 35%|███▌      | 7/20 [00:47<01:28,  6.84s/it]
 40%|████      | 8/20 [00:54<01:22,  6.84s/it]
 45%|████▌     | 9/20 [01:01<01:15,  6.83s/it]
 50%|█████     | 10/20 [01:08<01:08,  6.85s/it]
 55%|█████▌    | 11/20 [01:15<01:01,  6.86s/it]
 60%|██████    | 12/20 [01:21<00:54,  6.84s/it]
 65%|██████▌   | 13/20 [01:28<00:47,  6.83s/it]
 70%|███████   | 14/20 [01:35<00:40,  6.83s/it]
 75%|███████▌  | 15/20 [01:42<00:34,  6.90s/it]
 80%|████████  | 16/20 [01:49<00:27,  6.85s/it]
 85%|████████▌ | 17/20 [01:55<00:20,  6.82s/it]
 90%|█████████ | 18/20 [02:02<00:13,  6.80s/it]
 95%|█████████▌| 19/20 [02:09<00:06,  6.80s/it]
100%|██████████| 20/20 [02:12<00:00,  5.58s/it]
100%|██████████| 20/20 [02:12<00:00,  6.61s/it]

  0%|          | 0/20 [00:00<?, ?it/s]
  5%|▌         | 1/20 [00:04<01:30,  4.78s/it]
 10%|█         | 2/20 [00:09<01:26,  4.80s/it]
 15%|█▌        | 3/20 [00:14<01:21,  4.78s/it]
 20%|██        | 4/20 [00:19<01:17,  4.81s/it]
 25%|██▌       | 5/20 [00:24<01:12,  4.83s/it]
 30%|███       | 6/20 [00:29<01:09,  4.94s/it]
 35%|███▌      | 7/20 [00:34<01:03,  4.90s/it]
 40%|████      | 8/20 [00:38<00:58,  4.87s/it]
 45%|████▌     | 9/20 [00:43<00:53,  4.86s/it]
 50%|█████     | 10/20 [00:48<00:48,  4.87s/it]
 55%|█████▌    | 11/20 [00:53<00:43,  4.88s/it]
 60%|██████    | 12/20 [00:58<00:39,  4.89s/it]
 65%|██████▌   | 13/20 [01:03<00:34,  4.90s/it]
 70%|███████   | 14/20 [01:08<00:29,  4.91s/it]
 75%|███████▌  | 15/20 [01:13<00:24,  4.91s/it]
 80%|████████  | 16/20 [01:17<00:18,  4.62s/it]
 85%|████████▌ | 17/20 [01:21<00:14,  4.69s/it]
 90%|█████████ | 18/20 [01:27<00:09,  4.81s/it]
 95%|█████████▌| 19/20 [01:31<00:04,  4.84s/it]
100%|██████████| 20/20 [01:33<00:00,  3.98s/it]
100%|██████████| 20/20 [01:33<00:00,  4.70s/it]

Training LSTMs

Let’s now repeat the same process with LSTMs.

  0%|          | 0/20 [00:00<?, ?it/s]
  5%|▌         | 1/20 [00:00<00:07,  2.47it/s]
 10%|█         | 2/20 [00:00<00:07,  2.57it/s]
 15%|█▌        | 3/20 [00:01<00:06,  2.62it/s]
 20%|██        | 4/20 [00:01<00:06,  2.61it/s]
 25%|██▌       | 5/20 [00:01<00:05,  2.64it/s]
 30%|███       | 6/20 [00:02<00:05,  2.67it/s]
 35%|███▌      | 7/20 [00:02<00:04,  2.64it/s]
 40%|████      | 8/20 [00:03<00:04,  2.65it/s]
 45%|████▌     | 9/20 [00:03<00:04,  2.66it/s]
 50%|█████     | 10/20 [00:03<00:03,  2.65it/s]
 55%|█████▌    | 11/20 [00:04<00:03,  2.67it/s]
 60%|██████    | 12/20 [00:04<00:03,  2.66it/s]
 65%|██████▌   | 13/20 [00:04<00:02,  2.66it/s]
 70%|███████   | 14/20 [00:05<00:02,  2.67it/s]
 75%|███████▌  | 15/20 [00:05<00:01,  2.64it/s]
 80%|████████  | 16/20 [00:06<00:01,  2.66it/s]
 85%|████████▌ | 17/20 [00:06<00:01,  2.67it/s]
 90%|█████████ | 18/20 [00:06<00:00,  2.64it/s]
 95%|█████████▌| 19/20 [00:07<00:00,  2.66it/s]
100%|██████████| 20/20 [00:07<00:00,  2.96it/s]
100%|██████████| 20/20 [00:07<00:00,  2.69it/s]

  0%|          | 0/20 [00:00<?, ?it/s]
  5%|▌         | 1/20 [00:00<00:04,  4.09it/s]
 10%|█         | 2/20 [00:00<00:04,  4.04it/s]
 15%|█▌        | 3/20 [00:00<00:04,  4.13it/s]
 20%|██        | 4/20 [00:00<00:03,  4.19it/s]
 25%|██▌       | 5/20 [00:01<00:03,  4.23it/s]
 30%|███       | 6/20 [00:01<00:03,  4.27it/s]
 35%|███▌      | 7/20 [00:01<00:03,  4.20it/s]
 40%|████      | 8/20 [00:01<00:02,  4.22it/s]
 45%|████▌     | 9/20 [00:02<00:02,  4.26it/s]
 50%|█████     | 10/20 [00:02<00:02,  4.28it/s]
 55%|█████▌    | 11/20 [00:02<00:02,  4.23it/s]
 60%|██████    | 12/20 [00:02<00:01,  4.24it/s]
 65%|██████▌   | 13/20 [00:03<00:01,  4.27it/s]
 70%|███████   | 14/20 [00:03<00:01,  4.27it/s]
 75%|███████▌  | 15/20 [00:03<00:01,  4.24it/s]
 80%|████████  | 16/20 [00:03<00:00,  4.18it/s]
 85%|████████▌ | 17/20 [00:04<00:00,  4.21it/s]
 90%|█████████ | 18/20 [00:04<00:00,  4.23it/s]
 95%|█████████▌| 19/20 [00:04<00:00,  4.26it/s]
100%|██████████| 20/20 [00:04<00:00,  4.75it/s]
100%|██████████| 20/20 [00:04<00:00,  4.30it/s]

  0%|          | 0/20 [00:00<?, ?it/s]
  5%|▌         | 1/20 [00:00<00:03,  5.39it/s]
 10%|█         | 2/20 [00:00<00:03,  5.72it/s]
 15%|█▌        | 3/20 [00:00<00:02,  5.85it/s]
 20%|██        | 4/20 [00:00<00:02,  5.89it/s]
 25%|██▌       | 5/20 [00:00<00:02,  5.95it/s]
 30%|███       | 6/20 [00:01<00:02,  5.99it/s]
 35%|███▌      | 7/20 [00:01<00:02,  5.93it/s]
 40%|████      | 8/20 [00:01<00:02,  5.85it/s]
 45%|████▌     | 9/20 [00:01<00:01,  5.91it/s]
 50%|█████     | 10/20 [00:01<00:01,  5.93it/s]
 55%|█████▌    | 11/20 [00:01<00:01,  5.97it/s]
 60%|██████    | 12/20 [00:02<00:01,  5.99it/s]
 65%|██████▌   | 13/20 [00:02<00:01,  6.02it/s]
 70%|███████   | 14/20 [00:02<00:01,  5.83it/s]
 75%|███████▌  | 15/20 [00:02<00:00,  5.88it/s]
 80%|████████  | 16/20 [00:02<00:00,  5.91it/s]
 85%|████████▌ | 17/20 [00:02<00:00,  5.96it/s]
 90%|█████████ | 18/20 [00:03<00:00,  5.97it/s]
 95%|█████████▌| 19/20 [00:03<00:00,  5.99it/s]
100%|██████████| 20/20 [00:03<00:00,  6.67it/s]
100%|██████████| 20/20 [00:03<00:00,  6.03it/s]

16x16 images - Accuracy (RIMs): 74.08%
19x19 images - Accuracy (RIMs): 64.28%
24x24 images - Accuracy (RIMs): 34.83%
16x16 images - Accuracy (LSTMs): 72.67%
19x19 images - Accuracy (LSTMs): 44.19%
24x24 images - Accuracy (LSTMs): 15.17%

The accuracy of the model on 16x16 images is fairly close to what was observed on smaller images, indicating that the increase in size to 16x16 does not significantly impact the model’s ability to recognize the images. However, RIMs demonstrate generalization better, when working with the larger 19x19 and 24x24 images - compared to LSTMs.

Discussion point

Why do you think a RIM works better than an LSTM in this case?

RIMs and consciousness

You might wonder how RIMs relate to consciousness. As we have seen, RIMs focus on modularity in neural processing. In this approach, various modules or units operate semi-independently but coordinate through a mechanism akin to attention. This modularity allows the system to specialize in different tasks, with the attention mechanism directing computational resources efficiently by focusing on the most relevant parts of a problem at any given time.

Like RIMs, the brain is modularly organized. Many theories of consciousness posit that consciousness emerges from the interaction of various specialized, yet relatively independent, neural circuits or modules. Each of these modules processes specific types of information or performs distinct cognitive functions. Global Workspace Theory, which we’ll cover in the next section, is a canonical example of a modular theory of consciousness.


Section 1b: A Shared Workspace

Video 4: A Shared Workspace

Youtube
Bilibili

In this section, we explore a deep learning model based on Global Workspace Theory from cognitive neuroscience. You can read more about this model in the linked research paper here (https://arxiv.org/pdf/2103.01197.pdf). The core idea behind this model is the use of a shared global workspace which serves as a coordination platform for the various specialized modules within the network.

Essentially, the model incorporates multiple specialist modules, each focusing on different aspects of a problem. Unlike in the RIM mechanism, these modules do not communicate directly with each other, but rather interact indirectly through a central shared memory. Communication with the centeral shared memory is handled, once again, by an attention mechanism.

Picture which shows how a shared workspace mechanism works.

By centralizing communication this way, the model mimics how a human brain might focus only on the most relevant information at any given time. It mimics a sort of “cognitive economy,” where only the most relevant data is processed and shared among modules, filtered through a bottleneck that forces the model to use a highly efficient, reducing-redundancy useful representation, which enhances the overall performance of the system. Moreover, the theory embeds some of the assumptions of the Global Workspace Theory (GWT) of consciousness, which suggests that consciousness arises from the ability of various brain processes to access a shared information platform, the Global Workspace.

Coding Exercise 1: Creating a Shared Workspace

In our model, the interaction among the modules (or specialists) and the shared workspace is managed by a QKV cross-attention mechanism, as explained above.

Here’s how it works:

  • Key: Each specialist module generates a key which represents the type of information the module wants to share.

  • Query: The workspace generates a query at each computational step. This query represents what the workspace needs to know next to facilitate the overall task.

  • Value: Each specialist also prepares a value, which is the actual information it proposes to add to the workspace.

Please refer to the textual explanation above where some of this is defined in a bit more detail if this is still unclear to you.

Your task is to fill in the code below to implement this mechanism.

<torch._C.Generator at 0x76b60c7b4ab0>
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In[13], line 10
      7 # Generate deterministic specialists' states
      8 specialists_states = torch.randn(num_specialists, hidden_dim)
---> 10 workspace = SharedWorkspace(num_specialists, hidden_dim, num_memory_slots, memory_slot_dim)

Cell In[12], line 7, in SharedWorkspace.__init__(self, num_specialists, hidden_dim, num_memory_slots, memory_slot_dim)
      3 def __init__(self, num_specialists, hidden_dim, num_memory_slots, memory_slot_dim):
      4     #################################################
      5     ## TODO for students: fill in the missing variables ##
      6     # Fill out function and remove
----> 7     raise NotImplementedError("Student exercise: fill in the missing variables")
      8     #################################################
      9     super().__init__()

NotImplementedError: Student exercise: fill in the missing variables

After updating the shared workspace with the most critical signals, this information is then broadcast back to all specialists. Each specialist updates its state using this broadcast information, which can involve an attention mechanism for consolidation and an update function (like an LSTM or GRU step) based on the new combined state.

Let’s add this method!

This approach structures the shared workspace to function in a modular fashion:

  • Step 1: Aggregation of specialist states

  • Step 2: Competitive information update in the shared workspace

  • Step 3: Broadcasting updated information

After the shared workspace has been updated with the most pertinent information, this consolidated knowledge is then broadcast back to all the specialists. This means that each specialist receives the updated, aggregated information, allowing them to adjust their actions or processing based on the collective insights of the entire system.

Recap

In the past sections, we’ve discussed models like Recurrent Independent Mechanisms (RIMs) and those inspired by cognitive neuroscience’s Global Workspace Theory (GWT). These models embed different ideas about modularity:

  • RIMs are based on the concept of independent mechanisms that can communicate sparsely through an attention mechanism.

  • GWT-inspired models use a shared workspace to coordinate between specialized modules.

These frameworks inspired by the brain embed some of the characteristics of popular models of consciousness. By mimicking how different parts of the brain might communicate and dominate the global workspace at different times, these models provide insight into how conscious awareness and decision-making could emerge in the brain.


Section 2: Higher order assessment and metacognition

Video 5: Higher order assessment and metacognition

Youtube
Bilibili

Second order model

Blindsight is a neurological phenomenon where individuals with damage to their primary visual cortex can still respond to visual stimuli without consciously perceiving them. Megan showed you a video of this from a real patient navigating a corridor and successfully avoiding objects that researchers had strategically placed in his way, which the patient navigated successfully.

To study this, we use a simulated dataset that mimics the conditions of blindsight. This dataset contains 400 patterns, equally split between two types:

  • Random noise patterns consist of low activations ranging between 0.0 and 0.02.

  • Designed stimulus patterns - each pattern includes one unit that shows a higher activation level, varying between 0.0 and 1.0.

This dataset allows us to test hypotheses concerning how sensory processing and network responses adapt under different conditions of visual impairment.

We have three main testing scenarios, each designed to alter the signal-to-noise ratio to simulate different levels of visual impairment:

  • Suprathreshold stimulus condition: here, the network is tested against familiar patterns used during training to assess its response to known stimuli.

  • Subthreshold stimulus condition: this condition slightly increases the noise level, akin to actual blindsight conditions, testing the network’s capability to discern subtle signals.

  • Low vision condition: the intensity of stimuli is decreased to evaluate how well the network performs with significantly reduced sensory input.

/tmp/ipykernel_7448/3642818083.py:471: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at ../torch/csrc/utils/tensor_new.cpp:261.)
  patterns_tensor = torch.Tensor(patterns).to(device).requires_grad_(True)
<Figure size 800x800 with 2 Axes>
<Figure size 800x800 with 2 Axes>
<Figure size 800x800 with 2 Axes>

The first-order network model lays the groundwork for our experiments and is structured as follows:

  • Input layer: consists of 100 units representing either noise or stimulus patterns.

  • Hidden layer: includes a 40-unit layer tasked with processing the inputs.

  • Output layer: comprises 100 units where the responses to stimuli are recorded.

  • Dropout and activation: includes dropout layers to prevent overfitting and a temperature-controlled activation function to fine-tune response sharpness.

The primary aim of the first-order network is to accurately capture and react to the input patterns, setting a baseline for comparison with more complex models.

Coding Exercise 2: Developing a Second-Order Network

Your task is to expand upon the first-order network by integrating a second-order network that incorporates a metacognitive layer assessing the predictions of the first-order network. This metacognitive layer introduces a wagering mechanism, wherein the network “bets” on its confidence in its predictions.

  • The first-order network is designed as an autoencoder, a type of neural network trained to reconstruct the input stimulus. The autoencoder consists of an encoder that compresses the input into a latent representation and a decoder that reconstructs the input from this representation.

  • The second-order network, or metacognitive layer, operates by examining the difference (delta) between the original input and the output generated by the autoencoder. This difference provides insight into the reconstruction error, which is a measure of how accurately the autoencoder has learned to replicate the input data. By evaluating this reconstruction error, the second-order network can make a judgement about the certainty of the first-order network’s predictions.

These are the steps for completion:

  1. Architectural development: grasp the underlying principles of a second-order network and complete the architectural code.

  2. Performance evaluation: visualize training losses and test the model using provided code, assessing its initial performance.

  3. Model fine-tuning: leveraging the provided training function, experiment with fine-tuning the model to enhance its accuracy and efficiency.

The second-order network is structured as a feedforward backpropagation network.

  • Input layer: comprises a 100-unit comparison matrix. This matrix quantifies the discrepancy between each corresponding pair of input and output units from the first-order network. For example, if an input unit and its corresponding output unit have activations of 0.6 and 0.7, respectively, the comparison unit’s activation would be -0.1. This setup essentially encodes the prediction error of the first-order network’s outputs as an input pattern for the second-order network.

  • Output layer: consists of two units representing “high” and “low” wagers, indicating the network’s confidence in its predictions. The initial weights for these output units range between 0.0 and 0.1.

  • Comparator weights: set to 1.0 for connections from the first-order input layer to the comparison matrix, and -1.0 for connections from the first-order output layer. This configuration emphasizes the differential error as a critical input for the second-order decision-making process.

The second-order network’s novel approach uses the error generated by the first-order network as a direct input for making decisions—specifically, wagering on the confidence of its outputs. This methodology reflects a metacognitive layer of processing, akin to evaluating one’s confidence in their answers or predictions.

By exploring these adjustments, you can optimize the network’s functionality, making it a powerful tool for understanding and simulating complex cognitive phenomena like blindsight.

Seed 0
/opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/_reduction.py:42: UserWarning: size_average and reduce args will be deprecated, please use reduction='sum' instead.
  warnings.warn(warning.format(ret))
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In[18], line 135
    132 first_order_network, second_order_network, criterion_1, criterion_2, optimizer_1, optimizer_2, scheduler_1, scheduler_2 = prepare_pre_training(hidden, factor, gelu, stepsize, gam)
    134 # Conduct pre-training for both the first-order and second-order networks
--> 135 first_order_network_pre, second_order_network_pre, epoch_1_order, epoch_2_order , max_value_indices = pre_train(first_order_network, second_order_network, criterion_1,  criterion_2, optimizer_1, optimizer_2, scheduler_1, scheduler_2, factor, meta)
    137 # Plot the training progress of both networks to visualize performance and learning trends
    138 pre_train_plots(epoch_1_order, epoch_2_order, f"1st & 2nd Order Networks - Seed {i}" , max_value_indices )

Cell In[18], line 57, in pre_train(first_order_network, second_order_network, criterion_1, criterion_2, optimizer_1, optimizer_2, scheduler_1, scheduler_2, factor, meta)
     53 # Conditionally execute the second-order network pass and related operations
     54 if meta:
     55 
     56     # Forward pass through the second-order network with inputs from the first-order network
---> 57     output_second_order = second_order_network(patterns_tensor, output_first_order)
     59     # Calculate the loss for the second-order network (wagering decision based on comparison)
     60     loss_2 = criterion_2(output_second_order.squeeze(), order_2_tensor[:, 0])

File /opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/modules/module.py:1518, in Module._wrapped_call_impl(self, *args, **kwargs)
   1516     return self._compiled_call_impl(*args, **kwargs)  # type: ignore[misc]
   1517 else:
-> 1518     return self._call_impl(*args, **kwargs)

File /opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/modules/module.py:1527, in Module._call_impl(self, *args, **kwargs)
   1522 # If we don't have any hooks, we want to skip the rest of the logic in
   1523 # this function, and just call forward.
   1524 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
   1525         or _global_backward_pre_hooks or _global_backward_hooks
   1526         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1527     return forward_call(*args, **kwargs)
   1529 try:
   1530     result = None

Cell In[16], line 38, in SecondOrderNetwork.forward(self, first_order_input, first_order_output)
     34 def forward(self, first_order_input, first_order_output):
     35     ############################################################
     36     # Fill in the wager value
     37     # Applying dropout and sigmoid activation to the output of the wager layer
---> 38     raise NotImplementedError("Student exercise")
     39     ############################################################
     40 
     41     # Calculate the difference between the first-order input and output
     42     comparison_matrix = first_order_input - first_order_output

NotImplementedError: Student exercise

Discussion point

Let’s dive into the outcomes!

  • Did you notice any variations between the two models?

  • Can you explain how these differences influenced the performance?

  • What role does a second-order network play, and in which situations would it be more effective?

Video 6: Second Order Network

Youtube
Bilibili

Higher Order State Space (HOSS) model

Next, Steve is going to tell us about the higher order state space model of consciousness, including the computational and neurological underpinnings that differentiate conscious from unconscious perception.

Video 7: Higher-Order State Spaces

Youtube
Bilibili

In this section, we’ll merge ideas from earlier discussions to present a fresh perspective on how conscious awareness might arise in neural systems. This view comes from higher-order theory, which suggests that consciousness stems from the ability to monitor basic, or first-order, information processing activities, instead of merely broadcasting information globally. This concept emphasizes the need for a comprehensive monitor that oversees various first-order processes (like GWT). It extends the idea of the role of a second-order network, which helps us understand phenomena like blindsight.

To analyze how our brains handle and update perceptions, we’ll use a Bayesian framework. This framework helps us evaluate how we perceive reality based on the information we receive. For example, if you hear rustling leaves, your brain calculates the likelihood of it being caused by the wind versus an animal. This calculation involves updating what we initially guess (our prior belief) with new evidence (observed data), resulting in a new, more informed belief (posterior probability).

The function below calculates these updated beliefs and uses Kullback-Leibler (KL) divergence to quantify how much the new information changes our understanding. The KL divergence is a way of measuring the ‘distance’ between the initial belief and your updated belief. In essence, it’s measuring how much you have to change your mind given new evidence.

We base our analysis on a flat, or single-layer, Bayesian network model. This model directly connects our sensory inputs with our perceptual states, simplifying the complex interactions in our brain into a more manageable form. By stripping away the complexities of multi-layered networks, we focus purely on how direct observations impact our consciousness. This simplified approach helps us to better understand the intricate dance between perception and awareness in our neural systems.

Defining our Stimulus Space

The model we are using is grounded in classical Signal Detection Theory (SDT). SDT is a special case of a Bayesian generative model, in which an arbitrary evidence value is drawn from an unknown distribution. The task of the observer is to infer which distribution this evidence came from.

In SDT, an observer receives a piece of evidence (this could be any sensory input, like a sound, a light signal, or a statistical data point). The evidence comes from one of several potential distributions. Each distribution represents a different state of the world. For instance, one distribution might represent the presence of a signal (like a beep), while another might represent just noise. The observer uses Bayesian inference to assess the probability that the received evidence came from one distribution or another. This involves updating their beliefs (probabilities) based on the new evidence. Based on the probabilities calculated through Bayesian inference, the observer decides which distribution most likely produced the evidence.

Let’s now imagine we have two categories, A and B - for instance, left- and right-tilted visual stimuli. The sensory evidence can be written as 2D vector, where the first element is evidence for A, and the second element evidence for B:

The origin (0,0) represents low activation of both features, consistent with no stimulus (or noise) being presented. Comparing how the model handles inference on stimulus presence vs. absence - detecting, vs. not detecting a stimulus - allows us to capture the classical conscious vs. unconscious contrast in consciousness science.

Let’s start by creating our space, and placing three Gaussian distributions on the space that represent the likelihood of observing a pair of features given each of three stimulus classes:

  • leftward tilt (w1w_1)

  • rightward tilt (w2w_2)

  • noise/nothing (w0w_0)

By setting up this model, we aim to simulate and analyze how an observer infers the presence or absence of a stimulus. When the observer detects a stimulus, the inference process would lean towards either the leftward or rightward tilt, depending on which Gaussian (w1w_1 or w2w_2) the observed data points are closer to in feature space. When the observer fails to detect a stimulus, the inference process would recognize that the data points fall closer to the noise distribution centered at the origin.

<Figure size 500x500 with 1 Axes>

Let’s measure the evidence for each of the three classes at each point in the space. We’ll then use this evidence to calculate the posterior probability of each class given the evidence. This calculation will help us understand how the observer’s beliefs change based on the sensory data they receive.

<Figure size 800x600 with 4 Axes>

The model partitions the stimuli in the expected way. KL divergence is higher further away from the boundaries, as measuring stimuli far away from the boundaries makes the model rapidly update its beliefs. This is because the model is more certain about the stimuli’s class when they are far from the boundaries.

Add in higher-order node for global detection

So far, our model has been straightforward, or flat, where each perceptual state (like leftward tilt, rightward tilt, or no stimulus) is treated separately. However, real-life perception often requires more complex judgments about the presence or absence of any stimulus, not just identifying specific types. This is where a higher-order node comes into play.

Introducing the “A” Level:

Think of the “A” level as a kind of overseer or monitor that watches over the lower-level states (w1w_1, w2w_2, etc.). This higher-order node isn’t concerned with the specific content of the stimulus (like which direction something is tilting) but rather with whether there’s any significant stimulus at all versus just noise. It takes inputs from the same data (pairs of XX’s), but it adds a layer of awareness. It evaluates whether the data points suggest any meaningful content or if they’re likely just random noise.

The system can now answer questions on two levels:

  • the content level (W-level)

  • the awareness or presence of any content (A-level)

The output from the A-level, denoted as post_A, represents the posterior probability that there is any relevant content as opposed to mere noise. To make this work, we also need to set priors (initial guesses before seeing the data) at both the W-level (content) and A-level (awareness). This helps the model start with a baseline expectation about the likelihood of encountering various stimuli or noise.

In the next sections, we will illustrate the operation of a higher-order state space (HOSS) for monitoring first-order information processing. This model, with its higher-order node, mimics human perceptual processing where not every sensory input leads to awareness.

Picture about the HOSS model.

Model inference

We denote an observation X\mathbf{X} as a pair of features (X1,X2)(X_1, X_2), where X1X_1 and X2X_2 are the evidence for the presence of two different stimuli. The observer’s task is to infer which of three possible stimuli W∈[w0,w1,w2]W \in [w_0, w_1, w_2] generated the observation. Each stimulus WW is associated with a Gaussian distribution in the feature space:

p(X=x∣W)=N(μW,Σ)p(X=\mathbf{x}|W) = \mathcal{N}(\mathbf{\mu_W}, \mathbf{\Sigma})

where μW\mathbf{\mu_W} is the mean of each Gaussian, and Σ\mathbf{\Sigma} is the covariance matrix.

At a higher level, the observer also needs to infer the presence of any stimulus, regardless of its specific type. This is done by calculating the posterior probability of the awareness state AA given the observation:

P(A∣X=x)∝∑WP(A)P(W∣A)P(X=x∣W) ∝P(A)∑WP(W∣A)P(X=x∣W)\begin{aligned} P(A|X=x) &\propto \sum_{W} P(A)P(W|A)P(X=x|W) \ & \propto P(A)\sum_{W} P(W|A)P(X=x|W) \end{aligned}

where:

  • AA is the awareness state, a two-dimensional binary variable, with A0A_0 representing no stimulus and A1A_1 representing the presence of a stimulus

  • P(A)P(A) is the prior probability of each awareness state

  • P(W∣A)P(W|A) is the likelihood of each world state given the awareness state. This is 0 for the no stimulus state and p(W)p(W) for the stimulus present states.

  • P(X=x∣W)P(X=x|W) is the likelihood of the observation given each world state.

Finally, the observer can calculate the posterior probability of each stimulus class given the observation and the awareness state:

P(W∣X=x)∝∑AP(A)P(W∣A)P(X=x∣W)P(W|X=x) \propto \sum_{A} P(A)P(W|A)P(X=x|W)

With these equations, we’re ready to simulate the observer’s inference process and explore how the model behaves under different conditions.

Coding exercise

Now that we’ve coded our multi-level model, we’re ready to evaluate it! We first set the prior on presence (vs. absence), and then set the priors on w1w_1 vs. w2w_2, and the model takes care of the rest.

We’ll evaluate the model on the edge between the leftward stimulus w1w_1 and the absence of a stimulus w0w_0. This edge case is particularly interesting because it’s where the model is most uncertain about the presence of a stimulus.

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In[24], line 7
      4 Aprior = 0.5  # Prior probability of being aware
      6 # Call the HOSS_evaluate function with the specified parameters
----> 7 post_W, post_A, KL_W, KL_A = HOSS_evaluate(X, mu, Sigma, Aprior, Wprior)
      9 # Print the posterior probabilities
     10 print(f"Posterior probabilities at W level: {post_W}")

Cell In[23], line 10, in HOSS_evaluate(X, mu, Sigma, Aprior, Wprior)
      2 """
      3 
      4 Inference on 2D Bayes net for asymmetric inference on presence vs. absence.
      5 """
      7 #################################################
      8 ## TODO for students: fill in the missing variables ##
      9 # Fill out function and remove
---> 10 raise NotImplementedError("Student exercise: fill in the missing variables")
     11 #################################################
     12 
     13 # Initialise variables and conditional prob tables
     14 p_A = np.array([1 - Aprior, Aprior])  # prior on awareness state A

NotImplementedError: Student exercise: fill in the missing variables

We notice two things:

  • The model is fairly certain that the stimulus is absent; the probability of awareness is < 0.5.

  • The model nevertheless assigns much higher probability to the presence of the leftward stimulus w1w_1 than to the rightward stimulus w2w_2.

This captures the essence of a phenomenon like blindsight: there can be positive discrimination between different stimuli even when the observer is not consciously aware of the stimulus. Let’s look at how the awareness signal changes as the evidence changes.

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In[25], line 14
     12 awareness = []
     13 for i in range(Xs.shape[0]):
---> 14     post_W, post_A, KL_W, KL_A = HOSS_evaluate(Xs[i, :], mu, Sigma, Aprior, Wprior)
     15     rightwards.append(post_W[2] / (post_W[1] + post_W[2]))
     16     awareness.append(post_A[1])

Cell In[23], line 10, in HOSS_evaluate(X, mu, Sigma, Aprior, Wprior)
      2 """
      3 
      4 Inference on 2D Bayes net for asymmetric inference on presence vs. absence.
      5 """
      7 #################################################
      8 ## TODO for students: fill in the missing variables ##
      9 # Fill out function and remove
---> 10 raise NotImplementedError("Student exercise: fill in the missing variables")
     11 #################################################
     12 
     13 # Initialise variables and conditional prob tables
     14 p_A = np.array([1 - Aprior, Aprior])  # prior on awareness state A

NotImplementedError: Student exercise: fill in the missing variables

Notice that in the bottom left, the probability of awareness is low, even as the evidence for leftward or rightward tilt can be high.

We have included some further details on the notion of ignition. Please feel free to toggle the switch below to learn more. If you’re running low on time, then please feel free to run the cell below and come back to this section. The outro video will also cover the broad overview of this concept.

Simulate Ignition (assymetry vs symmetry)

The HOSS architecture is designed to detect whether something is there or not. When it detects something, it ends up making more prediction errors in its predictions compared to when it detects nothing. These prediction errors are tracked using a method called Kullback-Leibler (KL) divergence, particularly at a certain level within the model known as the W level.

This increase in prediction errors when something is detected is similar to what happens in the human brain, a phenomenon known as global ignition responses. These are big surges in brain activity that happen when we become conscious of something. Research like that conducted by Del Cul et al. (2007) and Dehaene and Changeux (2011) support this concept, linking it to the global workspace model. This model describes consciousness as the sharing of information across different parts of the brain.

In our model, we simulate this by adjusting the intensity of the stimulus and observing how the prediction errors vary in the model. Under a theory called predictive coding, which describes how the brain processes information, KL divergence acts like a marker for neural activity, making it a good stand-in for studying brain-like responses.

We then classify these prediction errors based on whether the model recognizes a stimulus as “seen” or “unseen.” If the model has a response indicating “seen,” it shows more activity than when it indicates “unseen.” This is what we refer to as ignition — more activity for “seen” stimuli.

However, it’s crucial to understand that in the HOSS model, these ignition-like responses don’t directly cause the global sharing of information in the network. Rather, they are secondary effects or byproducts of other calculations happening within the network. Essentially, these bursts of activity are outcomes of deeper processes in the network, not the direct mechanisms for distributing information throughout the system.

Processing gammas:   0%|          | 0/6 [00:00<?, ?it/s]

Subjects for gamma=0.1:   0%|          | 0/30 [00:00<?, ?it/s]

                                                              
Processing gammas:   0%|          | 0/6 [00:00<?, ?it/s]

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In[26], line 39
     37 # Model inversion for each trial
     38 for i, x in enumerate(X):
---> 39     post_w, post_A, KL_w[i], KL_A[i] = HOSS_evaluate(x, mu, Sigma, Aprior, Wprior)
     40     posteriorAware[i] = post_A[1]  # Assuming post_A is a tuple with awareness probability at index 1
     42 binaryAware = posteriorAware > 0.5

Cell In[23], line 10, in HOSS_evaluate(X, mu, Sigma, Aprior, Wprior)
      2 """
      3 
      4 Inference on 2D Bayes net for asymmetric inference on presence vs. absence.
      5 """
      7 #################################################
      8 ## TODO for students: fill in the missing variables ##
      9 # Fill out function and remove
---> 10 raise NotImplementedError("Student exercise: fill in the missing variables")
     11 #################################################
     12 
     13 # Initialise variables and conditional prob tables
     14 p_A = np.array([1 - Aprior, Aprior])  # prior on awareness state A

NotImplementedError: Student exercise: fill in the missing variables

Discussion point

What do you think is the main takeaway on the distinction between the Global Workspace model and the HOSS on ignition?

Now, Steve will give us a brief recap about how the greater prediction error in seen trials reveals the asymmetry in model architecture and its impact on understanding neural signatures of consciousness, contrasting the classical global workspace view with the higher order state view.

Video 8: Outro - Ignition

Youtube
Bilibili

The Big Picture

Hakwan will now discuss the critical aspects and limitations of current consciousness studies, addressing the challenges in distinguishing theories of consciousness from those merely describing general brain functions. Join us in the next two videos where we wrap up some of the big ideas and try to put them in context for you!

Video 9: Final Thoughts

Youtube
Bilibili

Congrats! You’ve made it to the end of this tutorial. Let’s wrap up.

Video 10: Final Thoughts

Youtube
Bilibili

Tutorial 3 today contains some bonus material based on extensions of what we’ve covered today. There, you’ll find some optional coding & discussion bonus content! Feel free to bookmark and come back to it whenever you are ready.

For the moment, let’s switch to our second topic on the day, arguably one of the most important topics we’ve covered so far: Ethics.