← 返回卷宗
數據預測

CNTK研究(一):MNIST的文件轉換

CNTKDeep LearningMNIST神經網絡

CNTK的MNIST例子中,它是一個py文件,首先是將圖像文件轉換為文本來表達,以方便CNTK中讀取。

文件位置:\cntk\Examples\Image\DataSets\MNIST\mnist_utils.py

import sys
import urllib
import gzip
import shutil
import os
import struct
import numpy as np

//定義一個讀數據的函數

def loadData(src, cimg):
 print ('Downloading ' + src)
 gzfname, h = urllib.urlretrieve(src, './delete.me')  //從URL下載該數據文件
 print ('Done.')
 try:
 with gzip.open(gzfname) as gz: //使用gzip打開它
 n = struct.unpack('I', gz.read(4)) //讀4個字節解包成無符號整型
 # Read magic number.
 if n[0] != 0x3080000: //如果文件開頭不對,則認為文件不對
 raise Exception('Invalid file: unexpected magic number.')
 # Read number of entries.
 n = struct.unpack('>I', gz.read(4))[0]  //再讀4個字節解包成無符號整型
 if n != cimg: //如果不屬於圖像文件,則拋出異常
 raise Exception('Invalid file: expected {0} entries.'.format(cimg)) 
 crow = struct.unpack('>I', gz.read(4))[0] //讀取4個數據為行
 ccol = struct.unpack('>I', gz.read(4))[0]  //讀取4個字節為列
 if crow != 28 or ccol != 28: //如果行與列不等於28,說明圖像文件有誤
 raise Exception('Invalid file: expected 28 rows/cols per image.')
 # Read data.  //讀取數據,後面需要讀取的大小為 行乘以列再乘以表達每個象素需要多少字節便是總長度
 res = np.fromstring(gz.read(cimg * crow * ccol), dtype = np.uint8) //
 finally:
 os.remove(gzfname)
 return res.reshape((cimg, crow * ccol))  //返回數據時,排成2維數組表達

//讀取標籤文件

def loadLabels(src, cimg):
 print 'Downloading ' + src
 gzfname, h = urllib.urlretrieve(src, './delete.me')
 print 'Done.'
 try:
 with gzip.open(gzfname) as gz:
 n = struct.unpack('I', gz.read(4))
 # Read magic number.
 if n[0] != 0x1080000:
 raise Exception('Invalid file: unexpected magic number.')
 # Read number of entries.
 n = struct.unpack('>I', gz.read(4))
 if n[0] != cimg:
 raise Exception('Invalid file: expected {0} rows.'.format(cimg))
 # Read labels.
 res = np.fromstring(gz.read(cimg), dtype = np.uint8)
 finally:
 os.remove(gzfname)
 return res.reshape((cimg, 1))//同樣返回2維數組表達


if __name__ == "__main__":
 trnData = loadData('http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz', 60000) //下載圖像文件
 trnLbl = loadLabels('http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz', 60000) //下載標籤文件
 trn = np.hstack((trnLbl, trnData)) //將數組進行合併
 print 'Writing train text file...'
 np.savetxt(r'./../Data/Train-28x28.txt', trn, fmt = '%u', delimiter='\t') //將數組用文本形式保存
 print 'Done.'
 testData = loadData('http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz', 10000) //下載測試數據
 testLbl = loadLabels('http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz', 10000) //下載測試標籤
 test = np.hstack((testLbl, testData)) //將數組進行合併
 print 'Writing test text file...'
 np.savetxt(r'./../Data/Test-28x28.txt', test, fmt = '%u', delimiter='\t') //轉寫為 txt 文件
 print 'Done.'

 

然而這有個問題,在國內下得太慢,所以修改了下文件,將:

def loadData(src, cimg):
 print ('Downloading ' + src)
 gzfname, h = urllib.urlretrieve(src, './delete.me')  //從URL下載該數據文件

均修改為:

def loadLabels(gzfname, cimg):
 #print ('Downloading ' + src)
 #gzfname, h = urlretrieve(src, './delete.me')

然後將install_mnist.py文件修改為:

from __future__ import print_function
import mnist_utils as ut

if __name__ == "__main__":
 train = ut.load('./train-images-idx3-ubyte.gz',
 './train-labels-idx1-ubyte.gz', 60000)
 print ('Writing train text file...')
 ut.savetxt(r'./Train-28x28_cntk_text.txt', train)
 print ('Done.')
 test = ut.load('./t10k-images-idx3-ubyte.gz',
 './t10k-labels-idx1-ubyte.gz', 10000)
 print ('Writing test text file...')
 ut.savetxt(r'./Test-28x28_cntk_text.txt', test)
 print ('Done.')

找個方法把MNIST的數據下載放在該目錄下,這樣就避免下了載速度上的問題。

 

本文由 三符道長 撰於 2016年10月27日。轉載請註明出處。