1

I have a bit of a vexing problem with loading the MNIST data in the way specified by Michael Nielsen in his online book Neural Networks and Deep Learning.

He has supplied a set of functions such as load_data() and load_data_wrapper() for loading the MNIST data he utilizes. This is what he has specified:

"""
"mnist_loader"
A library to load the MNIST image data.  For details of the data
structures that are returned, see the doc strings for ``load_data``
and ``load_data_wrapper``.  In practice, ``load_data_wrapper`` is the
function usually called by our neural network code.
"""

#### Libraries
# Standard library
import _pickle as cPickle
import gzip

# Third-party libraries
import numpy as np

def load_data():
    """Return the MNIST data as a tuple containing the training data,
    the validation data, and the test data.
    The ``training_data`` is returned as a tuple with two entries.
    The first entry contains the actual training images.  This is a
    numpy ndarray with 50,000 entries.  Each entry is, in turn, a
    numpy ndarray with 784 values, representing the 28 * 28 = 784
    pixels in a single MNIST image.
    The second entry in the ``training_data`` tuple is a numpy ndarray
    containing 50,000 entries.  Those entries are just the digit
    values (0...9) for the corresponding images contained in the first
    entry of the tuple.
    The ``validation_data`` and ``test_data`` are similar, except
    each contains only 10,000 images.
    This is a nice data format, but for use in neural networks it's
    helpful to modify the format of the ``training_data`` a little.
    That's done in the wrapper function ``load_data_wrapper()``, see
    below.
    """
    with gzip.open('./data/mnist.pkl.gz', 'rb') as f:
        training_data, validation_data, test_data = cPickle.load(f, encoding='latin1')
    return (training_data, validation_data, test_data)

def load_data_wrapper():
    """Return a tuple containing ``(training_data, validation_data,
    test_data)``. Based on ``load_data``, but the format is more
    convenient for use in our implementation of neural networks.
    In particular, ``training_data`` is a list containing 50,000
    2-tuples ``(x, y)``.  ``x`` is a 784-dimensional numpy.ndarray
    containing the input image.  ``y`` is a 10-dimensional
    numpy.ndarray representing the unit vector corresponding to the
    correct digit for ``x``.
    ``validation_data`` and ``test_data`` are lists containing 10,000
    2-tuples ``(x, y)``.  In each case, ``x`` is a 784-dimensional
    numpy.ndarry containing the input image, and ``y`` is the
    corresponding classification, i.e., the digit values (integers)
    corresponding to ``x``.
    Obviously, this means we're using slightly different formats for
    the training data and the validation / test data.  These formats
    turn out to be the most convenient for use in our neural network
    code."""
    tr_d, va_d, te_d = load_data()
    training_inputs = [np.reshape(x, (784, 1)) for x in tr_d[0]]
    training_results = [vectorized_result(y) for y in tr_d[1]]
    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]))
    return (training_data, validation_data, test_data)

def vectorized_result(j):
    """Return a 10-dimensional unit vector with a 1.0 in the jth
    position and zeroes elsewhere.  This is used to convert a digit
    (0...9) into a corresponding desired output from the neural
    network."""
    e = np.zeros((10, 1))
    e[j] = 1.0
    return e

What I did was to simply create a class object called "mnist_loader" that specified these function definitions as its arguments, i.e.:

class mnist_loader(object):

 def load_data():
 
etc.
etc.

 def vectorized_results():

However, when I run the code as he specified in his book:

training_data, validation_data, test_data = \
mnist_loader.load_data_wrapper()

I get the following error message:

"NameError: name 'load_data' is not defined"

I then tried to fork his GitHub to my own GitHub and downloaded his as a ZIP-file, and then I simply took the mnist_loader.py (the module he created for loading the data) and inserted it into my current working directory to see if it made any difference - however, it simply gave me the samme error message.

For further notice, I have changed gzip.open('./data/mnist.pkl.gz', 'rb') argument to be my own working directory, so this is not the problem I think.

I have no clue what else to do, but I would like to overcome this small hurdle since his book is very interesting.

Hope you can help.

Cheers.

joanis
  • 10,635
  • 14
  • 30
  • 40
Mike
  • 19
  • 2
  • Try to add self.load_data() instead of just load_data in the wrapper – PaoloJ42 Dec 18 '21 at 17:03
  • always put full error message (starting at word "Traceback") in question (not in comments) as text (not screenshot, not link to external portal). There are other useful information. – furas Dec 18 '21 at 19:40
  • it is good rule to use `CamelCaseNames` for classes - ie. `class MnistLoader(object):` - because it help recognize class `MnistLoader` and its instance `mnist_loader = MnistLoader()`. – furas Dec 18 '21 at 19:42
  • if `mnist_loader` is a class then you have to use `()` to create its instance - `mnist_loader()` - before you use its method - `mnist_loader().load_data()` or `mnist_loader().load_data_wrapper()` . If you would use class name `MnistLoader` then you could assign instance to variable `mnist_loader = MnistLoader()` and then you don't need `()` to run its method `mnist_loader.load_data()` – furas Dec 18 '21 at 19:44
  • if you have file `mnist_loader.py` with class `mnist_loader` and you `import mnist_loader` then you need `mnist_loader.mnist_loader().load_data()` – furas Dec 18 '21 at 19:50

1 Answers1

0

The data loader library was intended to be used exactly as provided. You should not change their code into a class, you should simply call the functions from the module as they were provided.

import mnist_loader
training_data, validation_data, test_data = mnist_loader.load_data_wrapper()

should work as is.

The syntax mnist_loader.load_data_wrapper() means call function load_data_wrapper() in module mnist_loader.

You can also do it this way:

from mnist_loader import load_data_wrapper
training_data, validation_data, test_data = load_data_wrapper()
joanis
  • 10,635
  • 14
  • 30
  • 40
  • Thank you very much for answering with such short notice (and sorry for a later answer - I had some Christmas preparations all of a sudden). Hmm, I might have found the problem. In the tutorial Michael stells us to import two packages as well - he writes "import cPickle" and "import gzip". I am able to import gzip with no problems, but whenever I try to import cPickle I get an error message: "ModuleNotFoundError: No module named 'cPickle". I get this same error message whenever I try to "import mnist_loader" - it also says there is no module named cPickle. – Mike Dec 20 '21 at 17:13
  • Yes of course, will do! However, I do not seem to have solved the problem completely yet. There are some problems with a package called "cPickle", since every time I attempt to "import mnist_loader" it returns the error message: "ModuleNotFoundError: No module named 'cPickle". When I then try to "import cPickle" it returns the same error message. Is it because "cPickle" is outdated? – Mike Dec 20 '21 at 17:18
  • The code you show in the question uses `import _pickle as cPickle`. That should work, no? See https://stackoverflow.com/a/37138791/3216427 – joanis Dec 20 '21 at 17:18
  • I would expect `import cPickle` to fail as you say, but `import _pickle as cPickle` to work instead. – joanis Dec 20 '21 at 17:20
  • So I redid the code and basically wrote this: import _pickle as cPickle import gzip import numpy as np def load_data(): f = gzip.open('~/GitHub/Neural network implementation/mnist.pkl.gz', 'rb') training_data, validation_data, test_data = cPickle.load(f) f.close() return (training_data, validation_data, test_data) ...etc... In other words, I did not make it a class object this time, but simply wrote the code for the functions and ran those, and then I went: "import mnist_loader" And it still gave me the error message that module cPickle was not found. – Mike Dec 20 '21 at 19:29
  • I then tried to do this instead: import _pickle as cPickle import gzip import numpy as np import pickle def load_data(): f = gzip.open('~/GitHub/Neural network implementation/mnist.pkl.gz', 'rb') training_data, validation_data, test_data = pickle.load(f) f.close() return (training_data, validation_data, test_data) etc... In other words, I substituted "cPickle" with "pickle" and went through the whole gamut and then I went: "import mnist_loader" And it again gave me the error message: "ModuleNotFoundError: No module named 'cPickle'" – Mike Dec 20 '21 at 19:33
  • It gave me "ModuleNotFoundError: No module named 'cPickle'" even though I changed cPickle to pickle (i.e. instead of using cPickle from "import _pickle as cPickle" I used the "pickle" from "import pickle". Sorry for all the trouble, but I have no idea what the underlying problem seems to be – Mike Dec 20 '21 at 19:37
  • Well, the challenge is all due to this code being fairly old, and the pickle library changing over the years. Ideally the author would maintain it, but that doesn't appear to be the case. I'll try to do some tests on my side and see if I can get further. I'll let you know if I find how it should work in 2021. – joanis Dec 20 '21 at 21:32
  • @Mike Can you specify your OS and the version of Python you're using, since that might make a difference. – joanis Dec 20 '21 at 21:33
  • Well, with Python 3.7 I get a different error: `python3.7 -c "import mnist_loader; mnist_loader.load_data_wrapper()"` gives me `UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 614: ordinal not in range(128)`. (This is after having set the import line to `import _pickle as cPickle`.) I get the same error from Python 3.9. So now I really don't know why you get the error you get at import time. – joanis Dec 20 '21 at 21:40
  • PS: Are you using the code from https://github.com/mnielsen/neural-networks-and-deep-learning or from somewhere else? It would be best if we're testing the same version! – joanis Dec 20 '21 at 21:43
  • OK, I just tested with the version of `mnist_loader.py` you put in the question and that one works as is for me, in both Python 3.7 and 3.9. So I'm back to needing to know your version of Python and OS before I can help any further. – joanis Dec 20 '21 at 21:48