【南投信義】丹大林道與消失的省道台16線|可徒步深入中央山脈的經典長程林道

圖片
布農族人有這麼一句話:「濁水溪的上游,不是終點,是我們布農文化的起源」,這句話揭開 丹大林道 的旅行序幕。下面是幾年前,丹大林道還沒被媒體大肆報導前,我曾在某個冬季前往安靜的丹大林道徒步健行和野營,以及在工寮過夜的三天兩夜重裝健行紀錄。 2024.01.31更新:合流坪的鋼便橋已於今日被台電撤除了 連結: 台電施工後丹大林道「恢復」通行! 拆橋挖巨溝「車輛恐無法通過」 丹大地區 位於臺灣本島中部之濁水溪上游,行政區隸屬於南投縣信義鄉,為全國面積第二大的鄉鎮。丹大地區也是濁水溪的發源處。東側翻過中央山脈可達花蓮,南鄰玉山國家公園,西接日月潭國家風景區,北側則與仁愛鄉相接。 潭南、雙龍、地利及人和四村等區域皆位於信義鄉,著名的 丹大(孫海)林道 便位於地利村中,沿著步道往東至花蓮邊界處可與七彩湖相接。其中地利村及雙龍村面積最大,合佔本區約七成面積,人和村次之,面積最小者為潭南村 。 丹大林道周邊地圖 丹大林道路徑示意圖 日治時期西元1943年,原本預計將東部花蓮木瓜溪流域附近的水力發電廠所生產的剩餘電力運輸到西部,但因為日本在1945年戰敗後,計畫就宣告中止,1948年台灣工業急速發展,用電量大增,直到1950年獲得美國援助執行了能高路線全長45公里的69kV東西向輸電計畫。 之後為了解決花東地區電力供應問題,台電於1985年開始研究新東西輸電之路線,最後決定自南投明潭發電廠與大觀第二發電廠輸送電力至花蓮鳳林超高壓變電所,此新東西輸電線於1990年開始辦理路線中心測量,1998年完工,全長72.4公里。 沿線共有196座電塔,線路橫跨中央山脈海拔2925公尺的崇山峻嶺,並在「 七彩湖 」附近的越嶺處設有「 光華復旦 」紀念碑,西以 丹大林道 、東以 萬榮林道 為維修保線道路。 丹大林道是深入丹大地區的重要通道,1958年(民國47年),出生於現今雲林縣口湖鄉的孫海,標得林務局巒丹大事業區第八林班地檜木原始林採伐權及伐木後的重新造林權,為了進入深林,孫海沿著原本的山徑開闢出可以卡車通行的丹大林道,因此丹大林道也被稱為「 孫海林道 」。 當年為了闢築林道與運輸需要,孫海建造了一座木橋於合流坪橫跨濁水溪,之後改為水泥橋,這座橋就是著名的「 孫海橋 」。 為了伐木業而開闢的丹大林道,其終點一開始並不是在七彩湖,後半段到光華復旦碑約12公里路段,是台電為了興建東西線輸電工程,才於

【筆記】從 Google 地圖爬取中文店家評論,透過 TensorFlow Lite 和 Firebase 進行文本分類,並將模型添加到 Android 應用上

這幾天碰巧看到這個東西,覺得有點有趣,初步先簡單學習了一下,本文簡單記錄一下學習過程


文本分類是根據文本內容為其分配標籤或類別的過程。它是自然語言處理 (NLP) 的基本任務之一,具有廣泛的應用,例如情感分析、主題標記、垃圾郵件檢測和意圖檢測。

情感分析是使用文本分析技術對文本數據中的情感(積極、消極和中性)進行解釋和分類。情緒分析使企業能夠在在線對話和反饋中識別客戶對產品、品牌或服務的情緒。 

以下我們學習構建一個用於情感分析的機器學習模型,特別是將文本分類為正面或負面。這是二元分類(或二類分類)的一個示例,是一種重要且廣泛適用的機器學習問題。

我們使用 TF Lite Model Maker 訓練 TensorFlow Lite(TF Lite) 文本分類模型,來預測給定文本的情緒,然後將這個 TF Lite 模型部署到 Firebase 機器學習(Firebase ML),並且從 Android 應用中訪問它。最後使用 TF Lite 任務庫將 TF Lite 情感分析模型集成到您的應用程序。

首先在 Google Colab 中打開 Train text classification models with TFLite Model Maker 這個筆記本。

註:“Colab” 是 Colaboratory 的簡稱,是 Google Research 團隊開發的一款產品。在 Colab 中,任何人都可以通過瀏覽器編寫和執行任意 Python 代碼。它尤其適合機器學習、數據分析和教育目的。從技術上來說,Colab 是一種託管式 Jupyter 筆記本服務。用戶無需設置,就可以直接使用,同時還能獲得 GPU 等計算資源的免費使用權限。

這個範例筆記本,使用 SST-2 (Stanford Sentiment Treebank),它是 GLUE 基準測試中的一項任務。其中包含 67,349 條用於訓練的電影評論和 872 條用於測試的電影評論。數據集有兩個類:正面電影評論負面電影評論。我們將用它來訓練一個文本分類模型。

由於這個教學範例是2020年發佈的,目前(2023年8月),Colab 的 Python 版本已經更新到 3.10,所以如果直接執行這個筆記本,預期會在執行 Install the required packages(安裝 TF Lite Model Maker)這一步時發生錯誤。

首先,如果使用的是免費版 Colab,它會在安裝 Python 套件時,就吃光免費方案的 78GB 硬碟空間,然後出現錯誤信息 ERROR: Could not install packages due to an OSError: [Errno 28] No space left on device。(Stack Overflow上面的討論


升級到付費的 Colab Plus 之後,再執行一次筆記本看看,最後仍然會在執行 from tflite_model_maker import configs 這行代碼時,出現錯誤信息 ModuleNotFoundError: No module named 'tflite_model_maker'

我查了一下,好像是 tflite-model-maker 在 Python 3.10 版本上的已知問題(參考:GitHub 上面的 Issue 討論

為了執行這個筆記本來訓練 TL Lite 模型,我們需要修改一下筆記本,我們使用 Python 3.9 版本作為環境,新的筆記本在這裡 -> Tflite_Model_Maker_Python_3_9.ipynb

首先將舊範例筆記本裡面的 Python 代碼,另存成 model.py 腳本,內容如下:

然後將這個腳本上傳到 Google Drive 雲端硬碟上,稍後會從 Colab 筆記本上直接 Mount 雲端硬碟,來存取這個 Python 腳本。

在新的筆記本裡面,透過 drive.mount('/content/gdrive') 指令,就能將 Google Drive 雲端硬碟掛載到 Colab 硬碟的目錄下(註:執行時會跳出對話框,必須先同意授權),這樣我們就可以在筆記本上存取雲端硬碟中的 model.py 腳本了,然後下面這行命令,是將雲端硬碟中的 model.py 腳本,複製一份到 Colab 本地目錄下。

!cp /content/gdrive/MyDrive/tflite-model-maker-workaround/model.py .

最後以 python /content/model.py 指令,來執行腳本


然後大約幾分鐘後,就會看到產生了兩個 model.tflite 模型到 average_word_vecmobilebert 兩個目錄下,點擊檔案右側的三個小圓點 icon 即可將模型下載到本地端。


現在有了 TF Lite 模型,接下來我們要將它上傳到 Firebase ML 上,首先從 GitHub 上面下載 Sample Code,我們直接使用 finish 資料夾裡面的 project,它的 Package 名稱是 org.tensorflow.lite.codelabs.textclassification,接著進入 Firebase 控制台,建立一個 Android 應用專案,專案的 PackageName 需填寫上面的名稱。

建立完成後,點選專案左側導航面板中的 機器學習(Machine Learning)頁面,然後選擇 Customize,在對話框輸入模型名稱並點選上傳,就能將稍少訓練出來的 TF Lite 模型上傳到 Firebase 服務上面。


我們可以隨時更新或者刪除這個模型


然後在 Android Studio 開發環境中,開啟稍早下載的專案,編譯並安裝到手機上執行,現在我們已經有了一個簡單的文本分類 AI 應用。

這個範例使用的是英文的 Movie Reviews 資料集,我們也可以嘗試使用不同類型的資料集,來訓練 TF Lite 模型,看會得到怎樣的結果。

作為例子,我們從 Kaggle 上面找到一個年份比較早的 Yelp Restaurant Reviews 英文資料集,現在我們可以下載這個餐廳評論資料集,然後將我們不需要的欄位刪除(只保留rating分數和評論內容兩個欄位),然後將資料集切分為訓練集和驗證集,分別儲存為 train.tsv 和 dev.tsv 文件。

最後將這兩個 .tsv 文件上傳到 Google Drive 雲端硬碟上(這裡我將它放到一個名為 SST-1 的資料夾裡)。

註:TSV 和 CSV 之間的唯一區别是,TSV 使用制表符 \t 字符作为分隔符,而不是 CSV 格式中的逗號。

接著編輯 model.py 腳本,用以根據這個餐廳評論資料集,產生 TF Lite 模型。腳本內容如下(註:這個腳本和先前的內容並沒有太大差別,只是些修改了資料集來源,我們將裡面透過網路下載資料集的代碼刪除了):

然後將修改後的 model.py 腳本上傳到 Google Drive 雲端硬碟,最後編輯 Tflite_Model_Maker_Python_3_9.ipynb 筆記本,在執行python腳本前,加入以下三行筆記:

編輯後的筆記本內容大致如下:


最後點選筆記本上面的執行階段 -> 全部執行,幾分鐘後就可以得到,這20,000筆餐廳評論資料集所訓練出來的 TF Lite 模型了。

將此模型命名為 yelp_mobilebert 並上傳到 Firebase ML,然後修改 Android 專案中 MainActivity.java 文件裡的模型名稱,這樣就可以在 Android 應用程式中,使用這個餐廳評論的文本分類模型了。

downloadModel("yelp_mobilebert");

在筆記本裡面,可以選擇使用 average_word_vec(平均單詞嵌入向量)或是 BERT 來作為 Model Maker 的模型架構。TensorFlow Lite Model Maker 目前支持 MobileBERT,平均單詞嵌入向量和 BERT-Base 模型。

若是使用平均單詞嵌入向量作為模型架構,我們可以透過 NLClassifier API 將模型集成到 Android 應用程式中。但如果要以 MobileBERT 架構對文本分類模型進行行訓練,那就需要使用 TensorFlow Lite Task Library 所提供的 BertNLClassifier API 將訓練後的模型集成到 Android 應用程式中。

也就是將 MainActivity.java 文件中,預設的 textClassifier 類型宣告:

private NLClassifier textClassifier;

修改為

private BertNLClassifier textClassifier;

另外在 downloadModel() 裡面的代碼也要修改,請將:

textClassifier = NLClassifier.createFromFile(model.getFile());

修改為

textClassifier = BertNLClassifier.createFromFile(model.getFile());

然後就可以編譯執行應用程式了!

我試著輸入中文和英文來做測試,因為模型是用英文資料集訓練的,所以可以發現,當使用中文輸入文本時,模型的判斷結果不是很理想,但若改用英文輸入文本,結果就會比較理想(結果如下截圖)。


為了獲取中文的餐廳評論資料集,我們可以從 Google 地圖上取得中文餐廳評論,來訓練文本分類模型。

怎麼獲得評論資料呢?當然不可能是人工一筆一筆去輸入,我找到一個叫做 SerpAPI 的網路服務(也有免費方案,只是每月的扣打很少),來抓取Google搜尋的內容。也就是說,Google 搜尋查到的資料,都可以從 SerpAPI 的服務取得。


除了 Google 搜尋的內容,SerpAPI 還支援其它常見的搜尋應用,比方抓取 YouTube 影片跟 Google 地圖上的餐廳、用戶評論等資料。SerpAPI 的 使用方式,它的網站上已有清楚的說明。

在這個簡單的應用中,我只會用到它的 Google Maps Local Results API,以及 Google Maps Reviews API 這兩個 API,前者用來獲取某地點(給定經緯度)附近的店家列表,並從資料中取得店家的 data_id,後者可以傳入 data_id 作為參數,獲取該店家的所有用戶評論。

然後我寫了一個簡單的 Python 腳本,它可以根據給定的經緯度,以及query的地點類型(例如:燒肉店),來爬取 Google 地圖上,該座標位置附近的燒肉店

SerpAPI 對 API 查詢的結果做了分頁機制,每一頁只會顯示最多20筆店家資料,所以我在腳本中加入查詢下一頁的功能,會查詢到最後一頁為止。然後再透過每個店家的 data_id 去獲取該店家的用戶評論。

SerpAPI 的評論查詢結果也有做分頁處理,每一頁只會顯示10筆用戶評論資料,以我也在腳本中加入查詢下一頁的功能,但是我設定最多只查詢到第20頁。

原因是 SerpAPI 的評論查詢結果,預設是以 the most relevant reviews 來排序查詢結果,太後面的頁面,經常出現只有 rating,而沒有評論文本的結果,所以這裡限制每個店家最多只查詢20頁的評論(也就是最多200筆評論)。

此外這個腳本,也過濾掉沒有文本內容、字數少於10個字,以及沒有包含中文內容的評論。原因是我在測試過程中,發現很多店家的評論,經常會出現:好吃、好好吃、真的好吃、Good,這一類本文很簡短的5顆星評論,一看就是店家洗出來的,我們將這一類的廢文給過濾掉。

最後將爬取到的 rating 值(1顆星~5顆星)和評論文本,儲存到一個包含 label 和 sentence 欄位的 google_reviews.csv 文件中。

我們過濾掉下面這種無用的評論內容


只保留下面這種比較有用的評論內容


以下是這個 Python 腳本的完整內容:

其中,search_restaurants() 裡面的 ll參數中,經緯度後面帶的15z,代表的是地圖的縮放等級(zoom level),SerpAPI 可接受的數值從 3z~21z,後者代表完全 zoomed in。這裡我設定為15z。不同的 zoom level 值會影響店家的搜尋結果。

經實際測試,若使用 SerpAPI 的 Developer Plan 查詢額度(每月5000次查詢,每小時不可超過1000次查詢),差不多能在可用的額度之內,爬取並儲存到 17,000 多筆經過篩選後的中文用戶評論。

註:如果在 serp.py 腳本中,修改評論內容字數長度的篩選條件(例如10 -> 30個字),那麼最後 CSV 文件中,經過篩選後的評論數量,理論上會少於 17,000 筆這個數目。

如果後續想抓取更多的評論文本,只需要傳入更多組經緯度資料,以及不同的店家類型(例如:拉麵、日本料理、法式料理、牛排、越南河粉、泰式料理 etc,.),就能在你的 SerpAPI 方案每月可使用的額度之下,去爬取更多的用戶評論資料。

註:有些類型的店家,不太可能會出現在郊區或者山上,例如你設定了一個宜蘭大同鄉山區的經緯度座標,然後query設定燒肉店,那麼可能根本查詢不到店家,只會浪費掉 API 查詢額度。所以在設定經緯度時,最好是選擇市區地點,才能盡可能爬取到最大數量的店家評論。

當爬取足夠多的用戶評論後,就可以用這個中文餐廳評論資料集,去訓練中文的文本分類模型,然後將模型添加到 Android 應用程式上。

在有限的時間及查詢額度下,我產生了一個包含約 22,450 筆中文店家評論的 CSV 文件,不過發現在 Mac 電腦上,使用 Numbers 和 Excel 軟體將這個中文的 CSV 文件轉換成 TSV 文件格式後,在 Colab 筆記本上執行 python /content/model.py 指令時,會出現 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 2: invalid start byte 這樣的錯誤信息,看起來是文件編碼相關的問題。

最後想到一個簡單快速的解決方案,就是在 Google 試算表上面載入這個 CSV 文件,然後點選檔案->下載->Tab鍵分隔值檔案 (.tsv),最後將這個 TSV 文件丟到雲端硬碟並掛載給 Colab 腳本使用,上面的問題就不見了。


接下來,就能在 Colab 筆記本上,用這個中文資料集來訓練 TF Lite 模型。最後將這個模型上傳到 Firebase ML 上面,就能在 Android 應用程式上使用它了。

註:這裡我只是學習和測試目的,所以只用兩萬多筆資料來訓練模型,在正式的場合,這樣的資料量是遠遠不夠用的。


最後執行一下 Android 範例應用程式,來看看這個文本分類模型的結果。




參考資料:

熱門文章

[轉載] 洛克菲勒寫給兒子的38封信(全文)

May 2023【台中南屯】地雷店食記|森鐵板燒|用餐體驗差,價格超貴卻豪無價值。小心別踩雷!!!

【美國加州】加州一號公路自駕遊~Half Moon Bay、17 Mile Drive、Bixby Greek Bridge、Big Sur、McWay Falls、Elephant Seal Rookery

【南投信義】丹大林道與消失的省道台16線|可徒步深入中央山脈的經典長程林道

Aug, 2023【桃園大溪】桃園小百岳編號23-溪洲山步道|適合訓練腳力、還能觀賞石門水庫的山水景色

Sep, 2021【苗栗南庄】蓬萊林道Off Road小試|雨後很爛很濕滑|二傳低底盤車勿輕易嘗試

Mar 12, 2022【重機一日遊】走北橫至宜蘭,經梨山、武嶺下埔里,再走台三線回桃園|16小時的半圈環島

Mar, 2024【桃園龍潭】石門山景春步道、小粗坑古道隨意走走|順遊石門水庫、黃大目豆干

Apr 7, 2024【屏東高樹鄉】南臺灣小百岳|尾寮山登山步道| 可以眺望高樹、六龜、美濃的鄉村風景

Feb, 2024【台中西區】桃太郎日本料理|隱身巷弄裡的39年老字號無菜單料理|食材新鮮、自然美味

文章列表

Contact

名稱

以電子郵件傳送 *

訊息 *