PyTorch训练神经网络报'int' object is not iterable错误排查
报错原因
触发TypeError: 'int' object is not iterable的核心原因是切片代码的括号位置写错了:
- Python内置
min()函数要求传入至少2个可比较的参数,或者1个可迭代对象,你写的min(x_train.shape[0])只传入了单个整数值,min()会尝试遍历这个整数求最小值,整数本身不可迭代,直接触发报错。 - 本质是写代码时笔误把切片的右括号提前闭合了,本来应该放在
i+batch_size后面的括号,错放到了x_train.shape[0]后面,导致i+batch_size被错误识别为张量第二个维度的索引,完全偏离了分批取数的逻辑。
你提到参考资料里代码完全相同,大概率是抄代码的时候漏看了括号位置,或者资料本身的代码排版存在括号错位的问题。
目标代码行的设计原意
你询问的input_data=x_train[i:min(x_train.shape[0]),i+batch_size]本来是用来实现训练集按批次读取的逻辑:
- 神经网络训练时不会一次性把所有训练集输入模型,会按
batch_size设定的大小,每次取一小批样本做前向传播、更新权重。 - 循环里的
i是当前批次的起始索引,从0开始每次递增batch_size,正常情况下批次的结束索引是i+batch_size。 - 调用
min()是为了防止索引越界:当遍历到数据集最后一段时,剩下的样本数可能不足batch_size,这时候直接取到数据集末尾(也就是x_train.shape[0],即样本总数)即可,不会触发索引越界错误。 - 这行逻辑只需要对张量的第0维(也就是样本维度)做切片,第二个及之后的特征/通道维度默认全部保留,不需要额外写索引。
修正方案
把分批取数的两行代码的括号位置调整正确即可,修改后的对应代码段如下:
for i in range(0,x_train.shape[0],batch_size): # 修正括号位置,正确计算批次结束索引 batch_end = min(i + batch_size, x_train.shape[0]) input_data = x_train[i:batch_end] labels = y_train[i:batch_end] # 后续训练逻辑不变 optimizer.zero_grad() output_data = model(input_data) loss = loss_function(output_data, labels) loss.backward() optimizer.step() # 按当前批次实际样本数累计损失,避免最后一个批次样本数不足时统计错误 train_loss += loss.item() * input_data.shape[0]
另外代码里还有两个容易触发后续报错的小问题可以一并修正:
- 存每轮损失的
loss_for_every_epoch不要用nn.ModuleList,这个类是专门用来存储神经网络层的,存普通浮点数损失用普通Python列表即可,改成loss_for_every_epoch = [] - 训练函数里预测阶段用到了
x_test,但没有作为参数传入函数,调用时会触发未定义错误,需要把x_test加到train_network的参数列表里。
内容的提问来源于stack exchange,提问作者David manga
相关产品推荐
相关产品推荐

