使用R语言Torch库Dataloader拟合模型时遇‘索引从1开始却发现0’错误
解决R Torch库使用Dataloader时的“Indexing starts at 1 but found a 0”报错
问题描述
在使用R语言的Torch和luz库拟合模型时,仅在通过Dataloader而非直接使用Dataset训练时出现报错:Error in to_index_tensor(target) : Indexing starts at 1 but found a 0。模型输入输出均为R对象(向量、矩阵或数组),可复现代码如下:
library(torch) library(luz) # For fit() function x <- torch_randn(1, 9) y <- torch_tensor(as.integer(c(0,0,1))) # y <- torch_tensor(as.integer(1)) # This doesn't give an error if out_features=1 below xy.ds <- tensor_dataset(x,y) xy.dl <- dataloader(xy.ds, batch_size = 1) # Create one-layer linear model linnet <- nn_module( initialize = function() { self$fc <- nn_linear(in_features = 9, out_features = 3) }, forward = function(x) { self$fc(x) } ) fitted <- linnet %>% setup( loss = nn_cross_entropy_loss(), optimizer = optim_adam ) %>% fit(xy.dl, epochs = 1) # Error occurs here # fit(xy.ds, epochs = 1) # No error with direct Dataset use
问题原因
报错根源在于nn_cross_entropy_loss()的R实现要求类别索引必须从1开始,而你的标签y中包含0值。当直接使用Dataset训练时,没有触发严格的索引校验;但Dataloader在批量处理数据时,会调用内部函数to_index_tensor()对标签进行标准化,该函数强制检查索引起始值,因此抛出错误。
解决方案
方案1:调整类别标签为1起始
将所有标签值加1,确保最小索引为1,适配nn_cross_entropy_loss()的要求:
# 修改y的定义,将0转为1,1转为2 y <- torch_tensor(as.integer(c(0,0,1)) + 1)
修改后重新运行代码,Dataloader即可正常工作。
方案2:更换损失函数(针对二分类场景)
如果你的任务是二分类,也可以改用nn_bce_with_logits_loss(),此时标签可以保留0/1格式,但需要调整模型输出层和标签维度:
# 调整模型输出特征数为1 linnet <- nn_module( initialize = function() { self$fc <- nn_linear(in_features = 9, out_features = 1) }, forward = function(x) { self$fc(x) } ) # 转换y为浮点型并调整维度 y <- torch_tensor(as.integer(c(0,0,1)), dtype = torch_float32)$unsqueeze(2) # 使用BCE损失函数 fitted <- linnet %>% setup( loss = nn_bce_with_logits_loss(), optimizer = optim_adam ) %>% fit(xy.dl, epochs = 1)
内容的提问来源于stack exchange,提问作者user29466667
相关产品推荐
相关产品推荐

