假設使用的是 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 張圖合併結果。