9/15/2023
我在網路上看到了有關機器學習中利用 Machine Learning 學習貪食蛇的玩法,並實際使用 Python 運行並自動通關。
在此我將記錄一些我所遇到的問題
我是在YT看到一個叫做林亦的中國YTber,他利用Pytorch去訓練電腦玩貪食蛇。因為它將所有的程式碼上傳到Github開放讓所有人取用,並且使用的環境既是Pytorch又使用CNN和MLP去訓練,剛好適合我用來熟悉這整的訓練過程所需要用到的各種套件、環境、流程,而且他甚至把他的程式做成Mac也適用的,順便也可以讓我累積在Mac上開發的經驗。
首先,這是影片的連結
再來,這是他Github Repo的連結
裡面資料齊全,也有寫好README的md檔
在他的指引裡面,他是建議我們使用Anaconda去建置虛擬環境,這樣可以獨立決定各種所使用的套件和其版本,方便你在不同需求的專案之間來回切換。
然而,我實在不想在我的Mac上裝Anaconda,主要有兩個理由:
所以我馬上就遇到了要把他寫在指引的 Conda 指令全部換成一般在 Terminal 的用法,雖然說沒有很難,但總會有人在這方面會有問題,所以還是記下來比較好。
眾所皆知,Pytorch 一開始能夠用的只有 Cuda 加速,直到去年 Pytorch 宣佈正式支援 Apple Silicon 的硬體加速後才開始實現能在 Mac 上開發 Machine Learning 這回事,所以在環境配置的時後也要特別注意在使用指令安裝 Pytorch 的時候不能用和在 Windows 上一樣的指令,在 Windows 上可以藉由在套件的名稱後面加上“=版本編號”來實現安裝特定版本的套件,但因為這些套件多半在 Mac 上要用原生支援的版本,所以不能在後面加上和 Windows 一樣的版本編號。
建議的做法是先確定你的電腦上沒有你所需要的套件的舊版本,不然你在用指令安裝時他會默認你已經安裝好了就不會執行,他也不會自動偵測目前有的版本的新舊,所以最好是先卸載一次後再重新裝一次,他就會直接抓最新的版本安裝了。回到剛剛說的 Pytorch,因為他無法像 Windows 那樣指定要安裝的版本,所以在確定沒有舊版本或不相容的X86版本後,你就直接用pip3 install torch torchvision torchaudio
去自動抓最新且最適配的版本來安裝,其他套件也是同理。
你也可以直接複製作者在他簡體中文的指引裡有特別再說明 Apple Silicon 環境配置的流程和使用的套件版本。
在環境都配置好之後理論上就可以試跑遊戲本身了。這裡我遇到了一個問題,在我去到指定檔案底下要執行程式時,他跳了錯誤,是程式碼的錯誤。
這就奇怪了,我用的程式碼是一字不差地從作者的開源社群上下載下來的,怎麼可能還會有錯誤呢?
不管,總之我遇到了這樣的錯誤:
File "/Users/jackiecdp/Desktop/Machine Learning/snake-ai-master/main/snake_game.py", line 133, in _generate_food food = random.sample(self.non_snake, 1)[0] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/random.py", line 439, in sample raise TypeError("Population must be a sequence. " TypeError: Population must be a sequence. For dicts or sets, use sorted(d).
可以看到,他在這裡所偵測到的錯誤是在133行中的 random.sample(self.non_snake, 1)[0]
所造成的,造成的原因是因為這個函式要吃進去的參數必須是 sequence,而不能是 dicts 或 sets,而貌似我們的self.non_snake
並不是一個 sequence,所以便出現了這樣的問題。解決方法很簡單,系統也直接告訴你說對於非 sequence 的資料型態向 dicts 和 sets,你只需要用 sorted() 函式將其轉換成 sequence 的資料型態即可,像這樣:
food = random.sample(sorted(self.non_snake), 1)[0]
這樣一來,就解決了當前所遇到的問題了。
我不確定是不是所有人都會遇到這樣的問題,也不知道是因為作者在 Windows 系統上開發到我這邊來因為作業系統的不同所延伸的問題亦或是 Python 的版本不同所造成的,但或許對於遇到一樣問題的人們,這是我所找到的解決方法。
在成功使遊戲本體運行之後,就來到訓練電腦玩遊戲的環節了。在這整個套組裡面,執行訓練的程式檔案是train_cnn.py
和 train_mlp.py
,分別指的是利用兩種不同的訓練模型下去跑深度學習,我照著指引執行了train_cnn.py
之後遇到了一個小問題,他說我的 PIL 套件是 X86 的版本,需要安裝 ARM 的版本才可以運行。
這時我猛然想起,我是最近才把我的電腦換成現在這台 M1 MacBook Pro 13寸 2020 的,在這之前我用的是 2017 年的 MBP 13寸,使用的是 intel i5 七代,而我當時在那台電腦上裝的 X86 版的 PIL 就這樣跟著我資料轉移時一起轉到了我這台 M1 Mac。要解決這個也很簡單,PIL 他的套件全名是 pillow,要做的也就是先卸載之後再重新下載,跟上面 Pytorch 版本的問題差不多,就是要確定所有的套件都是原生支援就好了。
在跑訓練這點有一件事我還沒確定,當我跑 CNN 的訓練時,因為我電腦效能的關係,他在一開始就是一直在訓練,從使用者的角度就是什麼都看不到,指引也沒有明確說明這個訓練的過程會有什麼提示告訴你訓練進行得如何,進行到哪裡,而時間也很晚了,我就想說那就放著讓他訓練我先去睡覺,等我睡起來總得訓練好了吧~。奇怪的是,當我隔天早上起床時,它貌似還在訓練!? 但我一去動它,它就突然結束了,還在 Terminal 旁邊的小燈號顯示紅色燈號,表示指令沒有成功執行,害我都不知道他跑一個晚上到底是有訓練到還是沒有(雖然後來發現是有的),總之在我進一步測試之前,這在我心中留下了一個問號,但答案待會就會知道了。
有稍微了解機器學習的都知道它使用一個很重要的理論:Gradient Descent
並且在訓練過程中有兩個我們常需要觀測的參數:Loss
和 Accuracy
要能夠觀察在訓練過程中這兩個參數的變化,在作者的指引中給了三個方法
tensorboard --logdir=logs/
指令:bash: tensorboard: command not found
,意思是說沒有這個指令。咦,有這回事?我上網爬了一下文,但到頭來都沒有找到能直接解決的方法,反倒是發現了一個和第三個方法有關的一個關鍵步驟。http://localhost:6006/
直接連上本地端的 IP 的 6006 接口來觀測:正當我一個頭兩個大時,我無意間爬到兩篇文提到了相似的解決辦法,那就是使用
python3 -m tensorboard.main --logdir=logs/
指令 (後面的=logs/是只適用於我的檔案路徑,實際上這裡是要打上你的 tensorboard 的路徑),在使用這個指令之後, Terminal 會顯示出
Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all TensorBoard 2.13.0 at http://localhost:6006/ (Press CTRL+C to quit)
這時候發生了一件事,還記得第三點所遇到的問題嗎,現在我可以成功用瀏覽器進到顯示 Tensorboard 的頁面了,到這裡才終於看到了我在訓練時所呈現的 accuracy 和 loss 的曲線,並且確定說我昨天跑一整晚的訓練是有成效的。
可以看到在時間的座標軸上,他總共訓練了9個多小時,也就是我開始讓他訓練到我隔天去動它之間所經過的時間,這讓我不禁懷疑,它原本的設計是不是本來就不存在終點,而是看你想讓它訓練多久就訓練多久,訓練越久 Acc 就越高,直到你想結束訓練為止,但我也忘記我是按到什麼就讓它停止訓練了。
關於綜合第二點和第三點的問題,我得出的結論就是第二點無解(或是說我還沒找到解啦),第三點則是要手動開啟 Tensorboard 在本地 IP 的窗口之後才能進去,並且在我按下 Ctr + C 後就會關閉,這樣在瀏覽器上刷新之後也會再顯示拒絕連線的頁面。
至於要怎麼驗證訓練的成果,那就是執行test_cnn.py
,它就會提取存在專案裡面的訓練成果,套用在一個由電腦控制的遊戲局裡面,然後就開始現場玩給你看。說實話,當你看到他現場玩到很高分的時候你真的會被他驚豔到,放它一個晚上訓練後居然就有如此成效,如果用更好的硬體加上更久的訓練時間豈不是就無敵了?
雖然我只是把別人的成果下載下來跑而已,想不到過程中還是遭遇許多問題,要一一解決也是花了我不少時間和心力,一想到我這週末還有一堆節預報要寫,還有電子和電磁的作業,頭就很大。
但是能在兩天的時間內就累積那麼完整的經驗,我覺得還算值得。雖然說有些問題我只是在這個當下找到一個可行的解決辦法,事實上我也還沒徹底了解這些問題的成因,所以往後遇到類似的問題也不一定靠同一招就可以解決。或許在以後的某次機會下可以遇到比我更了解這整個系統的運作原理的人,可以教我關於這些問題更深入的細節和背後根本的原因。
後來我又嘗試在我的 Windows 桌電上跑了一次,有幾個新的發現,但在那之前,我要再補充幾個我在 Windows 系統上遇到的問題:
程式對於套件版本的要求:
我在安裝指引所要求的套件時,一開始我是直接就用它所給出的套件名稱直接下去裝最新的版本,結果在到運行遊戲本體和跑測試訓練結果的程式為止都沒有問題,直到我想讓它跑訓練那一刻,它突然跳出許多錯誤通知,而它的錯誤通知並不像是缺什麼套件,因為如果是缺什麼套件的話他就會直接說找不到的套件名稱,就直接再裝就好了。
然而它產生的錯誤訊息卻是對於某個函式庫內部的參數名稱有辨識上的問題,理論上如果不是沒有裝或是和當初作者使用的版本有年代上過於遙遠的差距,應該都要相容的,並且也沒有像 Tensorflow 就有指定它所會應用到的其他套件像 numpy 就有指定的版本範圍,然後上網查也沒有什麼線索,讓我煩惱了一陣子,最後我決定就把那些有指定版本的套件降階回較舊但是作者使用的版本,而在這又遇上一個問題。
套件之間的版本相容性:
現在我要裝作者有在指引中要求的某些套件的特定版本,有被指定版本的有:
問題發生在我要裝 gym 時,他在抓資料時發生錯誤,導致沒辦法成功安裝,我原本打算繞過 gym 直接去裝 stable-baselines3,想不到它要裝這個版本就需要 gym 先是上面的版本,所以後面就直接無法繼續進行,最後終於在網路上找到說 gym 如果要裝 0.21.0 版的話連帶 setuptools 也要是舊的版本,所以我就只好把 setuptools 也降階回 65.5.0 (原本是 68.3),最後總算是成功安裝那幾個套件作者所指定的版本,也終於在 Windows 上讓訓練跑起來了。
雖然在上面我對於這些問題的描述非常簡短,但實際上從搞清楚問題的來源、上網爬文、發現解決辦法、交錯測試安裝不同版本、到最後終於成功讓程式跑起來為止,也是花了我不少時間,說真的其實不應該花那個多時間在單純處理開發環境的,有點浪費時間,但時間都花下去了,也確實又累積了一些經驗,希望往後遇到類似的問題能夠更快地解決。
還記得如果執行 test_cnn.py 的話就可以取用訓練結果來玩遊戲的這件事嗎?我上次搞錯了一件事,作者在上傳這整份專案時就已經連帶他當初已經訓練的成果資料一起上傳了,所以如果我直接執行的話他取用的會是作者的訓練結果,而不是我的。這代表我上次跑的訓練並沒有套用到我跑的測試上面,要改成我的訓練成果的話需要到程式碼裡面另外再改它讀取訓練資料的路徑。
另外,在瀏覽器所開啟的 tensorboard 也可以看到過去作者做的訓練所留下的曲線,上面也有標記經過的時間和走的步數,最重要的是有每單位時間的訓練步數,或許是硬體上的差距,我跑的分析在單位時間的步數上和作者的差距居然有到三倍之多,所以我還是就乖乖熟悉程式運作原理就好了,拿我的電腦跑訓練說實話意義不大。