{%hackmd 0I99hcNpQaqK3I5yYc5B2A %}
# 明道中學高中部資訊類專題第一次簡報
----
# Re:0 從零開始的AI底層實作
---
# 緣起
**(創新時勢)**
----
## 人工智慧?
## 機器學習?
## 神經網路?
<!-- 人工智慧、機器學習、神經網路?
這些詞是否曾在我們耳邊出現過?
他們是否如螢幕上的這般冰冷陌生?-->
----
## 這些詞是否耳熟能詳?
<!-- 其實這些詞都非常的耳熟能詳,校長在朝會的演講就
提到過幾次呢,可以說他是個時代性的象徵了。
-->
----
<!--
## 或許不只是聽過,甚至對它抱過憧憬

---- -->
## 當企業口中的喊著AI的口號

<!-- 當企業口中的喊著AI的口號,其實他們就像中國文革
的紅衛兵一樣,只懂喊口號,對於他真正的原理邏輯
沒有半點理解。-->
----
## 這笑話感覺是那些傳產大老闆搞出來的對吧?
<!-- 這些笑話感覺是那些傳產老闆搞出來的對吧?
其實在台灣,我們口中的AI工程師又何嘗不
是這樣呢?廉價碼農仗著老闆們聽不懂,拿著
模板、API到處吹牛卻不懂一點原理的有多少?-->
----
目前在台灣的AI產業大多是靠著現成API在做
缺乏自己的在底層優化的技術力
<!-- 目前在台灣的AI產業大多是靠著現成API,也就是
剛剛提到的Tensorflow在做,真正懂AI數學,有
能力優化訓練的大概沒多少吧-->
----
## 在資電圈流傳著這樣的話
## AI工程師其實只是Tensorflow參數調整工人
----
最大也最讓人不願面對的對比
中國...
他們積極發展底層,已經發明了許多強大的算法
<!-- 才剛嘲笑完中國文革,現在看看我們自己,在AI底層
,我們的產業就像文革時期的人們一樣孱弱,被中國
發明的不少演算法輾壓
-->
<!-- 1min40s -->
----
## 所以我們要...
<!-- 基於以上原因 -->
----
## 自己幹出底層
---
#### 研究規劃
**(整體架構(含比較分析))**
----
# 計畫規劃
----
## 研究方法
- 探討底層的構成
- 使用Rust做出可以運作的模型
- 應用層面的延伸
<!-- 我們希望從底層開始建構CNN神經網路,
而我們的目標大致分成三個部分,
第一就是理論的探討,畢竟AI的一切都是
建立在數學之上的
第二則是利用rust語言作出可以運作的
模型,至於為什麼是rust呢?主要是因
為rust在編譯上的安全性、記憶體的高
效利用,以及與C語言的兼容性可以配合
我們要用到的工具
最後則是希望在完成模型後作應用層面的
延伸測試,目前是希望用常見的手寫數字
集進行優化的測試
-->
<!-- 2min30s -->
----
## 研究流程

<!-- 2min50s -->
----
比較|程式語言|實踐方法|學習方向|
-|-|-|-
Tensorflow|python|利用API|實作方法
自幹的|rust|依原理重頭寫|理論實踐
----
## 工作分配
<!-- ----
### 簡報
組員 | 工作分配
-|-
陳茗祐 91XJ30 | 寫示範程式、做簡報
邱繼叡 91XC13 | 做簡報、畫圖
謝侑哲 91XC39 | 做簡報、寫國文 -->
組員 | 工作分配 | 專長
-|-|-
陳茗祐 91XJ30 | 研發筆記、專案管理、寫``code`` | 裝墊
邱繼叡 91XC13 | 讀筆記、寫``code``、文書處理 | 滑水
謝侑哲 91XC39 | 讀筆記、寫``code``、文書處理 | 真的很弱
<!--  -->
<!--  -->
<!-- 
這圖是三小 -->
---
## 文獻探討
**預期結果(含研究過程說明影片)**
----
### 捌、參考文獻
- 高中生也看得懂 機器學習的數學基礎
- 學AI真簡單(I):初探機器學習-從認識AI到Kaggle競賽
- 學AI真簡單(II):動手做深度學習-揭開神經網路的面紗
- 再強一點:用Go語言完成六個大型專案
- C++程式設計第三版
- [build artificial neural network scratch part 1](https://www.kdnuggets.com/2019/11/build-artificial-neural-network-scratch-part-1.html)
- [機器/深度學習-基礎數學(二):梯度下降法(gradient descent) | by Tommy Huang | Medium](https://chih-sheng-huang821.medium.com/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E5%9F%BA%E7%A4%8E%E6%95%B8%E5%AD%B8-%E4%BA%8C-%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D%E6%B3%95-gradient-descent-406e1fd001f)
----
- [機器/深度學習-基礎數學(三):梯度最佳解相關算法(gradient descent optimization algorithms) | by Tommy Huang | Medium](https://chih-sheng-huang821.medium.com/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E5%9F%BA%E7%A4%8E%E6%95%B8%E5%AD%B8-%E4%B8%89-%E6%A2%AF%E5%BA%A6%E6%9C%80%E4%BD%B3%E8%A7%A3%E7%9B%B8%E9%97%9C%E7%AE%97%E6%B3%95-gradient-descent-optimization-algorithms-b61ed1478bd7)
- [自动微分(Automatic Differentiation)简介_CarlXie-CSDN博客_自动微分](https://blog.csdn.net/aws3217150/article/details/70214422)
- [Backpropagation | Brilliant Math & Science Wiki](https://brilliant.org/wiki/backpropagation/)
- [Backpropagation](http://galaxy.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html)
- [[機器學習ML NOTE]SGD, Momentum, AdaGrad, Adam Optimizer | by GGWithRabitLIFE | 雞雞與兔兔的工程世界 | Medium](https://medium.com/%E9%9B%9E%E9%9B%9E%E8%88%87%E5%85%94%E5%85%94%E7%9A%84%E5%B7%A5%E7%A8%8B%E4%B8%96%E7%95%8C/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92ml-note-sgd-momentum-adagrad-adam-optimizer-f20568c968db)
----
- [backpropagation - Error function in Artificial Neural Network trained using backpropogation - Stack Overflow](https://stackoverflow.com/questions/22601258/error-function-in-artificial-neural-network-trained-using-backpropogation)
- [自動微分](http://fancyerii.github.io/books/autodiff/)
- [梯度](https://www.youtube.com/watch?v=npkl19rcpdY)
- [方向導數](https://www.youtube.com/watch?v=-DumtBiW4HE)
- [Machine Learning Foundations (機器學習基石) - YouTube](https://www.youtube.com/playlist?list=PLXVfgk9fNX2I7tB6oIINGBmW50rrmFTqf)
- [Backpropagation calculus | Chapter 4, Deep learning](https://www.youtube.com/watch?v=tIeHLnjs5U8)
- [為什麼需要反向傳播(裡面有圖解)](https://allen108108.github.io/blog/2020/06/01/%E7%82%BA%E4%BB%80%E9%BA%BC%E9%9C%80%E8%A6%81%E5%8F%8D%E5%90%91%E5%82%B3%E6%92%AD%20_%20Why%20Backpropagation%20_/)
- [Kohonen Networks]()
----
- [NVIDIA DOCUMENTATION CENTER](https://docs.nvidia.com/)
- [Rust 程式設計語言](https://rust-lang.tw/book-tw/)
- [syn example](https://github.com/dtolnay/syn/tree/3418c8434539542b1325ebc375cb2cd7560f5277/examples/trace-var)
- [python實作微分樹(建樹) ](https://towardsdatascience.com/build-your-own-automatic-differentiation-program-6ecd585eec2a)
---
## 警告
接下來的內容會有點難,但也只要中學畢業程度的數學知識就夠了
<!-- 接下來的內容會有點難,所以我也不期望所有人都聽得懂,我們也會省略困難的知識 -->
---
### 神經元運作方式
<!-- 神經網路是發想自生物的神經,但運作原理大有不同 -->
----

**由於figma(繪圖工具)不支援中文,所以只有英文**
<!-- 這是個非常簡單的有向圖,演算法的圖,附帶邊權重和節點權重 -->
----

<!-- 葉節點是輸入層,輸入層將數值成上該邊的邊權,傳遞給下一個節點 -->
----

<!-- 而我們對每一個邊做同樣的事 -->
----

<!-- 再來,我們要如何算出非葉節點的節點權重呢? -->
----

<!-- 我們會將每一個連入邊的輸出值加起來,最後加上節點權重 -->
----

<!-- 最後看看範例,大概長這樣 -->
**為了避免超出中學範圍,這裡省略了激勵函數**
---
## 自動微分
<!-- 我們在這裡設整個神經網路為f(x)
基本的深度學習依靠求出每個節點的權重對f(x)的微分,算出梯度,
利用數學調整權重以接近正解 -->
----
### 加法

**由於figma(繪圖工具)不支援中文,所以只有英文**
<!-- 這張圖示範了機器如何對f(x)=w1+w2微分,圖上是一個樹,演算法的樹,每一非葉節點之節點入度限制為2,出度為1。
加法把邊權標示為1 -->
----
### 乘法

<!-- 乘法則是把邊權標示為另一邊的節點輸出值 -->
----
### 前向模式
以$f(w_1,w_2,w_3)=(w_1+w_2)*w_3$為例
<!-- (照字念) -->
----
#### 預覽

<!-- 先預覽一下這張圖(10s) -->
----
#### 1. 算出節點值

<!-- 第一步,算出節點值,加法兩個子節點求和數,乘法兩個子節點求乘數 -->
----
#### 2. 算出邊權

<!-- 依照之前的方法算出邊權,就做完前向模式了 -->
----
### 後向模式
<!-- 後向模式利用前向模式的結果,快速算出每個節點的權重對f(x)的微分 -->
----
#### 直接DFS到葉節點

<!-- 直接深度優先搜尋,就這麼簡單 -->
----
然後``product``(連乘)
$$\frac{dw_1}{df(x)}=1*3=3$$
<!-- (照字念) -->
---
## 矩陣化
<!-- 矩陣是為了方便運算,有了矩陣,我們可以用矩陣微分替代建樹的過程,並且使專案具可維護性 -->
----
### 單層神經元

<!-- 我們從新看一下那張圖,可以已發現它可以化簡成(翻頁) -->
----
$$
(
\begin{bmatrix}
x & y
\end{bmatrix} *
\begin{bmatrix}
W_{1-1} & W_{1-2} \\
W_{2-1} & W_{2-2}
\end{bmatrix} +
\begin{bmatrix}
c & d
\end{bmatrix}
)*
\begin{bmatrix}
1 \\
1
\end{bmatrix}=
f(x)
$$
$$
(
\begin{bmatrix}
x & y
\end{bmatrix} *
\begin{bmatrix}
W_{1} & W_{2} \\
W_{3} & W_{4}
\end{bmatrix} +
\begin{bmatrix}
c & d
\end{bmatrix}
)*
\begin{bmatrix}
1 \\
1
\end{bmatrix}=
f(x)
$$
**為了避免超出中學範圍,這裡省略了矩陣微分**
<!-- 對,其實只有這樣,不會很難
接下來交給Hugo,講解張量 -->
---
## 張量(``tensor``)
不是tensorflow
----
### 因為matrix是在vector裡放vector,會造成取值要2倍的時間
----
### 將matrix拉平,變成tensor
---
## 捲積層
----
本質上就是放大特徵
主要有三層
----
### 捲積核
先看看捲積核長怎樣
<!--  -->

它是一個針對某個特性放大的,計算核心
----
實際是利用與捲積核的計算,改變原圖

以這張圖來說,就是針對橫線部分放大他的特性
----
總步驟是這樣

所以最後出來的圖大小會跟原本差不多
但特性更明顯
----
### 池化層
用來將資料簡化,讓運算更快
聽起來很難,但上個圖就好懂了
----
這是平均池化

也有其他不同的池化方式,像是:
最大化池化(最常見的)
----
### 全連接層
就是攤平圖,變成X丟進神經元
<!--
$$
\begin{bmatrix}
c & d
\end{bmatrix}
*
\begin{bmatrix}
1 \\
1
\end{bmatrix}
$$
-->
---
## 目前實作成果
----
<!-- 放程式 -->
### Matrix
```rust=
#[derive(Debug, PartialEq, Clone)]
struct Matrix<T>
where
T: Copy,
{
shape: [usize; 2],
data: Tensor<T>,
}
```
----
```rust=
// iter by row
// it is non-consum iterator
// faster than col iter
// 0 1 2
// 3 4 5
// 6 7 8
// 9 10 11
pub fn into_row_iter<'a>(&'a self) -> impl Iterator<Item = &T> + 'a {
self.data.iter()
}
```
----
```rust=
// iter by col
// it is non-consum iterator
// 0 4 8
// 1 5 9
// 2 6 10
// 3 7 11
pub fn into_col_iter<'a>(&'a self) -> impl Iterator<Item = &T> + 'a {
// 第1直排到第N直排的迭代器
(0..self.shape[1])
// flat_map 用來攤平 ex: [[1,2],[3,4],[5,6]] -> [1,2,3,4,5,6]
// step_by(self.shape[1]) 跳直的 , take()用來取迭代器,相對的原本迭代器裡的那個iter會被刪掉 , b的值會來自前面的(0..self.shape[1]) , 也就是 第 0,1,2項的迭代器,是flat_map自己抓的
.flat_map(move |b| (b..).step_by(self.shape[1]).take(self.shape[0]))
// map用來取迭代器的值 , map會自己抓上面flat_map跳到的位置n
.map(move |n| self.data.iter().nth(n).unwrap())
}
```
----
```rust=
impl_ops_all!(+[<K, T> where T: Add<K> + Copy,K: Copy,<T as Add<K>>::Output: Copy]
(left:Matrix<T>, right:Matrix<K>)->Matrix<<T as Add<K>>::Output>{
// !for debug
if cfg!(debug_assertions) {
assert_eq!(left.shape, right.shape)
}
Matrix {
shape: left.shape.clone(),
data: &left.data + &right.data,
}
}
);
```
----
```rust=
#[macro_export]
macro_rules! mat {
($elem:expr; $r:expr, $c:expr) => (
$crate::matrix::Matrix::new($elem, [$r, $c])
);
($($x:expr),+ $(,)?;$r:expr, $c:expr) => (
$crate::matrix::Matrix::from(($crate::ten![$($x),+], [$r, $c]))
);
}
```
----
{%youtube 9Ti9qf0zdFI%}
[影片音樂版權標示在影片簡介](https://youtu.be/9Ti9qf0zdFI)
---
## 目標
----
- 學習深度學習的基礎原理
- 學習rust
----
## 發展可能
**未來發展**
----
- 手寫數字辨識

----
~~打敗Tensorflow~~
<!-- ----
- 完成神經網路的應用
- 比tensorflow快 ~~(但效果不好)~~
- ~~成為下一代的張量流~~
-->
---
# END
---
<!--
flow
flowchart LR
神經網路相關理論-->理論整理資料;
理論整理資料-->學習rust,IDE等;
學習rust,IDE等-->建構出基本的ANN模型;
建構出基本的ANN模型
合併已建構的完成的部分-->變成可運作之CNN神經網路;
變成可運作之CNN神經網路-->優化及加蓋;
優化及加蓋-->測試不同的優化結果;
-->
---
{"metaMigratedAt":"2023-06-16T14:26:13.261Z","metaMigratedFrom":"YAML","title":"明道中學高中部資訊類專題第一次簡報","breaks":true,"slideOptions":"{\"transition\":\"slide\"}","contributors":"[{\"id\":\"f547d745-63f3-4bad-986b-1751eeec19d1\",\"add\":3238,\"del\":1372},{\"id\":\"6d8efe8e-dbdf-4e5a-8c38-356b0d1df76d\",\"add\":7409,\"del\":2454},{\"id\":\"1acbf739-4837-4867-be73-4a41bb7c42a7\",\"add\":2113,\"del\":211},{\"id\":\"a6fc7cba-c9c5-42a4-854f-b3deb8636bea\",\"add\":1526,\"del\":302}]"}