柯尔莫戈罗夫-阿诺德网络层(Fourier层,Laplace层,Legendre层,Wavelet层)

Fourier层

python 复制代码
improt torch
import torch.nn as nn
class NaiveFourierKANLayer(nn.Module):
    def __init__(self, inputdim, outdim, initial_gridsize, addbias=True):
        super(NaiveFourierKANLayer, self).__init__()
        self.addbias = addbias
        self.inputdim = inputdim
        self.outdim = outdim

        # Learnable gridsize parameter
        self.gridsize_param = nn.Parameter(torch.tensor(initial_gridsize, dtype=torch.float32))

        # Fourier coefficients as a learnable parameter with Xavier initialization
        self.fouriercoeffs = nn.Parameter(torch.empty(2, outdim, inputdim, initial_gridsize))
        nn.init.xavier_uniform_(self.fouriercoeffs)

        if self.addbias:
            self.bias = nn.Parameter(torch.zeros(1, outdim))

    def forward(self, x):
        gridsize = torch.clamp(self.gridsize_param, min=1).round().int()
        xshp = x.shape
        outshape = xshp[:-1] + (self.outdim,)
        x = torch.reshape(x, (-1, self.inputdim))
        k = torch.reshape(torch.arange(1, gridsize + 1, device=x.device), (1, 1, 1, gridsize))
        xrshp = torch.reshape(x, (x.shape[0], 1, x.shape[1], 1))
        c = torch.cos(k * xrshp)
        s = torch.sin(k * xrshp)
        y = torch.sum(c * self.fouriercoeffs[0:1, :, :, :gridsize], (-2, -1))
        y += torch.sum(s * self.fouriercoeffs[1:2, :, :, :gridsize], (-2, -1))
        if self.addbias:
            y += self.bias
        y = torch.reshape(y, outshape)
        return y

Laplace层

python 复制代码
import torch
import torch.nn as nn

class NaiveLaplaceKANLayer(nn.Module):
    def __init__(self, inputdim, outdim, initial_gridsize, addbias=True):
        super(NaiveLaplaceKANLayer, self).__init__()
        self.addbias = addbias
        self.inputdim = inputdim
        self.outdim = outdim

        # Learnable gridsize parameter
        self.gridsize_param = nn.Parameter(torch.tensor(initial_gridsize, dtype=torch.float32))

        # Laplace coefficients as a learnable parameter with Xavier initialization
        self.laplacecoeffs = nn.Parameter(torch.empty(2, outdim, inputdim, initial_gridsize))
        nn.init.xavier_uniform_(self.laplacecoeffs)

        if self.addbias:
            self.bias = nn.Parameter(torch.zeros(1, outdim))

    def forward(self, x):
        gridsize = torch.clamp(self.gridsize_param, min=1).round().int()
        xshp = x.shape
        outshape = xshp[:-1] + (self.outdim,)
        x = torch.reshape(x, (-1, self.inputdim))

        # Create a grid of lambda values
        lambdas = torch.reshape(torch.linspace(0.1, 1., gridsize, device=x.device), (1, 1, 1, gridsize))
        xrshp = torch.reshape(x, (x.shape[0], 1, x.shape[1], 1))

        # Exponential functions for Laplace transform
        exp_neg = torch.exp(-lambdas * xrshp)
        exp_pos = torch.exp(lambdas * xrshp)

        # Applying Laplace coefficients to the input
        y = torch.sum(exp_neg * self.laplacecoeffs[0:1, :, :, :gridsize], (-2, -1))
        y += torch.sum(exp_pos * self.laplacecoeffs[1:2, :, :, :gridsize], (-2, -1))

        if self.addbias:
            y += self.bias
        y = torch.reshape(y, outshape)
        return y

Legendre层

python 复制代码
import torch
import torch.nn as nn

class RecurrentLegendreLayer(nn.Module):
    def __init__(self, max_degree, input_dim, output_dim):
        super(RecurrentLegendreLayer, self).__init__()
        self.max_degree = max_degree
        self.input_dim = input_dim
        self.output_dim = output_dim

        # Parameters for the linear combination of Legendre polynomials
        # Adjust dimensions: one set of weights for each polynomial degree, across all input/output dimension pairs
        self.weights = nn.Parameter(torch.randn(max_degree + 1, self.input_dim, self.output_dim))
        # nn.init.xavier_normal_(self.weights)
        nn.init.orthogonal_(self.weights)
        # nn.init.kaiming_normal_(self.weights)


        self.dropout = nn.Dropout(.1)
        # Optional: Bias for each output dimension
        self.bias = nn.Parameter(torch.zeros(self.output_dim))

    def forward(self, x):
        batch_size = x.shape[0]

        # Initialize P0 and P1 for the recurrence relation
        P_n_minus_2 = torch.ones((batch_size, self.input_dim), device=x.device)
        P_n_minus_1 = x.clone()

        # Store all polynomial values
        polys = [P_n_minus_2.unsqueeze(-1), P_n_minus_1.unsqueeze(-1)]

        # Compute higher order polynomials up to max_degree
        for n in range(2, self.max_degree + 1):
            P_n = ((2 * n - 1) * x * P_n_minus_1 - (n - 1) * P_n_minus_2) / n
            polys.append(P_n.unsqueeze(-1))
            P_n_minus_2, P_n_minus_1 = P_n_minus_1, P_n

        # Concatenate all polynomial values
        polys = torch.cat(polys, dim=-1)  # Shape: [batch_size, input_dim, max_degree + 1]
        polys = self.dropout(polys)
        # Linearly combine polynomial features
        output = torch.einsum('bif,fio->bo', polys, self.weights) + self.bias

        return output

Wavelet层

python 复制代码
import torch
import torch.nn as nn
import numpy as np

class NaiveWaveletKANLayer(nn.Module):
    def __init__(self, inputdim, outdim, initial_gridsize, addbias=True):
        super(NaiveWaveletKANLayer, self).__init__()
        self.addbias = addbias
        self.inputdim = inputdim
        self.outdim = outdim

        # Learnable gridsize parameter
        self.gridsize_param = nn.Parameter(torch.tensor(initial_gridsize, dtype=torch.float32))

        # Wavelet coefficients as a learnable parameter with Xavier initialization
        self.waveletcoeffs = nn.Parameter(torch.empty(2, outdim, inputdim, initial_gridsize))
        nn.init.xavier_uniform_(self.waveletcoeffs)

        if self.addbias:
            self.bias = nn.Parameter(torch.zeros(1, outdim))

    def forward(self, x):
        gridsize = torch.clamp(self.gridsize_param, min=1).round().int()
        xshp = x.shape
        outshape = xshp[:-1] + (self.outdim,)
        x = torch.reshape(x, (-1, self.inputdim))

        # Create a range of scales and translations for the wavelet
        scales = torch.linspace(1, gridsize, gridsize, device=x.device).unsqueeze(0).unsqueeze(0).unsqueeze(0)
        translations = torch.linspace(0, 1, gridsize, device=x.device).unsqueeze(0).unsqueeze(0).unsqueeze(0)

        # Morlet wavelet calculations
        xrshp = torch.reshape(x, (x.shape[0], 1, x.shape[1], 1))
        u = (xrshp - translations) * scales
        real = torch.cos(np.pi*u) * torch.exp(-u**2 /2.)
        imag = torch.sin(np.pi*u) * torch.exp(-u**2 /2.)

        # Apply wavelet coefficients to the wavelet transform outputs
        y_real = torch.sum(real * self.waveletcoeffs[0:1, :, :, :gridsize], (-2, -1))
        y_imag = torch.sum(imag * self.waveletcoeffs[1:2, :, :, :gridsize], (-2, -1))
        y = y_real + y_imag

        if self.addbias:
            y += self.bias
        y = torch.reshape(y, outshape)
        return y

工学博士,担任《Mechanical System and Signal Processing》《中国电机工程学报》《控制与决策》等期刊审稿专家,擅长领域:现代信号处理,机器学习,深度学习,数字孪生,时间序列分析,设备缺陷检测、设备异常检测、设备智能故障诊断与健康管理PHM等。

相关推荐
Java后端的Ai之路17 分钟前
Python进阶探索17 - Python中的深拷贝与浅拷贝
人工智能·python·ai·浅拷贝·深拷贝
知识分享小能手33 分钟前
深度学习学习教程,从入门到精通,深度生成模型 —— 知识点详解与代码实现(20)
人工智能·深度学习·学习
hzxxxz44 分钟前
26%的研发交给AI之后-人的位置换到了哪里
人工智能
m0_587383001 小时前
深圳24小时自助健身房系统软件开发实战:架构设计与部署指南
人工智能·数据挖掘·系统架构·需求分析
Joy T1 小时前
Spring AI 2.0 Agent 进阶:Memory、State 与 Context Engineering 常见技术全景
java·人工智能·后端·spring·agent入门·agent state
估值探索者1 小时前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
西柚研究生1234561 小时前
论文分析17:YOLOv11_UAVNet:无人机航拍图像专用目标检测算法
人工智能·python·深度学习·算法·目标检测
m4Rk_1 小时前
【论文阅读】Agent 记忆机制(74):CompassMem——从相似度检索走向事件图上的记忆导航
论文阅读·人工智能·学习·开源·github
镭封1 小时前
短剧多人对白怎么配?一人完成多角色配音的办法
人工智能·音视频·语音识别·媒体