神经网络无输出故障:大CSV分块读取后训练停滞问题
解决你的神经网络分块训练卡住问题
嘿,我看了你的代码,程序卡住没输出、资源没负载的问题其实是几个明显的代码错误导致的,咱们一步步来解决:
核心问题分析
- 凭空调用未定义的函数:你代码里的
process(chunk)和get_chunk()完全没实现啊!程序运行到这里要么直接抛错,要么在某些环境下卡住不动——你没看到错误可能是因为Shell的输出被压制了。 - 离谱的
chunksize设置:10**8也就是1亿行,14GB的CSV总行数估计都没这么多,pandas会尝试一次性读整个文件,这要么慢到假死,要么直接内存爆炸,但你说CPU内存没负载,那肯定是前面的未定义函数先出问题了。 - 测试部分的变量未定义:你把
test_data_list的读取代码注释掉了,但后面直接用这个变量,这肯定会触发错误。 - 分块读取逻辑错了:pandas的
read_csv返回的chunk本身就是DataFrame,直接遍历行就行,不需要额外的process和get_chunk操作。
修复后的完整代码
我把所有问题都修正了,还加了一些实用的进度提示,你直接用就行:
import numpy as np import scipy.special from tqdm import tqdm import pandas as pd class neuralNetwork: def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate): self.inode = inputnodes self.hnode = hiddennodes self.onode = outputnodes # 修正权重初始化的方差计算:输入层到隐藏层应该用输入节点数的倒数开方 self.wih = np.random.normal(0.0, pow(self.inode, -0.5), (self.hnode, self.inode)) self.who = np.random.normal(0.0, pow(self.hnode, -0.5), (self.onode, self.hnode)) self.lr = learningrate self.activation_function = lambda x: scipy.special.expit(x) def train(self, inputs_list, targets_list): inputs = np.array(inputs_list, ndmin=2).T targets = np.array(targets_list, ndmin=2).T hidden_inputs = np.dot(self.wih, inputs) hidden_outputs = self.activation_function(hidden_inputs) final_inputs = np.dot(self.who, hidden_outputs) final_outputs = self.activation_function(final_inputs) output_errors = targets - final_outputs hidden_errors = np.dot(self.who.T, output_errors) self.who += self.lr * np.dot((output_errors * final_outputs * (1.0 - final_outputs)), np.transpose(hidden_outputs)) self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), np.transpose(inputs)) def test(self, inputs_list): inputs = np.array(inputs_list, ndmin=2).T hidden_inputs = np.dot(self.wih, inputs) hidden_outputs = self.activation_function(hidden_inputs) final_inputs = np.dot(self.who, hidden_outputs) final_outputs = self.activation_function(final_inputs) return final_outputs # 超参数设置 input_nodes = 784 hidden_nodes = 500 output_nodes = 10 learning_rate = 0.1 epochs = 5 # 调整chunksize为合理值,10000行适合大多数内存情况,你可以根据自己的机器调整 chunksize = 10000 n = neuralNetwork(input_nodes, hidden_nodes, output_nodes, learning_rate) # 训练部分:修正分块读取逻辑 for e in range(epochs): print(f"开始训练第 {e+1} 轮") # 遍历每个chunk for chunk in pd.read_csv('C:/Users/Anwender/Documents/Uni/KI/Python/train.csv', chunksize=chunksize): # 用iterrows遍历chunk的每一行,tqdm显示进度 for _, row in tqdm(chunk.iterrows(), total=len(chunk)): all_values = row.values # 预处理输入数据 inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 targets = np.zeros(output_nodes) + 0.01 targets[int(float(all_values[0]))] = 0.99 n.train(inputs, targets) # 测试部分:修正分块读取和变量未定义问题 scorecard = [] print("开始测试模型") for chunk in pd.read_csv('C:/Users/Anwender/Documents/Uni/KI/Python/test.csv', chunksize=chunksize): for _, row in tqdm(chunk.iterrows(), total=len(chunk)): all_values = row.values correct_label = int(all_values[0]) inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 outputs = n.test(inputs) label = np.argmax(outputs) scorecard.append(1 if label == correct_label else 0) scorecard_array = np.asarray(scorecard) print(f"Genauigkeit = {scorecard_array.sum() / scorecard_array.size}")
关键修改点说明
- 删掉无效函数调用:移除了
process(chunk)和get_chunk(),直接用chunk.iterrows()遍历每一行数据。 - 调整
chunksize:把1亿行改成了1万行,这个值可以根据你的内存大小调整——如果内存大可以调大,内存小就调小,确保每个chunk能被高效处理。 - 修复权重初始化错误:原来输入层到隐藏层的权重方差用错了节点数,现在改成了输入节点数的倒数开方,这是神经网络权重初始化的标准做法。
- 测试部分重构:去掉了未定义的
test_data_list,直接用分块读取测试数据,和训练逻辑保持一致。 - 添加进度提示:每轮训练开始时打印提示,配合
tqdm显示处理进度,这样你能直观看到程序在运行,不会以为卡住了。
额外排查建议
如果修改后还是有问题,可以按以下步骤排查:
- 先测小数据集:先用CSV的前1000行测试代码,确认逻辑没问题后再跑全量数据。
- 检查CSV格式:确保train.csv和test.csv的第一列是标签,后面784列是图像像素值,没有缺失值或格式错误。
- 命令行运行脚本:如果Python Shell看不到错误,试试在命令行运行脚本,这样能看到完整的错误信息,方便排查。
内容的提问来源于stack exchange,提问作者mugdi
相关产品推荐
相关产品推荐

