2024.7.14周报

目录

摘要

ABSTRACT

一、文献阅读

一、题目

二、摘要

三、文献解读

一、Introduction

二、KINN框架

三、主要结果

四、Conclusion

二、KAN

一、KAN与MLP区别

二、KAN网络解析

三、激活函数参数化(B-splines)

三、网络架构代码

摘要

本周我阅读了一篇题目为Kolmogorov–Arnold-Informed neural network: A physics-informed deep learning framework for solving PDEs based on Kolmogorov–Arnold Networks的文献,它是将PINN中的网络架构用KAN来代替,提出了KINN。其次对KAN和KAN的网络架构进行了初步学习,加深了对其的认识。

ABSTRACT

This week I read a paper titled "Kolmogorov–Arnold-Informed Neural Network: A Physics-Informed Deep Learning Framework for Solving PDEs Based on Kolmogorov–Arnold Networks." The paper proposes replacing the network architecture in PINN with KAN, introducing KINN. Additionally, I conducted a preliminary study of KAN and its network architecture, which deepened my understanding of it.

一、文献阅读

一、题目

题目:Kolmogorov–Arnold-Informed neural network: A physics-informed deep learning framework for solving PDEs based on Kolmogorov–Arnold Networks

链接:https://arxiv.org/html/2406.11045v1

二、摘要

受Kolmogorov-Arnold表示定理的启发,本文提出Kolmogorov-Arnold网络(KAN)作为多层感知器(MLP)的有前途的替代品。MLP在节点(“神经元”)上有固定的激活函数,而KAN在边缘(“权重”)上有可学习的激活函数。KAN根本没有线性权重——每个权重参数都被参数化为样条的单变量函数所取代。这个看似简单的改变使得KAN在准确性和可解释性方面优于MLP。就准确性而言,在数据拟合和PDE求解方面,更小的KAN可以达到与更大的MLP相当或更好的准确性。从理论和经验上看,KAN比MLP具有更快的神经尺度规律。对于可解释性,KAN可以直观地可视化,并且可以轻松地与人类用户交互。通过数学和物理的两个例子,KAN被证明是有用的“合作者”,帮助科学家(重新)发现数学和物理定律。

Inspired by the Kolmogorov-Arnold representation theorem, this paper proposes the Kolmogorov-Arnold Network (KAN) as a promising alternative to the Multilayer Perceptron (MLP). While MLPs have fixed activation functions at the nodes ("neurons"), KANs feature learnable activation functions at the edges ("weights"). KANs have no linear weights at all—each weight parameter is replaced by a univariate function parameterized as a spline. This seemingly simple change enables KANs to surpass MLPs in terms of both accuracy and interpretability. In terms of accuracy, smaller KANs can achieve comparable or better accuracy than larger MLPs in data fitting and PDE solving. Both theoretically and empirically, KANs exhibit faster neural scaling laws than MLPs. For interpretability, KANs can be intuitively visualized and can easily interact with human users. Through two examples from mathematics and physics, KANs are demonstrated to be useful "collaborators" in helping scientists (re)discover mathematical and physical laws.

三、文献解读

一、Introduction

用于PDEs的AI中有三种重要的方法:物理信息神经网络(PINNs)、算子学习和物理信息神经算子(PINO)。PINNs:由于同一个PDE可以有不同的表达形式,每种形式的准确性和效率各不相同,基于这些表达形式开发了不同形式的PINNs。这些形式包括强形式的PINNs、弱形式的PINNs(hp-VPINNs)、能量形式的PINNs(深度能量方法:DEM)和逆形式的PINNs(边界元方法:BINN)。算子学习:代表性的有DeepONet和傅里叶神经算子(FNO)。最初提出的算子学习方法完全是数据驱动的,非常适合大数据问题。PINO:它将物理方程与算子学习结合起来。通过在算子学习的训练过程中加入物理方程,传统的算子学习可以实现更高的精度。此外,PINO可以利用算子学习首先获得一个好的近似解,然后使用PDEs进行精细化,大大加快了PDEs的计算速度。KAN(Kolmogorov-Arnold网络)加深了浅层Kolmogorov网络,创造了具有良好性质的单变量函数。KAN与MLP非常相似,主要区别在于KAN的激活函数需要学习。在原始的KAN中,由于其出色的拟合能力,使用B样条作为激活函数的构建。KAN的核心是引入了一个可以学习激活函数的复合函数框架。因此本文提出了KINN,它是PDEs不同形式(强形式、能量形式和逆形式)的KAN版本。由于在使用不同逼近函数替代B样条的广泛工作,我们使用原始的B样条版本的KAN与PDEs的不同形式的MLP直接比较,系统地比较精度和效率是否有所改善。KAN的参数比MLP少,而且由于KAN的激活函数是B样条,KAN的函数构建更符合解决PDEs的数值算法的本质。因此,有理由相信将KAN与各种形式的PINNs结合以替代MLP将取得更好的结果。

二、KINN框架

KINN的思想是在不同形式的PDEs(强形式、能量形式和逆形式)中用Kolmogorov-Arnold网络(KAN)替代MLP。在KAN中,主要训练参数是激活函数中B样条的未确定系数c_{i}。KINN基于PDEs的不同数值格式建立损失函数并优化c_{i}。虚拟网格的大小由KAN中的网格尺寸决定。

三、主要结果

验证MLP和KAN在拟合u=sin(2\pi x)+0.1sin(50\pi x)时的“频谱偏差”。(a) 精确解、MLP预测和KAN预测在训练周期100, 1000和10000时的情况;(b) MLP和KAN的特征值分布;(c) 第一行是从大到小排序的最大特征值的特征向量,第二行是最小三个特征值的特征向量;(d) MLP和KAN的损失函数的演变。

MLP和KAN拟合高低频混合热传导问题。(a) 频率为 (F = 50) 的精确解;(b) 在5000次迭代后,频率 (F = 50) 的MLP预测;(c) 在5000次迭代后,频率 (F = 50) 的MLP的绝对误差;(d) 在5000次迭代后,频率 (F = 50) 的KAN预测;(e) 在5000次迭代后,频率 (F = 50) 的KAN的绝对误差;(f) 在不同网格尺寸和频率下,经过3000次迭代及网络结构为[2,5,1]的KAN的相对误差。

介绍模式III裂纹。(a) 模式III裂纹的结构,位于一个正方形区域内,尺寸为[-1,1]^{2}。蓝色和黄色区域代表两个神经网络,因为裂纹处的位移是不连续的(x<0,y=0),因此需要两个神经网络来拟合裂纹上下的位移。(b) 这个问题的解析解为u=\frac{1}{r^{2}}sin(\theta /2) ,其中r是从坐标x到原点x=y=0的距离, \theta是角度,以x>0,y=0为参考,逆时针方向为正角。(c) KINN的网格分布,顺序为3,网格大小为10,在x和y方向上均匀分布。(d) 用于PINN、DEM和KINN的无网格随机采样点。红色点代表上部区域神经网络的必要边界位移点(256点),蓝色点代表下部区域神经网络的点(2048点),黄色点是接口采样点(1000点)。

不同的基于MLP或KAN的PINNs、DEM和BINN算法之间的比较。参数意味着NNs架构中的训练参数。相对误差代表收敛时的L2误差。网格范围是KAN网格的初始范围。阶数是KAN中B样条的阶数。NNs的架构是相应神经网络的结构。参数是相应网络的可训练参数。时间是相应算法1000个周期的持续时间。

PINNs、DEM、BINN及其对应的KINN版本预测的位移解:(a) FEM参考解,(b) PINNs,(c) DEM,(d) BINN,(e) KINN-PINNs,(f) KINN-DEM,(g) KINN-BINN。

四、Conclusion

本文比较了KAN和MLP在不同形式的偏微分方程(PDE)中的表现,并提出了KINN算法用于解决KAN在强形式、能量形式和逆问题中的PDE。进行了系统的数值实验和工程力学常见基准验证。结果显示,在大多数PDE问题中,特别是在奇异性问题、应力集中问题、非线性超弹性问题和异质问题中,KAN具有比MLP更高的精度和收敛速度。然而,由于KAN算法缺乏特定的优化,其效率目前比同样epoch下的MLP低。通过优化,KINN的效率可以显著提高。此外,从NTK(神经正切核)的角度系统分析了KAN,发现其谱偏差远小于MLP,使其更适合解决高低频混合问题。最后,我们发现KAN在复杂几何PDE问题上表现不佳,主要是由于网格尺寸与几何复杂性之间的冲突。然而,目前KINN存在局限性和扩展空间。在实验过程中,我们发现过大的网格尺寸可能导致KAN失败,即由于过拟合而增加误差。因此,在使用KINN时,根据问题的复杂性确定合适的网格尺寸至关重要。

二、KAN

一、KAN与MLP区别

MLP:线性组合,非线性激活
KAN:非线性激活(每个输入),线性组合

可以理解为顺序换了一下,下图左边是MLP,右边是KAN,很好理解。最大的点是激活函数不再是固定的Sigmoid或ReLU,它被参数化了,可学。

二、KAN网络解析

就是f是一个多元函数(有多个x变量,吐出来一个数),可以被表示为多个单元函数的线性组合,就是单元函数和加法,可以构建出乘法!

其实两层理论上可以拟合任何函数,但是激活函数有时会变得非常不光滑,非常病态,才能满足要求,所以这也是多层KAN的必要性。

三、激活函数参数化(B-splines)

激活函数所以必须先参数化,才能 learnable。作者是选了B样条函数下图说明了这个样条函数怎么来的:

其实就是多个basic函数的相加,C参数控制每个basic的幅值。Φ函数有粗粒度和细粒度选择,就是选多些basic函数相加就越精准嘛,上图是展示7和12两种情况。G=5表示interval是5。

MLPs通过增加模型的宽度和深度可以提高性能,但这种方法效率低下,因为需要独立地训练不同大小的模型。KANS:开始可以用较少的参数训练,然后通过简单地细化其样条网格来增加参数,无需重新训练整个模型。基本原理就是通过将样条函数(splines)旧的粗网格转换为更细的网格,并对应地调整参数,无需从头开始训练就能扩展现有的 KAN 模型。这种技术称为“网格扩展”(grid extension)。

三、网络架构代码

class KANLinear(torch.nn.Module):def __init__(self,in_features,out_features,grid_size=5,spline_order=3,scale_noise=0.1,scale_base=1.0,scale_spline=1.0,enable_standalone_scale_spline=True,base_activation=torch.nn.SiLU,grid_eps=0.02,grid_range=[-1, 1],):super(KANLinear, self).__init__()self.in_features = in_featuresself.out_features = out_featuresself.grid_size = grid_sizeself.spline_order = spline_orderh = (grid_range[1] - grid_range[0]) / grid_sizegrid = ((torch.arange(-spline_order, grid_size + spline_order + 1) * h+ grid_range[0]).expand(in_features, -1).contiguous())self.register_buffer("grid", grid)self.base_weight = torch.nn.Parameter(torch.Tensor(out_features, in_features))self.spline_weight = torch.nn.Parameter(torch.Tensor(out_features, in_features, grid_size + spline_order))if enable_standalone_scale_spline:self.spline_scaler = torch.nn.Parameter(torch.Tensor(out_features, in_features))self.scale_noise = scale_noiseself.scale_base = scale_baseself.scale_spline = scale_splineself.enable_standalone_scale_spline = enable_standalone_scale_splineself.base_activation = base_activation()self.grid_eps = grid_epsself.reset_parameters()def reset_parameters(self):torch.nn.init.kaiming_uniform_(self.base_weight, a=math.sqrt(5) * self.scale_base)with torch.no_grad():noise = ((torch.rand(self.grid_size + 1, self.in_features, self.out_features)- 1 / 2)* self.scale_noise/ self.grid_size)self.spline_weight.data.copy_((self.scale_spline if not self.enable_standalone_scale_spline else 1.0)* self.curve2coeff(self.grid.T[self.spline_order : -self.spline_order],noise,))if self.enable_standalone_scale_spline:# torch.nn.init.constant_(self.spline_scaler, self.scale_spline)torch.nn.init.kaiming_uniform_(self.spline_scaler, a=math.sqrt(5) * self.scale_spline)def b_splines(self, x: torch.Tensor):"""Compute the B-spline bases for the given input tensor.Args:x (torch.Tensor): Input tensor of shape (batch_size, in_features).Returns:torch.Tensor: B-spline bases tensor of shape (batch_size, in_features, grid_size + spline_order)."""assert x.dim() == 2 and x.size(1) == self.in_featuresgrid: torch.Tensor = (self.grid)  # (in_features, grid_size + 2 * spline_order + 1)x = x.unsqueeze(-1)bases = ((x >= grid[:, :-1]) & (x < grid[:, 1:])).to(x.dtype)for k in range(1, self.spline_order + 1):bases = ((x - grid[:, : -(k + 1)])/ (grid[:, k:-1] - grid[:, : -(k + 1)])* bases[:, :, :-1]) + ((grid[:, k + 1 :] - x)/ (grid[:, k + 1 :] - grid[:, 1:(-k)])* bases[:, :, 1:])assert bases.size() == (x.size(0),self.in_features,self.grid_size + self.spline_order,)return bases.contiguous()def curve2coeff(self, x: torch.Tensor, y: torch.Tensor):"""Compute the coefficients of the curve that interpolates the given points.Args:x (torch.Tensor): Input tensor of shape (batch_size, in_features).y (torch.Tensor): Output tensor of shape (batch_size, in_features, out_features).Returns:torch.Tensor: Coefficients tensor of shape (out_features, in_features, grid_size + spline_order)."""assert x.dim() == 2 and x.size(1) == self.in_featuresassert y.size() == (x.size(0), self.in_features, self.out_features)A = self.b_splines(x).transpose(0, 1)  # (in_features, batch_size, grid_size + spline_order)B = y.transpose(0, 1)  # (in_features, batch_size, out_features)solution = torch.linalg.lstsq(A, B).solution  # (in_features, grid_size + spline_order, out_features)result = solution.permute(2, 0, 1)  # (out_features, in_features, grid_size + spline_order)assert result.size() == (self.out_features,self.in_features,self.grid_size + self.spline_order,)return result.contiguous()@propertydef scaled_spline_weight(self):return self.spline_weight * (self.spline_scaler.unsqueeze(-1)if self.enable_standalone_scale_splineelse 1.0)def forward(self, x: torch.Tensor):assert x.size(-1) == self.in_featuresoriginal_shape = x.shapex = x.reshape(-1, self.in_features)base_output = F.linear(self.base_activation(x), self.base_weight)spline_output = F.linear(self.b_splines(x).view(x.size(0), -1),self.scaled_spline_weight.view(self.out_features, -1),)output = base_output + spline_outputoutput = output.reshape(*original_shape[:-1], self.out_features)return output@torch.no_grad()def update_grid(self, x: torch.Tensor, margin=0.01):assert x.dim() == 2 and x.size(1) == self.in_featuresbatch = x.size(0)splines = self.b_splines(x)  # (batch, in, coeff)splines = splines.permute(1, 0, 2)  # (in, batch, coeff)orig_coeff = self.scaled_spline_weight  # (out, in, coeff)orig_coeff = orig_coeff.permute(1, 2, 0)  # (in, coeff, out)unreduced_spline_output = torch.bmm(splines, orig_coeff)  # (in, batch, out)unreduced_spline_output = unreduced_spline_output.permute(1, 0, 2)  # (batch, in, out)# sort each channel individually to collect data distributionx_sorted = torch.sort(x, dim=0)[0]grid_adaptive = x_sorted[torch.linspace(0, batch - 1, self.grid_size + 1, dtype=torch.int64, device=x.device)]uniform_step = (x_sorted[-1] - x_sorted[0] + 2 * margin) / self.grid_sizegrid_uniform = (torch.arange(self.grid_size + 1, dtype=torch.float32, device=x.device).unsqueeze(1)* uniform_step+ x_sorted[0]- margin)grid = self.grid_eps * grid_uniform + (1 - self.grid_eps) * grid_adaptivegrid = torch.concatenate([grid[:1]- uniform_step* torch.arange(self.spline_order, 0, -1, device=x.device).unsqueeze(1),grid,grid[-1:]+ uniform_step* torch.arange(1, self.spline_order + 1, device=x.device).unsqueeze(1),],dim=0,)self.grid.copy_(grid.T)self.spline_weight.data.copy_(self.curve2coeff(x, unreduced_spline_output))def regularization_loss(self, regularize_activation=1.0, regularize_entropy=1.0):"""Compute the regularization loss.This is a dumb simulation of the original L1 regularization as stated in thepaper, since the original one requires computing absolutes and entropy from theexpanded (batch, in_features, out_features) intermediate tensor, which is hiddenbehind the F.linear function if we want an memory efficient implementation.The L1 regularization is now computed as mean absolute value of the splineweights. The authors implementation also includes this term in addition to thesample-based regularization."""l1_fake = self.spline_weight.abs().mean(-1)regularization_loss_activation = l1_fake.sum()p = l1_fake / regularization_loss_activationregularization_loss_entropy = -torch.sum(p * p.log())return (regularize_activation * regularization_loss_activation+ regularize_entropy * regularization_loss_entropy)class KAN(torch.nn.Module):def __init__(self,layers_hidden,grid_size=5,spline_order=3,scale_noise=0.1,scale_base=1.0,scale_spline=1.0,base_activation=torch.nn.SiLU,grid_eps=0.02,grid_range=[-1, 1],):super(KAN, self).__init__()self.grid_size = grid_sizeself.spline_order = spline_orderself.layers = torch.nn.ModuleList()for in_features, out_features in zip(layers_hidden, layers_hidden[1:]):self.layers.append(KANLinear(in_features,out_features,grid_size=grid_size,spline_order=spline_order,scale_noise=scale_noise,scale_base=scale_base,scale_spline=scale_spline,base_activation=base_activation,grid_eps=grid_eps,grid_range=grid_range,))def forward(self, x: torch.Tensor, update_grid=False):for layer in self.layers:if update_grid:layer.update_grid(x)x = layer(x)return xdef regularization_loss(self, regularize_activation=1.0, regularize_entropy=1.0):return sum(layer.regularization_loss(regularize_activation, regularize_entropy)for layer in self.layers)

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

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

相关文章

Kafka基础入门篇(深度好文)

Kafka简介 Kafka 是一个高吞吐量的分布式的基于发布/订阅模式的消息队列&#xff08;Message Queue&#xff09;&#xff0c;主要应用与大数据实时处理领域。 1. 以时间复杂度为O(1)的方式提供消息持久化能力。 2. 高吞吐率。&#xff08;Kafka 的吞吐量是MySQL 吞吐量的30…

输入法发展历史

输入法的发展历史&#xff0c;尤其是中文输入法&#xff0c;是一个相当丰富和多元的话题&#xff0c;它反映了技术进步、用户需求变化以及计算机和移动设备界面设计的演进。以下是一个概览&#xff1a; 早期阶段 1970s&#xff1a;朱邦复在1976年发明了仓颉输入法&#xff0c;…

python:绘制一元四次函数的曲线

编写 test_x4_x2_4x.py 如下 # -*- coding: utf-8 -*- """ 绘制函数 y x^4x^24x-3 在 -2<x<2 的曲线 """ import numpy as np from matplotlib import pyplot as plt# 用于正常显示中文标题&#xff0c;负号 plt.rcParams[font.sans-s…

Amazon EC2 部署Ollama + webUI

最近和同事闲聊&#xff0c;我们能不能内网自己部署一个LLM&#xff0c;于是便有了Ollama webUI的尝试 对于Linux&#xff0c;使用一行命令即可 curl -fsSL https://ollama.com/install.sh | shollama --help Large language model runnerUsage:ollam…

网络规划设计师教程(第二版) pdf

网络规划设计师教程在网上找了很多都是第一版&#xff0c;没有第二版。 所以去淘宝买了第二版的pdf&#xff0c;与其自己独享不如共享出来&#xff0c;让大家也能看到。 而且这个pdf我已经用WPS扫描件识别过了&#xff0c;可以直接CtrlF搜索关键词&#xff0c;方便查阅。 链接…

PostgreSQL 中如何解决因频繁的小事务导致的性能下降?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中解决因频繁小事务导致性能下降的方法 PostgreSQL 中解决因频繁小事务导致性能下降的方法…

基于SpringBoot的校园志愿者管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot框架 工具&#xff1a;MyEclipse、Tomcat 系统展示 首页 个人中心 志愿者管理 活动信息…

three-tile开发: 5. 取得地图的地面信息

three-tile 是一个开源的轻量级三维瓦片库&#xff0c;它基于threejs使用typescript开发&#xff0c;提供一个三维地形模型&#xff0c;能轻松给你的应用增加三维瓦片地图。 项目地址&#xff1a;GitHub - sxguojf/three-tile: 3D tile map using threejs 示例地址&#xff1a;…

IT运维也有自己的节日 724向日葵IT运维节,三大版本如何选?

“724运维节”&#xff0c;是2016年由开放运维联盟发起倡议&#xff0c;广大运维人员共同投票产生的属于运维人自己的节日。 对于运维人最大的印象&#xff0c;那就是工作都需要7x24小时待命&#xff0c;是名副其实的“日不落骑士”&#xff0c;这也是大家选择724这一天作为运…

原理图大结局

一、总结哪些地方是5V供电&#xff1f;哪些地方是4V供电&#xff1f;哪些地方是3.3V供电&#xff1f;为什么会这样&#xff1f;根据什么原则来划分供电区域&#xff1f; 二、 5V 供电为什么有的地方要100uF&#xff0b; 0.1uF 滤波&#xff1f;有的地方只要 10uF 滤波&#xff…

RabbitMQ - 延迟消息 - 死信交换机

目录 1、怎么理解延迟消息&#xff1f; 2、如何实现延迟消息&#xff1f; 2.1、方案一&#xff1a;死信交换机 2.1.1、什么是死信&#xff1a; 2.1.2、什么是死信交换机&#xff1f; 2.2、方案二&#xff1a;延迟消息插件 2.2.1、插件安装&#xff1a; 2.2.2、代码实现 …

AndroidStudio2023.3版本avd manager模拟器无法创建

创建到最后一步的时候提示WARN - #com.android.sdklib.internal.avd.AvdManager - com.android.prefs.AndroidLocationsException: Can’t locate Android SDK installation directory for the AVD .ini file. 前提&#xff1a; 1.sdk路径没问题 2.安装了下图内容 那是什么原因…

提高项目透明度:有效的跟踪软件

国内外主流的10款项目进度跟踪软件对比&#xff1a;PingCode、Worktile、Teambition、Tower、Asana、Trello、Jira、ClickUp、Notion、Liquid Planner。 在项目管理中&#xff0c;确保进度跟踪的准确性与效率是每位项目经理面临的主要挑战之一。选用合适的项目进度跟踪软件不仅…

【Python进阶】正则表达式、pymysql模块

目录 一、正则表达式的概述 1、基本介绍 2、快速使用re模块 二、正则的常见规则 1、匹配单个字符 2、原始字符串 3、匹配多个字符 4、匹配开头和结尾 5、匹配分组 三、Python与MySQL交互 1、pymysql模块的安装 2、pymysql的操作步骤 3、connection对象 4、cursor…

可重入锁深入学习(有码)

【摘要】 ​今天&#xff0c;梳理下java中的常用锁&#xff0c;但在搞清楚这些锁之前&#xff0c;先理解下 “临界区”。临界区在同步的程序设计中&#xff0c;临界区段活称为关键区块&#xff0c;指的是一个访问共享资源&#xff08;例如&#xff1a;共享设备或是共享存储器&a…

6、evil box one

低—>中 目标&#xff1a;获取root权限以及2个flag 主机发现 靶机 192.168.1100.40 或者使用fping -gaq 192.168.100.1/24发现主机使用ping的方式。 端口扫描 发现开放了22和80 可以使用-A参数&#xff0c;-A参数会得到更多的扫描细节 访问80端口就是一个apache的基本的…

基于Python/MATLAB长时间序列遥感数据处理及在全球变化、植被物候提取、植被变绿与生态系统固碳分析、生物量估算与趋势分析应用

植被是陆地生态系统中最重要的组分之一&#xff0c;也是对气候变化最敏感的组分&#xff0c;其在全球变化过程中起着重要作用&#xff0c;能够指示自然环境中的大气、水、土壤等成分的变化&#xff0c;其年际和季节性变化可以作为地球气候变化的重要指标。此外&#xff0c;由于…

怎么安装Manim库在Windows环境下的Jupyter Notebook上

Manim 是解释性数学视频的动画引擎。 您可以使用它来制作数学视频&#xff08;或其他字段&#xff09;。也许你们会在有有些平台上会看过特别好看的数学动画&#xff0c;例如 3Blue1Brown等。这些动画特别好看&#xff0c;还特别丝滑&#xff0c;基本找不到太大的毛病。 我当初…

推荐 2 个 硬核的 AI 开源项目

01 AI 助手在你的终端中配对编程 Aider 由 Paul Gauthier 精心打造的开源AI配对编程工具&#xff0c;已经在GitHub上赢得了超过 12.8k 颗星星&#xff0c;人气爆棚&#xff01; 这不仅仅是个工具&#xff0c;它是你在终端中的 AI 编程伙伴&#xff0c;帮你编辑存储在本地 Git 仓…

mavsdk_server安卓平台编译

1.下载好mavsdk并进入mavsdk目录 2.生成docker安卓平台文件 docker run --rm dockcross/android-arm64 >./dockcross-android-arm64 3.生成makefile ./dockcross-android-arm64 cmake -DCMAKE_BUILD_TYPERelease -DBUILD_MAVSDK_SERVERON -DBUILD_SHARED_LIBSOFF -Bbuild/…