天天看點

機器學習入門資料集--3.手寫數字識别

MNIST

MNIST 資料集來自美國國家标準與技術研究所, National Institute of Standards and Technology (NIST)。訓練集 (training set) 由來自 250 個不同人手寫的數字構成, 其中 50% 是高中學生, 50% 來自人口普查局 (the Census Bureau) 的從業人員。測試集(test set) 也是同樣比例的手寫數字資料。

機器學習入門資料集--3.手寫數字識别

手寫數字樣式

  • 原文出處MINST

    官網非常“質樸”。

機器學習入門資料集--3.手寫數字識别

官網截圖

資料格式

在資料集中,每張圖檔的大小是28*28,存儲時1*784的向量儲存。

列印資料,檢視原始資訊:

機器學習入門資料集--3.手寫數字識别
機器學習入門資料集--3.手寫數字識别

代碼

import numpy
import gzip
# Params for MNIST
IMAGE_SIZE = 28
NUM_CHANNELS = 1
PIXEL_DEPTH = 255
NUM_LABELS = 10
# Extract the images
def extract_data(filename, num_images):
    """Extract the images into a 4D tensor [image index, y, x, channels].
    Values are rescaled from [0, 255] down to [-0.5, 0.5].
    """
    print('Extracting', filename)
    with gzip.open(filename) as bytestream:
        bytestream.read(16)
        buf = bytestream.read(IMAGE_SIZE * IMAGE_SIZE * num_images * NUM_CHANNELS)
        data = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.float32)
        data = (data - (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH
        data = data.reshape(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)
        data = numpy.reshape(data, [num_images, -1])
        return data
def extract_labels(filename, num_images):
    """Extract the labels into a vector of int64 label IDs."""
    print('Extracting', filename)
    with gzip.open(filename) as bytestream:
        bytestream.read(8)
        buf = bytestream.read(1 * num_images)
        labels = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.int64)
        # num_labels_data = len(labels)
        # one_hot_encoding = numpy.zeros((num_labels_data,NUM_LABELS))
        # one_hot_encoding[numpy.arange(num_labels_data),labels] = 1
        # one_hot_encoding = numpy.reshape(one_hot_encoding, [-1, NUM_LABELS])
        # sklearn的logisticsRegression 标簽不用one-hot編碼
        return labels
path= '/Users/wangsen/ai/03/4day_tensorflow/data'
train_data = extract_data(path+'/train-images-idx3-ubyte.gz', 60000)
train_labels = extract_labels(path+'/train-labels-idx1-ubyte.gz', 60000)
test_data = extract_data(path+'/t10k-images-idx3-ubyte.gz', 10000)
test_labels = extract_labels(path+'/t10k-labels-idx1-ubyte.gz', 10000)

print(train_data.shape)
print(train_labels.shape)

from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(train_data,train_labels)
score = lr.score(test_data,test_labels) 
print("sklearn logisticRegression score:",score)           

複制

結果:

(60000, 784)
(60000,)
sklearn logisticRegression score: 0.9194           

複制

代碼分析

上例子中,把784個像素作為特征,标簽是數字,進行邏輯回歸。score是準确率,最終的結果在測試集上達到90%以上的準确率。

這段程式時間較長,10分鐘以上。

降維

由于原圖次元過大784,導緻訓練時間較長。可以通過降維算法,将資料壓縮到較小的次元,再進行訓練,可以調高訓練速度。

from sklearn.decomposition import PCA
pca =  PCA(60)
train_data= pca.fit_transform(train_data)
print('降維後訓練集的次元',train_data.shape)

from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(train_data,train_labels)

test_data = pca.transform(test_data)
score = lr.score(test_data,test_labels) 
print("sklearn logisticRegression score:",score)           

複制

結果:

降維後訓練集的次元 (60000, 60)
sklearn logisticRegression score: 0.9088           

複制

總結

MNIST手寫資料集可以作為機器學習入門練手資料。在官網原文中,包含了機器學習和深度學習最終處理的結果,最低誤差為0.35%。

本文用最簡單的邏輯回歸模型,從官網資料上看,取得最好評分模型的的還是卷積神經網絡。

下一篇: 常變量