この記事の目的
MPSYOKOHAMA第10回のDNNの実装で利用する、手書き数字文字の訓練データと教師データのライブラリであるpython-mnistがwindows環境で動かなかったので、無理やり動かした時のメモ
##経緯
・pipでpython-mnist 0.3をインストール
・MINST DATABASEサイトから、train-images-idx3-ubyte.gz:
train-labels-idx1-ubyte.gz:
をダウンロード
・pythonを実行しているディレクトリの中に、mnistとうい名前のフォルダを作成。
・その中に、上記の2ファイルを解凍して、保存。
つまり
実行環境 > mninst > train-images-idx3-ubyte > train-images.idx3-ubyte(ファイル)
実行環境 > mninst > train-labels-idx1-ubyte > train-labels.idx1-ubyte(ファイル)
という状況にした。
それで、読み込もうとしてまず、実行環境下にあるmnistフォルダを指定するのだけど「\」これはwindowsだと¥(半角)。
from mnist import MNIST
mndata = MNIST('.\mnist')
で、その後、ファイルを読み込むために
train_img, train_label = mndata.load_training()
と実行すると、permissionの問題で拒否された云々。。。色々ファイルのパーミッションをいじってみるものの解決はできず。
PermissionError: [Errno 13] Permission denied: '.\\mnist\\train-labels-idx1-ubyte'
でも、直接import osいれてreadしてみるとファイルにアクセスできる状況。う~む。
with open('.\mnist\\train-labels-idx1-ubyte\\train-labels.idx1-ubyte', 'rb') as f:
line = f.readline()
print(line)
>>>b'\x00\x00\x08\x01\x00\x00\xea....
仕方ないので、ライブラリを参考にしながら直接読み込むようにしようかな。
C:\Python34\Lib\site-packages\mnist
ここにある、loader.pyを参考にして、今回必要なことだけができるコードを見様見真似で書くことに。
##実装
本当はかっこよくos.joinみたいのつかって、どんな保存場所でも動くようにしたかったけど実力不足で断念。mnist直下にファイルをおいてそれを読み込むようにした。
実行環境 > mninst > train-images.idx3-ubyte(ファイル)
実行環境 > mninst > train-labels.idx1-ubyte(ファイル)
WMINST.py
# coding: utf-8
import os
import struct
from array import array
class MNIST(object):
def __init__(self):
self.train_img_fname = 'train-images-idx3-ubyte'
self.train_lbl_fname = 'train-labels-idx1-ubyte'
self.train_images = []
self.train_labels = []
def load_training(self): #作業フォルダ内にmninstというフォルダ作って、その中にtrain-images.idx3-ubyte,train-labels.idx1-ubyte入れた。
ims, labels = self.load(('.\mnist\\train-images.idx3-ubyte'),
('.\mnist\\train-labels.idx1-ubyte'))
self.train_images = ims
self.train_labels = labels
return ims, labels
@classmethod
def load(cls, path_img, path_lbl):
with open(path_lbl, 'rb') as file:
magic, size = struct.unpack(">II", file.read(8))
if magic != 2049:
raise ValueError('Magic number mismatch, expected 2049,'
'got {}'.format(magic))
labels = array("B", file.read())
with open(path_img, 'rb') as file:
magic, size, rows, cols = struct.unpack(">IIII", file.read(16))
if magic != 2051:
raise ValueError('Magic number mismatch, expected 2051,'
'got {}'.format(magic))
image_data = array("B", file.read())
images = []
for i in range(size):
images.append([0] * rows * cols)
for i in range(size):
images[i][:] = image_data[i * rows * cols:(i + 1) * rows * cols]
return images, labels
ハマったのはファイルパスを指定するのが、'.\mnist\\train-labels.idx1-ubyte'
のように、最初のmnistフォルダ以降は\\
二つでつなげること。(\\
は¥¥(半角))
このファイルに適当な名前(WMINST.py)つけて、作業ディレクトリに保存して、読み込んだら無事動いた。MNIST()となって、(.\mnist)としないのは、直接ファイルパスをloadできるように書いたから。
from WMNIST import MNIST
mndata = MNIST()
train_img, train_label = mndata.load_training()
どうやら無事動いたみたい。
※正しいかどうかはわかりませんが。。。