You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构建指定连接占比的半全连接神经网络?适配GPU与正交初始化

构建稀疏连接的全连接网络(半全连接网络)

你可以通过生成带稀疏掩码的权重矩阵来实现半全连接网络,这种方法既能满足指定连接占比的需求,又能利用PyTorch的GPU加速能力,避免低效的循环操作。同时也能轻松支持正交初始化,以下是具体实现方案:

核心思路

  1. 为每层权重矩阵生成随机稀疏掩码:掩码中仅保留指定比例的位置为1(代表存在连接),其余为0(无连接)。
  2. 先对全权重矩阵做正交初始化,再与掩码相乘得到稀疏权重,确保保留的连接权重符合正交性要求。
  3. 前向传播直接使用稀疏权重做矩阵乘法,PyTorch会自动处理并行计算并利用GPU加速。

代码实现

1. 稀疏权重生成与正交初始化工具函数

import torch
import torch.nn.init as init

def create_sparse_orthogonal_weights(in_features, out_features, connection_percent):
    # 计算每个输入神经元需要连接的输出神经元数量
    num_connections = int(out_features * connection_percent)
    
    # 初始化全权重矩阵并执行正交初始化
    weights = torch.empty(in_features, out_features)
    init.orthogonal_(weights)
    
    # 生成稀疏掩码:每个输入神经元随机选择指定数量的输出神经元建立连接
    mask = torch.zeros_like(weights)
    for i in range(in_features):
        # 随机挑选不重复的输出神经元索引
        indices = torch.randperm(out_features)[:num_connections]
        mask[i, indices] = 1.
    
    # 应用掩码得到最终的稀疏权重
    sparse_weights = weights * mask
    return sparse_weights

2. 构建10层稀疏连接网络

# 输入张量(可直接移至GPU)
input_tensor = torch.rand(1, 10).cuda() if torch.cuda.is_available() else torch.rand(1, 10)

# 定义网络结构参数
layer_sizes = [10] + [32] * 10  # 输入层10个神经元,后续10层各32个神经元
connection_percent = 0.1        # 每个神经元仅连接下一层10%的神经元

# 生成各层稀疏权重
layers_weights = []
for i in range(len(layer_sizes)-1):
    in_size = layer_sizes[i]
    out_size = layer_sizes[i+1]
    w = create_sparse_orthogonal_weights(in_size, out_size, connection_percent)
    if torch.cuda.is_available():
        w = w.cuda()
    layers_weights.append(w)

# 前向传播计算
x = input_tensor
for w in layers_weights:
    x = torch.sin(torch.mm(x, w))

print(x.shape)  # 输出:torch.Size([1, 32])

优化说明

  • GPU加速:将张量和权重移至GPU后,PyTorch的矩阵乘法会自动调用CUDA并行计算,效率远高于循环实现。
  • 固定连接结构:如果需要训练过程中保持连接结构不变,只需在网络初始化时生成一次掩码即可;若需动态调整连接,可在每次前向传播时重新生成掩码(不推荐,会增加计算开销)。
  • 内存优化(可选):如果网络规模极大,可使用PyTorch的torch.sparse.Tensor存储稀疏权重,进一步降低内存占用:
def create_sparse_tensor_weights(in_features, out_features, connection_percent):
    num_connections = int(out_features * connection_percent)
    total_nonzeros = in_features * num_connections
    
    # 生成非零元素的行列索引
    rows = torch.repeat_interleave(torch.arange(in_features), num_connections)
    cols = torch.cat([torch.randperm(out_features)[:num_connections] for _ in range(in_features)])
    
    # 生成归一化的权重值(模拟正交初始化效果)
    weights = torch.empty(total_nonzeros)
    init.normal_(weights)
    weights = weights.view(in_features, num_connections)
    weights = torch.nn.functional.normalize(weights, p=2, dim=1)
    weights = weights.flatten()
    
    # 创建稀疏张量
    sparse_weights = torch.sparse_coo_tensor(
        torch.stack([rows, cols]),
        weights,
        size=(in_features, out_features),
        device='cuda' if torch.cuda.is_available() else 'cpu'
    )
    return sparse_weights

使用时前向传播改为torch.sparse.mm(x, sparse_weights)即可。

内容的提问来源于stack exchange,提问作者Penguin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 17:12:54