PyTorch强化学习——马尔科夫链

451 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

马尔科夫链概念

马尔可夫链描述了一系列符合马尔可夫性质的事件。它由一组可能的状态 S={s0,s1,...,sm}S = \{s_0, s_1, ..., s_m\} 和转移矩阵 T(s,s)T(s, s') 定义,转移矩阵由状态 ss 转换为状态 ss' 的概率组成。马尔可夫性质是指,给定当前状态,该过程的未来状态在条件上独立于过去状态,换句话说,在 t+1t + 1 时的状态仅取决于在 tt 时的状态。我们以 studysleep 的过程为例,并基于 s0(study)s_0(study)s1(sleep)s_1(sleep) 两个状态创建马尔可夫链。假设我们有以下转移矩阵:

马尔科夫链

接下来,我们学习如何计算 kk 个时间步后的转移矩阵,以及在给定状态的初始分布的情况下计算 kk 个时间步后的状态分布,当状态的初始分布为 [0.8,0.2][0.8, 0.2] 时,意味着该过程有 80% 的机会从 study 开始,有 20% 的机会从 sleep 开始。

创建马尔科夫链

本节中,我们将使用 PyTorch 创建马尔可夫链并对其进行分析。 导入相关库并定义转移矩阵:

import torch
T = torch.tensor([[0.4, 0.6], [0.8, 0.2]])

计算 kk 个时间步后的转移概率,以 kk 分别等于 25102025 为例:

T_2 = torch.matrix_power(T, 2)
T_5 = torch.matrix_power(T, 5)
T_10 = torch.matrix_power(T, 10)
T_20 = torch.matrix_power(T, 20)
T_25 = torch.matrix_power(T, 25)

定义具有两个状态的初始状态分布,并计算 kk 等于 125102025 个时间步之后的状态分布:

v = torch.Tensor([[0.8, 0.2]])

v_1 = torch.matmul(v, T)
v_2 = torch.matmul(v, T_2)
v_5 = torch.matmul(v, T_5)
v_10 = torch.matmul(v, T_10)
v_20 = torch.matmul(v, T_20)
v_25 = torch.matmul(v, T_25)

计算 kk 个时间步之后的转移概率,就是计算转移矩阵的第 kk 次幂,我们可以打印输出:

print("Transition probability after 2 steps:\n{}".format(T_2))
print("Transition probability after 5 steps:\n{}".format(T_5))
print("Transition probability after 10 steps:\n{}".format(T_10))
print("Transition probability after 20 steps:\n{}".format(T_20))
print("Transition probability after 25 steps:\n{}".format(T_25))

输出结果如下,可以看到,大约经过 10 个时间步,转移概率就会收敛。这意味着,无论此时状态如何,它都具有相同的转换概率:

Transition probability after 2 steps:
tensor([[0.6400, 0.3600],
        [0.4800, 0.5200]])
Transition probability after 5 steps:
tensor([[0.5670, 0.4330],
        [0.5773, 0.4227]])
Transition probability after 10 steps:
tensor([[0.5715, 0.4285],
        [0.5714, 0.4286]])
Transition probability after 20 steps:
tensor([[0.5714, 0.4286],
        [0.5714, 0.4286]])
Transition probability after 25 steps:
tensor([[0.5714, 0.4286],
        [0.5714, 0.4286]])

接下来,我们打印计算的 kk 等于 125102025 个时间步之后的状态分布,即初始状态分布与转移矩阵的乘积:

print("Distribution of states after 1 step:\n{}".format(v_1))
print("Distribution of states after 2 step:\n{}".format(v_2))
print("Distribution of states after 5 step:\n{}".format(v_5))
print("Distribution of states after 10 step:\n{}".format(v_10))
print("Distribution of states after 20 step:\n{}".format(v_20))
print("Distribution of states after 25 step:\n{}".format(v_25))

输出结果如下所示,可以看到,大约经过 10 个时间步,状态分布收敛。也就是说,在之后的时间步中,处于 s0s_0 的概率 (57.14%) 和处于 s1s_1 的概率 (42.86%) 保持不变:

Distribution of states after 1 step:
tensor([[0.4800, 0.5200]])
Distribution of states after 2 step:
tensor([[0.6080, 0.3920]])
Distribution of states after 5 step:
tensor([[0.5691, 0.4309]])
Distribution of states after 10 step:
tensor([[0.5715, 0.4285]])
Distribution of states after 20 step:
tensor([[0.5714, 0.4286]])
Distribution of states after 25 step:
tensor([[0.5714, 0.4286]])

从初始分布 [0.80.2][0.8,0.2] 开始,一次转换后的状态分布变为 [0.480.52][0.48,0.52],可以使用下图说明计算的详细过程:

状态分布

在下一次迭代之后,状态分布变为 [0.5920.408][0.592,0.408],如下图所示:

状态分布

随着时间步的增加,状态分布达到平衡状态。实际上,无论从何种初始状态开始,状态分布都将收敛到 [0.57140.4286][0.5714,0.4286]。我们可以使用其他初始分布进行测试,例如 [0.30.7][0.3,0.7][10][1,0] 等。10 个时间步后,分布都将转换为 [0.57140.4286][0.5714,0.4286]

马尔可夫链不一定会收敛,特别是当它包含瞬态时。但是,如果它确实可以收敛,则无论初始分布如何,它都将达到相同的平衡状态。