最近在学习《Neural Networks and Deep Learning》这本书,其中在运行第一个程序时遇到一些问题,现总结记录如下。
1、书中的源代码给的都是基于python2的,有几个函数在python3中做了改动,因此将源代码在python3上运行肯定报错,有两种方法解决,要么下载python2,要么改代码,我选择了第二张方式。
我用的是python自带的IDLE,因此为了避免每次都在IDLE输入代码,所以创建了一个py文件,其中是书中写的用来执行BP神经网络的代码,即:
import mnist_loader
import network
training_data, validation_data, test_data =mnist_loader.load_data_wrapper()
net = network.Network([784, 30, 10])
net.SGD(training_data, 30, 10, 3.0, test_data=test_data)
随意起了个名字,就叫1.py,运行程序会发现程序会报错,接下来一一解决这些因为python版本不同导致的错误。
改动1:ModuleNotFoundError: No module named ‘cPickle’
查看报错信息,
Traceback (most recent call last):
File "E:\python\daima\neural-networks-and-deep-learning-master-python2\neural-networks-and-deep-learning-master\src\1.py", line 1, in <module>
import mnist_loader
File "E:\python\daima\neural-networks-and-deep-learning-master-python2\neural-networks-and-deep-learning-master\src\mnist_loader.py", line 13, in <module>
import cPickle
ModuleNotFoundError: No module named 'cPickle'
可以看出cPickle这个函数在python3中已经没有了,只保留了pickle这个函数,两个功能一样,在mnist_loader.py文件中做相应改动:
改动前:import cPickle
改动后:import pickle
同时在引用cPickle函数的地方也要做相应的修改,就是data_load函数中的 training_data, validation_data, test_data = cPickle.load(f)
改成 training_data, validation_data, test_data = pickle.load(f)
改动后保存mnist_loader.py文件并关闭,再重新运行前面的执行程序,(重新运行执行程序1.py前一定要保存改动过的程序,不然相当于没保存),此时发现第二个错误。
改动2:SyntaxError: invalid syntax
Traceback (most recent call last):
File "E:\python\daima\neural-networks-and-deep-learning-master-python2\neural-networks-and-deep-learning-master\src\1.py", line 2, in <module>
import network
File "E:\python\daima\neural-networks-and-deep-learning-master-python2\neural-networks-and-deep-learning-master\src\network.py", line 64
print "Epoch {0}: {1} / {2}".format(
^
SyntaxError: invalid syntax
报错文件为:network.py,这是因为python3中print函数必须要用()把输出内容括起来。一定要用英文括号,不能用中文括号
改动前:
` if test_data:
print "Epoch {0}: {1} / {2}".format(
j, self.evaluate(test_data), n_test)
else:
print "Epoch {0} complete".format(j)`
改动后:
if test_data:
print ("Epoch {0}: {1} / {2}".format(
j, self.evaluate(test_data), n_test))
else:
print ("Epoch {0} complete".format(j))
保存并运行,继续报错。
改动3:UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0x90 in position 614: ordinal not in range(128)
这是默认编码格式错误造成的,可能早期的编码方式和python3编码方式不一样,有兴趣的可以自行搜索,这个问题在mnist_loader.py文件的load_data函数做改动开始添加:
改动前:
`training_data, validation_data, test_data = pickle.load(f)`
改动后:
training_data, validation_data, test_data = pickle.load(f, encoding='bytes')
即可解决。
改动4:TypeError: object of type ‘zip’ has no len()
这个是因为python2和3不同版本zip格式运行机制不同,python2返回一个list,而python3只返回一个对象,
参考:zip函数报错
在执行文件1.py中做如下改动:
改动前:
import mnist_loader
import network
training_data, validation_data, test_data =mnist_loader.load_data_wrapper()
net = network.Network([784, 30, 10])
net.SGD(training_data, 30, 10, 3.0, test_data=test_data)
改动后:
import mnist_loader
import network
training_data, validation_data, test_data =mnist_loader.load_data_wrapper()
net = network.Network([784, 30, 10])
training_data=list(training_data)
test_data=list(test_data)
validation_data=list(validation_data)
net.SGD(training_data, 30, 10, 3.0, test_data=test_data)
添加了三行数据处理代码,目的是从zip函数的对象中获得list数据。保存文件运行,继续报错。
改动5:NameError: name ‘xrange’ is not defined
这个错误也是因为版本不同造成的,参加传送门:
参考:xrange报错
安装错误提示的位置把所有xrange改成range即可。
至此,大功告成!
文件:传送门