模型訓(xùn)練之?dāng)?shù)據(jù)集操作:矩陣變換
對(duì)神經(jīng)網(wǎng)絡(luò)技術(shù)有所了解的人應(yīng)該都知道,要想訓(xùn)練一個(gè)高性能的神經(jīng)網(wǎng)絡(luò)模型,除了神經(jīng)網(wǎng)絡(luò)本身的設(shè)計(jì)之外,還一個(gè)非常重要的前提就是數(shù)據(jù)集的質(zhì)量問題;因此,打造一個(gè)高質(zhì)量的數(shù)據(jù)集就是一個(gè)必不可少的過程。
但具體怎么才能開發(fā)一個(gè)合格的數(shù)據(jù)集,這時(shí)就離不開對(duì)數(shù)據(jù)集的各種操作;而由于在神經(jīng)網(wǎng)絡(luò)中,數(shù)據(jù)的主要載體是多維數(shù)組,也就是矩陣;因此一般情況下,數(shù)據(jù)集的數(shù)據(jù)格式也會(huì)以矩陣的形式存在。
而學(xué)會(huì)對(duì)矩陣的操作就是一個(gè)必不可少的技能之一;下面我們就以MINST數(shù)據(jù)集為例,來簡(jiǎn)單介紹一下對(duì)數(shù)據(jù)集的操作過程。
數(shù)據(jù)集操作
MINST數(shù)據(jù)集是一個(gè)經(jīng)典的數(shù)據(jù)集,其內(nèi)容是一個(gè)手寫數(shù)字識(shí)別的數(shù)據(jù)集;對(duì)學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)技術(shù)的人來說,手寫數(shù)字識(shí)別就相當(dāng)于編程入門中的Hello World。
因此,了解MINST數(shù)據(jù)集也是學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)技術(shù)的入門課程之一。
關(guān)于MINST數(shù)據(jù)集的下載方式,基本有兩種選擇;一種是自己手動(dòng)下載,另一種是從pytorch官網(wǎng)下載,使用PyTorch的數(shù)據(jù)集API即可下載。
from torchvision import datasets
# 執(zhí)行以下代碼即可從pytorch官網(wǎng)下載minst數(shù)據(jù)集到本地data目錄
datasets.MNIST(root='data', train=True, download=True)
MINST數(shù)據(jù)集主要有四個(gè)壓縮文件組成,分別由train開頭的圖片數(shù)據(jù)(images)和標(biāo)簽數(shù)據(jù)(labels);以及t10k開頭的測(cè)試圖片數(shù)據(jù)(t10k-images)和標(biāo)簽數(shù)據(jù)(t10k-labels)組成。
MNIST數(shù)據(jù)集的具體內(nèi)容是由0?9手寫數(shù)字圖片和數(shù)字標(biāo)簽所組成的,由60000個(gè)訓(xùn)練樣本和10000個(gè)測(cè)試樣本組成,每個(gè)樣本都是一張28 * 28像素的灰度手寫數(shù)字圖片。如下圖所示。
由于下載的MINST數(shù)據(jù)集文件是已經(jīng)處理好的矩陣格式,并且用二進(jìn)制格式存儲(chǔ),因此無法直接使用文本工具打開。
而我們可以使用python提供的numpy工具包,或者pytorch提供的工具包來讀取數(shù)據(jù)。
import numpy as np
import gzip
with gzip.open("./MNIST/train-images-idx3-ubyte.gz", 'rb') as f:
x_train = np.frombuffer(f.read(), np.uint8, offset=16)
print("MINST數(shù)據(jù)集信息打印, 數(shù)據(jù)集內(nèi)容:%s, 類型: %s, 長(zhǎng)度: %s, 矩陣數(shù)據(jù)類型: %s, 形狀: %s, 大?。?s, 維度: %s" % (x_train, type(x_train), len(x_train), x_train.dtype, x_train.shape, x_train.size, x_train.ndim))
以上代碼輸出結(jié)果如下,可以明顯看出讀取結(jié)果是一個(gè)一維數(shù)組;并且長(zhǎng)度為47040000;不是說數(shù)據(jù)集是六萬個(gè)28*28的手寫數(shù)字圖片嗎?為什么會(huì)是一個(gè)47040000長(zhǎng)度的一維數(shù)組。
原因就在于此數(shù)據(jù)集是經(jīng)過處理之后的數(shù)據(jù)集,為了存儲(chǔ)方便使用一維數(shù)組最簡(jiǎn)單;因此,在使用過程中需要把數(shù)據(jù)變換成一個(gè)三維矩陣,也就是升維的操作;47040000 / (28 * 28) = 60000。
import numpy as np
import gzip
with gzip.open("./MNIST/train-images-idx3-ubyte.gz", 'rb') as f:
x_train = np.frombuffer(f.read(), np.uint8, offset=16)
print("MINST數(shù)據(jù)集信息打印, 數(shù)據(jù)集內(nèi)容:%s, 類型: %s, 長(zhǎng)度: %s, 矩陣數(shù)據(jù)類型: %s, 形狀: %s, 大?。?s, 維度: %s" % (x_train, type(x_train), len(x_train),
x_train.dtype, x_train.shape, x_train.size, x_train.ndim))
# 矩陣變換
x_train = x_train.reshape(-1, 28, 28)
print("MINST數(shù)據(jù)集信息變換之后打印, 數(shù)據(jù)集內(nèi)容:%s, 類型: %s, 長(zhǎng)度: %s, 矩陣數(shù)據(jù)類型: %s, 形狀: %s, 大?。?s, 維度: %s" % ( x_train, type(x_train), len(x_train), x_train.dtype, x_train.shape, x_train.size, x_train.ndim))
結(jié)果如下圖所示:
經(jīng)過變換之后,打印矩陣并顯示圖片:
import numpy as np
import gzip
from PIL import Image
with gzip.open("./MNIST/train-images-idx3-ubyte.gz", 'rb') as f:
x_train = np.frombuffer(f.read(), np.uint8, offset=16)
print("MINST數(shù)據(jù)集信息打印, 數(shù)據(jù)集內(nèi)容:%s, 類型: %s, 長(zhǎng)度: %s, 矩陣數(shù)據(jù)類型: %s, 形狀: %s, 大?。?s, 維度: %s" % (x_train, type(x_train), len(x_train), x_train.dtype, x_train.shape, x_train.size, x_train.ndim))
x_train = x_train.reshape(-1, 28, 28)
print("MINST數(shù)據(jù)集信息變換之后打印, 數(shù)據(jù)集內(nèi)容:%s, 類型: %s, 長(zhǎng)度: %s, 矩陣數(shù)據(jù)類型: %s, 形狀: %s, 大?。?s, 維度: %s" % ( x_train, type(x_train), len(x_train), x_train.dtype, x_train.shape, x_train.size, x_train.ndim))
print(len(x_train), x_train[0])
# 轉(zhuǎn)換為圖片 并顯示
pil_img = Image.fromarray(np.uint8(x_train[0]))
pil_img.show()
執(zhí)行以上代碼 用戶即可輸出手寫數(shù)字圖片。