强化学习方法

# Deep Reinforcement Learning

Introduction

机器学习的最终目标是学习一个function用于我们的tasks,强化学习是机器学习的一个分支,去深度学习不同,强化学习的训练机制是要与环境交互,并且是以一个孩子的身份从自己以往的经验去学习。

以上是我们的强化学习学习图,Policy是我们要学习的function with parameter,用\(\pi_{\theta}\)表示,我们的输入是observation \(o\), 以及输出 action \(a\),其中action作用于环境中会有一个函数判断我们的reward \(r\)。对于我们的每一组实验,我们在不同时间段有不同的观测和动作,其中我们定义一组实验(游戏)为trajectory \(\tau = \left\{s_1, a_1, s_2, a_2, \cdots, s_T, a_T\right\}\),对于\(\tau\),我们可以定义其概率

\[\begin{aligned} &p_\theta(\tau) =p\left(s_1\right) p_\theta\left(a_1 \mid s_1\right) p\left(s_2 \mid s_1, a_1\right) p_\theta\left(a_2 \mid s_2\right) p\left(s_3 \mid s_2, a_2\right) \cdots \end{aligned} \\ =p\left(s_1\right) \prod_{t-1} p_\theta\left(a_t \mid s_t\right) p\left(s_{t+1} \mid s_t, a_t\right) \]

并且,对于每一组 \(\tau\),我们定义最终的Reward \(R(\tau) =\sum_t^T r_t\),定义其均值

\[\bar{R}_\theta=\sum R(\tau) p_\theta(\tau) =E_{\tau \sim p_\theta(\tau)}[R(\tau)] \]

所以整个学习的目标找到最佳的\(\theta^*\)

\[\theta^*=\arg \max _\theta \bar{R}_\theta \]

那么现在问题就变成了我们怎么去优化得到最佳的\(\theta\)

Policy Gradient

我们根据\(\bar{R}_{\theta}\)的梯度优化模型参数

\[\nabla \bar{R}_\theta=\sum_\tau R(\tau) \nabla p_\theta(\tau)=\sum_\tau R(\tau) p_\theta(\tau) \frac{\nabla p_\theta(\tau)}{p_\theta(\tau)} \\ =\sum_\tau R(\tau) p_\theta(\tau) \nabla \log p_\theta(\tau) = E_{\tau \sim p_\theta(\tau)}\left[R(\tau) \nabla \log _\theta(\tau)\right] \\ \approx \frac{1}{N} \sum_{n=1} R\left(\tau^n\right) \nabla \log p_\theta\left(\tau^n\right) \\ =\frac{1}{N} \sum_{n=1}^N \sum_{t=1}^{T_n} R\left(\tau^n\right) \nabla \log p_\theta\left(a_t^n \mid s_t^n\right) \]

之后我们通过 \(\nabla \bar{R}_{\theta}\)去优化参数

\[\theta \leftarrow \theta+\eta \nabla \bar{R}_\theta \]

Add a Baseline

如果当 \(R(\tau^n)\)总是是正的,由于我们计算的\(\bar{R}_{\theta}\)是用采样的,由于某些行为被采样的概率是很小的,然后 \(r\)又是正的,所以会导致容易采样到的action的概率越大,所以我们要加一个baseline或者理解为一个bias,我们在优化的时候使用这个方法

\[\nabla \bar{R}_\theta \approx \frac{1}{N} \sum_{n=1}^N \sum_{t=1}^{i n}\left(R\left(\tau^n\right) {-b}\right) \nabla \log p_\theta\left(a_t^n \mid s_t^n\right) \]

Assign Suitable Credit

由于上式中,在相同的\(\tau\)中的每一个action中都有相同的 \(r\),这并非是公平的,因为其实每一个action的好坏其实是不同,而且一个动作的收益只能从后面的结果中才能体现出来,并且随着时间戳越长,\(r\)的权重应该是越小的,所以我们做出如下改变

\[\nabla \bar{R}_\theta \approx \frac{1}{N} \sum_{n=1}^N \sum_{t=1}^{i n}\left(\sum_{t^{\prime}=t}^{T_n} \gamma^{t^{\prime}-t} r_{t^{\prime}}^n {-b}\right) \nabla \log p_\theta\left(a_t^n \mid s_t^n\right) \\ \gamma < 1 \]

并且,我们把上式的 \(\left(\sum_{t^{\prime}=t}^{T_n} \gamma^{t^{\prime}-t} r_{t^{\prime}}^n {-b}\right)\)称为 Advantage Function,用于评价我们\((s_t,a_t)\)下,\(a_t\)相较于其他行为action更好的的程度

Proximal Policy Optimization

Importance Sampling

由于如果当我们对p(x)并不了解的时候,我们可以使用另一个分布\(q(x)\)去模拟\(p(x)\),如下证明

\[E_{x \sim p}[f(x)] = \int f(x) p(x) d x=\int f(x) \frac{p(x)}{q(x)} q(x) d x=E_{x \sim q}\left[f(x) \frac{p(x)}{q(x)}\right ]. \]

我们在使用分布\(q\)去计算 均值的时候,需要乘上\(\frac {p(x)} {q(x)}作修正\)

但是分布\(p(x)\)\(q(x)\)不能差太多,因为这样做出的模拟其实是有弊端的,我们考虑两个分布的方差

\[\begin{aligned} &\operatorname{Var}_{x \sim p}[f(x)]=E_{x \sim p}\left[f(x)^2\right]-\left(E_{x \sim p}[f(x)]\right)^2 \\ &\begin{aligned} \operatorname{Var}_{x \sim q}\left[f(x) \frac{p(x)}{q(x)}\right] &=E_{x \sim q}\left[\left(f(x) \frac{p(x)}{q(x)}\right)^2\right]-\left(E_{x \sim q}\left[f(x) \frac{p(x)}{q(x)}\right]\right)^2 \\ &=E_{x \sim p}\left[f(x)^2 \frac{p(x)}{q(x)}\right]-\left(E_{x \sim p}[f(x)]\right)^2 \end{aligned} \end{aligned} \]

我们使用Importance Sampling的思路用于我们的训练Policy的过程,我们先介绍On-policy和Off-policy的直观概念

  • On-policy:意味着直接和环境做互动,从自己以往的经验中学习
  • Off-policy:表示让别人和环境做互动,从别人的行为中学习

那么使用Off-policy时,我们使用\(\pi_{\theta}\),去收集数据\(\tau\)。当\(\theta\)被更新时,我们可以多次使用样本数据,使用的方法就是使用 \(\pi_{\theta^{\prime}}\)去训练\(\theta\),使用如下的函数,并且使用之前提到的梯度函数

\[\nabla \bar{R}_\theta={E_{\tau \sim p_{\theta^{\prime}}(\tau)}}\left[\frac{p_\theta(\tau)}{p_{\theta^{\prime}}(\tau)} R(\tau) \nabla \log p_\theta(\tau)\right] \quad (1)\\ = E_{\left(s_t, a_t\right) \sim \pi_{\theta^{\prime}}}\left[\frac{P_\theta\left(s_t, a_t\right)}{P_{\theta^{\prime}}\left(s_t, a_t\right)} A^\theta\left(s_t, a_t\right) \nabla \log p_\theta\left(a_t^n \mid s_t^n\right)\right] \quad (2)\\ = E_{\left(s_t, a_t\right) \sim \pi_{\theta^{\prime}}}\left[\frac{p_\theta\left(a_t \mid s_t\right)}{p_{\theta^{\prime}}\left(a_t \mid s_t\right)} \frac{p_\theta\left(s_t\right)}{p_{\theta^{\prime}}\left(s_t\right)} A^{\theta^{\prime}}\left(s_t, a_t\right) \nabla \log p_\theta\left(a_t^n \mid s_t^n\right)\right] \quad (3) \\ =E_{\left(s_t, a_t\right) \sim \pi_{\theta^{\prime}}}\left[\frac{p_\theta\left(a_t \mid s_t\right)}{p_{\theta^{\prime}}\left(a_t \mid s_t\right)} A^{\theta^{\prime}}\left(s_t, a_t\right) \nabla \log p_\theta\left(a_t^n \mid s_t^n\right)\right] \quad (4) \]

\((1) \rightarrow (2)\)使用了之前提到的Policy Gradient,\((2) \rightarrow (3)\)使用了条件概率优化,但是由于$\frac{p_\theta\left(s_t\right)}{p_{\theta^{\prime}}\left(s_t\right)} \(计算方面的难度很大,所以我们可以将其忽略去计算\)(4)$

那么,我们根据 \(\theta^{\prime}\)去优化的方法\(\theta\)的目标函数如下

\[J^{\theta^{\prime}}(\theta)=E_{\left(s_t, a_t\right) \sim \pi_{\theta^{\prime}}}\left[\frac{p_\theta\left(a_t \mid s_t\right)}{p_{\theta^{\prime}}\left(a_t \mid s_t\right)} A^{\theta^{\prime}}\left(s_t, a_t\right)\right] \]

同样的,我们要保证 \(p_{\theta}(a_t \mid s_t)\)\(q_{\theta^{\prime}}(a_t \mid s_t)\) 差距不能太大所以我们要使用PPO方法,我们使用的目标函数如下

\[J_{P P O}^{\theta^{\prime}}(\theta)=J^{\theta^{\prime}}(\theta)-\beta K L\left(\theta, \theta^{\prime}\right) \\ J^{\theta^{\prime}}(\theta) =E_{\left(s_t, a_t\right) \sim \pi_{\theta^{\prime}}}\left[\frac{p_\theta\left(a_t \mid s_t\right)}{p_{\theta^{\prime}}\left(a_t \mid s_t\right)} A^{\theta^{\prime}}\left(s_t, a_t\right)\right] \]

除了PPO之外,我们还有一个限制 \(KL({\theta},{\theta^{\prime}})\)的方法去优化,TRPO(Trust Region Policy Optimization),公式如下:

\[J_{T R P O}^{\theta^{\prime}}(\theta)=E_{\left(s_t, a_t\right) \sim \pi_{\theta^{\prime}}}\left[\frac{p_\theta\left(a_t \mid s_t\right)}{p_{\theta^{\prime}}\left(a_t \mid s_t\right)} A^{\theta^{\prime}}\left(s_t, a_t\right)\right] \\ \quad KL({\theta},{\theta^{\prime}}) < {\delta} \]

我们写出PPO算法如下:

  1. 初始化 \(\theta\) 作为模型参数
  2. 使用 \(\theta^k\)去环境进行交互,并收集数据\({s_t, a_t}\),并且计算 \(A^{\theta^k}(s_t, a_t)\)
  3. 优化\(\theta\)通过 off-policy做gradient ascent

\[J_{P P O}^{\theta^k}(\theta)=J^{\theta^k}(\theta)-\beta K L\left(\theta, \theta^k\right) \]

然而在实际训练时,\(\beta\)是超参数,所以我们要通过实际情况去调节

  1. 如果\(KL(\theta, {\theta}^k)>KL_{max}\),增大 \(\beta\),如果 \(KL(\theta,\theta^k)<KL_{min}\),减小 \(\beta\)

由于上述算法,我们还需要计算 KL散度,这个过程可以使用PPO2进行化简

\[J_{P P O 2}^{\theta^k}(\theta) \approx \sum_{\left(s_t, a_t\right)} \min \left(\frac{p_\theta\left(a_t \mid s_t\right)}{p_{\theta^k}\left(a_t \mid s_t\right)} A^{\theta^k}\left(s_t, a_t\right)\right., \\ \left.\operatorname{clip}\left(\frac{p_\theta\left(a_t \mid s_t\right)}{p_{\theta^k}\left(a_t \mid s_t\right)}, 1-\varepsilon, 1+\varepsilon\right) A^{\theta^k}\left(s_t, a_t\right)\right) \]

Q-Learning

Q-learning 和之前提到的训练policy的策略不同,它训练的是一个critic,批评家。critic的作用是去评判一个action的好坏,也就是给出actor \(\pi\),critic给出 \(V^{\pi}(s)\)(代表了在状态 \(s\)下,累计的reward的预期值),也就是说critic评价是actor,首先 \(V^{\pi}\)是一个网络,那么我们接下来介绍怎么得到\(V^{\pi}\)

Monte-Carlo(MC)based approach

MC方法就是计算累计reward的方法,需要在episode结束后计算,我们要让模型去拟合 \(G\)

Temporal-difference (TD)approach

由于我们使用的MC方法要将游戏结束后,我们才能得到我们的累计reward,但是如果有个游戏特别长的话,MC方法是不合适的,所以可以使用TD方法,它基于的公式是 \(V^\pi\left(s_t\right)=V^\pi\left(s_{t+1}\right)+r_t\)

MC v.s. TD

由于MC的方法需要拟合的 \(G_a\)是比较大的reward,而TD需要拟合的小的每一步的reward,所以会导致MC的方法会产生较大的variance,这会导致过拟合。但是TD的方法的准确率较低,目前的话比较常用的依旧是TD的方法

Other

计算 \(Q^{\pi}(s,a)\),计算对于 policy \(\pi\),在当前状态 \(s\)下给出action \(a\)后的累计奖励预期值

以上我们说的 \(Q^{\pi}\)是用来评估 \(\pi\)的好坏,但是接下来我们要说的是运用学习出来的\(Q^{\pi}\)去训练一个更好的 \(\pi\),我们给出以下结论: 如果对于一个 \(\pi\),我们学习到了其critic \(Q^{\pi}\),那么我们可以找到更好的 \(\pi^{\prime }\)

Q-Learning

我们承接之前所说的,我们要用我们训练出来的 critic \(Q^{\pi}\)去学习一个更好的 \(\pi^{\prime}\),定义以上提到的更好,我们给出下列表示

\[\pi^{\prime}(s)=\arg \max _a Q^\pi(s, a) \]

证明: \(\pi^{\prime}\)\(\pi\)更好的,即证 \(V^{\pi}(s) > V^{\pi^{\prime}}(s)\)

\[\pi^{\prime} = \operatorname{argmax}Q^{\pi}(s,a) \\ V^{\pi}(s) = Q(s,\pi(s)) \leq \operatorname{max}\limits_a Q^{\pi}(s,a) = Q^{\pi} (s, \pi^{\prime}(s)) \\ \]

根据上式,我们从 \(Q^{\pi}(s,\pi^{\prime})\)推导到 \(V^{\pi^{\prime}(s)}\)

\[\begin{aligned} &V^\pi(s) \leq Q^\pi\left(s, \pi^{\prime}(s)\right) \\ &=E\left[r_{t+1}+V^\pi\left(s_{t+1}\right) \mid s_t=s, a_t=\pi^{\prime}\left(s_t\right)\right] \\ &\leq E\left[r_{t+1}+Q^\pi\left(s_{t+1}, \pi^{\prime}\left(s_{t+1}\right)\right) \mid s_t=s, a_t=\pi^{\prime}\left(s_t\right)\right] \\ &=E\left[r_{t+1}+r_{t+2}+V^\pi\left(s_{t+2}\right) \mid \ldots\right] \\ &\leq E\left[r_{t+1}+r_{t+2}+Q^\pi\left(s_{t+2}, \pi^{\prime}\left(s_{t+2}\right)\right) \mid \ldots\right] \ldots \leq V^{\pi^{\prime}}(s) \end{aligned} \]

Target Network

固定下面的\(Q^{\pi}\)去得到我们的target \(r_t+Q^{\pi}(s_{t+1},\pi(s_{t+1}))\),我们训练上面模型 \(Q^{\pi}\)的参数,经过训练多次之后把固定的网络的参数更新,进行重新训练,要注意的是,上下两个模型的输出是不一样的

Exploration

由于我们使用Q函数去决定采取的行为时,我们的选择策略是 \(a=\arg \max _a Q(s, a)\),这并不利于数据采样,我们总是会选择我们觉得会好的行为,但是实际上可能会有 \(a\)比起我们认为的最好的\(a^{\prime}\)最佳

有两个方法解决这个问题

  • Epsilon Greedy

我们采取action依据这个公式 ,\(a=\left\{\begin{array}{cl} \arg \max _a Q(s, a) & \text { with probability } 1-\varepsilon \\ \text { raindom } & \text { otherwise } \end{array}\right.\)

上面的 \(\epsilon\)会随着时间变小,这个是非常符合直观理解的,因为最开始我们跟倾向于让模型选择一些其他结果,在训练一段时间后在选择自己认为的最好的结果,这是符合经验积累的过程

  • Boltzmann Exploration

\[P(a \mid s)=\frac{\exp (Q(s, a))}{\sum_a \exp (Q(s, a))} \]

使用上述概率,去使用最好的action,为什么这种方法会work呢,因为在训练的初期,我们的\(Q\)函数对于一种state采取的action的结果倾向于相同的,所以使用上式相当于使这种发布更为平均,使在训练早期呈现出一种随机采样的结果

Replay Buffer

重复使用交互样本,将交互样本存进Buffer中,这有点Off-policy的味道,因为交互完的样本用于模型学习之后,后面还会用于模型学习,这就是新的模型学习旧的模型的样本,是学习它人的经验。这会让我们的学习样本更diverse,并且在一定程度上减小模型训练的时间消耗,因为训练模型用的时间大部分是在与环境的交互中

Typical Q-Learning Algorithm

  1. 初始化
  2. 收集训练材料
  3. 模型拟合训练材料
  4. 更新目标 \(Q\)后迭代 2-4操作

Continuous Actions

我们上述提到的action是离散的,也就是说他是有限值去收集\((s_t,a_t,r_t,s_{t+1})\)的训练材料,但是如果我们的action是连续的,比如说射击角度这样的值得话,我们无法穷举所有得action,首先我们回到最初得假设,我们使用\(Q\)函数得目的是为了得到\(a\)满足

\[a = arg \operatorname{max}Q(s,a) \]

我们先给出几个比较容易思考的到的解决方案

  • Approximate Sampling

我们不需要去找到确定的\(a\),使得满足最大的奖励,我们可以通过采样多组实验,从中选择最大的\(a\)去执行,这样的\(a\)可能是近似于最大的行为,当时这会增大计算量,并且不一定能找到好的\(a\)

  • Optimization

我们将\(a\)看作是一个我们要训练的参数,使用优化算法比如梯度上升去找到最好的\(a\)去最大化\(Q(s,a)\),但是每一次找一个\(a\)还要调用优化的方法去训练,这无疑是非常耗时的行为

基于上面两个方法的不好的地方,我们设计出第三种解决方法

我们通过专门设计\(Q^{\pi}\)的结构,得到了三个值\(u(s),\Sigma(s),V(s)\),分别是向量,矩阵和标量,这里有个假设很重要,我们得出的\(\Sigma\)是正定的。我们让得出的三个数做交互,与action做运算。需要注意的是,我们的三个值是根据状态得出的,我们最大化下面的\(Q(s,a)\)

\[Q(s, a)=-(a-\mu(s))^T \Sigma(s)(a-\mu(s))+V(s) \\ u(s) = arg \operatorname{max}Q(s,a) \]

由于我们要最大化\(Q\),由于\(\Sigma\)是正定的,所以我们我们就要最小化\((a-\mu(s))^T \Sigma(s)(a-\mu(s))\),那么最小化的方法就是,使\(a= u(s)\),这样我们就找到的最佳的\(a\)

Actor-Critic (A3C)

我们回到之前提到的Policy Gradient的 表达式

\[\nabla \bar{R}_\theta \approx \frac{1}{N} \sum_{n=1}^N \sum_{t=1}^{i n}\left(\sum_{t^{\prime}=t}^{T_n} \gamma^{t^{\prime}-t} r_{t^{\prime}}^n {-b}\right) \nabla \log p_\theta\left(a_t^n \mid s_t^n\right) \\ \gamma < 1 \]

我们将上式的\(\sum_{t^{\prime}=t}^{T_n} \gamma^{t^{\prime}-t} r_{t^{\prime}}^n {-b}\)定义为 \(G_t^n\),它是通过模型和环境交互得来的,回顾Q-Learning中的两种函数

  • 状态值函数 \(V^{\pi}(s)\),给定状态\(s\),在\(\pi\)下的累计预期奖励
  • 转台行为值函数\(Q^{\pi}(s,a)\),给定actor \(\pi\),在状态\(s\)下做出\(a\)的行为,之后的累计预期奖励

由于我们在Policy Gradient中要计算Advantage Function,由于\(G^n_t\)的值代表的含义也是目前行为的奖励值,那么一种很natural的想法就是把我们的\(G^n_t\)通过Q-Learning中的函数去计算,而\(b\)的值作为一种基线可以用\(V^{\pi}\)来代替

\[E\left[G_t^n\right]=Q^{\pi_\theta}\left(s_t^n, a_t^n\right) \\ b = V^{\pi_{\theta}}(s_t^{\theta}) \]

所以我们的Advantage Function就变为了\(Q^\pi\left(s_t^n, a_t^n\right)-V^\pi\left(s_t^n\right)\),那么此时我们要预测两个网络\(Q^{\pi}(s_t^n)-V^{\pi}(s_t^n)\),由于实际上\(Q^{\pi}(s^n_t,a^n_t)\)实际上是一种期望值,

\[Q^\pi\left(s_t^n, a_t^n\right)=E\left[r_t^n+V^\pi\left(s_{t+1}^n\right)\right] \]

由于我们在实际过程中,我们是不计算这种均值的,改为下列式子

\[Q^\pi\left(s_t^n, a_t^n\right)=r_t^n+V^\pi\left(s_{t+1}^n\right) \]

于是我们可以把最开始训练两个网络的Advantage Function变为下式

\[r_t^n+V^\pi\left(s_{t+1}^n\right)-V^\pi\left(s_t^n\right) \]

这样我们就只用训练一个网络,但是我们也因此引入了一个随机值 \(r^n_t\),但是我们可以在每一步都得出相应的值

Advantage Actor-Critic

在训练模型的过程中,\(\pi(s)\)\(V^{\pi}\)的参数可以共享,并且使用输出熵作为regularization,可以让不同的actor尝试不同的action

Asynchronous

Pathwise Derivative Policy Gradient

使用actor和critic结合的方法,直接训练actor和critic

原来的将s输入进\(\pi\)然后得到\(a\),将这个\(a\)\(s\)再重新输入进\(Q^{\pi}\),算法解释如下

  1. 初始化 两个\(Q\)函数,actor \(\pi\),和目标 \(\hat{\pi}\)
  2. 收集交互样本 \((s_t,\pi(s_t),r_t,s_{t+1})\),储存进buffer中
  3. 使用前面的交互样本出\((s_i,a_i,r_i,s_{i+1})\) 拟合\(Q^{\pi}\)\(y = r_i+\hat{Q(s_{i+1}),\hat{\pi}(s_{i+1})}\),通过几组交互数据更新\(Q^{\pi}\)参数,更新\(\pi\)的参数去 \(\operatorname{maxmize}Q(s_i,\pi(s_i))\)
  4. \(\hat{Q}=Q, \hat{\pi}=\pi\),迭代2-4步

Sparse Reward

当我们使用强化学习去训练网络时,在外面训练初期,模型的能力是很低的,这导致获得奖励可能是十分稀少的,那么Sparse Reward的情况下,如何训练我们的模型。

Reward Shaping

通过人工设计reward,来调整这个issue,这是很合理的一件事情。比如射击游戏中,原本是击杀敌人能够得分,但是由于在训练初期,机器做到这种这个行为是很困难的。但是我们可以设计一些其他的reward来平衡,比如说开枪reward,存活之类的reward。

Curiosity

增加模型的好奇心,让模型敢于去冒险

可以发现我们重新有训练了两个网络,网络1的作用是接收到\(a_t\)\(\phi(s_t)\)之后输出我们预测的\(\hat{\phi}(s_{t+1})\),如果\(\hat{\phi}(s_{t+1})\)\(\phi(s_{t+1})\)的差别很大,那么我们输出一个新的reward很大。也就是说我们的新的reward和根据网络一的预测有关,如果网络一越不能预测出那个结果,那么奖励越大。那么网络二的作用是什么呢,这个是由\(a_t\)\(\hat{a_t}\)的拟合网络,通过输入\(\phi(s_t)\)\(\phi(s_{t+1})\),来预测\(\hat{a_t}\)。网络二的训练和Feature Ext有关,或者说Feature Ext的作用就是用来过滤掉那些无关紧要的\(a_t\)带来的冒险reward。

Curriculum Learning

上面提到一开始我们的模型能力去做我们的task时,其能力最开始是不够的。那么就像我们上课一样,如果课程太难,那么我们先打好基础从简单开始。Curriculum Learning就是让模型从简单的任务还是学起,逐渐增加难度和挑战。但是机器设计课程也是需要技巧的,有一种常用的方法是Reverse Curriculum Generation,关于这个方法需要搜索一下相关资料

Hierarchical RL

通过设计层级关系,上层下达任务给下层网络,如果下层执行不了,那么上层就会收到惩罚,这个就让上层指定的task是让下层能够学习的。那么强化学习用这个方法也是为了让模型能够从简单的task坐起,并且简单的task具体由上层模型来做。

posted @ 2022-09-25 15:03  1zeryu  阅读(444)  评论(0)    收藏  举报