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 張圖合併結果。

2019年12月24日 星期二

UltraEdit 搜尋時出現一個無效的引數錯誤

這個問題我猜是因為曾經在搜尋某值時,也許是特殊字元,當 UltraEdit 在開啟搜尋功能時,它會去載入設定檔中 [Find History] 區塊的歷史紀錄,因為特殊字元的緣故導致它產生錯誤。

當這個問題一發生時,每次搜尋時都要多 click 好幾次,實在是讓人阿雜。

解決方式也很簡單,直接砍掉 C:\Users\XXX\AppData\Roaming\IDMComp\UltraEdit\uedit32.INI[Find History] 區塊,並重開 UltraEdit 即可。

解決問題後才發現,在進階 -> 配置 -> 工具列/功能表 -> 其他,就有一個清除歷程的按鍵,使用它應該也能夠解決問題,差別在會多清除一些開啟文件等記錄。

EDK2 編譯時期前置作業概略

我們在 build UEFI Application 時,第一個步驟便是會呼叫 edksetup.bat,以下是針對我感興趣的部份作記錄。

1. Call edksetup.bat, it will call BaseTools\toolsetup.bat.
2. In BaseTools\toolsetup.bat, if it can't find Conf\target.txt and Conf\tools_def.txt, it will copy BaseTools\Conf\target.template and BaseTools\Conf\tools_def.template to Conf folder to generate Conf\target.txt and Conf\tools_def.txt.
3. When you call build.exe(BaseTools\Source\Python\build\build.py), it will pass these two files in LoadConfiguration function.

2019年12月23日 星期一

EDK2 預設視警告為錯誤

一般來說,撰寫 UEFI Application 時,如果編譯過程中遇到警告,會出現 C2220 錯誤訊息。

這個是因為在 UDK\Conf\tools_def.txt 檔案中,在所屬的 VC 版本編譯選項中預設有 /WX 選項,故會將警告視為錯誤。

下面以我最常用的 VC 版本為例:
DEBUG_VS2012x86_X64_CC_FLAGS  = /nologo /c /WX /GS- /X /W4 /Gs32768 /D UNICODE /O1ib2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm

如果我們想忽略某警告,最簡單的方式便是在 UEFI Application 的 INF 中加上 /wd9999 選項,9999 便是警告編號。

還有一種方式是去動態改變 warning 層級,假設 9999level 1 的 warning,而我們現在是使用 level 2 check,只要指定 /w39999 後,9999 便會變成 level 3 warning,故不會產生 C9999 警告訊息,在某些情境下還蠻好用的。

另外,LINKER 也有 /WX 選項,這個倒是可以用 /WX:NO 覆寫。

2019年12月19日 星期四

Chrome Extension + Export Excel

之前寫的 The books list 小工具,可以幫忙把網頁上顯示的購買書籍書名 parsing 出來,以方便後續使用,目前支援 Readmoo 舊版書櫃,Kobo 以及 Google Play Books。另外,Google Play Books 的書購買的不夠多,故不確定分頁機制如何,無法處理。

原本是直接將書名顯示在 Web 視窗,但似乎還是有點麻煩,雖然我現在也懶得另外整理清單了,前天趁著測試的空檔,使用 SheetJS 這個純 javascript 套件,便順利的產出了 Excel 2007 格式。

另外,調整格式等功能需要 Pro 版本才行,但一般使用已經夠用。

如果想自己改 Community 版本的話,只要 follow 他的 License,應該也可以自行加上 Style 等功能,這個可以找其他語言的 Open Source 專案,便知道如何比照辦理。

或許也可以使用 Golang 的任一專案,來個 Golang -> WebAssembly -> Javascript 乾坤大挪移也說不定?

2019年12月16日 星期一

Ubuntu 16.04 + NVIDIA-Linux-x86_64-410.93.run driver 循環登入視窗解決方式

當初這個系統是為了跑 TensorFlow-gpu 版本安裝的,中間一度有幫人 build tool,測試發送 ARP 廣播封包等。

最近使用 TensorFlow Lite 時偶然發現,在本機前面登入時,會一直循環登入,也就是輸入帳密後,又會回到輸入帳密的登入視窗。

有嘗試重裝同一版 driver,但過程會一直報錯,看 /var/log/nvidia-installer.log 也看不出什麼特別的,只能看出似乎幾個 c code 的 structure 有衝突,直覺是我的 GCC 版本似乎跟之前安裝時的不一致,但我印象中幫人測試 tool 時,我並沒有做額外的更新。

沒辦法,使出最後一招,下載最新版的  NVIDIA-Linux-x86_64-440.44.run,安裝後馬上恢復正常。

稍微查了一下,網路上是建議安裝 NVIDIA driver 時,不要預設使用圖型登入,聽說比較容易有問題,記錄一下,避免忘記。

2019年12月15日 星期日

mooInk Pro 購買中獎發票

之前購買電子書發票都是直接捐贈,不知從什麼時候開始,改成歸戶至手機條碼。

今天為了註冊新的自然人憑證,無聊查了一下這次中獎發票明細是什麼,才發現居然是購買 mooInk Pro 的發票。


不過這不是要記錄的重點,因為自然人憑證只有 5 + 3 年可用,重點是重新申請自然人憑證時,要如何做電子發票設定?

只要到財政部電子發票整合服務平台,點選登入→自然人憑證→註冊即可,完畢後原本已歸戶的資料就會再併回此張新的自然人憑證。