How to unpack pkl file?

I have a pkl file from MNIST dataset, which consists of handwritten digit images.

I'd like to take a look at each of those digit images, so I need to unpack the pkl file, except I can't find out how.

Is there a way to unpack/unzip pkl file?

340776 次浏览

一般来说

实际上,您的 pkl文件是一个序列化的 pickle文件,这意味着它已经使用 Python 的 pickle模块进行了转储。

要解读数据,你可以这样做:

import pickle




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

For the MNIST data set

注意,只有在压缩文件时才需要 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加载数据。如你所见,这很简单。;-)

巧妙的俏皮话

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

将为 pickle 对象打印 __str__

可视化对象的一般问题当然是未定义的,所以如果 __str__还不够,您将需要一个自定义脚本。

如果您想使用原始 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')

该脚本不会像 pickle 文件中那样对像素值进行标准化。要做到这一点,你只需要

train_images = train_images/255
test_images = test_images/255

需要使用 泡菜(如果压缩了文件,则使用 Gzip)模块

注意: 这些已经在标准的 Python 库中。 No need to install anything new