如何解包pkl文件
我有一个来自MNIST数据集的pkl文件,这个文件里面包含了手写数字的图片。
我想看看这些数字图片,所以我需要把这个pkl文件解压出来。请问有没有办法解压这个pkl文件呢?
5 个回答
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=[])
我们会得到如下结果:
1 这个网址指向的是存储在Michael Nielsen的神经网络与深度学习的Github仓库中的MNIST数据集。
如果你想使用原始的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
实用的一行代码
pkl() (
python -c 'import pickle,sys;d=pickle.load(open(sys.argv[1],"rb"));print(d)' "$1"
)
pkl my.pkl
这段代码会打印出被“腌制”的对象的 __str__
方法的内容。
想要查看一个对象的内容其实是个比较复杂的问题,如果 __str__
方法提供的信息不够,你可能需要写个自定义的脚本。可以考虑使用 @dataclass
和 pprint
,具体可以参考这个链接:有没有内置函数可以打印对象的所有当前属性和它们的值?
批量提取 MNIST -idx3-ubyte.gz
文件为 PNG 格式
你也可以很方便地从这个网站下载官方的数据集文件:http://yann.lecun.com/exdb/mnist/,然后按照下面的方法将它们解压成 PNG 格式:
这些方法使用了来自这个链接的脚本:https://github.com/myleott/mnist_png
一般情况
你的 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()
另外一个选择是查看原始数据:
http://yann.lecun.com/exdb/mnist/
不过这样会比较麻烦,因为你需要写一个程序来读取那些文件中的二进制数据。所以我建议你使用 Python,并用 pickle
来加载数据。正如你所看到的,这非常简单。;-)