当前位置: 首页 > article >正文

Efficient physics-informed neural networks using hash encoding

论文阅读:Efficient physics-informed neural networks using hash encoding

  • Efficient physics-informed neural networks using hash encoding
    • 简介
    • 方法
      • PINN
      • 哈希编码
      • 具有哈希编码的 PINN
    • 实验
      • Burgers 方程
      • Helmholtz 方程
      • N-S 方程
      • 训练效率对比
  • 总结

Efficient physics-informed neural networks using hash encoding

简介

在 PINN 中,一个偏微分方程问题的求解就需要一次对神经网络的优化才能获得,这使得求解 PDE 问题的成本可能很高。传统的 PINN 训练需要消耗 10000 个 epoch,其成本通常远高于传统的数值方法,这使得除了求解奇异方程之外,将 PINN 用于实际应用的吸引力较小。 PINN 成本高的主要原因是收敛所需的 epoch 数量,特别是对于复杂的函数解决方案。其中一些限制可归因于神经网络的低频偏差。随机初始化的多层感知器需要一段时间的训练才能找到通往潜在局部最小值(有时是数千个epoch)的路径。换句话说,考虑到神经网络空间通常具有高维性质,在找到局部最小值之前,它首先会在随机搜索中迷失。部分问题是由于解的坐标值(输入)受其维度(通常是三个空间维度再加上时间维度)的限制,对神经网络施加的影响很小,这迫使网络最初在参数空间中自由漫游,几乎没有受到任何指引。通过编码增加输入的影响,这一限制已得到部分解决,编码允许输入空间具有更高维度的表示,其中标量输入被向量替换。频率或位置编码给出的示例将相邻样本坐标的微小差异替换为位置向量表示中较大差异所表示的网络中更深刻的变化。

提高 PINN 训练的效率的方法大致可以分为以下三个组成部分:神经网络 (NN) 架构设计、损失函数设计和训练过程。本文重点关注神经网络的设计,特别是表示输入(使用嵌入层)。在某种程度上,PINN 可以被视为神经场表示任务(例如NeRF),其输入是空间坐标,输出是体素或物理场,但以偏微分方程损失作为训练信号。受嵌入方法成功的启发,特别是对神经场表示的输入坐标的编码,以及多分辨率哈希编码在 NeRF 上最近取得的巨大进展,引发了一个逻辑问题:可以利用哈希编码来加速 PINN 训练吗?多年来用作输入坐标加密形式的哈希编码可以提供更本地化的坐标值表示。这一多分辨率特征为图像神经网络功能表示(NeRF)的收敛提供了相当大的加速。 1000 个 epoch 的收敛率降低到 100 以下。这是一项重大改进,使 NeRF 得以实际使用。然而,此类表示中涉及的监督训练不需要计算导数,而 PINN 中的 PDE 损失函数则需要计算导数。

本文将哈希编码引入 PINN,并研究了它通过减少收敛所需的 epoch 数来解决 PINN 的成本限制。本文还研究了通过哈希编码自动微分的适用性。具体来说,本文使用有限差分方法来确保具有哈希编码的 NN 函数导数的稳定计算,并将其用于 PINNs 训练。在数值示例中,在几个偏微分方程上测试了本文的方法,以证明其在显着降低 PINN 成本方面的潜力,并分享了可能遇到的限制。

方法

PINN

考虑 n n n Ω ⊆ R n \Omega \subseteq \mathbb R^n ΩRn 和边界 ∂ Ω \partial \Omega Ω 的连通域,一般的时间相关 PDE 可以定义为:
u t ( x ) + S ( u ( x ) , a ( x ) ) = 0 , x ∈ Ω , t ∈ [ 0 , T ] u_t(\mathbf{x})+S(u(\mathbf{x}),a(\mathbf{x}))=0,\quad\mathbf{x}\in\Omega,\quad t\in[0,T] ut(x)+S(u(x),a(x))=0,xΩ,t[0,T]
其中 t t t x x x 分别是时间和空间坐标, S ( u , a ) S(u, a) S(u,a) 是非线性微分算子, a ∈ A a \in A aA 表示偏微分方程的参数,例如系数和初始或边界条件, u u u 表示我们想要解决的物理场。在普通 PINN 中,由可训练参数 θ \theta θ 参数化的神经网络 Φ ( θ , x , t ) \varPhi (\theta, x, t) Φ(θ,x,t) 经过训练,将输入坐标(包括与时间相关的方程的时间)映射到输出,输出代表物理场(例如, 速度、压力、涡度等)在输入坐标位置,满足以下方程:
∂ Φ ( θ , x ) ∂ t + S ( Φ ( θ , x ) , a ( x ) ) = 0. \frac{\partial\Phi(\theta,\mathbf{x})}{\partial t}+S(\Phi(\theta,\mathbf{x}),a(\mathbf{x}))=0. tΦ(θ,x)+S(Φ(θ,x),a(x))=0.
因此,我们可以在损失函数中使用该偏微分方程的均方残差以及任何初始或边界条件,
L = 1 N i ∑ j = 1 N i ( ∂ Φ ( θ , x j ) ∂ t + S ( Φ ( θ , x j ) , a ( x j ) ) ) 2 ⏟ Interior PDE loss + 1 N b ∑ i = 1 N b ( B ( Φ ( θ , x i ) ) − u b ( x i ) ) 2 , ( 3 ) ⏟ Supcrivesd loss on boundary \mathrm{L}=\underbrace{\frac1{N_i}\sum_{j=1}^{N_i}\left(\frac{\partial\Phi(\theta,\mathbf{x}_j)}{\partial t}+S(\Phi(\theta,\mathbf{x}_j),a(\mathbf{x}_j))\right)^2}_{\text{Interior PDE loss}}+\underbrace{\frac1{N_b}\sum_{i=1}^{N_b}\left(\mathcal{B}(\Phi(\theta,\mathbf{x}_i))-u_b\left(\mathbf{x}_i\right)\right)^2,\quad(3)}_{\text{Supcrivesd loss on boundary}} L=Interior PDE loss Ni1j=1Ni(tΦ(θ,xj)+S(Φ(θ,xj),a(xj)))2+Supcrivesd loss on boundary Nb1i=1Nb(B(Φ(θ,xi))ub(xi))2,(3)
优化神经网络的参数 θ \theta θ,其中 N i N_i Ni 是域内收集点的数量, N b N_b Nb 是边界上的收集点的数量, u b u_b ub 是边界值, B \mathcal B B 是边界算子,表示域的导数或值。

哈希编码

对于函数学习,本文的目标是提高神经网络对偏微分方程的逼近质量,以及给定神经网络的训练速度。请注意,速度是本文的主要目标。一种聪明的方法是将输入查询(例如空间坐标和时间)编码到高维空间。在这里,本文使用 Müller 等人提出的哈希编码。哈希编码的总体思想是将多分辨率分解与哈希表相结合,以紧凑地表示 3D 形状。然后,复杂的 3D 现实世界可以通过小型神经网络和可训练的哈希编码参数来表示。

在这里插入图片描述

上图描述了根据 Müller 等人使用的图表建模的哈希编码机制。 模拟域 x i x_i xi 中的每个样本都可以使用从低到高的 S S S 级分辨率来描述。对于每个分辨率级别,如上图中的粉色或蓝色点,计算嵌入向量。具体来说,首先找到它的体素顶点(2D 情况下有 4 个顶点,3D 情况下有 8 个顶点),然后使用可训练的哈希表,其中包括每个分辨率级别的长度为 L L L 的固定特征和哈希表大小 T T T,评估每个顶点相应的嵌入向量。然后,我们使用顶点向量的线性插值来获得 x i x_i xi 在不同级别的嵌入向量。最后, x i x_i xi 的哈希编码是来自不同级别的这些嵌入向量的串联。

具体地,给定编码级别S以及最细和最粗分辨率 R f R_f Rf R c R_c Rc,每个级别的分辨率 R s R_s Rs 由几何级数确定,如下:
R s : = ⌊ R c ⋅ b s ⌋ , b : = exp ⁡ ( ln ⁡ R f − ln ⁡ R c S − 1 ) . \begin{aligned} R_s&:=\left\lfloor R_c\cdot b^s\right\rfloor,\\ b&:=\exp\left(\frac{\ln R_f-\ln R_c}{S-1}\right). \end{aligned} Rsb:=Rcbs,:=exp(S1lnRflnRc).
那么对于 x i x_i xi,它的顶点是 $\lfloor\mathbf{x}_{i,s}\rfloor:=\lfloor\mathbf{x}i\cdot R_s\rfloor $ 和 $\lceil\mathbf{x}{i,s}\rceil:=\lceil\mathbf{x}_i\cdot R_s\rceil $。对于粗分辨率,当顶点数 ( R s + 1 ) d (R^s+1)^d (Rs+1)d 小于哈希表 T T T 时,哈希表可以提供一对一的查询。然而,为了更高分辨率,顶点和哈希表之间的映射是通过哈希函数来实现的
h ( x i ) = ( ⨁ j = 1 d x i , j π j ) m o d   T h(\mathbf{x}_i)=\left(\bigoplus_{j=1}^dx_{i,j}\pi_j\right)\quad\mathrm{mod~}T h(xi)=(j=1dxi,jπj)mod T
其中 ⨁ \bigoplus 是按位“异或”XOR, π j \pi_j πj 是唯一且大的素数。这种编码不仅提供了输入维度的紧凑表示,而且由于几乎即时的哈希表查找机制,计算复杂度为 O ( 1 ) O(1) O(1),非常高效。

具有哈希编码的 PINN

本文的目标是利用哈希编码来加速 PINN 的收敛。然而,与 NeRF 应用不同,PINN 的损失函数需要输出场相对于输入坐标的导数。由于所提出的哈希编码包括线性插值,因此这些导数可能是不连续的,这导致评估不准确,尤其是在分辨率网格的边界附近,并且这些潜在的不连续导数对于哈希编码的高分辨率级别更为频繁。以一个简单函数 f ( x ) = s i n ( x ) f (x) = sin(x) f(x)=sin(x) 为例,其各种阶导数很容易获得,可以在一个简单的输入为 x x x 的网络上测试自动微分(PINN 中经常使用)的性能,该网络函数经过训练以输出 f ( x ) f (x) f(x) 的值。然而,这个简单的网络将包含一个哈希编码层。

在这里插入图片描述

如上图所示,可以观察到基于哈希编码的神经网络的导数值并不准确,其准确性很大程度上取决于哈希编码的超参数。具体来说,需要仔细选择最粗和最细的分辨率、编码级别以及哈希表大小,以减轻不连续性的影响,这也取决于搭配点。本文的观点是,与高分辨率哈希中的高频细节非常适合的哈希编码的强度将被自动微分计算中的这一弱点所抵消。例如,使用很多级别并包括最精细的分辨率将使整个神经网络(带编码的神经网络)更好近似训练样本点的值,但生成的函数将缺乏平滑性,导致不稳定的导数。这是用于哈希向量的线性插值的直接结果。因此,使用当前哈希编码实现通过自动微分评估的神经网络的导数是不稳定的。

为了寻求有效的实现,本文转而使用有限差分(FD)方法来计算导数,因为自动微分对于高阶导数来说也很昂贵。由于有限差分(顾名思义)计算有限长度上的导数,因此它相对不受点引起的导数不连续性的影响。然而,在处理突然变化的函数时,准确性可能会略有下降,这是 PINN 的普遍弱点。 FD 方法建立在泰勒级数展开的基础上。给定一个网格点 x i x_i xi,可以通过限制其泰勒级数展开的长度来近似其物理场 u ( x i ) u(x_i) u(xi),如下:
u ( x i + Δ x ) = u ( x i ) + Δ x ∂ u ∂ x ∣ x i + Δ x 2 2 ∂ 2 u ∂ x 2 ∣ x i + ⋯ u\left(\mathbf{x}_i+\Delta\mathbf{x}\right)=u\left(\mathbf{x}_i\right)+\left.\Delta\mathbf{x}\frac{\partial u}{\partial\mathbf{x}}\right|_{\mathbf{x}_i}+\left.\frac{\Delta\mathbf{x}^2}2\frac{\partial^2u}{\partial\mathbf{x}^2}\right|_{\mathbf{x}_i}+\cdots u(xi+Δx)=u(xi)+Δxxu xi+2Δx2x22u xi+
停在二阶精度,有限差分一阶和二阶导数由下式给出:
∂ u ∂ x ∣ x i ≈ u ( x i + Δ x ) − u ( x i − Δ x ) 2 Δ x , ∂ 2 u ∂ x 2 ∣ x i ≈ u ( x i + Δ x ) − 2 u ( x i ) + u ( x i − Δ x ) Δ x 2 . \begin{aligned} \left.\frac{\partial u}{\partial\mathbf{x}}\right|_{\mathbf{x}_i}& \approx\frac{u\left(\mathbf{x}_i+\Delta\mathbf{x}\right)-u\left(\mathbf{x}_i-\Delta\mathbf{x}\right)}{2\Delta\mathbf{x}}, \\ \left.\frac{\partial^2u}{\partial\mathbf{x}^2}\right|_{\mathbf{x}_i}& \approx\frac{u\left(\mathbf{x}_i+\Delta\mathbf{x}\right)-2u\left(\mathbf{x}_i\right)+u\left(\mathbf{x}_i-\Delta\mathbf{x}\right)}{\Delta\mathbf{x}^2}. \end{aligned} xu xix22u xixu(xi+Δx)u(xiΔx),Δx2u(xi+Δx)2u(xi)+u(xiΔx).
在训练过程中,导数计算所需的网格点应输入神经网络以获得相应的场值。

在这里插入图片描述

如上图所示,具有哈希编码的 NN 的导数通常比自动微分的导数更准确,但同样需要仔细选择编码超参数。在这里,上图© 中 FD 方法出现了失败的情况,该案例是由于使用小型哈希表而导致的,这迫使神经网络学习区分不同位置的样本,从而导致导数计算的准确性下降。与自动微分方法相比,(b)中的二阶导数虽然不平滑,但其趋势与解析解一致。

实验

本文通过其在三个众所周知的偏微分方程(PDE)上的应用来展示该方法的有效性。在所有情况下,都使用 MLP 架构作为主干,使用 Tanh 作为激活函数。为了公平的效率比较,使用 FD 方法来获得普通 PINN 和带有哈希编码的 PINN 的导数。同时稍微增加了普通 PINN 的宽度,使可训练参数的数量几乎等于具有哈希编码的 PINN。本文在所有实验中使用 Adam 优化器和衰减学习率来训练这些神经网络。

对于每个测试,通过设置解决方案精度的阈值(通过神经网络预测的解决方案与参考解决方案之间的绝对误差)以停止训练并根据轮数和每个轮次的成本评估方法。由于 FD 方法在导数计算方面的灵活性,本文使用 tiny-cuda-nn 框架实现了神经网络以进一步加速训练过程。

Burgers 方程

首先,考虑一个具有代表粘性流体一维流动的狄利克雷边界条件的一维时间相关方程,称为 Burgers 方程,它是 PINN 中广泛使用的基准。控制方程如下:
∂ u ∂ t + u ∂ u ∂ x = ν ∂ 2 u ∂ x 2 , t ∈ [ 0 , 1 ] , x ∈ [ − 1 , 1 ] , u ( t , − 1 ) = u ( t , 1 ) = 0 , u ( 0 , x ) = − s i n ( π x ) , \begin{aligned} &\begin{aligned}\frac{\partial u}{\partial t}+u\frac{\partial u}{\partial x}&=\nu\frac{\partial^2u}{\partial x^2},&t\in[0,1],&x\in[-1,1],\end{aligned} \\ &u(t,-1)=u(t,1)=0, \\ &u(0,x)=-sin(\pi x), \end{aligned} tu+uxu=νx22u,t[0,1],x[1,1],u(t,1)=u(t,1)=0,u(0,x)=sin(πx),
其中 ν \nu ν 是粘度参数,此处设置为 0.01 π 0.01 \pi 0.01π。对于普通 PINN,使用具有三个隐藏层 { 96 , 96 , 96 } \{96,96,96\} {96,96,96} 的 MLP,而对于具有哈希编码的 PINN,使用大小为 { 64 , 64 , 64 } \{64,64,64\} {64,64,64} 的 MLP。学习率为 1 e − 3 1\text e-3 1e3,在 3000、5000、7000 和 10000 epoch 时减少 0.8 倍。使用数值解作为评估预测准确性的参考。

在这里插入图片描述

上图 (a) 显示了所提出的方法和使用 12800 个配置点的普通 PINN 的收敛速度。如前所述,通过测量达到预定义精度阈值所需的 epoch 数来关注收敛速度,可以发现采用哈希编码的 PINN 可以在不到 2500 epoch 内达到此目标精度,而普通 PINN 需要近20000个epoch。这里考虑的阈值精度为与参考解等效的解上图 (b)

Helmholtz 方程

接下来,在二阶导数问题上测试偏微分方程,该问题由著名的亥姆霍兹方程给出,该方程描述了波动现象并在地震和电磁领域有很多应用。这里考虑亥姆霍兹方程的简单形式:
∂ 2 u ∂ 2 x + ∂ 2 u ∂ 2 y + λ u − f ( x , y ) = 0 , u ( x , 2 ) = 0 , u ( − 2 , y ) = 0 , u ( x , − 2 ) = 0 , u ( y , 2 ) = 0 , f = − ( a 1 π ) 2 sin ⁡ ( a 1 π x ) sin ⁡ ( a 2 π y ) − ( a 2 π ) 2 sin ⁡ ( a 1 π x ) sin ⁡ ( a 2 π y ) + λ sin ⁡ ( a 1 π x ) sin ⁡ ( a 2 π y ) , \begin{aligned} &\begin{aligned}\frac{\partial^2u}{\partial^2x}+\frac{\partial^2u}{\partial^2y}+\lambda u-f(x,y)=0,\end{aligned} \\ &\begin{aligned}u(x,2)=0,&u(-2,y)=0,&u(x,-2)=0,&u(y,2)=0,\end{aligned} \\ &f=-\left(a_1\pi\right)^2\sin\left(a_1\pi x\right)\sin\left(a_2\pi y\right) \\ &-\left(a_2\pi\right)^2\sin\left(a_1\pi x\right)\sin\left(a_2\pi y\right) \\ &+\lambda\sin\left(a_1\pi x\right)\sin\left(a_2\pi y\right), \end{aligned} 2x2u+2y2u+λuf(x,y)=0,u(x,2)=0,u(2,y)=0,u(x,2)=0,u(y,2)=0,f=(a1π)2sin(a1πx)sin(a2πy)(a2π)2sin(a1πx)sin(a2πy)+λsin(a1πx)sin(a2πy),
其中 f f f 是源函数, u u u 是波场, λ \lambda λ 是波数的平方, a 1 a_1 a1 a 2 a_2 a2 是控制源项正弦特性的参数。该方程存在解析解:
u ( x , y ) = s i n ( a 1 π x ) s i n ( a 2 π y ) u(x,y)=sin(a_1\pi x)sin(a_2\pi y) u(x,y)=sin(a1πx)sin(a2πy)
在本例中,本文对普通 PINN 使用具有三个隐藏层 { 144 , 144 , 144 } \{144,144,144\} {144,144,144} 的 MLP,而对于具有哈希编码的 PINN,使用 { 128 , 128 , 128 } \{128,128,128\} {128,128,128} 的 MLP。学习率为 1.5 e − 3 1.5\text e-3 1.5e3,在 3000、5000 和 7000 epoch 时降低了 0.8 倍。统一采样 10000 个收集点来训练神经网络。

在这里插入图片描述

亥姆霍兹方程训练的收敛速度如上图 (a) 所示。可以观察到,使用哈希编码的 PINN 收敛速度更快,并且使用哈希编码的 PINN 的 PDE 损失和测试数据错误仍然可以减少。尽管如此,预测解和参考解(如上图 (b) 所示)看起来是相同的。

N-S 方程

最后,在动态流体中的一个著名方程——纳维-斯托克斯方程上测试了所提出的方法。具体来说,考虑不可压缩流体的情况,产生基于质量和动量守恒的两个控制方程,如下所示:
∂ t u ⃗ ( x , y , t ) + u ⃗ ( x , y , t ) ⋅ ∇ u ⃗ ( x , y , t ) + ∇ p = 1 R e Δ u ⃗ ( x , y , t ) + f ( x , y ) , x ∈ ( 0 , 1 ) 2 , t ∈ ( 0 , T ] ∇ ⋅ u ⃗ ( x , t ) = 0 x ∈ ( 0 , 1 ) 2 , t ∈ [ 0 , T ] u ⃗ ( x , 0 ) = u ⃗ 0 ( x ) x ∈ ( 0 , 1 ) 2 \begin{aligned} \partial_{t}\vec{u}(x,y,t)+\vec{u}(x,y,t)\cdot\nabla\vec{u}(x,y,t)+\nabla p& =\frac1{Re}\Delta\vec{u}(x,y,t)+f(x,y), &x\in(0,1)^2,t\in(0,T] \\ \nabla\cdot\vec{u}(x,t)& =0 & x\in(0,1)^2,t\in[0,T] \\ \vec{u}(x,0)& =\vec{u}_0(x) & x\in(0,1)^2 \\ \end{aligned} tu (x,y,t)+u (x,y,t)u (x,y,t)+pu (x,t)u (x,0)=Re1Δu (x,y,t)+f(x,y),=0=u 0(x)x(0,1)2,t(0,T]x(0,1)2,t[0,T]x(0,1)2
其中 R e Re Re 是雷诺数,在实验中设置为100, ∇ \nabla 是散度算子, Δ \Delta Δ 是拉普拉斯算子, u ⃗ \vec{u} u 是速度场, u ⃗ 0 \vec{u}_0 u 0 是初始速度场, p p p 是压力, f f f 是外力,这里设置为零。普通 PINN 具有三个隐藏层 { 112 , 112 , 112 } \{112,112,112\} {112,112,112} ,相比之下,使用 { 64 , 64 , 64 } \{64,64,64\} {64,64,64} 作为具有哈希编码的 PINN。学习率为 1.2 e − 3 1.2\text e-3 1.2e3,在 3000、5000 和 7000 epoch 时降低了 0.8 倍。统一采样 10000 个收集点来训练神经网络。

在这里插入图片描述

结果如上图所示,其中参考解是从数值求解器获得的。与之前的实验一样,所提出的方法具有快速收敛性,并且只需 2270 个 epoch 即可达到目标精度(1.5e-3)。然而,即使有 50000 个 epoch,vanilla PINN 也无法满足目标精度。这表明所提出的方法加速了训练并提高了准确性。

训练效率对比

上述实验表明,使用哈希编码的 PINN 可以在比普通 PINN 少得多的 epoch 内进行训练,从而实现良好的目标准确度。

在这里插入图片描述

在上表中,对此处使用的三个示例的两种方法进行了定量比较。可以发现采用哈希编码的 PINN 可以使用单个 NVIDIA A100 GPU 卡在 30 秒内求解这三个著名方程。

总结

本文将哈希编码引入 PINN 中,并使用有限差分方法克服了哈希编码带来的自动微分的不准确性,加速了 PINN 的训练过程。

之前一直觉得 NeRF 和求解 PINN 之间有共同之处,也在2022中科大计算机图形学暑期课程里看过哈希编码加速NeRF的那篇文章,但没有意识到在这点上是共通的,看来在这方面敏感度还是不太够。当然,将输入映射到高维这一方法也是十分有趣的话题,而本人对这方面其实不太感兴趣,或许我该多看点这方面的方法。

相关链接:

  • 原文:[2302.13397] Efficient physics-informed neural networks using hash encoding (arxiv.org)

http://www.kler.cn/news/162808.html

相关文章:

  • 逻辑漏洞与越权
  • 【1day】致远 A8系统getAjaxDataServlet-xxe接口任意文件读取学习
  • windows 安装两个mysql
  • frp内网穿透部署,轻松实现内网服务对外访问
  • Gan论文阅读笔记
  • SQL FOREIGN KEY 约束- 保障表之间关系完整性的关键规则
  • 解释区块链技术的应用场景和优势。
  • LinuxBasicsForHackers笔记 -- 压缩和归档
  • AIGC创作系统ChatGPT网站源码,Midjourney绘画,GPT联网提问/即将支持TSS语音对话功能
  • 【漏洞复现】万户协同办公平台ezoffice wpsservlet接口存在任意文件上传漏洞 附POC
  • 因为 postman环境变量全局变量设置好兄弟被公司优化了!
  • C语言精选——选择题Day39
  • 共享娱乐宝库:电视盒子影视源分享攻略
  • 常用Nmap脚本
  • 新时代商业旨意:传统商家如何变革?
  • 潮落云起:中国云桌面的产业变局
  • maven学习笔记总结
  • TCP/IP_整理起因
  • 【已解决】MySQL:执行存储过程报错(MySQL字符集和排序方式冲突)
  • 计算机网络入侵检测技术研究
  • n个人排成一圈,数数123离队
  • 在 Mac 上使用浅色或深色外观
  • 扁平的MutableList元素每隔若干元素一组装入新MutableList,Kotlin
  • Fabric.js 实战开发使用介绍
  • 谈谈c语言中的sizeof
  • 天文馆元宇宙3d展厅打造沉浸式的参观体验
  • Spring Boot实现接口幂等
  • 国产接口测试工具APIpost
  • 数据结构线性表-栈和队列的实现
  • kafka高吞吐、低延时、高性能的实现原理