pretty code

顯示具有 TensorFlow 標籤的文章。 顯示所有文章
顯示具有 TensorFlow 標籤的文章。 顯示所有文章

2020年4月21日 星期二

Tiny-YOLOv2 on 拾穗

Dataset:COCO, 80 classes
Framework:TensorFlow Lite 1.15.0 (Windows)
Model:Converted from TensorFlow Keras mode (h5)
Code:https://github.com/tylpk1216/tiny-yolov2-tflite

在找資料的過程,依稀有看到 YOLO 類演算法對美術作品的辨識度不錯,隨便找了一張圖片來測試,結果居然是下圖,難怪常看到有些圖案可以騙過 AI 的文章。


2020/04/22 更新

原本的 code 使用的是 anchor box 裡面的 confidence score,並未乘上 classes 的 confidence score,調整程式碼後,一個物件都辨識不出來了(Threshold 0.6),不過我想欺騙 AI 的原理應該是一致的,就是想辦法把訓練好 model 學習到的特徵集表現出來就能騙過 AI ?

將右上角的卡通狗辨識成泰迪熊。

調整左上角物品的大小,卡通狗就不是泰迪熊了。

將原本辨識出來的狗,放大到整個輸入大小,模型就失效了。

TensorFlow 2.1 新變更

最近有在 Windows 透過 pip 安裝 TensorFlow 的人應該都會發現,安裝時名稱沒有帶 '-gpu',但安裝的貌似是 GPU 版,故執行時都會跳出下面的警告:

W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'cudart64_100.dll'; dlerror: cudart64_100.dll not found

在警告下面,TensorFlow 也很貼心的提醒可以忽略它:

I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.

雖然猜測是 GPU 版,但一直不知道為什麼?直到看到 stackoverflow 的某篇文章才了解其來龍去脈。

簡單來說,從 TensorFlow 2.1.0 發佈後,pip 在 Linux 和 Windows 上預設都是 GPU 版,而這個版本有沒有 NVIDIA GPU 都可以執行,而原本的 'tensorflow-gpu' 名稱仍然存在,如果想要減少安裝空間,也可以單獨安裝 CPU 版,名稱則是 'tensorflow-cpu'。

即使安裝的是舊版本(1.x),看起來預設也是 GPU 版,至少我在 Win10 安裝的 1.15.0 是如此。

2020年2月21日 星期五

Build a TensorFlow pip package from source on Windows

一直以來都有這樣的感覺,想要編譯任何大專案,最好還是乖乖在 Linux,否則即使該專案有提供在 Windows 編譯的方法,根據我的經驗都沒有那麼順風順水。

底下是我在 Windows 7 成功編譯的方法以及遇到坑的處理方式,記錄一下避免忘記。

官方指南
https://www.tensorflow.org/install/source_windows

TensorFlow:r1.15 (CPU-Only)

Install Python 以及相關 modules
這部份直接照官方網站即可。

Install Bazel
這個要配合 TensorFlow 的版本,我是下載 0.26.1,並放在 C:\Windows\System32 下。

Install MSYS2
這部份直接照官方網站即可。

Install VS2017
安裝完需要更新到最新,即執行 cl 時版本要為 19.16,也就是 "_MSC_VER" 這個值要是 1916

開啟 cmd prompt
適用於 VS 2017 的 x64 Native Tools 命令提示字元。

設定環境變數
set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC
set Path=C:\msys64\usr\bin;%Path%

切換工作目錄
切到 TenosorFlow code root。

開始編譯
bazel --connect_timeout_secs=120 build --config=opt //tensorflow/tools/pip_package:build_pip_package --test_timeout=120 --http_timeout_scaling=3.0

編譯過程中遇到的問題
1. 一開始沒多久就遇到網路問題,即使如上面放寬相關 timeout 也沒用,後來靈機一動判斷是公司網路問題,改用自己的網路即可。

2. "_MSC_VER" 版本太舊,這個問題花了我 2 天才搞定,底下是個人猜測,原來是我的 VS2017 環境一直有更新,故我的 "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC" 裡面會有各種不同的版本,而 bazel 在一開始會去此路徑下找到第一個擁有相關 bin 檔的路徑,並將其寫到 "C:\Users\XXX\_bazel_XXX\mfg32ytw\external\local_config_cc\cc_toolchain_config.bzl" 等相關檔案的區塊,例如 cpp_link_nodeps_dynamic_library_action 此區塊,故即使你開的 cmd prompt 是對的,但此處的 cl 版本如果是在錯的資料夾, "_MSC_VER" 這個變數便會是錯的。

解決方式也很簡單,去控制台針對 VS2017 做修改,把較舊版本的 tool 移除,印象中我原本有多達 6 ~ 7 個之多,後來就只剩 "14.16.27023" 這個資料夾,而這個就是 1916 的版本。

其實我也有安裝 VS2019 Build Tools,但一樣會有 "_MSC_VER" 版本太舊的問題,但因為我那時還不知道問題在哪,故並未更新 VS2019 到新版本。

在我解決了上面 2 個問題後,我就順利的編譯出 "bazel-bin\tensorflow\tools\pip_package\build_pip_package" 這個執行檔,而我們需要它來產生 pip 的安裝檔,這部份就參考官網即可。

一些小秘訣
1. bazel 可以使用 --jobs=2 --local_cpu_resources=2 參數去限制 CPU 資源,一開始沒限制每個 Core 都跑到 100%,此時電腦做什麼事都很慢。
2. 成功編譯過一次後,如果都沒改檔案並用上上面的參數,再檢查一次大概要花 3 分鐘多。
3. 檢查需不要需要重新編譯的程式應該是用 java 寫的。
4. C:\Users\XXX\_bazel_XXX\mfg32ytw 裡面會有編譯過程的 log 及 java 的 log。

VS2019相關(未嘗試,僅猜測)
1. 如果是安裝 VS2019 Build Tools,VC 路徑是在 "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC"。
2. 相對 VS2017,VS2019  多個版本是在 "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC",用一樣的方式留下最新的即可。

2020年2月19日 星期三

The migration of tensorflow/contrib/lite path

最近一直在看相關的文章,很多文章在提到 lite 時,路徑都是指向 tensorflow/contrib/lite,但實際上已經沒有這個路徑,好奇查了一下,原來是在 2018/10/31 時,TensorFlow 將 tensorflow/contrib/lite 改成 tensorflow/lite。

故文章看到有 contrib 這層的都是舊資料,自行修正即可。

2020年2月17日 星期一

Run MLPerf-inference Mobilenet on Windows.

My Environment

Windows 7 x64
Python 3.6.8 x64

Install python modules

1. pip install TensorFlow==2.0.0
2. pip install wheel
3. pip install Cython
4. pip install onnx
5. pip install git+https://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI(This is pycocotools module that someone built).

Install Load_Gen

1. cd mlperf\loadgen
2. set CFLAGS=-std=c++14
3. python setup.py develop
4. cd mlperf\v0.5\classification_and_detection
5. python setup.py develop

Prepare Dataset

Because the link of imagenet is gone, you must search by Google.

Prepare Model

https://zenodo.org/record/2269307/files/mobilenet_v1_1.0_224.tgz

Run Mobilenet-tflite

1. cd mlperf\v0.5\classification_and_detection
2. modify python\main.py, add profile below.
"mobilenet-tflite": {
    "inputs": "input:0",
    "outputs": "MobilenetV1/Predictions/Reshape_1:0",
    "dataset": "imagenet_mobilenet",
    "backend": "tflite",
    "model-name": "mobilenet",
},
3. py python\main.py --backend=tflite --cache=1 --config=..\mlperf.conf --dataset-path=D:\MLPerf-Win\Dataset\dataset-imagenet-ilsvrc2012-val --max-batchsize=1 --model=D:\MLPerf-Win\Model\mobilenet_v1_1.0_224.tflite --model-name=mobilenet --profile=mobilenet-tflite --scenario=SingleStream --threads=2 --output=D:\MLPerf-Win\Result\tflite-mobilenet-singlestream

2020年2月7日 星期五

TensorFlow 和 numpy 相容性問題

跑較高版本 TensorFlow 時,都會出現下列訊息:

FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy

Google 了一下,是因為 numpy 版本太新,只要安裝 numpy 1.16 版本即可。

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月13日 星期五

Tensorflow Lite on Windows - 使用 Google 並且不求甚解

雖然我很喜歡 Linux,但我工作的環境都是使用 Windows 居多,由於手邊還有 Linux 的電腦,故遇到 OS 相關問題就是跑去該電腦前打開電源開機,然後回到自己座位使用 SSH 登入,中間如果需要傳輸檔案便使用 WinSCP 解決。

最近嘗試使用 Tensorflow Lite 轉換 Tensorflow Model,但在 Windows 上無法成功,隨便 Google 一下錯誤訊息,看起來似乎要跑在 Linux 上,後來果然在 Linux 上成功轉出 Model。

但因為要改 Model 和 Code,不論是 python 還是 Tensorflow 都不是我平常會用的傢伙,故常常改來改去,每次都要用 WinSCP 上傳還真是麻煩,雖然 UltraEdit 貌似有支援 SSH,但我的版本是灰色狀態( 寫文章時,已經找到解決方法 ),目前要處理的事一籮筐,故暫時沒時間解決,只好乖乖的再重頭看一次錯誤訊息。

首先,錯誤訊息是長這樣。

"'toco_from_protos' \xa4\xa3\xacO\xa4\xba\xb3\xa1\xa9\xce\xa5~\xb3\xa1\xa9R\xa5O\xa1B\xa5i\xb0\xf5\
xa6\xe6\xaa\xba\xb5{\xa6\xa1\xa9\xce\xa7\xe5\xa6\xb8\xc0\xc9\xa1C\r\n"

感覺就是一堆火星文,老辦法還是 Google,貌似是 python 16 進位字串,不確定對不對?反正簡單使用 python 是可以轉換的,我們得到下列錯誤訊息。

s = "'toco_from_protos' \xa4\xa3\xacO\xa4\xba\xb3\xa1\xa9\xce\xa5~\xb3\xa1\xa9R\xa5O\xa1B\xa5i\xb0\xf5\
xa6\xe6\xaa\xba\xb5{\xa6\xa1\xa9\xce\xa7\xe5\xa6\xb8\xc0\xc9\xa1C\r\n"

print(s)

Traceback (most recent call last):
  File "Test.py", line 5, in
    print(s)
UnicodeEncodeError: 'cp950' codec can't encode character '\xa4' in position 19: illegal multibyte sequence

一樣繼續 Google,搜尋如何改變 code page,原來使用 "chcp 65001" 就可以改成 UTF8,雖然我也不知道 python string 預設編碼是什麼?管他的,時間寶貴,不行在回來查。

這次有了比較清楚的錯誤訊息,但還是回到一開始隨便 Google 到的結果,找不到 "toco_from_protos" 這支轉換程式。

tensorflow.lite.python.convert.ConverterError: See console for info.
'toco_from_protos' is not recognized as an internal or external command,
operable program or batch file.

坦白講,實在是沒道理,堂堂 Google 霸主加上又是 python,沒道理只支援 Linux,更何況使用關鍵字查詢,看起來就是包在 Tensorflow 裡面的,非 Linux 其他安裝時所安裝的工具。

既然 Tensorflow Lite 並沒有說只支援 Linux,一樣繼續 Google,看到了關鍵字 "C:\Python\Scripts\toco_from_protos.exe"。

果然在我安裝目錄下是有這個執行檔的,接下來問題就簡單了,把該目錄加到 Path 路徑即可,雖然我也不知道為什麼我安裝時沒有選擇自動加入?

終於可以在 Windows 下繼續改 Code 了,這條不歸路不知道還要走多久?


後記

人對沒興趣的東西真的會不求甚解,我對 python 和 Tensorflow 都沒有興趣,故我只想快速解決問題,雖然真的是很快速解決問題,因為打這篇文章比我解決問題所花的時間還要多!

還是老話一句,學海無涯,Code 海茫茫,我也想有無限制的精神時光屋可以修練XD