Python3导入Michael Nielsen MNIST加载器报UnicodeDecodeError
报错根因
你使用的mnist_loader.py是原教材针对Python2环境编写的版本,在Python3环境下运行存在两处兼容性问题:
- pickle加载逻辑不兼容:Python3的
pickle.load默认使用ASCII编码读取序列化文件,而配套的MNIST数据集pkl压缩包是在Python2环境下序列化生成的,编码不匹配直接触发UnicodeDecodeError - zip返回值类型不兼容:Python2中
zip()返回可重复遍历的列表,Python3中zip()返回一次性迭代器,就算解码问题修复,后续网络训练遍历一次数据后迭代器就会清空,会出现数据集为空的异常
修复步骤
- 修复pickle解码错误
打开mnist_loader.py,找到load_data()函数中的数据加载行,给cpickle.load传入encoding='latin1'参数,修改后对应代码段为:
f = gzip.open('../data/mnist.pkl.gz', 'rb') training_data, validation_data, test_data = cpickle.load(f, encoding='latin1') f.close()
- 修复zip返回值兼容问题
找到load_data_wrapper()函数中三处调用zip()的位置,给所有zip返回值外层套上list()转换为可重复遍历的列表,修改后对应代码段为:
training_data = list(zip(training_inputs, training_results)) validation_inputs = [np.reshape(x, (784, 1)) for x in va_d[0]] validation_data = list(zip(validation_inputs, va_d[1])) test_inputs = [np.reshape(x, (784, 1)) for x in te_d[0]] test_data = list(zip(test_inputs, te_d[1]))
修改完成后保存文件,重新在Python交互环境执行导入和加载逻辑即可正常运行,不会再抛出解码错误,后续网络训练也能正常读取数据集。
内容的提问来源于stack exchange,提问作者luc
相关产品推荐
相关产品推荐

