2024.7.14周报

news2024/12/25 9:22:06

目录

摘要

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_features
        self.out_features = out_features
        self.grid_size = grid_size
        self.spline_order = spline_order

        h = (grid_range[1] - grid_range[0]) / grid_size
        grid = (
            (
                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_noise
        self.scale_base = scale_base
        self.scale_spline = scale_spline
        self.enable_standalone_scale_spline = enable_standalone_scale_spline
        self.base_activation = base_activation()
        self.grid_eps = grid_eps

        self.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_features

        grid: 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_features
        assert 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()

    @property
    def scaled_spline_weight(self):
        return self.spline_weight * (
            self.spline_scaler.unsqueeze(-1)
            if self.enable_standalone_scale_spline
            else 1.0
        )

    def forward(self, x: torch.Tensor):
        assert x.size(-1) == self.in_features
        original_shape = x.shape
        x = 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_output
        
        output = 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_features
        batch = 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 distribution
        x_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_size
        grid_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_adaptive
        grid = 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 the
        paper, since the original one requires computing absolutes and entropy from the
        expanded (batch, in_features, out_features) intermediate tensor, which is hidden
        behind the F.linear function if we want an memory efficient implementation.

        The L1 regularization is now computed as mean absolute value of the spline
        weights. The authors implementation also includes this term in addition to the
        sample-based regularization.
        """
        l1_fake = self.spline_weight.abs().mean(-1)
        regularization_loss_activation = l1_fake.sum()
        p = l1_fake / regularization_loss_activation
        regularization_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_size
        self.spline_order = spline_order

        self.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 x

    def 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.coloradmin.cn/o/1925912.html

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

相关文章

Vue1-Vue核心

目录 Vue简介 官网 介绍与描述 Vue的特点 与其它 JS 框架的关联 Vue周边库 初识Vue Vue模板语法 数据绑定 el与data的两种写法 MVVM模型 数据代理 回顾Object.defineProperty方法 何为数据代理 Vue中的数据代理 数据代理图示 事件处理 事件的基本使用 事件修…

【Python 项目】类鸟群:仿真鸟群

类鸟群&#xff1a;仿真鸟群 仔细观察一群鸟或一群鱼&#xff0c;你会发现&#xff0c;虽然群体由个体生物组成&#xff0c;但该群体作为一个整体似乎有它自己的生命。鸟群中的鸟在移动、飞越和绕过障碍物时&#xff0c;彼此之间相互定位。受到打扰或惊吓时会破坏编队&#xf…

数据库管理-第218期 服务器内存(20240711)

数据库管理218期 2024-07-11 数据库管理-第218期 服务器内存&#xff08;20240711&#xff09;1 内存2 ECC内存3 原理3.1 多副本传输3.2 纠错码3.3 汉明码 总结 数据库管理-第218期 服务器内存&#xff08;20240711&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文…

TCP三次握手四次挥手原理

学习视频&#xff1a;TCP三次握手四次挥手 TCP报文格式 源端口号和目的端口号&#xff1a;同IP数据报中的源IP与目的IP唯一确定一条TCP连接 序号seq&#xff08;4字节32位&#xff09;:用来标识TCP发端向TCP收端发送的数据字节流 确认序号&#xff08;4字节32位&#xff09;&a…

5.SpringBoot核心源码-启动类源码分析

目录 概述技巧spring boot 如何启动应用程序run方法里面核心逻辑 SpringApplicaiton.run(xxx.class,args)结束 概述 SpringBoot核心源码-启动类源码分析 技巧 如何给外部源码加注释&#xff0c;想要在源码中添加自己的注释&#xff0c;会弹出 file is read only&#xff0c;代…

光电门与电压放大器做电磁感应定律验证实验

根据上述原理可知&#xff0c;实验需要测量的量有两个&#xff1a;挡光时间间隔和挡光时的电压平均值。挡光时间可通过Arduino的数字输入端口采集光电门信号并计算得到&#xff0c;电压值可以通过Arduino的模拟信号输入端口采集。但是由于Arduino的模拟信号输入端只能精确到5mV…

【微信小程序开发】如何定义公共的js函数,其它页面可以调用

在微信小程序开发中&#xff0c;可以通过以下步骤定义和使用公共的 JS 函数&#xff0c;使得其它页面可以调用&#xff1a; 1. 创建一个公共的 JS 文件&#xff1a;在项目的 utils 目录下创建一个 JS 文件&#xff0c;例如 utils/util.js。 2. 定义公共函数&#xff1a;在 uti…

【Python从入门到进阶】60、Pandas中DataFrame对象的操作(一)

接上篇《59、Pandas库中Series对象的操作(二)》 上一篇我们讲解了Series对象的运算、函数应用、时间序列操作&#xff0c;以及Series的案例实践。本篇我们来讲解Pandas中DataFrame对象的操作。 一、DataFrame对象的基本概念及特点 在Pandas库中&#xff0c;DataFrame是一种非…

基于Python+Django+MySQL的心理咨询预约系统

心理咨询预约系统 DjangoMySQL 基于PythonDjangoMySQL的心理咨询预约系统 项目主要依赖Django3.2&#xff0c;MySQL 支持随机验证码生成与登录验证 简介 基于PythonDjangoMySQL的心理咨询预约系统通过连接数据库获取数据&#xff0c;登录新增随机数字验证码验证。具体可以看…

网络请求优化:如何让你的API飞起来

网络请求优化&#xff1a;如何让你的API飞起来 亲爱的开发者朋友们&#xff0c;你是否曾经遇到过这样的场景:用户疯狂点击刷新按钮,你的服务器却像老年人散步一样慢吞吞地响应。或者,你的应用像个贪吃蛇,疯狂吞噬用户的流量包。如果你对这些情况再熟悉不过,那么恭喜你,你正需要…

【Linux】进程间通信(IPC)——匿名管道

目录 为什么要进行进程间通信&#xff1f; 匿名管道的具体实现 pipe创建内存级文件形成管道 pipe的简单使用 匿名管道的四种情况和五种特性 四种情况 五种特性 PIPE_BUF 命令行管道 | 功能代码&#xff1a;创建进程池 为什么要进行进程间通信&#xff1f; 1.数据传输&…

1.27、基于径向基神经网络的曲线拟合(matlab)

1、基于径向基神经网络的曲线拟合简介及原理 1)原理简介 基于径向基神经网络(Radial Basis Function Neural Network, RBFNN)的曲线拟合是一种常用的非线性拟合方法,通过在输入空间中使用径向基函数对数据进行处理,实现对非线性关系的拟合。 RBFNN的基本原理是将输入空…

opencascade AIS_InteractiveContext源码学习8 trihedron display attributes

AIS_InteractiveContext 前言 交互上下文&#xff08;Interactive Context&#xff09;允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是&#xff0c;对于已经被交互上下文识别的交互对象&#xff0c;必须使用上下文方法进行…

Hash表(C++)

本篇将会开始介绍有关于 unordered_map 和 unordered_set 的底层原理&#xff0c;其中底层实现其实就是我们的 Hash 表&#xff0c;本篇将会讲解两种 Hash 表&#xff0c;其中一种为开放定址法&#xff0c;另一种为 hash 桶&#xff0c;在unordered_map 和 unordered_set 的底层…

【Git从入门到精通】——Git常用命令总结

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

火星全球彩色影像图介绍(中分辨率相机)

一、数据基本信息 该数据是利用天问一号轨道器中分辨率相机获取的影像经光度校正、几何校正、全球制图等制作而成的全火星地图数据DOM&#xff0c;每个数据包含一个tif数据文件。该影像图分辨率为76米。 任务型号&#xff1a;天问一号 搭载平台&#xff1a;环绕器 数据获…

批量提取网页表格内容至excel文件

问题背景 将网页的表格内容&#xff08;5237个股票信息&#xff09;复制粘贴到excel文件中 网址&#xff1a;A股上市公司名单-A股上市公司名录-A股上市公司大全-商业计划书-可研报告-中商产业研究院数据库-中商情报网 实现代码 # 导入包 import pandas as pd import time# 创…

[安洵杯 2019]easy_web1

知识点&#xff1a; 1.base64加解密 2.md5加解密 3.md5碰撞绕过强类型比较 4.Linux命令绕过 进入页面发现url地址中存在 img参数和一个cmd参数&#xff0c;img参数看上去像是base64编码&#xff0c;可以去尝试一下解码. 进行了两次base64解密得到3535352e706e67看着像16进制那么…

SSM整合--笔记总结

1.概述 ssm(springmvc spring mybatis)这三个框架的整合。 spring和springmvc他们隶属于一家公司&#xff0c;他们无需整合。 spring和mybatis框架的整合。 spring把mybatis中的配置内容放到自己的配置文件中。因为我们可以让tomcat加载spring配置文件。 思考:mybatis配置文件…

SD card知识学习

一、基础知识 1、简介 SD Card 全称(Secure Digital Memory Card)&#xff0c;日本电子公司松下&#xff08;Panasonic&#xff09;、瑞典公司爱立信&#xff08;Ericsson&#xff09;、德国公司西门子&#xff08;Siemens&#xff09;共同开发的&#xff0c;于1999年发布根…