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

如何在R的Keras/Torch中为layer_dense输入dgCMatrix稀疏矩阵

解决方法

一、Keras(TensorFlow后端)方案

Keras的layer_dense支持直接处理TensorFlow稀疏张量,无需将dgCMatrix转为稠密格式。核心思路是把dgCMatrix转换成TensorFlow的SparseTensor,再传入模型训练。

修改后完整代码

library(Matrix)
library(keras)
library(reticulate)
library(magrittr)

inputs <- rsparsematrix(10000, 1000, 0.1)
targets <- keras::to_categorical(sample(0:9, 1000, replace = T), num_classes = 10)

# 将dgCMatrix转为TensorFlow SparseTensor(转置为样本×特征维度)
sparse_input <- inputs %>%
  t() %>%
  {
    tf$sparse$SparseTensor(
      indices = matrix(c(.@i, .@j), ncol = 2),  # 0-based索引匹配TensorFlow规则
      values = .@x,
      dense_shape = as.integer(dim(.))
    )
  } %>%
  tf$sparse$reorder()  # 必须确保索引按行优先排序,避免训练报错

# 构建支持稀疏输入的模型
model <- keras_model_sequential() %>%
  layer_input(shape = nrow(inputs), sparse = TRUE) %>%
  layer_dense(units = 100, activation = "relu") %>%
  layer_dense(units = 50, activation = "relu") %>%
  layer_dense(units = ncol(targets), activation = "softmax")

compile(model,
        loss = "categorical_crossentropy",
        optimizer = optimizer_adam(),
        metrics = c("accuracy"))

# 直接用稀疏张量训练,无需转稠密
fit(model, sparse_input, targets, epochs = 10, batch_size = 32)

二、Torch方案

R的torch包原生支持稀疏张量,线性层(nn_linear())可直接处理稀疏输入,效率更适配大数据量场景。

完整代码示例

library(Matrix)
library(torch)

# 生成数据
inputs <- rsparsematrix(10000, 1000, 0.1)
targets <- sample(0:9, 1000, replace = TRUE) %>%
  torch_tensor(dtype = torch_long())  # 分类任务需用long类型标签

# 将dgCMatrix转为Torch稀疏张量(转置为样本×特征维度)
sparse_input <- inputs %>%
  t() %>%
  {
    indices <- torch_tensor(rbind(.@i, .@j), dtype = torch_long())
    values <- torch_tensor(.@x)
    size <- torch_tensor(dim(.))
    torch_sparse_coo_tensor(indices, values, size)
  }

# 定义模型结构
model <- nn_module(
  initialize = function(input_dim, hidden_dim1, hidden_dim2, output_dim) {
    self$fc1 <- nn_linear(input_dim, hidden_dim1)
    self$fc2 <- nn_linear(hidden_dim1, hidden_dim2)
    self$fc3 <- nn_linear(hidden_dim2, output_dim)
  },
  forward = function(x) {
    x %>%
      self$fc1() %>%
      nnf_relu() %>%
      self$fc2() %>%
      nnf_relu() %>%
      self$fc3() %>%
      nnf_log_softmax(dim = 2)
  }
)

net <- model(input_dim = nrow(inputs), hidden_dim1 = 100, hidden_dim2 = 50, output_dim = 10)

# 设置优化器与损失函数
optimizer <- optim_adam(net$parameters, lr = 0.001)
loss_fn <- nn_nll_loss()

# 训练循环
epochs <- 10
batch_size <- 32
num_samples <- ncol(inputs)

for (epoch in 1:epochs) {
  net$train()
  perm <- sample(num_samples)
  total_loss <- 0
  
  for (i in seq(1, num_samples, batch_size)) {
    batch_idx <- perm[i:min(i+batch_size-1, num_samples)]
    # 提取小批量稀疏张量,避免稠密转换
    batch_mask <- inputs@j %in% (batch_idx - 1)
    batch_indices <- rbind(inputs@i[batch_mask], inputs@j[batch_mask])
    batch_values <- inputs@x[batch_mask]
    batch_sparse <- torch_sparse_coo_tensor(
      indices = torch_tensor(batch_indices, dtype = torch_long()),
      values = torch_tensor(batch_values),
      size = torch_tensor(c(nrow(inputs), length(batch_idx)))
    ) %>% t()  # 转置为样本×特征
    
    optimizer$zero_grad()
    output <- net(batch_sparse)
    loss <- loss_fn(output, targets[batch_idx])
    loss$backward()
    optimizer$step()
    
    total_loss <- total_loss + loss$item()
  }
  
  cat(sprintf("Epoch %d, Loss: %.4f\n", epoch, total_loss / ceiling(num_samples / batch_size)))
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 18:55:16