CompModCogPsy
  • 全书介绍和写作计划
  • 第一章 计算认知科学导论
    • 前言
    • 1.1 交叉学科三角
    • 1.2 认知科学的特点
    • 1.3 认知科学的发展历史
    • 1.4 我们为什么需要计算认知
      • 1.4.1 认知科学的基础假设:信息处理理论
      • 1.4.2 挑战与“诞生”
      • 1.4.3 计算认知的必要性
  • 第二章 计算模型基础
    • 2.1 什么是计算模型?
    • 2.2 模型选择
    • 2.3 模型拟合
    • 2.4 模型准确度
    • 2.5 模型可信度
  • 第三章 概率推断和贝叶斯理论
    • 3.1 概率基础
    • 3.2 概率推断
      • 3.2.1 似然函数
      • 3.2.2 最大似然估计
    • 3.3 贝叶斯理论
    • 3.4 拓展阅读:p值
    • 3.5 编程练习-最大似然估计
  • 第四章 心理物理学和信号检测论
    • 心理物理学基础
    • 心理物理曲线
      • 几种常见的心理物理曲线
      • 拟合心理物理曲线
    • 信号检测论
      • dprime
      • 决策标准
      • receiver operating curve (ROC)曲线和area under curve (AUC)
      • dprime和AUC的关系
      • 2AFC的应用
      • Page
    • 展望
  • 第五章 近似推断
    • 马尔科夫链蒙特卡洛采样
      • Metropolis-Hasting算法
    • 变分推断
    • 展望
  • 第六章 知觉决策
    • 模拟一个简单知觉决策
    • 模拟决策和反应时
    • 权衡反应时和正确率
    • 6.4 经典漂移扩散模型
    • 漂移扩散模型的应用
      • 基于价值的决策
      • 精神疾病的应用
      • 社会认知
    • 展望
  • 第七章 价值决策
    • 人类决策基础
    • 前景理论
    • 风险决策
    • 展望
  • 第八章 强化学习
    • 机器学习强化学习基础
      • 动态规划
      • 时间差分学习
      • 基于模型和无模型强化学习
    • 心理学的强化学习
    • 强化学习的交叉关系
    • 强化学习模型和参数估计
    • Rescorlar-wagner模型
    • 二阶段任务
    • 展望
  • 第九章 社会决策和社会学习
    • 社会决策
    • 社会学习
    • 展望
  • 第十章 神经网络
    • 神经网络和心理学引言
    • 神经网络基础
      • 多层感知机
      • 卷积神经网络
      • 循环神经网络
    • 神经网络和人脑加工的关系
      • 感知觉的编解码
      • 工作记忆
      • 长时记忆
      • 学习和决策
    • 展望
由 GitBook 提供支持
在本页
  1. 第六章 知觉决策

模拟决策和反应时

在上一节中,我们仅使用一致性(coherence)和持续时间(duration)模拟了被试的决策正确率。然而,在认知心理学中,我们不仅关注被试在决策时的正确率,还关注他们做出决策的反应时(Reaction Time),即从接收到感知信息到做出决策所需的时间长度。

因此,为了更全面地理解被试的决策过程,我们需要引入在知觉决策领域最常见的模型:漂移扩散模型(Drift Diffusion Model, DDM),漂移扩散模型是一种证据积累模型,模型假设在决策过程中,个体会从环境中连续的获取信息,这些信息被视为“证据”。这些证据以随机但有方向性的方式积累,逐渐接近决策边界。

在之前的模型中,我们在每一帧刺激中统计向左或者向右移动的点的数量,并在$T$帧后将向两个方向移动的点的数量相加进行比较。在这一节中,我们尝试另一种替代方法:在每一帧中,我们计算向正确方向运动的点的数量和向错误方向运动的点的数量的差,最后累加每一帧中所得到的差值delta。

接下来,我们用这个方法来模拟一次决策:

import numpy as np
from scipy.stats import bernoulli
import matplotlib.pyplot as plt

T = 20 # 刺激呈现的帧数
D = 10 # 刺激中点的数量
f = 0.55 # 正确点所占的比例

N_correct = 0 # 正确点的计数器
N_wrong = 0 # 错误点的计数器

delta = np.empty(T+1) # 计算每帧中的数量差
delta[0] = 0

#
for t in range(T): # 循环每一帧
    dir = bernoulli.rvs(f, size=1)
    N_correct = N_correct + dir # 正确点数量+1
    N_wrong = N_wrong + (1-dir) # 错误点数量+1
    
    # 数完这一帧中点的数量之后,计算并保存他们的差值
    delta[t+1] = N_correct - N_wrong

可视化出随着刺激呈现帧数TTT增加而变化的差值:

fig = plt.figure(figsize=(4,4))
plt.plot(range(T+1), delta)
plt.ylabel('Running difference')
plt.xlabel('# of frame')

根据上图,尽管正确点和错误点之间的Running differnce随着$T$的变化略有波动,但总体呈现上升趋势。这个过程就可以视为一个证据积累的过程:在每一帧中,如果Ncorrect>NwrongN_{\text{correct}} > N_{\text{wrong}}Ncorrect​>Nwrong​,那么被试就会获得一些支持正确方向的证据;反之,如果Ncorrect<NwrongN_{\text{correct}} < N_{\text{wrong}}Ncorrect​<Nwrong​,则会会的一些支持错误方向的证据。如果感觉证据随着时间积累,总体证据(即决策变量,上图中的蓝色曲线)会增加,是的被试有可能做出正确的选择。

对于固定持续时间的刺激,被试根据最终决策变量的符号来做出决策。然而,由被试自行决定持续时间的刺激(即反应时),我们该如何对这一过程进行建模呢?在这种情况下,我们假设一旦决策变量漂移到一个固定的边界,漂移扩散过程就会停止。在这里,我们假设这个边界为B=40B = 40B=40:

B = 40 # 一个固定的决策边界
D = 10 # 刺激中的总点数
f = 0.55 # 正确点所占的比例

N_correct = 0 # 正确点的计数器
N_wrong = 0 # 错误点的计数器


delta = [] # 将delta定义为一个列表
delta.append(N_correct - N_wrong)

i = 0
while np.abs(delta[i]) < B: # 循环,直至决策变量到达决策边界
    dir = bernoulli.rvs(f, size=1)[0]
    N_correct = N_correct + dir # 正确点数量+1
    N_wrong = N_wrong + (1-dir) # 错误点数量+1        
    
    # 更新帧数
    i = i + 1
    # 计算并保存感觉差异
    delta.append(N_correct - N_wrong)

# 所积累的感觉证据的符号决定了最中的决策
if delta[-1] > 0:
    print('The answer is correct in this trial')
else:
    print('The answer is wrong in this trial')

RT = i
print(f'Reaction time in this trial is {RT} frames')

让我们来可视化出这个漂移扩散过程:

fig = plt.figure(figsize=(4,4))
plt.plot(delta, '-o', label='accumulated evidence') # 画出evidence accumulation
plt.axhline(B, color='k', label='decision boundary') # 画出决策边界
plt.ylabel('Accumulated evidence')
plt.xlabel('# of frames (reaction time)')
plt.ylim([-10, 60])
plt.legend()

上述代码只能模拟出一次漂移扩散过程,我们像之前一样将这个过程写成一个函数,以便于我们进行多次模拟:

def ddm1(D=10, f=0.55, B=40):
    # <D>: 总点数
    # <f>: 向正确方向移动的点的比例
    # <B>: 决策边界

    i = 0
    N_correct = 0
    N_wrong = 0
    delta = [] # 将delta设为一个列表
    delta.append(N_correct - N_wrong)

    while np.abs(delta[i]) < B:
        for j in range(D):
            # 取样这个点的移动方向
            dir = bernoulli.rvs(f, size=1)[0] 
            # 更新计数
            N_correct = N_correct + dir
            N_wrong = N_wrong + (1-dir)
        
        # 增加一帧
        i = i + 1
        # 计算差异
        delta.append(N_correct - N_wrong)

    correct = (delta[-1]>0) #正确与否
    RT = i # 反应时
        
    return correct, RT, delta # 返回正确与否,反应时,整个证据积累的过程

现在我们可以利用这个函数来同时进行多次模拟了,让我们模拟20个试次并看看结果怎么样吧:

nTrial = 20 # trial number
for i in range(nTrial):
    _,_,delta = ddm1(D=10, f=0.55, B=40)
    plt.plot(delta)
plt.axhline(B, color='k', label='Decision boundary')
plt.xlabel('# of frames (reaction time)')
plt.ylabel('Accumulated evidence')

我们可以看到,大多数试次的感觉证据在以不同的速度不断上升,这是一个简单的随机游走过程,我们可以进一步分析当证据到达决策边界时的反应时间:

from seaborn import displot, histplot
from scipy.stats import gamma

nTrial = 1000 # 试次数

RT = np.empty(nTrial)

for i in range(nTrial): # 循环多个试次
    _,RT[i],_ = ddm1(D=10, f=0.55, B=40)
    
# 我们可视化出反应时的分布
#displot(RT, hist=True, kde=True)
from seaborn import displot, histplot
plt.figure(figsize=(4,4))
histplot(RT, kde=True)
plt.xlabel('# of frames(reaction time)')
plt.ylabel('Count')

我们可以发现,模拟出的反应时服从一个Gamma分布,这与认知心理学中已有的关于反应时的发现一致。

最后更新于8个月前