pretty code

2019年12月27日 星期五

Fashion MNIST 資料集概述

Fashion MNIST 是 TensorFlow 官網入門影像分類範例所使用的一個資料集。

假設使用的是 python 範例,載入資料時便會自動下載,以 Windows 來說,會儲存在 C:\Users\XXX\.keras\datasets\fashion-mnist 資料夾下,共有 4 個檔案:

train-images-idx3-ubyte.gz  60,000 張的訓練資料
train-labels-idx1-ubyte.gz 60,000 張的訓練資料分類結果

另外 2 個檔案便是 10,000 張的測試資料及分類結果

以 train-images-idx3-ubyte.gz 來說,解壓縮後的檔名為 "train-images-idx3-ubyte",此為 binary 檔案,前面 16 個 Byte 是描述此 binary 檔案用,剩下的 Byte 開始每 28 x 28 個 Byte 就是 1 張 28 x 28 的灰階圖片,每 1 個 Byte 就是 1 個 pixel 的灰階值,其順序是由左而右,由上至下。

因此,我們可以很簡單的寫個 C code 來把 binary 資料儲存成 BMP 檔案,以 24 位元的點陣圖為例,每 1 個顏色都寫一樣的值,其結果便會是灰色圖,這裡要注意的是 BMP 是先填底部的值,故要記得調整。

#include <stdio.h>
#include <mem.h>

unsigned char header[] = {
    0x42, 0x4D, 0x66, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
    0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

int main(void)
{
    FILE *src = fopen("train-images-idx3-ubyte", "rb");
    if (!src) {
        return -1;
    }

    fseek(src, 16, SEEK_SET);

    unsigned char value;
    unsigned char gray_img[28*28];
    unsigned short img_size = sizeof(gray_img);
    unsigned short header_size = sizeof(header);

    FILE *dst;
    char img_name[32];
    unsigned short index = 1;

    while (1) {
        memset(gray_img, 0x00, img_size);
        fread(gray_img, 1, img_size, src);

        if (feof(src)) break;

        sprintf(img_name, "train_images_%05d.bmp", index++);

        dst = fopen(img_name, "wb");
        if (!dst) {
            fclose(src);
            return -1;
        }

        fwrite(header, 1, header_size, dst);

        for (int i = 0; i < 28; i++) {
            for (int j = 0; j < 28; j++) {
                value = gray_img[(27-i) * 28 + j];
                //value = 255 - value;
                fwrite(&value, 1, 1, dst);
                fwrite(&value, 1, 1, dst);
                fwrite(&value, 1, 1, dst);
            }
        }

        fclose(dst);
    }

    fclose(src);

    return 0;
}

甚至可以再透過較高階的語言,把個別的 BMP 圖再合併回一張圖,當然也可以一開始就都用 python,底下為訓練資料集的前 400 張圖合併結果。

沒有留言: