强化学习之:价值学习Value-Based Learning

news2024/12/23 16:49:26

文章目录

参考内容

  • 参考视频:不愧是王树森教授!6小时让我搞定了【深度强化学习完整版】我不信还有人学不明白!

  • 强化学习基础

动作价值函数(Action-value Function)

  • 这部分是对价值函数的回顾,在 强化学习基础 中进行了详细的讲解,看不懂这篇文章的先去简单翻一下
    在这里插入图片描述

  • U t U_t Ut 代表的是 discounted return,是从当前时刻 t t t 到游戏结束得到的 reward 的折算总和,我们的目标是在游戏结束的时候,希望 U t U_t Ut 能够越大越好

  • U t U_t Ut 中的每个 R i R_i Ri 都取决于其所处的环境状态 S i S_i Si 和采取的行为 A i A_i Ai,因此 U t U_t Ut 直接与 R t , R t + 1 , . . . R_t, R_{t+1},... Rt,Rt+1,... 相关,也就是直接与 A t , A t + 1 , . . . A_t, A_{t+1},... At,At+1,... 以及 S t , S t + 1 , . . . S_t, S_{t+1},... St,St+1,... 相关

  • 强化学习过程中有两个部分会引入随机性:

    1. agent 采取 action 的时候是根据 策略函数(分布) π \pi π 进行随机抽样得到的
    2. 是 环境产生 state 的时候是根据 状态转移函数(分布) p ( s ′ , s , a ) p(s',s,a) p(s,s,a) 随机抽样得到的
  • 因为在每个 actionstate 的产生过程中都会引入随机性,就导致了每个 R i R_i Ri 都是随机变量,而这也进而导致了 U t U_t Ut 是个随机变量

  • U t U_t Ut 的值可以反映出从 t t t 直到未来游戏结束的 reward 总和

  • 而由于 s t , a t s_t, a_t st,at 是在 t t t 时刻可以观察到的,因此对于 t t t 时刻往后的 a i a_i ai s i s_i si 我们通过 期望 的计算来消除随机性: Q π ( s t , a t ) = E [ U t ∣ S t = s t , A t = a t ] Q_{\pi}(s_t, a_t)=\mathbb{E}[U_t|S_t=s_t, A_t=a_t] Qπ(st,at)=E[UtSt=st,At=at]

  • 因此 Q π ( s t , a t ) Q_{\pi}(s_t, a_t) Qπ(st,at) 只与 π , s t , a t \pi, s_t, a_t π,st,at 这三个部分有关:

    • π \pi π 是当前 agent 采用的 策略,也可以看做是个概率分布
    • s t s_t st 是在 t t t 时刻的环境状态
    • a t a_t at 是在 t t t 时刻,agent 面对环境 s t s_t st策略 中随机抽样获得的 action
  • 当然, Q π ( s t , a t ) Q_{\pi}(s_t, a_t) Qπ(st,at) 的值越大,代表在当前环境状态 s t s_t st 下,按照当前使用的 π \pi π 策略 采样得到的 action a t a_t at 越正确。但 策略 有很多种,未必当前这种就是最好的,因此如果在所有可选的 策略 中得到一个使 Q π ( s t , a t ) Q_{\pi}(s_t, a_t) Qπ(st,at) 最大的值,即 Q ∗ ( s t , a t ) = max ⁡ π Q π ( s t , a t ) Q^{*}(s_t, a_t)=\max_{\pi}Q_{\pi}(s_t, a_t) Q(st,at)=πmaxQπ(st,at)

  • Q ∗ ( s t , a t ) Q^{*}(s_t, a_t) Q(st,at) 终于摆脱了策略 π \pi π 的影响,能够代表在当前环境状态 s t s_t st 的情况下,无论你采用何种 策略,采取 a t a_t at 在未来得到的最大的 action 收益的总和就是 Q ∗ ( s t , a t ) Q^{*}(s_t, a_t) Q(st,at)

  • 然而 a t a_t at 可能取值的范围是 agent 的所有动作集合,例如马里奥游戏中的 up, right, left 这三种 action 构成了马里奥所有的动作。那么当在 t t t 时刻马里奥面对环境 s t s_t st 时按照 π \pi π 进行抽样得到了 a t → u p a_t \rightarrow up atup,马里奥应该向上跳,此刻我们可以用 Q ∗ Q^{*} Q 来评估出 向上跳 这个动作能够在未来获得的最大 return

  • 我们这里完全可以不采取 随机抽样 的方式得到 a t a_t at ,而是遍历所有的 a t a_t at 从而获得在当前 t t t 时刻对于所有 a t 1 , . . . a t n a_{t1},...a_{tn} at1,...atn 中能够获得最大 Q ∗ Q^{*} Q 分数的 a t a_t at 作为当前 t t t 时刻的 action,比如 t t t 时刻:

    • up 行为的 Q ∗ ( s t , u p ) = 5000 Q^{*}(s_t, up)=5000 Q(st,up)=5000
    • right 行为的 Q ∗ ( s t , r i g h t ) = 3000 Q^{*}(s_t, right)=3000 Q(st,right)=3000
    • left 行为的 Q ∗ ( s t , l e f t ) = 1000 Q^{*}(s_t, left)=1000 Q(st,left)=1000
  • 那么毫无疑问,我们应该让 agent 选择 up 作为 t t t 时刻的 action

深度强化学习(DQN)

学习目标(Goal)

在这里插入图片描述

  • 在游戏结束时获得的总收益 total reward 越大越好
  • 在上个部分我们已经说明了如何用 Q ∗ Q^{*} Q 描述 agent t t t 时刻面对环境 s t s_t st 时采取agent 所有可能的action从而选取最大的 Q ∗ Q^{*} Q 值,这个过程我们描述成: a ∗ = arg max ⁡ a Q ∗ ( s t , a ) a^{*}=\argmax_{a}Q^{*}(s_t, a) a=aargmaxQ(st,a)
  • a ∗ a^{*} a 是在 t t t 时刻面对 s t s_t st 能够选取的最好的 action
  • 下面对几点进行重点的说明:
    • Q ∗ Q^{*} Q 虽然能够帮我们在 t t t 时刻确定最好的行为 a ∗ a^{*} a,但得出这个结论并不代表着这个 a ∗ a^{*} a 完全就是最好选择,而是 期望,证明 a ∗ a^{*} a 这种行为从概率的角度来看是最好的选择,但未来啥样谁也不能精确描述

    • 基于 动作价值函数 的强化学习求解思路就是帮我们用神经网络模拟一个强大的 Q ∗ Q^{*} Q 函数,从而在每个时刻 i i i 帮我们决定采取最好的 a ∗ a^{*} a 作为 action

    • 如果我们想象现实的情况,这似乎不可能,因为 Q ∗ Q^{*} Q 函数好像一个先知,它是怎么知道某个 action 在未来的 期望 的?这就好像是一个人告诉你说:“小伙子,你可以选下面三只股票,虽然我不能告诉你他们的具体交易细节,但是我可以告诉你的是,在游戏结束的时候, a 1 a_1 a1 股票会翻 10 10 10 倍, a 2 a_2 a2 3 3 3 倍,而 a 3 a_3 a3 亏钱”

    • 但其实这在一些特定的环境(游戏环境)中是有可能的。比如你把自己看做一个 Q ∗ Q^{*} Q 当你玩一个特定的游戏 100000 100000 100000 局的时候,你其实就变成了先知,因为对于过去大量的数据,你已经知道因果了,而且你玩的局数越多,对于因果的对应关系和发展规律就捕捉的越全面,所以此时如果你指导一个 agent,他觉得你未卜先知,其实只是你通过大量的数据推算了大致的情况。而且你给他提供的建议也并不完全是真正的 期望,而是你根据你自己的已知情况推出的近似真实 期望 的结果。

    • 更通俗讲:

      • 你看似是先知,其实是看了大量的数据,你可以通过大量的数据无限逼近真实的先知,但你永远是个假的先知
      • 你可以根据看过的数据来推算 agent 在当前状态下采取所有行为的 期望(并非真实的 期望,而是你基于过去数据而计算的 期望
      • agent 根据你提供的 期望 作为参考,选择一个当前时刻最好的行为
    • 深度神经网络就是在扮演这个 伪装的先知 的角色。通过大量的数据训练,神经网络似乎在某个时刻 t t t 能够帮 agent 判断每个动作在未来的 期望收益,如果神经网络足够好,那么 期望 的结果就足够准确,agent 就能够足够好。

如何获得尽可能好的 Q ∗ ( s t , a ) → Q^{*}(s_t, a) \rightarrow Q(st,a) 用神经网络通过学习获得

  • Q ( s t , a ; w ) Q(s_t, a; w) Q(st,a;w) 表示神经网络,我们的目标是近似真实情况的 Q ∗ ( s t , a ) Q^{*}(s_t,a) Q(st,a)
    在这里插入图片描述

  • 我们构造一个神经网络,将 state 作为输入,输出是神经网络对于每个 action 的打分,在这个例子中:

    • left 得分为 2000
    • right 得分为 1000
    • up 得分为 3000
  • 那么我们认为马里奥应该采取 up 作为 action

  • 重复这个过程,流程图如下:
    在这里插入图片描述

    • t t t 时刻根据神经网路的结果选择出 a t a_t at 然后环境状态更新为 s t + 1 s_{t+1} st+1 的同时给出 a t a_t at 的奖励 r t r_t rt
    • 神经网络根据 r t , r t + 1 , . . . r_t, r_{t+1},... rt,rt+1,... 进行训练,得到更好的对动作的评估结果一直到游戏结束

时间差分算法(Temporal Difference, TD)算法

  • 我们要训练一个好的神经网络来模拟 Q ∗ ( s t , a ) Q^{*}(s_t, a) Q(st,a) 要用 TD 算法来完成训练
  • 文章下面的思路是:
    • 讲述 TD 算法的核心思想
    • TD 算法的核心思想应用到强化学习的神经网络训练中,从而获得更好的 Q ∗ ( s t , a ) Q^{*}(s_t, a) Q(st,a) 函数近似

TD 算法的核心思想

  • NYC, Atlanta, DC 都是地名
  • 现在有一个时间评估器 Q ( w ) Q(w) Q(w), 它的参数是 w w w,开始它很不准确,但现在我们想训练 Q ( w ) Q(w) Q(w) 使得它能够给出某地到另一地的路程花费时间精确值。所以训练目标是得到一个更好的 Q ( w ) Q(w) Q(w)
  • 为了训练 Q ( w ) Q(w) Q(w) 我们需要在现实世界中通过多次开车的实际测量值来修正 Q ( w ) Q(w) Q(w) 做出的预测结果,这样 Q ( w ) Q(w) Q(w) 的预测才会越来越准确

  • 用一组实际的数值来更详细地描述这个过程:
    在这里插入图片描述
    • 我要驱车从 NYCAtlanta 假设现在 Q ( w ) Q(w) Q(w) 没有进行任何的训练,那么它给出了一个近似瞎猜的评估结果 q = 1000 q=1000 q=1000,即, Q ( w ) Q(w) Q(w) 认为 NYCAtlanta 要花费 1000 m i n 1000min 1000min
    • 但是当我真正开车从 NYCAtlanta 发现真实的距离 y = 860 k m y=860km y=860km
    • 所以我们定义损失函数 L = 1 2 ( q − y ) 2 L=\frac{1}{2}(q-y)^2 L=21(qy)2 (你可以按照自己的喜好定义损失,这里就用最简单的平方差损失),根据损失函数,我们可以得到这趟旅程 Q ( w ) Q(w) Q(w) 的损失值的具体数值是 14 0 2 140^2 1402
    • 然后采用神经网络优化常用的梯度下降算法来更新 Q ( w ) Q(w) Q(w) 中的权重参数 w w w,这样当我下一次用 Q ( w ) Q(w) Q(w) 的时候,它就能够给出比现在更好的结果了。
    • 当我重复这个过程非常多的次数, Q ( w ) Q(w) Q(w) 就会被训练的越来越好
    • 但现在同样面对一个问题:我只要想更新 Q ( w ) Q(w) Q(w) 就必须完成一整趟旅程,这代价也太大了。有没有一种方式能够利用部分的信息来更新参数,从而不浪费任何一点机会呢?
    • 这就是 TD 算法的核心思想了

在这里插入图片描述

  • NYC 开车去 Atlanta 时车抛锚在了 DC,然后修了三天车从 DC 折返回 NYC
  • 假设 Q ( w ) Q(w) Q(w) 只能给出从 NYCAtlanta 的预测值 q n a q_{na} qna 以及从 DCAtalanta 的预测值 q d a q_{da} qda 那么这时候 TD 算法 是如下更新参数的:
    在这里插入图片描述
    • 首先开车开到 DC 的时候一看路程,发现走了 300 m i n 300min 300min 这是真实的观测值

    • 现在模型给出从 DCAtlanta 要花费的预估时间 600 m i n 600min 600min,所以结合 真实的 300 m i n 300min 300min 和第二次预测的值 600 m i n 600min 600min 我们将从 NYCAtlanta 的整体预估结果更新成 900 m i n 900min 900min,这个 900 m i n 900min 900min 就是 TD-target 虽然这个值也是个估测值,但是比开始的 1000 m i n 1000min 1000min 更加可靠在这里插入图片描述

    • 当你越接近 Atlanta 通过 TD-target 的方式获得的值就估计的越准

    • 现在我们的形式化以上的过程:

      • q = 1000 q=1000 q=1000,但是 y t d = 900 y_{td}=900 ytd=900
      • 因此这时候如果依然采用 均方误差 计算 L L L,那么损失值是 L = ( q − y t d ) 2 = 10 0 2 L=(q-y_{td})^2=100^2 L=(qytd)2=1002,可以看到通过这种方式我们并不需要真正到达目的地,通过 部分真实值 + 部分预估值 的方式也能够不断地更新 Q ( w ) Q(w) Q(w) 的参数

TD 算法在 DQN 中的应用

  • 使用 TD 算法的条件是: T N Y C → A T L ≈ T N Y C → D C + T D C → A T L T_{NYC\rightarrow ATL}\approx T_{NYC\rightarrow DC} + T_{DC\rightarrow ATL} TNYCATLTNYCDC+TDCATL
    • 其中 T N Y C → A T L , T D C → A T L T_{NYC\rightarrow ATL}, T_{DC\rightarrow ATL} TNYCATL,TDCATL 是通过同一个模型 Q ( w ) Q(w) Q(w) 估计值,而 T N Y C → D C T_{NYC\rightarrow DC} TNYCDC 是真实的能够确定的值
      在这里插入图片描述
  • DQN 中,我们知道在 t t t 时刻的奖励 r t r_t rt 是环境在 t + 1 t+1 t+1 时刻给出的,因此我们确切地可以知道 r t r_t rt 的值,因此我们构建公式: Q ( s t , a t ; w ) ≈ r t + γ Q ( s t + 1 , a t + 1 ; w ) Q(s_t, a_t; w) \approx r_t + \gamma Q(s_{t+1}, a_{t+1};w) Q(st,at;w)rt+γQ(st+1,at+1;w)
    • Q ( s t , a t ; w ) Q(s_t, a_t; w) Q(st,at;w) 表示从 t t t 时刻往后直到游戏结束时的 return 的期望值,这个值越大代表当前的 a t a_t at 越合理
    • Q ( s t + 1 , a t + 1 ; w ) Q(s_{t+1}, a_{t+1}; w) Q(st+1,at+1;w) 代表从 t + 1 t+1 t+1 时刻往后直到游戏结束时的 return 的期望值,这个值越大代表 t + 1 t+1 t+1 时刻采取的 a t + 1 a_{t+1} at+1 越好
    • 那么这个公式是怎么得到的呢?

Q ( s t , a t ; w ) ≈ r t + γ Q ( s t + 1 , a t + 1 ; w ) Q(s_t, a_t; w) \approx r_t + \gamma Q(s_{t+1}, a_{t+1};w) Q(st,at;w)rt+γQ(st+1,at+1;w) 公式来源

在这里插入图片描述

  • 之前我们推导过: U t = R t + γ R t + 1 + γ 2 R t + 2 + . . . . U_t=R_t+\gamma R_{t+1}+\gamma^2 R_{t+2}+.... Ut=Rt+γRt+1+γ2Rt+2+....
  • 简单地加个括号: U t = R t + γ ( R t + 1 + γ R t + 2 + . . . . ) = R t + γ ( U t + 1 ) U_t=R_t+\gamma (R_{t+1}+\gamma R_{t+2}+....) = R_t+\gamma (U_{t+1}) Ut=Rt+γ(Rt+1+γRt+2+....)=Rt+γ(Ut+1),即: U t = R t + γ U t + 1 U_t= R_t+\gamma U_{t+1} Ut=Rt+γUt+1
  • 又因为我们知道 Q π ( s t , a t ) = E [ U t ∣ s t , a t ] ⇒ max ⁡ π Q π ( s t , a t ) = Q ∗ ( s t , a t ) Q_{\pi}(s_t, a_t)=\mathbb{E}[U_t|s_t, a_t] \Rightarrow \max_{\pi}Q_{\pi}(s_t, a_t)=Q^{*}(s_t, a_t) Qπ(st,at)=E[Utst,at]πmaxQπ(st,at)=Q(st,at),而我们通过神经网络模拟的是 a t = arg max ⁡ a Q ∗ ( s t , a ) ; Q ( s t , a t ; w ) = Q ∗ ( s t , a t ) a_t=\argmax_{a}Q^{*}(s_t, a);\\Q(s_t, a_t; w)=Q^{*}(s_t, a_t) at=aargmaxQ(st,a);Q(st,at;w)=Q(st,at),神经网络的输出结果可以看成是对 U t U_t Ut 期望 的一个估计值(因为我们只能近似 U t U_t Ut 的期望而不可能得到真实的 U t U_t Ut 的期望)
  • 所以我们可以如下表示: Q ( s t , a t ; w ) ≈ E [ U t ] Q(s_t, a_t; w)\approx \mathbb{E}[U_{t}] Q(st,at;w)E[Ut],同样的: Q ( s t + 1 , a t + 1 ; w ) ≈ E [ U t + 1 ] Q(s_{t+1}, a_{t+1}; w)\approx \mathbb{E}[U_{t+1}] Q(st+1,at+1;w)E[Ut+1]
  • 所以我们可以进一步得到: Q ( s t , a t ; w ) ≈ E [ r t + γ Q ( S t + 1 , A t + 1 ; w ) ] Q(s_t, a_t; w)\approx \mathbb{E}[r_t+\gamma Q(S_{t+1}, A_{t+1}; w)] Q(st,at;w)E[rt+γQ(St+1,At+1;w)]

利用 TD 算法更新神经网络模型

在这里插入图片描述

  • 根据以上结果我们知道,在 t t t 时刻:
    • 通过神经网络得到 q = Q ( s t , a t ; w t ) q=Q(s_t, a_t; w_t) q=Q(st,at;wt)
    • 同时 TD target 的结果: y t d = r t + Q ( s t + 1 , a t + 1 ; w t ) , a t + 1 = arg max ⁡ a Q ( s t + 1 , a ; w t ) y_{td}=r_t+Q(s_{t+1}, a_{t+1}; w_t),\\ a_{t+1}=\argmax_{a}Q(s_{t+1},a; w_t) ytd=rt+Q(st+1,at+1;wt),at+1=aargmaxQ(st+1,a;wt)
    • 所以利用 q q q y t d y_{td} ytd 可以求算 L = 1 2 [ q − y t d ] 2 L=\frac{1}{2}[q-y_{td}]^2 L=21[qytd]2
    • 并采用梯度下降来更新神经网络
      在这里插入图片描述

Value-Based 强化学习总结

在这里插入图片描述

  • 最优价值函数定义: Q ∗ ( s t , a t ) = max ⁡ π E [ U t ∣ S t = s t , A t = a t ] Q^{*}(s_t, a_t)=\max_{\pi} \mathbb{E}[U_t|S_t=s_t, A_t=a_t] Q(st,at)=πmaxE[UtSt=st,At=at], 其中

    • a t a_t at 最初是从 π \pi π 中随机采样出来的
    • s t s_t st 是从状态转移函数 p ( s ′ , s , a ) p(s',s,a) p(s,s,a) 中随机采样出来的
    • 当确定了 a t , s t a_t, s_t at,st 之后就可以挑选出当前情况下最大的 Q Q Q Q ∗ ( s t , a t ) Q^{*}(s_t, a_t) Q(st,at)
    • 得到了 Q ∗ ( s t , a t ) Q^{*}(s_t, a_t) Q(st,at) 这个函数之后,我们就可以对所有的 a t a_t at 进行打分(虽然之前的 a t a_t at 是随机采样出来的,但现在不同了,我们已经得到了 Q ∗ Q^{*} Q函数,我们要遍历 t t t 时刻所有的行为从而获得最优的 a t a_t at
  • 基于价值的强化学习最终目标就是学习一个神经网络来近似 Q ∗ ( s , a ) Q^{*}(s, a) Q(s,a) 函数:

    • 输入是环境的某个状态 s s s
    • 输出是当前每个可选行为的分数
  • 使用 TD 算法训练神经网络:
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/189343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

cocos creater 3.x 开发笔记(踩坑总结)

1、cocos creater 3.x 花屏闪屏黑屏 1.1 花屏 排序是一个很简单的功能,但是最终的呈现却是根据不同平台提供的渲染能力来的。因此,在这里说明一下,如果遇到了 UI 渲染出错,花屏,闪屏等现象,首先要检查的就…

【安装合集】Mysql8.0安装 2023年1月31日 22点15分

1.鼠标右击【Mysql8.0】压缩包选择【解压到Mysql8.0】。 2. 鼠标右击【mysql-installer-community-8.0.17.0】选择【安装】 3. 勾选【I accept the license terms】然后点击【Next】。 4. 选择【Custom】然后点击【Next】。 5. 双击【MySQL Servers】 双击【MySQL Server】&am…

数据指标体系的建设思考(四)

这一篇主要介绍对数据指标体系的价值、数据指标管理平台的理解及数据分析的趋势解读。 一、数据指标体系价值 关于数据指标体系的价值,我想大多数从事数据工作的人员都可以感受得到,毕竟数据指标的输出可以通过可视化的方式(如大屏、驾驶舱…

Linux 中去除 vi/vim 和 git diff 中的 ^M 问题解决办法

去除 vi/vim 和 git diff 中的 ^M 问题解决办法问题现象初步分析进一步查看问题解决Source Insightdos2unixNodpadVimsed 命令综上Reference问题现象 git diff 时发现下面的情况,新修改的代码之处都是携带 ^M 字符, 初步分析 肯定是因为 Windows 和 …

推荐5款常用的有限元分析CAE软件

正如我们之前谈到的,计算机辅助软件有助于进行有限元分析。但是我们如何识别好的 CAE 软件呢?CAE 软件必须满足以下要求才能被纳入其类别使用户能够通过图形用户界面 (GUI) 创建模拟允许在模拟中测试组件,同时具有可自定义的环境变量协助优化…

JAVA队列-接口

前言 说到队列,大家都不陌生,很多场景都需要使用到队列,今天我们一起学习JDK提供的队列源码 类图 Queue接口的实现类有很多 从中,我们看到几个熟悉的,BlockingQueue 阻塞队列、Deque 双端队列 Queue 官方介绍: A collection designed for holding elements prior to proce…

MORPHVOX PRO 变声器 软件 Crack

MORPHVOX PRO 变声器 变音的全新层次 在网上聊天和游戏中使你变音 它具有超高语音学习技术,背景取消和高音质特点,将变音带向全新层次。 上好的变音质量 聆听MorphVOX Pro上好的变音质量。 *变音的音频因人而异,但它确实是同一个说话者发出…

国内爬虫图鉴

文章目录爬虫图鉴1.三个问题2.互联网上的爬虫2.1豪哥与爬虫2.2爬虫简介2.3APP身边的爬虫2.4爬虫排名1、排名第一的是出行2、排名第二的是社交。3、排名第三的是电商。4、接下来是 O2O 和搜索引擎。5、最后再说说政府部门。3.关于爬虫的几点疑问4.爬虫的TopN爬虫图鉴 本文案例来…

【数学建模】层次分析法(AHP)-Python实现

1 前言 本文主要讲解层次分析法(AHP)的python实现,后续会跟进实例分析 2 代码实现 导入包 import numpy as np2.1 构造判断矩阵 判断矩阵一般采用专家意见法,也就是德尔菲法。但是比赛的时候也没有什么专家,大家自…

2019-arXiv-Edge Contraction Pooling for Graph Neural

2019-arXiv-Edge Contraction Pooling for Graph Neural Paper: https://arxiv.org/abs/1905.10990 Code: https://github.com/pyg-team/pytorch_geometric/tree/master/benchmark/kernel 图神经网络的边缘收缩池化 池化层可以使GNN对抽象的节点组而不是单个节点进行推理。为…

【基础篇】5 # 链表(下):写好链表代码的六个实用技巧

说明 【数据结构与算法之美】专栏学习笔记 技巧一:理解指针或引用的含义 指针或引用都是存储所指对象的内存地址。将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针。 例如: p —> next q:表示 p 结点中的 ne…

opencv——Canny边缘检测

1、Canny边缘检测流程a、使用高斯滤波器,以平滑图像,滤除噪声。b、计算图像中每个像素点的梯度强度和方向。c、应用非极大值抑制,以消除边缘检测带来的杂散效应。d、应用双阈值检测来确定真实的和潜在的边缘。e、通过抑制孤立的弱边缘最终完成…

webpack4和webapck5的及新特性

30.webpack——webpack5新特性(启动、持久化缓存、资源模块、URIs、moduleIds和chunkIds、tree shaking、nodeJs的polyfill被移除、模块联邦)_俞华的博客-CSDN博客_chunkids 1、新特性1——启动命令 webpack4启动devServer,用的命令是webpac…

clickhouse库通过字段分组后获取排序后每天的前N条数据

各种查资料,都没找到,建议还是多看文档 方法1 :简单便捷: order by date,count desc limit 5 by date (取每天前5条数据,5可以随便换) sql可以随便写: 统计每天学生人数,按降序排序&#xff…

高级Spring之jdk 和 cglib 在 Spring 中的统一

Spring 中对切点、通知、切面的抽象如下 切点:接口 Pointcut,典型实现 AspectJExpressionPointcut 通知:典型接口为 MethodInterceptor 代表环绕通知 切面:Advisor,包含一个 Advice 通知,PointcutAdvisor…

关于构建校园能源管理平台的研究进展

摘要:能源与发展的矛盾已成为当今世界关注的焦点,高等学校做为一个特定的环境,近年来办学规模、校园面积、师生数量急剧增长,对能源的消耗也大幅提高。为抑制能源不合理增长,实现低碳发展,本文通过对校园能…

Go protobuf 的简单应用

环境搭建 安装 protobuf 编译器 https://github.com/protocolbuffers/protobuf/releases 解压,将bin目录加入环境变量 安装 protocol-gen-go 生成器 用于生成Go代码 https://github.com/protocolbuffers/protobuf-go/releases 解压,将可执行文件加…

第27章 分布式缓存数据库的定义实现

1 Core.HashHelper using System.Security.Cryptography; namespace Core { /// <summary> /// 【哈希助手--类】 /// <remarks> /// 摘要&#xff1a; /// 该类通过1个指定哈希加密算法生成1个唯一性的字符串(当前安全性较强的SHA-2包括有&#xff1a;SHA-2…

九龙证券|三胎概念股拉升…港股跳水,恒生科指重挫近5%

兔年首个交易日&#xff0c;A股迎来开门红&#xff0c;沪指开盘即打破3300点&#xff0c;创业板指一度涨近3%&#xff1b;港股却大幅下挫&#xff0c;恒生科技指数一度跌超5%。 详细来看&#xff0c;A股方面&#xff0c;两市股指全线高开&#xff0c;沪指开盘即打破3300点&…