contributed by < willy-liu
>
make test
的測試。但沒有研讀shannon entropy和網頁伺服器的部分有觀看完大多數的教材,作業只有回顧一題第一週的課堂題目。
教材觀看至浮點數運算,kxo目前只讀了部分第一頁的內容,還不理解kernel相關的指令、程式。
遇到的問題很多
Jserv給的回應
故事的最後&我的想法
看到結束,讓我覺得有點遺憾,他們付出了這麼多,學了很多知識,花了很多錢,也因為他延畢;然而,卻因為當兵、機器穩定度和各式各樣的原因沒有繼續維護下去,也沒有真正投入使用,最後只好拆掉放在那邊。
這點我覺得不只是他們,大多數的計劃、點子都因為現實的原因而停留在提案、prototype階段就胎死腹中了,包含大多數人的專題成果、產學合作,能真正被投入到生產環境的寥寥無幾,我認為最大的原因是學校裡所學的理論固然重要,但與現實脫鉤,就像是Jserv老師上課提到的,我們都知道process life cycle長這樣
然而在現實的linux實現卻是這樣
因為我們的理論在現實會因為各式各樣的因素干擾,我們必須做出妥協,但這些在正規的大學教育中卻不會告訴你,直到你碰壁了才會理解到這個道理。
另外一點是大學的理論和實操也嚴重脫鉤,理論學得再多,用不出來有什麼用?讓我們的學生出現資工系的學生不會寫程式,機械系的學生不會做機械,現在又多一條電工系的學生不會焊電路(22)。這就是Jerv老師常說的 大學的悲哀。
修了linux這堂課,我知道我完全跟不上課,但我開始「誠實面對自己」,正視自己學了哪些內容,還有什麼不足。老師常說「缺什麼,就補什麼」,在這篇文章中體現的淋漓盡致,這兩句話是我在課堂中學到最重要的精神。
想做這個是因為既然來上這堂課就想要真正寫一些kernel相關的程式,而我的專業又跟人工智慧、深度學習有關,在看過kxo的作業說明後發現目前已經用定點數實作MCTS,那我搞不好可以實作看看mlp,讓kxo不只包含ML,也能納入DL。
還沒有研讀相關的教材
這題所使用的是Q16.16定點數,意思是將int32_t
的前16bit儲存整數,後16bit儲存小數,以下是範例。
= = (Q8.8) = (Q8.8)
,也就是將123*,等價於123<<8,就可以將整數轉換為定點數。
= (Q8.8) = (Q8.8)
,要注意由於浮點數無法直接使用位元運算,所以只能乘上,另一點要注意的是rounding的問題,由於C的int會無條件捨去小數部份,這會導致精確度大幅下降,所以要根據最後的值是正數還負數,補償 +/- 0.5來做四捨五入。
所以公式會變(Q8.8)再無條件捨去一樣是(Q8.8)。
可以直接相乘,但要注意兩個32bits的值相乘最多會需要使用64bits儲存,而且在定點數已經先做過一次位移,所以相乘時要記得shift回去
同乘法,要記得先向左shift再相除,避免小數部分遺失
這個函式要實作fix16的exp(in),前四個if用來提前處理特殊情況,
接著先來看neg的作用,由於exp(-x)=1/exp(x),所以統一把負值轉為正的再進行運算,最後再轉成倒數,fix16_div(FIX16_ONE/result)【CCCC】
中間的迴圈部分為exp的泰勒展開式
可以發現每一項都是前一項乘x後除i,所以就可以用term代表當前的項,累加到result。
公式為:
我有注意到fix16轉回float的過程,有小數時就只能乖乖使用很慢的浮點數除法,但我們可以判斷a是否包含小數部分,如果他沒有小數部分就可以直接用位元運算加速轉換。
當前計算tanh計算exp(x), exp(-x)都是呼叫fix16_exp,但其實只要呼叫一次就好,exp(-x)只要用exp(x)的倒數就好。
原本嘗試改進tanh的精確度,我打算先從exp的計算下手,我嘗試使用kahan的方式進行補償
然而,在我測試時卻發現和原本方法算出來的誤差值一模一樣。
接著我嘗試直接去估計tanh,不經過exp來計算
我首先使用泰勒展開式直接估計tanh
然而,這種方式除了限制外,算出來的誤差反而更大了
Range of difference over [-1, 1]: min=7.45058e-08, max=0.0155462, avg=0.00174431
原因是因為分子項的x冪次方太大了,精度損失的更快。
而原本的方法不但可以更大的範圍外,還更精準。
Range of difference over [-10, 10]: min=1.78814e-07, max=4.15146e-05, avg=1.15705e-05