Author name: 楊慶忠

基本觀念之5~巢狀結構與輸出格式

1-5:巢狀結構與輸出格式 如果有兩個以上迴圈包含在一起,其中內部迴圈縮排,從屬於外部迴圈,則稱此種迴圈為巢狀結構。很多情況會用到此種結構,例如一張圖片中像素值的處理,就要用到一個二維串列,再搭配上巢狀迴圈。除此之外,如果在選擇敘述 if 式子裡面,還有其它縮排的 if 敘述,也可稱為巢狀結構。 在這裡,我們使用大家都知道的九九乘法表,來舉例說明巢狀迴圈的特點,並且結合數據字串輸出設定,讓乘法表能夠格式化整齊排列。 巢狀結構,外層迴圈變數每變化一個值,內層迴圈變數值就要全部變化一次,所以可以戲稱:「外圈慢慢走,內圈跑斷腿。」。 上圖中,第1行的外層迴圈變數 i ,當其取出值為1或2或3或其他,內層迴圈變數 j 就要從1到9全部變化一次。所以外層迴圈變數 i 總共從1到9只跑一遍,但內層迴圈變數 j 從1到9跑了九遍。請讀者思考第3、4行兩個print( )的縮排位置不同之原因。 第3行print(f”{ j }*{ i }={ i*j:2d }”,end=” “)的小括弧中,後面的end=” “,表示每次輸出後會空一格再接續下次輸出,比較重要的,是前面 f”{ j }*{ i }={ i*j:2d }” 的部份。 左右兩個雙引號 “…..” 表示,當中的…..被視為輸出字串,但 f”…..” 又再特別表示,其內的成對大括弧 { i }、{ j }, 是要將 i、j 所代表的變數值取出,f”…..” 的f代表格式化(format)的意思。 甚至{ i*j : 2d}還更進一步要求,i*j 的變數值輸出,必須合乎 2d 的格式,要預留兩個字元的位置給預設靠右對齊的整數,因此乘法表中等號右邊的值,其個位數才能夠垂直對齊。2d的d,原文是decimal,表十進位的整數。 在上圖第1行中的7d,表預留7個字元位置給整數123輸出,123靠右對齊後,左邊會留下4個空位。第2行的7.2f,表預留7個字元位置給浮點數123.456輸出,而且小數點第2位以下四捨五入。第3行的7s,表預留7個字元位置給字串 ‘apple’ 輸出,字串預設是靠左對齊,所以會在右邊留下2個空位。 […]

基本觀念之5~巢狀結構與輸出格式 Read More »

基本觀念之4~串列與迴圈

1-4:串列與迴圈 我們前面曾提到過,變數包括有變數名稱和變數值兩部份,其中的變數值除了單一數據外,也可以指定為多個數據,例如一個班上的數學成績可能有幾十筆,都屬於同一個變數。這種情況,在平日生活中,常有機會碰到,所以多個數據的資料表示方式,及其運算處理技巧,在Python裡面是相當重要的。 在這裡,我們先熟悉一種資料型態叫做串列(list),它是好幾個數據被中括弧包含起來,彼此間用逗號分開,比如像變數 lista = [11, 22, 33, 44],其中括弧內的每個數據可稱之為元素(element)。 這種資料型態也叫做容器(container),非常適合使用for迴圈來處理運算,因為它的資料整齊排列,被限制在一定範圍內,讓人很直覺的看出來,每個數據可以依序被迴圈取出。所以要輸出所有數據,或者加總其數據,都可以援用上一次的做法。 上圖中,第2行和第7行,for迴圈中的 i,現在是 in 在lista裡面了,可想而知,就是隨著不同次的迴圈,依序把11、22、33、44分別指定給變數 i ,然後把它的值印出來或加總。 這種 in 在某個容器內,然後隨著迴圈將元素一一取出的方法,非常直覺,但很好用,也有一些變化的型式。 在上面的程式執行過程當中,我們不得不將所有元素一口氣處理完畢,但如果要個別取出某個元素,就要用到索引的技巧了。 上述的11、22、33、44,它們在lista裡面的索引值,分別是0、1、2、3,可以利用中括弧加索引值將lista編號,個別取出裡面的元素。當然也可利用迴圈變數當作編號,一一將元素值取出,如下圖所示。 在第2行最右邊,我們使用反斜線””來強迫換行,讓太長的程式碼變得比較好閱讀。讀者可以自行print(lista)看看,觀察其和第3行輸出的異同處,並想辦法解釋其差異。 第5和第6行當中的迴圈變數 i,在這裡,不再是直接取用來輸出,而是將它當作串列的索引值,把每個元素都編號後,再做輸出。讀者也可以用這種方法,將元素值加總看看。索引加迴圈,是初學者開始會感到挫折的地方,動手多練習,是克服困難的唯一良方。 容器(container) 有多個種類,中括弧裡面的數據如果用空格代替逗號,就是陣列(array);大括弧裡面數據用逗號分開的稱為集合(set),如果數據是成對的則稱為字典(dictionary);小括弧裡面數據用逗號分開的,稱為元組(tuple)。 元組(tuple)這個字中英文看起來都有點彆扭,不容易顧名思義,剛開始都會聯想到元祖雪餅。它其實只是一組相關的數據被整理在一起,目的在便於閱讀及取用其訊息,而非將數據做運算處理。例如記錄陣列的維度、函式的多個回傳值等。

基本觀念之4~串列與迴圈 Read More »

基本觀念之3~for迴圈

1-3:for迴圈 迴圈,會重複執行相同的程式碼來進行工作,執行次數可以一開始就做設定,每次在重複相同指令時,其迴圈變數都會增減一個固定數量,一直到條件滿足為止。我們先用for迴圈來舉例說明。 在這個練習中,我們在print( )括弧中加上一些參數和字元,來設定它的輸出格式。如果加上end=” , “參數,表示每次輸出不要自動換行,只在後面加逗號,下次輸出會在逗號後面接續下去。 print( )中加”n”字元,表示自動換行一行,加三個”n”字元,表示自動換行三行。適當做這樣的設定,會讓程式輸出結果比較好閱讀。 第2行for的敘述,表示對 i 這個迴圈變數而言,它是在range(6)範圍之中從0到5的整數。每執行完一次第3行縮排的print(i,end=”,” )指令,就是跑1次迴圈,總共要跑6次迴圈,這6次依序先把0、1、2、3、4、5分別指定給變數 i ,然後把它的值印出來。 第6行for敘述的範圍,變成range(1,6),就是從1到5的整數1、2、3、4、5。 第10行for敘述的範圍,變成range(1,6,2),就是從1到5每差2取一個整數,得到1、3、5。 for迴圈最普遍的用途,就是累加一系列相關的數據。日常所見最簡單的累加像1加到5,這數據少到甚至可以直接print(1+2+3+4+5),但如果從1累加到100甚至1000,這樣就行不通了。我們先看看下圖第14行到第20行,這是累加計算的程式碼,看起來好像更麻煩。 但我們注意到從第15到19行,它們有些動作是重複的。它們都是從變數summ裡面先把舊值取出來,加上一個新的數據後,存到summ裡面去,下次再取用,而每次加上的新數據,都比前一次的數據大 1 。 這就可以用第23、24行的for迴圈來代替了。因為新加的數據每次都比前一次大 1 ,我們就可以用 i 迴圈變數來代替這些新數據,它是範圍在range(1,6)的5個整數,依序被取出。每次summ的舊累加值加上新數據後,將這新的累加值存進summ裡面,再進行下一次迴圈。 上面第25行程式碼,試著將它縮排4個空格後再執行,看看結果有甚麼不同,並想辦法解釋原因。 程式碼中的range(1,6),如果改成range(1,101),就會讓我們聯想到德國數學家高斯的故事了,只不過他小時候是用肉眼找對稱再相乘,現在電腦裡面的運算大多是快速計算加法所得。 圖1-3-3:高斯和他弟子黎曼所在的哥廷根大學,是歐洲數學重鎮。當時流傳一句話:「想學好你的數學嗎?打起你的背包,到哥廷根去。」

基本觀念之3~for迴圈 Read More »

基本觀念之2~條件敘述

1-2:條件敘述 條件敘述的語法很簡單,就是if(假如)….else(否則),其精神也很好掌握,假如條件成立,就做某些事,否則就做其他的事(或者甚麼事也不做)。很容易用日常生活所見,舉例來說明它的適用情況。 例如有一所M理工學院名聞遐邇,它的入學標準非常嚴格,假如PR>=95才會通知接受(accept),否則一律通知拒絕(reject),這就可以寫成下列程式碼: 上面程式碼第3行,在 if PR>=95的敘述中,條件PR>=95是需要做判斷的,可因為第2行已經設定PR=98,滿足了這個條件,所以判斷為真(True),會直接執行下面第4行print(“accept”)。 但到了第8行,PR改成88,做PR>=95判斷的結果為假(False),所以會執行第11行else下面的print(“reject”)。 要注意在程式碼冒號(:)後面按下Enter鍵時,系統會自動在下一行做縮排(indent),有縮排的程式碼是從屬於沒有縮排的上一行。程式碼上下之間,如果有從屬階層關係就會有縮排,初學者沒有理解這點,即使打字沒有打錯,也會產生編譯執行錯誤。 圖1-2-1:AMD執行長蘇丰姿曾質疑:「沒道理麻省電機博士,要在哈佛企管碩士下面做事。」  上面的程式碼,可以將else及從屬於它的部份省略,只單獨使用if的部份,用以表示這個條件敘述,只在乎判斷為真的時候該做些甚麼,判斷為假的時候,它甚麼事都不做。從另一個角度來看,也就是容許把功能再擴充,讓條件敘述並不僅僅只能做二元判斷,還可以有多重的選擇。 例如另一所鄰近的H大學,學術聲譽並不弱於M理工學院,但其選才標準比較多元,認為課外活動的表現也不容忽視,所以PR值的設定較為寬鬆。PR>=95是一定會接受的,但在85和95之間的學生,它會給予考慮,當然,PR<85它也會拒絕了,程式碼就可以改成下列內容: 我們在上圖第5行,插入了elif指令,它其實是else+if的綜合體,else的部份表示不滿足前面的條件PR>=95,也就是得到PR<95;if的部份表示,在這種情況下(PR<95),再給它設定條件PR>=85。所以這個elif指令得到的整合條件,就是85<=PR<95。 第7行的else,表示在不滿足前面所有條件的情況下,只剩下PR<85的條件了。 因為第2行設定PR=88,所以這個程式會執行第5行elif下面第6行縮排的指令,輸出”consider”。 在條件有好幾項且彼此互斥的情況下,elif可以多次使用。例如學生成績的分等第,就可以善用elif的功能。

基本觀念之2~條件敘述 Read More »

基本觀念之1~變數與資料型態

1-1:變數與資料型態 Python的變數,和國中時候學過的未知數X、Y、Z,有些類似,但又差異甚大。未知數的值從頭到尾都是固定的,計算過程只是在求解唯一的答案;但變數(variable)的值卻是可改變的,從程式一開始、到程式中段、到程式結尾,都可以因為運算處理,而改變其所代表的值。 所以一個變數有兩個含意,一個是變數名稱,另一個是變數值。例如num=100,表示其變數名稱為num,而其變數值為100,等號”=”在這裡,有指定、賦予變數值的意思。 我們可以用一個箱子表面貼的標籤來表示變數名稱,放進箱子裡面的資料為變數值。變數名稱是維持固定的,但放進箱子的變數值,卻可隨程式的執行而改變,如下圖所示: 我們將上面num=200的例子再延伸。在代數式的運算中,x=x+100是不合理的,因為等號左右的x消掉後,會得到0=100;但在程式設計中,類似num=num+100的運算,卻常常會出現。 因為在等號(=)右邊的num,代表變數值200,它和100相加得到300,然後再把300指定給左邊自己的變數名稱num,從而取代了舊值200。 這個過程,我們用程式碼和示意圖來表示: 我們還記得變數有兩個含意,在此謹記著,出現在等號左手邊的,代表變數名稱;出現在等號右手邊的,代表變數值。 變數的名稱,和往後會介紹的函式名稱、類別名稱,都稱為識別字(identifier),顧名思義,就是一看到名稱,大概就能猜測到它被賦予的資料性質。例如name代表姓名(字串,str),age代表年紀(整數,int),average代表平均值(浮點數,float)。所以在變數命名上,應該使用有意義的英文名稱。 除此之外,還有一些命名的規則要遵循。例如,名稱的字首,最好用小寫或大寫的英文字母,但大小寫是有差別的,像num和Num是代表不同的變數;字首不可以是數字,如5name、8age等;不可使用程式或系統的指令(關鍵字/保留字),好比像print,if、else,class這些。 如果需要使用到兩個以上英文字來命名,字間用底線隔開不要有空格,例如bool_for_comparison=100>200,是表示有一個bool(布林)資料型態的變數值,它得自比較運算100>200後的結果,執行print(bool_for_comparison),會得到布林資料型態中的False值。

基本觀念之1~變數與資料型態 Read More »

基本觀念

第一章:基本觀念 工欲善其事必先利其器,想學好Python的第一步,當然就是要趕快把軟體準備好。對初學者而言,最好先熟悉Anaconda整合環境之後,再進入Google雲端硬碟,免費運用其Colab限量GPU。 Anaconda是以Spyder編輯頁面為開發環境,內建有常用的套件模組,供編譯執行Python時匯入連結之用。它有多種版本可選擇,學員可從下列藍色字體的網站,點選下載檔案較小且穩定的版本,在此推薦Anaconda3-2025.06-0-Windows-x86_64.exe,將其存至桌機或筆電的資料夾: https://repo.anaconda.com/archive/ 請用滑鼠左鍵雙擊下載的執行檔進行安裝,過程中大部份只要下一步、下一步(next)就可以。完成後從開始功能表展開Anaconda3資料夾,可以看到Spyder的蜘蛛網圖示,點選開啟它,過程中看到的無作用小視窗一律關掉,最後可以看到下列編輯環境: 預設的版面,左半部是程式編輯欄位(Editor);右半部的下方是執行輸出欄位(IPython Console),其上方是多個視窗疊在一起,我習慣將其上方所有視窗都關掉(Close),讓執行輸出視窗佔滿右半部欄位。 接著點選工具列的板手圖示(偏好設定,Preference),進去修改字型大小,然後開始第一個程式。以下為視訊影片教學導引: https://mobile-learning-testing.com/wp-content/uploads/2024/09/Python-0.mp4 不能免俗,我們也是要輸入輸出”Hello World!”。 在左半部程式編輯欄位,預留有註解行,包括單行註解和多行註解。前者是#字號後面的灰色字體,後者是成對的三個雙引號當中的綠色字體。可將其全部刪掉,不妨害程式碼的執行。 我們用「print(“Hello World!”)」輸入第一條指令,也可以輸入print(123),或print(123.456),或print(123.456+456.789)。 執行全部程式碼的按鈕,是在工具列中方向朝右的綠色小三角形;執行部份選取程式碼的按鈕,是工具列中有”工”字型加下方綠色小三角形的圖示。 坐而言不如起而行,Action speaks louder than words!趕緊將軟體下載、安裝、啟動,跑一下最簡單的程式,踏出最基本的第一步。

基本觀念 Read More »

強化式學習之3~隨機決策

3-3:隨機決策 早先提到的CNN神經網路中,其遮罩的係數(也就是權重),一開始是用隨機的方式來指定,在多次的訓練之後,會利用越來越小的誤差,逐步修正到比較合適的權重值。中間的步驟,也有用拋棄層(Dropout Layer)來做隨機處理的。 而增強式學習的隨機選擇考量,則是因為訓練初期獲得的資訊量有限,所以讓模型勇於嘗試各種可能性,在歷經了各種情況且反覆摸索之後,計算出最大報酬值以找出最好的策略。 前者隨機的部份是在訓練開始就全部完成,後者是在訓練過程逐次降低其比重。兩者相似的地方,就是隨機計算的處理都很快速,只不過一個是在神經層,另一個在時間序列當中。 蒙地卡羅模擬(Monte Carlo Simulation),是著名的隨機運算技術,它利用亂數產生器得到大量隨機數據,分析其統計分佈,進而引用來估計實際問題的答案,常被應用在增強式學習當中。 圖3-3-1. 提到蒙地卡羅的博弈產業,很容易聯想到隨機決策。 我們把先前的9×9迷宮訓練例子,用Python軟體再做一次比較完整的介紹。 編輯的軟體名稱為”Spyder”,是下載自Anaconda網站。程式在執行的時候,除了輸出的數據,也呈現出動態的迷宮視窗。”O”型的藍色圈代表尋找寶藏的主角(agent),經過數十回合的摸索與計算,終於找到最佳的路徑策略。 在這裡隨機選擇的比重,第1回合自然是100%,接下來就以0.8的等比級數下降。剛開始的前10個回合的機率都在10%以上,到了30回合以後漸趨為零,因為這時候得到的數據,已足夠自主判斷接下來的路徑了。當然這只是基礎的範例,比較大的問題訓練回合數可達幾萬甚至幾百萬。 https://mobile-learning-testing.com/wp-content/uploads/2024/08/mymaze.mp4 我們在”人工智慧入門”這一單元的貼文,暫時告一段落,隨後會用不定期的方式,進行這方面的發文。緊接著,我們將進入到”Python程式設計”單元,介紹實務上的一些常用指令,歡迎有心想鑽研技術細節的朋友,繼續閱讀本社團貼文。

強化式學習之3~隨機決策 Read More »

強化式學習之2~監督式學習之瓶頸

3-2:監督式學習之瓶頸 監督式學習,好像是學生在準備社會科考試一樣,唸的題目越多,背的標準答案越多,答題的準度和分數就會越高。但是要從90分考到95分,究竟要再多記憶多少內容,沒有人能提出精準的數據評估,甚至多背些考題是否一定就會提高分數,也很難講。 而且,除了記憶事物之外,舉一反三、觸類旁通的能力也很重要啊!它讓我們可以從有限的記憶中,摸索推理出不曾背誦過的資訊,這也許是人類智慧中更重要的部份。 例如有個題目問,“美國第一大都市在哪裡?”,我們很快可以回答是“紐約市”。如果再問“紐約在荷蘭人佔領期間的名稱是甚麼?”,或者“新阿姆斯特丹的北城牆,為現今金融中心的甚麼街?”,這些加以思考推理或許就可得到的答案,監督式學習必須輸入更多的資料來訓練,否則無法回答。 所以有好事者比喻,一味地只知道使用監督式學習,就像是古代巴比倫人建好巴別塔,自認為已經可以通達天際了,實際上還差了十萬八千里。 圖3-2-1. 古巴比倫人建立的巴別塔,高聳入雲霄,他們認為可以藉此和天際溝通了。 這個時候,強化式學習就可以提供有價值的處理方向了。 強化式學習,訓練次數少則數十回合(episode),多則數萬甚至數百萬回合。剛開始訓練的少數回合當中,在做決定過程時,會有比較多的隨機選擇,等到訓練過較多的回合了,能夠藉以參考的數據足夠了,就會逐漸增加自我判斷的比率,同時持續減少隨機選擇的次數。 這隨機選擇的功能,就程式設計而言,是要避免它無法跳脫不定次數迴圈;就策略規劃而言,是希望它儘量嘗試各種可能性,以真正找出最佳的報酬策略,這當中自然就會帶有一些推理成份了。 下面的9×9迷宮遊戲,主角起始位置在迷宮正中央,右下角格子的reward=+30,代表寶藏地點,找到這裡該回合即結束;左上角格子的reward= – 30,是大魔王地點,抵達此處會被吃掉,該回合同樣結束。黑色格子是不可穿越之障礙區,其餘格子皆reward= – 0.2,所以每多走一步都會被扣0.2,要用最少的步數才能得到最大的報酬(return)。 圖3-2-2. 一個9×9的迷宮遊戲,希望用最少的步數,讓主角由正中央的起始位置,找到右下角寶藏地點。 我們第一次執行模型,讓它跑100個回合,並刻意使其隨機選擇的比率以較快的速度減少,發現它要找到最佳步數的8次會比較吃力。 第二次同樣讓模型跑100個回合,但讓它的隨機選擇以較慢的速度減少,發現它的訓練成效有改善了。

強化式學習之2~監督式學習之瓶頸 Read More »

強化式學習之1~馬可夫決策過程

3-1:馬可夫決策過程 增強式學習這幾年來廣受各方矚目,主要的原因,當然是它成功地被引用在ChatGPT當中。但除了大型語言模型,增強式學習還有很多重要的應用,例如像無人載具、機器人的路徑規劃,以及數位電路、核融合及渦輪引擎的效率最佳化設計等。 增強式學習的基本概念,在於透過多次訓練逐步形成最佳策略,以找出最大報酬的最適路徑。迷宮遊戲,是最常被拿來舉例說明的範本。 圖3-1-1上圖之中,橘色球形代表遊戲的主角(agent),整個6×6迷宮就是環境(environment),其中任何一個格子的x,y座標就是狀態(state),橘球要上下左右朝哪一方向移動,就是行動(action)。 走到相鄰任何格子的獎勵(reward)應為 -1,但有兩個格子獎勵為4和5,其中並有黑色的障礙禁止區。想要成功走完迷宮的基本邏輯思考,就是以最少的步數走到獎勵為5的格子,來獲得最大的“累積獎勵”(稱為“報酬”,return)。 圖3-1-1下圖之中,是在說明,經過多個回合(episode)的訓練,系統會慢慢計算出每個格子的價值(state value),agent在決定要朝哪個方向移動下一步時,就會傾向鄰近價值最高的格子,並更新目前所在格子的價值,這就是所謂的策略(policy)。 圖3-1-1. 迷宮遊戲,是增強式學習常用的範例。 迷宮遊戲只是增強式學習的起步,但已需要一些程式設計的基礎了,這方面,適當的Python語言訓練,加上良好的直覺(intuition)是很有幫助的。 學理方面,則必須面對比較不好掌握的統計機率。這個部份,馬可夫決策過程(Markov Decision Process, MDP)當中,有一個假設需要先瞭解。 這個假設是說,“目前的時序狀態,只取決於前一個時序的狀態與行動”。換句話講,它假設了前面的時序已包含了更前面時序的訊息。所以可以利用遞迴的做法,將所有時序的關係串接起來。 馬可夫先生(1856~1922),早年就讀彼德堡文法學校,格格不入。後來就讀聖彼得堡大學,在隨機過程領域做出重要貢獻。但他並未忘情早年訓練,曾利用馬可夫鏈來模擬俄國文學中輔音和元音的頭韻法。 圖3-2. 馬可夫(Markov)畢業自聖彼得堡大學,是俄國著名的數學家。

強化式學習之1~馬可夫決策過程 Read More »

強化式學習

第三章:強化式學習 ChatGPT這種語言模型,是屬於監督式學習,例如訓練英翻中的時候,輸入一個英文句子“I have been expecting you.”,一定要同時輸入它的中文翻譯“我恭候您多時了”,用以計算其損失函數,做為回饋修正模型權重之用。模型訓練完成可以回答提問者的問題了,就是到了模型預測的階段。 但我們在不同時間點,問ChatGPT同一個問題,常常會得到有所差異的答覆。這是因為,模型一般是利用(exploit)學習經驗回答問題,但有時會探索(explore)隨機答案,目的是想增加回答內容的多樣性。 如此一來,在預測階段所提的問題,如果不同的答覆內容給予不同的評分,就可以再放進模型裡面,當作另一筆訓練的資料和標記值。這樣的學習訓練方式,讓ChatGPT在往後的答覆更加合理,並且文字益形通順。 例如,“You should have studied harder.”,如果翻譯成“你原本應該更用功讀書”給予5分,如果翻成“你應該更用功讀書”給予3分,如果翻成“你應該用功讀書”給予1分。這樣的獎懲方式是「強化式學習」的基本概念,搭配上既有的監督式學習,是OpenAI公司迎頭趕上Google的重要關鍵。 圖3-1. 強化式學習(Reinforcement Learning, RL),其獎勵或懲罰(Reward),是建立最佳行動策略的重要因素。 強化式學習,和監督式及非監督式學習,並稱是人工智慧的三大學習方式。但這種學習方式有其獨特的地方。 它在建立其內部神經網路時,資料集是由自己計算所得,不需要再從外部蒐集資料;它應用的範圍甚廣,包括遊戲策略、自動駕駛、機器人控制、金融投資策略…………。 OpenAI早期喜用強化式學習來訓練遊戲,看似不務正業,實則在蓄積能量,待時機成熟即一鳴驚人。有志於這方面研發的工作人員,建議應先打好程式及理論基礎。 圖3-2. 捉迷藏遊戲,是OpenAI相當著名的強化式學習遊戲。

強化式學習 Read More »

Shopping Cart