从 Michael Nielsen 教程问题中加载 MNIST 数据

Posted

技术标签:

【中文标题】从 Michael Nielsen 教程问题中加载 MNIST 数据【英文标题】:Loading MNIST data from Michael Nielsen tutorial problems 【发布时间】:2022-01-21 02:19:00 【问题描述】:

按照 Michael Nielsen 在他的在线书籍《神经网络和深度学习》中指定的方式加载 MNIST 数据时,我遇到了一个棘手的问题。

他提供了一组函数,例如 load_data() 和 load_data_wrapper() 来加载他使用的 MNIST 数据。这是他指定的:

"""
"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

我所做的是简单地创建一个名为“mnist_loader”的类对象,将这些函数定义指定为其参数,即:

class mnist_loader(object):

 def load_data():
 
etc.
etc.

 def vectorized_results():

但是,当我按照他在书中指定的方式运行代码时:

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

我收到以下错误消息:

"NameError: name 'load_data' is not defined"

然后我尝试将他的 GitHub 分叉到我自己的 GitHub 并下载他的 ZIP 文件,然后我简单地将 mnist_loader.py(他为加载数据创建的模块)插入到我当前的工作目录中看看它是否有任何区别 - 但是,它只是给了我同样的错误消息。

为了进一步通知,我已将 gzip.open('./data/mnist.pkl.gz', 'rb') 参数更改为我自己的工作目录,所以这不是我认为的问题。

我不知道还能做什么,但我想克服这个小障碍,因为他的书很有趣。

希望你能帮忙。

干杯。

【问题讨论】:

尝试在包装器中添加 self.load_data() 而不仅仅是 load_data 始终将完整的错误消息(从单词“Traceback”开始)作为文本(不是屏幕截图,不是指向外部门户的链接)(不是在 cmets 中)。还有其他有用的信息。 在课程中使用CamelCaseNames 是一个很好的规则——即。 class MnistLoader(object): - 因为它有助于识别类 MnistLoader 及其实例 mnist_loader = MnistLoader() 如果 mnist_loader 是一个类,那么你必须使用 () 来创建它的实例 - mnist_loader() - 在你使用它的方法之前 - mnist_loader().load_data()mnist_loader().load_data_wrapper() 。如果您使用类名MnistLoader,那么您可以将实例分配给变量mnist_loader = MnistLoader(),然后您就不需要() 来运行它的方法mnist_loader.load_data() 如果你有 mnist_loader.pymnist_loader 而你 import mnist_loader 那么你需要 mnist_loader.mnist_loader().load_data() 【参考方案1】:

数据加载器库旨在完全按照提供的方式使用。你不应该把他们的代码改成一个类,你应该简单地调用模块中提供的函数。

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

应该按原样工作。

语法mnist_loader.load_data_wrapper()表示在模块mnist_loader中调用函数load_data_wrapper()

你也可以这样做:

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

【讨论】:

非常感谢您在这么短的时间内回答(对于稍后的回答,我很抱歉 - 我突然准备了一些圣诞节)。嗯,我可能发现了问题。在教程中,Michael 告诉我们也要导入两个包——他写了“import cPickle”和“import gzip”。我可以毫无问题地导入 gzip,但每当我尝试导入 cPickle 时,我都会收到一条错误消息:“ModuleNotFoundError: No module named 'cPickle”。每当我尝试“导入 mnist_loader”时,我都会收到同样的错误消息 - 它还说没有名为 cPickle 的模块。 是的,当然可以!但是,我似乎还没有完全解决这个问题。名为“cPickle”的包存在一些问题,因为每次我尝试“import mnist_loader”时它都会返回错误消息:“ModuleNotFoundError: No module named 'cPickle”。然后当我尝试“导入 cPickle”时,它返回相同的错误消息。是因为“cPickle”已经过时了吗? 您在问题中显示的代码使用import _pickle as cPickle。那应该有效,不是吗?见***.com/a/37138791/3216427 我希望 import cPickle 会像你说的那样失败,但 import _pickle as cPickle 会起作用。 所以我重新编写了代码,基本上是这样写的: 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) ...等等... 换句话说,我没做到这次是一个类对象,但只是简单地编写了函数的代码并运行了它们,然后我去了:“import mnist_loader”,它仍然给了我找不到模块 cPickle 的错误消息。

以上是关于从 Michael Nielsen 教程问题中加载 MNIST 数据的主要内容,如果未能解决你的问题,请参考以下文章

Jsoup使用教程以及使用案例

图像在 iframe 中加载后未从缓存中加载

PyTorch教程-5:详解PyTorch中加载数据的方法--DatasetDataloaderSamplercollate_fn等

从数组中加载列表

在 Android 中从内存中加载声音

如何在 Symfony 2 中从功能测试中加载固定装置