如何解包pkl文件

142 投票
5 回答
445930 浏览
提问于 2025-04-18 14:24

我有一个来自MNIST数据集的pkl文件,这个文件里面包含了手写数字的图片。

我想看看这些数字图片,所以我需要把这个pkl文件解压出来。请问有没有办法解压这个pkl文件呢?

5 个回答

0

Pandas库让解压缩(unpickling)变得非常简单。它在后台使用了标准库中的pickle,但为我们处理了一些常见的问题(比如,要打开一个MNIST的压缩数据,你可能需要传入编码,比如:pickle.load(f, encoding='bytes');这些问题Pandas都帮我们解决了)。

一般来说,要解压一个压缩文件,可以这样使用:

import pandas as pd
data = pd.read_pickle("serialized.pkl")

它也能处理压缩文件。

train_set, valid_set, test_set = pd.read_pickle("mnist.pkl.gz")

你也可以直接传入一个网址:

url = "https://raw.githubusercontent.com/mnielsen/neural-networks-and-deep-learning/master/data/mnist.pkl.gz"
train_set, valid_set, test_set = pd.read_pickle(url)

如果我们把训练集中的第一张图片画出来,并用它的标签作为标题:

import matplotlib.pyplot as plt
plt.imshow(train_set[0][0].reshape((28, 28)), cmap='gray')
plt.gca().set(title=train_set[1][0], xticks=[], yticks=[])

我们会得到如下结果:

result

1 这个网址指向的是存储在Michael Nielsen的神经网络与深度学习的Github仓库中的MNIST数据集。

2

要使用 pickle 模块(如果文件是压缩的,还需要用到 gzip 模块)。

注意:这些模块已经包含在标准的 Python 库里,没必要再安装其他东西。

2

如果你想使用原始的MNIST文件,这里有一个方法可以将它们解压缩。

如果你还没有下载这些文件,先在终端运行下面的命令来下载:

wget http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
wget http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
wget http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
wget http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz

然后把下面的内容保存为 deserialize.py 文件,并运行它。

import numpy as np
import gzip

IMG_DIM = 28

def decode_image_file(fname):
    result = []
    n_bytes_per_img = IMG_DIM*IMG_DIM

    with gzip.open(fname, 'rb') as f:
        bytes_ = f.read()
        data = bytes_[16:]

        if len(data) % n_bytes_per_img != 0:
            raise Exception('Something wrong with the file')

        result = np.frombuffer(data, dtype=np.uint8).reshape(
            len(bytes_)//n_bytes_per_img, n_bytes_per_img)

    return result

def decode_label_file(fname):
    result = []

    with gzip.open(fname, 'rb') as f:
        bytes_ = f.read()
        data = bytes_[8:]

        result = np.frombuffer(data, dtype=np.uint8)

    return result

train_images = decode_image_file('train-images-idx3-ubyte.gz')
train_labels = decode_label_file('train-labels-idx1-ubyte.gz')

test_images = decode_image_file('t10k-images-idx3-ubyte.gz')
test_labels = decode_label_file('t10k-labels-idx1-ubyte.gz')

这个脚本不会像在压缩文件中那样对像素值进行标准化。如果你想要标准化,只需要做以下操作:

train_images = train_images/255
test_images = test_images/255
11

实用的一行代码

pkl() (
  python -c 'import pickle,sys;d=pickle.load(open(sys.argv[1],"rb"));print(d)' "$1"
)
pkl my.pkl

这段代码会打印出被“腌制”的对象的 __str__ 方法的内容。

想要查看一个对象的内容其实是个比较复杂的问题,如果 __str__ 方法提供的信息不够,你可能需要写个自定义的脚本。可以考虑使用 @dataclasspprint,具体可以参考这个链接:有没有内置函数可以打印对象的所有当前属性和它们的值?

批量提取 MNIST -idx3-ubyte.gz 文件为 PNG 格式

你也可以很方便地从这个网站下载官方的数据集文件:http://yann.lecun.com/exdb/mnist/,然后按照下面的方法将它们解压成 PNG 格式:

这些方法使用了来自这个链接的脚本:https://github.com/myleott/mnist_png

相关内容:如何将我的数据集放入一个 .pkl 文件中,格式和数据结构与 "mnist.pkl.gz" 完全相同?

262

一般情况

你的 pkl 文件其实是一个经过序列化的 pickle 文件,这意味着它是通过 Python 的 pickle 模块生成的。

要解压这个数据,你可以:

import pickle


with open('serialized.pkl', 'rb') as f:
    data = pickle.load(f)

关于 MNIST 数据集

注意,只有在文件被压缩的情况下才需要用到 gzip

import gzip
import pickle


with gzip.open('mnist.pkl.gz', 'rb') as f:
    train_set, valid_set, test_set = pickle.load(f)

每个数据集可以进一步划分(比如训练集):

train_x, train_y = train_set

这些就是你数据集中的输入(数字)和输出(标签)。

如果你想显示这些数字:

import matplotlib.cm as cm
import matplotlib.pyplot as plt


plt.imshow(train_x[0].reshape((28, 28)), cmap=cm.Greys_r)
plt.show()

mnist_digit

另外一个选择是查看原始数据:

http://yann.lecun.com/exdb/mnist/

不过这样会比较麻烦,因为你需要写一个程序来读取那些文件中的二进制数据。所以我建议你使用 Python,并用 pickle 来加载数据。正如你所看到的,这非常简单。;-)

撰写回答