From 1ef588b6b3ed0f000d82687558cd9219c723d835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Wed, 31 Mar 2021 22:23:48 +0800 Subject: [PATCH 01/84] =?UTF-8?q?=E6=96=B0=E5=BB=BA=2018340246016?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-1/submission/18340246016/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-1/submission/18340246016/.keep diff --git a/assignment-1/submission/18340246016/.keep b/assignment-1/submission/18340246016/.keep new file mode 100644 index 0000000..e69de29 -- Gitee From 5ca46c0e2e2a6b2a27e8a210e7ff9a982d9a68c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Wed, 31 Mar 2021 22:24:27 +0800 Subject: [PATCH 02/84] add assignment-1/submission/18340246016. --- assignment-1/submission/18340246016/source.py | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 assignment-1/submission/18340246016/source.py diff --git a/assignment-1/submission/18340246016/source.py b/assignment-1/submission/18340246016/source.py new file mode 100644 index 0000000..6da0614 --- /dev/null +++ b/assignment-1/submission/18340246016/source.py @@ -0,0 +1,3 @@ +import numpy as np +import matplotlib.pyplot as plt + -- Gitee From 9275105f3472ae128e23398a7d7a6aeeaa4e7a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Wed, 31 Mar 2021 22:24:52 +0800 Subject: [PATCH 03/84] update assignment-1/submission/18340246016/source.py. --- assignment-1/submission/18340246016/source.py | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/assignment-1/submission/18340246016/source.py b/assignment-1/submission/18340246016/source.py index 6da0614..ceb7e79 100644 --- a/assignment-1/submission/18340246016/source.py +++ b/assignment-1/submission/18340246016/source.py @@ -1,3 +1,100 @@ import numpy as np import matplotlib.pyplot as plt +class KNN: + + def __init__(self): + self.train_data = None + self.train_labels = None + self.k = None + + def train_test_split(self,x,y,rate): + shuffled_indexes = np.random.permutation(len(x)) + test_size = int(len(x) * rate) + train_index = shuffled_indexes[test_size:] + test_index = shuffled_indexes[:test_size] + return x[train_index], x[test_index], y[train_index], y[test_index] + + def distance(self,v1,v2): + + weight_array = (v1-v2)**2 + weight_array_sum = np.sum(weight_array) + return weight_array_sum**(0.5) + + def fit(self, train_data, train_label): + + # 归一化 + mu = np.mean(train_data, axis=0) + sigma = np.std(train_data, axis=0) + train_data = (train_data - mu) / sigma + #train_data = train_data / np.sqrt(np.sum(train_data**2)) + + # 划分训练集/验证集 with rate =0.3 + X_train, X_test, Y_train, Y_test = self.train_test_split(train_data,train_label,0.3) + + # 对于不同的K[1-0.5*len(train)],计算验证集到训练集的欧氏距离 + best_k=0 + k_candi=0; + for k in range(1,int(0.5*len(X_train))+1): + + true_couter=0 + for test_counter in range(0,len(X_test)): + pos_vec_list=[] + + for train_counter in range(0,len(X_train)): + pos_vec = np.array([self.distance(X_test[test_counter],X_train[train_counter]),Y_train[train_counter]]) + pos_vec_list.append(pos_vec) + + #对距离list根据距离排序 + pos_vec_list = np.array(pos_vec_list) + pos_vec_list_sorted = pos_vec_list[np.lexsort(pos_vec_list[:,::-1].T)] + #k-近邻结果列表 + result_list = pos_vec_list_sorted[:k][:,1] + + + + #test预测结果 + label = int(result_list[np.argmax(result_list)]) + + + #检验本次test在给定k下是否正确 + if (label == Y_test[test_counter] ): + true_couter=true_couter+1 + + + #最优K取值 + if (true_couter >= best_k): + best_k = true_couter + k_candi = k + + self.k = k_candi + self.train_data = train_data + self.train_labels = train_label + return self.k + + def predict(self, test_data): + test_label=[] + result_list=[] + + # 归一化 + mu = np.mean(test_data, axis=0) + sigma = np.std(test_data, axis=0) + test_data = (test_data - mu) / sigma + #test_data = test_data / np.sqrt(np.sum(test_data**2)) + + for i in range (0,len(test_data)): + pos_vec_list=[] + for m in range(0,len(self.train_data)): + pos_vec = np.array([self.distance(self.train_data[m],test_data[i]),self.train_labels[m]]) + pos_vec_list.append(pos_vec) + + + + pos_vec_list = np.array(pos_vec_list) + pos_vec_list_sorted = pos_vec_list[np.lexsort(pos_vec_list[:,::-1].T)] + + result_list = pos_vec_list_sorted[:(self.k)][:,1] + test_label.append(result_list[np.argmax(result_list)]) + + return test_label + \ No newline at end of file -- Gitee From 169edea5f44dd38eef04a63b55fb618c164cd560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Wed, 31 Mar 2021 22:25:43 +0800 Subject: [PATCH 04/84] add assignment-1/submission/18340246016. --- assignment-1/submission/18340246016/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-1/submission/18340246016/README.md diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md new file mode 100644 index 0000000..e69de29 -- Gitee From 3c12a1eb9998381e7c1bccb5f8b0adf173b58104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Wed, 31 Mar 2021 22:26:49 +0800 Subject: [PATCH 05/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index e69de29..8e40f5c 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -0,0 +1 @@ +![输入图片说明](https://images.gitee.com/uploads/images/2021/0331/222640_06e435c4_8823823.png "屏幕截图.png") \ No newline at end of file -- Gitee From dbd75c0b8593ca3cd168fbfed5e05228159dc47f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Wed, 31 Mar 2021 22:38:14 +0800 Subject: [PATCH 06/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 8e40f5c..cd15cf2 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -1 +1,13 @@ -![输入图片说明](https://images.gitee.com/uploads/images/2021/0331/222640_06e435c4_8823823.png "屏幕截图.png") \ No newline at end of file +1. 解释一下实现过程 +1.1 sup +1.2 fit +1.3 predict +2. 高斯分布探究试验 +2.1 mean集中 + xy分散 = 对应的k +2.2 mean集中 + xy集中 = 对应的k +2.3 mean分散 + xy分散 = 对应的k +2.4 mean分散 + xy集中 = 对应的k +3.K值 +3.1 不同量下的best_k +3.2 不同K下的锯齿图 +3.3 不同K下的acc \ No newline at end of file -- Gitee From 45c6c5da81bd7a0f0bf59cb519a9303ec99ca570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 09:59:57 +0800 Subject: [PATCH 07/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index cd15cf2..374abde 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -1,5 +1,5 @@ -1. 解释一下实现过程 -1.1 sup + **1. KNN实现过程 +** 1.1 sup 1.2 fit 1.3 predict 2. 高斯分布探究试验 -- Gitee From 5a3180ff238da453a133b97fcecd85f455163dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:01:49 +0800 Subject: [PATCH 08/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 374abde..0c41536 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -1,5 +1,15 @@ - **1. KNN实现过程 -** 1.1 sup +1. KNN实现过程 +1.1 sup + +``` +# 这里我们用train_test_split实现训练集与验证集以给定的比例划分与打乱 +def train_test_split(self,x,y,rate): + shuffled_indexes = np.random.permutation(len(x)) + test_size = int(len(x) * rate) + train_index = shuffled_indexes[test_size:] + test_index = shuffled_indexes[:test_size] + return x[train_index], x[test_index], y[train_index], y[test_index]``` + 1.2 fit 1.3 predict 2. 高斯分布探究试验 -- Gitee From ab8bfc81ae4732eddffe0e627f814b9f61322965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:02:31 +0800 Subject: [PATCH 09/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 0c41536..9b1dba0 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -8,7 +8,8 @@ def train_test_split(self,x,y,rate): test_size = int(len(x) * rate) train_index = shuffled_indexes[test_size:] test_index = shuffled_indexes[:test_size] - return x[train_index], x[test_index], y[train_index], y[test_index]``` + return x[train_index], x[test_index], y[train_index], y[test_index] +``` 1.2 fit 1.3 predict -- Gitee From e6cc90b27f5dc9b7f479e7c0c4ef95d9862e5dfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:04:15 +0800 Subject: [PATCH 10/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 9b1dba0..4add29c 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -1,5 +1,6 @@ -1. KNN实现过程 -1.1 sup + **1. KNN实现过程 +** +1.1 辅助方法的实现 ``` # 这里我们用train_test_split实现训练集与验证集以给定的比例划分与打乱 @@ -11,6 +12,18 @@ def train_test_split(self,x,y,rate): return x[train_index], x[test_index], y[train_index], y[test_index] ``` + +``` +# 用distance方法计算两组向量之间的欧式距离 +def distance(self,v1,v2): + + weight_array = (v1-v2)**2 + weight_array_sum = np.sum(weight_array) + return weight_array_sum**(0.5) +``` + + + 1.2 fit 1.3 predict 2. 高斯分布探究试验 -- Gitee From e0b06a6434b7ffa9a3f40ec02cf04baa3d411e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:04:36 +0800 Subject: [PATCH 11/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 4add29c..967769b 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -1,5 +1,5 @@ - **1. KNN实现过程 -** + **1. KNN实现过程** + 1.1 辅助方法的实现 ``` -- Gitee From 686121c8207506ad63a461b9e4e0574c5ead6678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:05:24 +0800 Subject: [PATCH 12/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 967769b..ec767fd 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -1,6 +1,6 @@ **1. KNN实现过程** -1.1 辅助方法的实现 +*1.1 辅助方法的实现* ``` # 这里我们用train_test_split实现训练集与验证集以给定的比例划分与打乱 -- Gitee From 539d4afd793a3b9a08ec92c0211294001f1d271e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:09:14 +0800 Subject: [PATCH 13/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index ec767fd..e701704 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -24,7 +24,63 @@ def distance(self,v1,v2): -1.2 fit +*1.2 fit* + + +``` +# 我们用fit方法实现 1. 对训练数据的归一化 2. 训练数据内部subdivide为训练集与测试集,取最优K值 3. 将训练数据赋值self.data +def fit(self, train_data, train_label): + + # 归一化 + mu = np.mean(train_data, axis=0) + sigma = np.std(train_data, axis=0) + train_data = (train_data - mu) / sigma + + # 划分训练集/验证集 with rate =0.3 + X_train, X_test, Y_train, Y_test = self.train_test_split(train_data,train_label,0.3) + + # 对于不同的K[1-0.5*len(train)],计算验证集到训练集的欧氏距离 + best_k=0 + k_candi=0; + for k in range(1,int(0.5*len(X_train))+1): + + true_couter=0 + for test_counter in range(0,len(X_test)): + pos_vec_list=[] + + for train_counter in range(0,len(X_train)): + pos_vec = np.array([self.distance(X_test[test_counter],X_train[train_counter]),Y_train[train_counter]]) + pos_vec_list.append(pos_vec) + + #对距离list根据距离排序 + pos_vec_list = np.array(pos_vec_list) + pos_vec_list_sorted = pos_vec_list[np.lexsort(pos_vec_list[:,::-1].T)] + #k-近邻结果列表 + result_list = pos_vec_list_sorted[:k][:,1] + + + + #test预测结果 + label = int(result_list[np.argmax(result_list)]) + + + #检验本次test在给定k下是否正确 + if (label == Y_test[test_counter] ): + true_couter=true_couter+1 + + + #最优K取值 + if (true_couter >= best_k): + best_k = true_couter + k_candi = k + + self.k = k_candi + self.train_data = train_data + self.train_labels = train_label + return self.k +``` + + 1.3 predict 2. 高斯分布探究试验 2.1 mean集中 + xy分散 = 对应的k -- Gitee From 2832e09057af7e54527b51fa37605e67a5e5bfb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:12:50 +0800 Subject: [PATCH 14/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index e701704..e153822 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -24,7 +24,7 @@ def distance(self,v1,v2): -*1.2 fit* +*1.2 fit方法的实现* ``` @@ -81,7 +81,38 @@ def fit(self, train_data, train_label): ``` -1.3 predict +*1.3 predict方法的实现* + +``` + # 根据fit方法带入的数据data以及训练结果K,预测test_label + def predict(self, test_data): + test_label=[] + result_list=[] + + # 归一化原始训练数据 + mu = np.mean(test_data, axis=0) + sigma = np.std(test_data, axis=0) + test_data = (test_data - mu) / sigma + + for i in range (0,len(test_data)): + pos_vec_list=[] + for m in range(0,len(self.train_data)): + pos_vec = np.array([self.distance(self.train_data[m],test_data[i]),self.train_labels[m]]) + pos_vec_list.append(pos_vec) + + + # KNN结果列表 + pos_vec_list = np.array(pos_vec_list) + pos_vec_list_sorted = pos_vec_list[np.lexsort(pos_vec_list[:,::-1].T)] + + result_list = pos_vec_list_sorted[:(self.k)][:,1] + test_label.append(result_list[np.argmax(result_list)]) + + return test_label +``` + + + 2. 高斯分布探究试验 2.1 mean集中 + xy分散 = 对应的k 2.2 mean集中 + xy集中 = 对应的k -- Gitee From 95423483bff247c6a7d86058859f44336f4e91bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:25:56 +0800 Subject: [PATCH 15/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index e153822..be84c79 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -113,8 +113,26 @@ def fit(self, train_data, train_label): -2. 高斯分布探究试验 -2.1 mean集中 + xy分散 = 对应的k + **2. 高斯分布探究试验** + +*2.1 均值集中 + xy分布分散 = 对应的k* + +$$cov= +\left\{ + \begin{matrix} + a & b \\ + f & g \\ + + \end{matrix} +\right\} +? + +作者:xxq2dream +链接:https://juejin.cn/post/6844903650024767501 +来源:掘金 +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 + + 2.2 mean集中 + xy集中 = 对应的k 2.3 mean分散 + xy分散 = 对应的k 2.4 mean分散 + xy集中 = 对应的k -- Gitee From 12060eec5f19b3a955b411ebae5e31c9734d1f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:27:08 +0800 Subject: [PATCH 16/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index be84c79..f9a1184 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -117,20 +117,13 @@ def fit(self, train_data, train_label): *2.1 均值集中 + xy分布分散 = 对应的k* -$$cov= -\left\{ - \begin{matrix} - a & b \\ - f & g \\ - - \end{matrix} -\right\} -? - -作者:xxq2dream -链接:https://juejin.cn/post/6844903650024767501 -来源:掘金 -著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 +$$ + \begin{matrix} + 1 & 2 & 3 \\ + 4 & 5 & 6 \\ + 7 & 8 & 9 + \end{matrix} \tag{1} +$$ 2.2 mean集中 + xy集中 = 对应的k -- Gitee From dbe92ea7cd043b86e1eb0287c9ac3e98524e242a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:45:24 +0800 Subject: [PATCH 17/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index f9a1184..c499215 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -115,18 +115,22 @@ def fit(self, train_data, train_label): **2. 高斯分布探究试验** -*2.1 均值集中 + xy分布分散 = 对应的k* +*2.1 均值集中 + xy分布集中 = 对应的k* $$ - \begin{matrix} - 1 & 2 & 3 \\ - 4 & 5 & 6 \\ - 7 & 8 & 9 - \end{matrix} \tag{1} +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +35 & 0 \\\\ +0 & 23 +\end{array}\right] \\\\ +\mu=\left[\begin{array}{ll} +13 & 4 +\end{array}\right] +\end{array} $$ -2.2 mean集中 + xy集中 = 对应的k +2.2 mean集中 + xy分散 = 对应的k 2.3 mean分散 + xy分散 = 对应的k 2.4 mean分散 + xy集中 = 对应的k 3.K值 -- Gitee From 3801048141d20a7647300f181fc7a9a9769cb458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:47:21 +0800 Subject: [PATCH 18/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index c499215..14bb501 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -120,15 +120,43 @@ def fit(self, train_data, train_label): $$ \begin{array}{l} \Sigma=\left[\begin{array}{cc} -35 & 0 \\\\ -0 & 23 +1 & 0 \\\\ +0 & 1 \end{array}\right] \\\\ \mu=\left[\begin{array}{ll} -13 & 4 +10 & 10 \end{array}\right] \end{array} $$ +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +2 & 0 \\\\ +0 & 1 +\end{array}\right] \\\\ +\mu=\left[\begin{array}{ll} +8 & 8 +\end{array}\right] +\end{array} +$$ + +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +2 & 1 \\\\ +1 & 1 +\end{array}\right] \\\\ +\mu=\left[\begin{array}{ll} +12 & 12 +\end{array}\right] +\end{array} +$$ + + + + + 2.2 mean集中 + xy分散 = 对应的k 2.3 mean分散 + xy分散 = 对应的k -- Gitee From 14d1d4e31825f461c74fdf2ac42a994c1dd5844a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:48:28 +0800 Subject: [PATCH 19/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 14bb501..bd7b2bc 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -134,7 +134,8 @@ $$ \Sigma=\left[\begin{array}{cc} 2 & 0 \\\\ 0 & 1 -\end{array}\right] \\\\ +\end{array}\right] + \mu=\left[\begin{array}{ll} 8 & 8 \end{array}\right] @@ -146,7 +147,7 @@ $$ \Sigma=\left[\begin{array}{cc} 2 & 1 \\\\ 1 & 1 -\end{array}\right] \\\\ +\end{array}\right] \mu=\left[\begin{array}{ll} 12 & 12 \end{array}\right] -- Gitee From b6b2531f6ae5b73d48462c76e483ce1e117b41d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:49:28 +0800 Subject: [PATCH 20/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index bd7b2bc..fb5a0e2 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -122,20 +122,20 @@ $$ \Sigma=\left[\begin{array}{cc} 1 & 0 \\\\ 0 & 1 -\end{array}\right] \\\\ +\end{array}\right] \mu=\left[\begin{array}{ll} 10 & 10 \end{array}\right] \end{array} $$ + $$ \begin{array}{l} \Sigma=\left[\begin{array}{cc} 2 & 0 \\\\ 0 & 1 -\end{array}\right] - +\end{array}\right] \mu=\left[\begin{array}{ll} 8 & 8 \end{array}\right] -- Gitee From 1011ce111e717a9cdd19f47eb8a4e0dbb73020f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:50:38 +0800 Subject: [PATCH 21/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index fb5a0e2..ba03e39 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -155,8 +155,8 @@ $$ $$ - - +![训练集分布](https://images.gitee.com/uploads/images/2021/0401/105007_0d3f874d_8823823.png "屏幕截图.png") +![测试集分布](https://images.gitee.com/uploads/images/2021/0401/105032_733d6b01_8823823.png "屏幕截图.png") 2.2 mean集中 + xy分散 = 对应的k -- Gitee From fede853ada5c1c5df0325141eea076a2d3365b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:52:09 +0800 Subject: [PATCH 22/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index ba03e39..cfb6d7e 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -155,8 +155,8 @@ $$ $$ -![训练集分布](https://images.gitee.com/uploads/images/2021/0401/105007_0d3f874d_8823823.png "屏幕截图.png") -![测试集分布](https://images.gitee.com/uploads/images/2021/0401/105032_733d6b01_8823823.png "屏幕截图.png") +[训练集分布](https://images.gitee.com/uploads/images/2021/0401/105007_0d3f874d_8823823.png "屏幕截图.png") +[测试集分布](https://images.gitee.com/uploads/images/2021/0401/105032_733d6b01_8823823.png "屏幕截图.png") 2.2 mean集中 + xy分散 = 对应的k -- Gitee From 4e48ea5a162cbc234609bfa4a73e6814de0ca7e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:52:45 +0800 Subject: [PATCH 23/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index cfb6d7e..46d3cef 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -154,8 +154,9 @@ $$ \end{array} $$ - +训练集分布 [训练集分布](https://images.gitee.com/uploads/images/2021/0401/105007_0d3f874d_8823823.png "屏幕截图.png") +测试集分布 [测试集分布](https://images.gitee.com/uploads/images/2021/0401/105032_733d6b01_8823823.png "屏幕截图.png") -- Gitee From 25af1019ff636595e0d333c4ba2be1dcae2e420b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:53:07 +0800 Subject: [PATCH 24/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 46d3cef..e1f3828 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -155,9 +155,9 @@ $$ $$ 训练集分布 -[训练集分布](https://images.gitee.com/uploads/images/2021/0401/105007_0d3f874d_8823823.png "屏幕截图.png") +![训练集分布](https://images.gitee.com/uploads/images/2021/0401/105007_0d3f874d_8823823.png "屏幕截图.png") 测试集分布 -[测试集分布](https://images.gitee.com/uploads/images/2021/0401/105032_733d6b01_8823823.png "屏幕截图.png") +![测试集分布](https://images.gitee.com/uploads/images/2021/0401/105032_733d6b01_8823823.png "屏幕截图.png") 2.2 mean集中 + xy分散 = 对应的k -- Gitee From 9194b762ef77c7ec05c307d378806a7034df6ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:53:48 +0800 Subject: [PATCH 25/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index e1f3828..d8481ae 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -154,9 +154,12 @@ $$ \end{array} $$ -训练集分布 +*训练集分布* + ![训练集分布](https://images.gitee.com/uploads/images/2021/0401/105007_0d3f874d_8823823.png "屏幕截图.png") -测试集分布 + +*测试集分布* + ![测试集分布](https://images.gitee.com/uploads/images/2021/0401/105032_733d6b01_8823823.png "屏幕截图.png") -- Gitee From 8d7ab95f9350f3c7b8c0cbd7b66ea0c0704e1a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 10:55:12 +0800 Subject: [PATCH 26/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index d8481ae..f1e58dd 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -156,12 +156,11 @@ $$ *训练集分布* -![训练集分布](https://images.gitee.com/uploads/images/2021/0401/105007_0d3f874d_8823823.png "屏幕截图.png") +![训练集分布](https://images.gitee.com/uploads/images/2021/0401/105433_e7ec4619_8823823.png "屏幕截图.png") *测试集分布* -![测试集分布](https://images.gitee.com/uploads/images/2021/0401/105032_733d6b01_8823823.png "屏幕截图.png") - +![测试集分布](https://images.gitee.com/uploads/images/2021/0401/105459_56af4a90_8823823.png "屏幕截图.png") 2.2 mean集中 + xy分散 = 对应的k 2.3 mean分散 + xy分散 = 对应的k -- Gitee From 03702af752031b5fcb57db3d82f1304a11d2b7cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 11:06:21 +0800 Subject: [PATCH 27/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index f1e58dd..fb194d0 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -115,6 +115,74 @@ def fit(self, train_data, train_label): **2. 高斯分布探究试验** +*2.0 生成以及展示函数* + + +``` +# 赋值矩阵 +mean = (10, 10) +cov = np.array([[1,0], [0, 1]]) +x = np.random.multivariate_normal(mean, cov, (200,)) + +mean = (8, 8) +cov = np.array([[2, 0], [0, 1]]) +y = np.random.multivariate_normal(mean, cov, (200,)) + +mean = (12, 12) +cov = np.array([[2,1],[1,1]]) +z = np.random.multivariate_normal(mean, cov, (400,)) + +# 合并xyz三组函数 +data = np.concatenate([x,y,z]) +# 为xyz打标签 +label = np.concatenate([ + np.zeros((200,),dtype=int), + np.ones((200,),dtype=int), + np.ones((400,),dtype=int)*2 + ]) +# 按8:2的比例分割训练集与测试集 +X_train, X_test, Y_train, Y_test = model.train_test_split(data,label,0.2) + +``` + + +``` +# 展示函数 +def display(x,y): + type1_x = []; type1_y = [] + type2_x = []; type2_y = [] + type3_x = []; type3_y = [] + + plt.figure(figsize=(8,6)) + + for i in range(0,len(x)): + if(y[i]==0): + type1_x.append(x[i][0]) + type1_y.append(x[i][1]) + if(y[i]==1): + type2_x.append(x[i][0]) + type2_y.append(x[i][1]) + if(y[i]==2): + type3_x.append(x[i][0]) + type3_y.append(x[i][1]) + + fig = plt.figure(figsize = (10, 6)) + ax = fig.add_subplot(111) + + type1 = ax.scatter(type1_x, type1_y, s = 30, c = 'brown') + type2 = ax.scatter(type2_x, type2_y, s = 30, c = 'lime') + type3 = ax.scatter(type3_x, type3_y, s = 30, c = "darkviolet") + + + + ax.legend((type1, type2, type3), ("A", "B", "C"), loc = 0) + + plt.show() + +``` + + + *2.1 均值集中 + xy分布集中 = 对应的k* $$ -- Gitee From 51b9ab10652cda0db8da897675f20572235cfaf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 11:13:34 +0800 Subject: [PATCH 28/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index fb194d0..94b5226 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -230,6 +230,11 @@ $$ ![测试集分布](https://images.gitee.com/uploads/images/2021/0401/105459_56af4a90_8823823.png "屏幕截图.png") +*K与准确率结果* +| k | 准确率 | +| ---------------- | ------ | +| 1 | 78.75% | + 2.2 mean集中 + xy分散 = 对应的k 2.3 mean分散 + xy分散 = 对应的k 2.4 mean分散 + xy集中 = 对应的k -- Gitee From 737f72377b45ffa45f5d22672b36aad59ab8c530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 11:19:18 +0800 Subject: [PATCH 29/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 55 ++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 94b5226..2aba0a1 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -185,6 +185,55 @@ def display(x,y): *2.1 均值集中 + xy分布集中 = 对应的k* +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +4 & 0 \\\\ +0 & 2 +\end{array}\right] +\mu=\left[\begin{array}{ll} +10 & 10 +\end{array}\right] +\end{array} +$$ + + +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +2 & 0 \\\\ +0 & 4 +\end{array}\right] +\mu=\left[\begin{array}{ll} +8 & 8 +\end{array}\right] +\end{array} +$$ + +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +8 & 1 \\\\ +1 & 6 +\end{array}\right] +\mu=\left[\begin{array}{ll} +12 & 12 +\end{array}\right] +\end{array} +$$ + +*训练集分布* + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/111859_687c068b_8823823.png "屏幕截图.png") +*测试集分布* + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/111906_d0e2e134_8823823.png "屏幕截图.png") +*K与准确率结果* +| k | 准确率 | +| ---------------- | ------ | +| 1 | 78.75% | + +*2.2 mean集中 + xy分散 = 对应的k* $$ \begin{array}{l} \Sigma=\left[\begin{array}{cc} @@ -235,10 +284,12 @@ $$ | ---------------- | ------ | | 1 | 78.75% | -2.2 mean集中 + xy分散 = 对应的k + 2.3 mean分散 + xy分散 = 对应的k 2.4 mean分散 + xy集中 = 对应的k -3.K值 + +**3.K值** + 3.1 不同量下的best_k 3.2 不同K下的锯齿图 3.3 不同K下的acc \ No newline at end of file -- Gitee From 14eab53ac5f492e17dc93538c008893c9fcce9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 11:21:27 +0800 Subject: [PATCH 30/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 2aba0a1..9a18ef1 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -183,7 +183,7 @@ def display(x,y): -*2.1 均值集中 + xy分布集中 = 对应的k* +*2.1 均值集中 + xy分布分散 = 对应的k* $$ \begin{array}{l} @@ -222,18 +222,20 @@ $$ \end{array} $$ + *训练集分布* ![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/111859_687c068b_8823823.png "屏幕截图.png") + *测试集分布* ![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/111906_d0e2e134_8823823.png "屏幕截图.png") *K与准确率结果* | k | 准确率 | | ---------------- | ------ | -| 1 | 78.75% | +| 4 | 62.5% | -*2.2 mean集中 + xy分散 = 对应的k* +*2.2 mean集中 + xy集中 = 对应的k* $$ \begin{array}{l} \Sigma=\left[\begin{array}{cc} -- Gitee From 95ac2d2371d7de6a57f2c8e57008cc89b5b66e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 11:25:31 +0800 Subject: [PATCH 31/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 9a18ef1..9aab188 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -287,7 +287,61 @@ $$ | 1 | 78.75% | -2.3 mean分散 + xy分散 = 对应的k +***2.3 mean分散 + xy分散 = 对应的k*** + + +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +4 & 0 \\\\ +0 & 2 +\end{array}\right] +\mu=\left[\begin{array}{ll} +2 & 2 +\end{array}\right] +\end{array} +$$ + + +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +2 & 0 \\\\ +0 & 4 +\end{array}\right] +\mu=\left[\begin{array}{ll} +4 & 6 +\end{array}\right] +\end{array} +$$ + +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +8 & 1 \\\\ +1 & 6 +\end{array}\right] +\mu=\left[\begin{array}{ll} +10 & 10 +\end{array}\right] +\end{array} +$$ + + +*训练集分布* + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/112426_09535d36_8823823.png "屏幕截图.png") + +*测试集分布* + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/112437_53a32eec_8823823.png "屏幕截图.png")*K与准确率结果* + + +| k | 准确率 | +| ---------------- | ------ | +| 2 | 86.25% | + + 2.4 mean分散 + xy集中 = 对应的k **3.K值** -- Gitee From 7c88f32407cf34e8ed2e855bf59f479bca89755b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 11:29:07 +0800 Subject: [PATCH 32/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 9aab188..2c150ce 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -334,7 +334,9 @@ $$ *测试集分布* -![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/112437_53a32eec_8823823.png "屏幕截图.png")*K与准确率结果* +![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/112437_53a32eec_8823823.png "屏幕截图.png") + +*K与准确率结果* | k | 准确率 | @@ -342,7 +344,64 @@ $$ | 2 | 86.25% | -2.4 mean分散 + xy集中 = 对应的k +*2.4 mean分散 + xy集中 = 对应的k* + + + + +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +1 & 0 \\\\ +0 & 1 +\end{array}\right] +\mu=\left[\begin{array}{ll} +2 & 2 +\end{array}\right] +\end{array} +$$ + + +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +2 & 0 \\\\ +0 & 2 +\end{array}\right] +\mu=\left[\begin{array}{ll} +4 & 6 +\end{array}\right] +\end{array} +$$ + +$$ +\begin{array}{l} +\Sigma=\left[\begin{array}{cc} +2 & 1 \\\\ +1 & 3 +\end{array}\right] +\mu=\left[\begin{array}{ll} +10 & 10 +\end{array}\right] +\end{array} +$$ + + +*训练集分布* + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/112759_754208e4_8823823.png "屏幕截图.png") + +*测试集分布* + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/112810_ca9d4230_8823823.png "屏幕截图.png") + +*K与准确率结果* + + +| k | 准确率 | +| ---------------- | ------ | +| 1 | 95.625% | + **3.K值** -- Gitee From 09c735138f878a03a47d6d4283f058c09a17fac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 11:30:28 +0800 Subject: [PATCH 33/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 2c150ce..ddd781c 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -183,7 +183,7 @@ def display(x,y): -*2.1 均值集中 + xy分布分散 = 对应的k* +***2.1 均值集中 + xy分布分散 = 对应的k*** $$ \begin{array}{l} @@ -230,12 +230,14 @@ $$ *测试集分布* ![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/111906_d0e2e134_8823823.png "屏幕截图.png") + *K与准确率结果* | k | 准确率 | | ---------------- | ------ | | 4 | 62.5% | -*2.2 mean集中 + xy集中 = 对应的k* +***2.2 mean集中 + xy集中 = 对应的k*** + $$ \begin{array}{l} \Sigma=\left[\begin{array}{cc} @@ -344,7 +346,7 @@ $$ | 2 | 86.25% | -*2.4 mean分散 + xy集中 = 对应的k* +***2.4 mean分散 + xy集中 = 对应的k*** -- Gitee From 34088143a60d7ec6900d6ecf51e0075f4924853b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 11:39:51 +0800 Subject: [PATCH 34/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index ddd781c..61877f6 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -405,6 +405,12 @@ $$ | 1 | 95.625% | +***2.5 有关高斯分布的结论*** +1. 与直观体会到的类似,模型准确率与高斯分布均值离散程度正相关,与xy方差负相关 +2. 模型在均值分散,方差集中的情况下表现最好,在均值集中,方差分散的情况下表现最差 +3. 最佳K的取值与准确率无直接联系,准确性更多取决于分布情况 + + **3.K值** 3.1 不同量下的best_k -- Gitee From ee9ac51821f0ce42029f2aaeea5b3fe0cf95c8df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 11:47:50 +0800 Subject: [PATCH 35/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 61877f6..a1b275d 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -119,29 +119,30 @@ def fit(self, train_data, train_label): ``` -# 赋值矩阵 -mean = (10, 10) -cov = np.array([[1,0], [0, 1]]) -x = np.random.multivariate_normal(mean, cov, (200,)) +def generate (amount_1,amount_2,amount_3): -mean = (8, 8) -cov = np.array([[2, 0], [0, 1]]) -y = np.random.multivariate_normal(mean, cov, (200,)) - -mean = (12, 12) -cov = np.array([[2,1],[1,1]]) -z = np.random.multivariate_normal(mean, cov, (400,)) - -# 合并xyz三组函数 -data = np.concatenate([x,y,z]) -# 为xyz打标签 -label = np.concatenate([ - np.zeros((200,),dtype=int), - np.ones((200,),dtype=int), - np.ones((400,),dtype=int)*2 - ]) -# 按8:2的比例分割训练集与测试集 -X_train, X_test, Y_train, Y_test = model.train_test_split(data,label,0.2) + mean = (2, 2) + cov = np.array([[1,0], [0, 1]]) + x = np.random.multivariate_normal(mean, cov, (amount_1,)) + + mean = (4, 6) + cov = np.array([[2, 0], [0, 2]]) + y = np.random.multivariate_normal(mean, cov, (amount_2,)) + + mean = (10, 10) + cov = np.array([[2,1],[1,3]]) + z = np.random.multivariate_normal(mean, cov, (amount_3,)) + + + data = np.concatenate([x,y,z]) + + label = np.concatenate([ + np.zeros((amount_1,),dtype=int), + np.ones((amount_2,),dtype=int), + np.ones((amount_3,),dtype=int)*2 + ]) + + return model.train_test_split(data,label,0.2) ``` @@ -411,8 +412,13 @@ $$ 3. 最佳K的取值与准确率无直接联系,准确性更多取决于分布情况 -**3.K值** -3.1 不同量下的best_k +** +3. K值 +** + +***3.1 不同量下的best_k*** + + 3.2 不同K下的锯齿图 3.3 不同K下的acc \ No newline at end of file -- Gitee From 979ab862116ae3f5039d310ef1393d0f97660677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 12:03:22 +0800 Subject: [PATCH 36/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index a1b275d..2feaf97 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -419,6 +419,34 @@ $$ ***3.1 不同量下的best_k*** +(这里以2.4高斯分布为例) + +``` +# 准备数据集维度 +amount_list = [[10,10,10],[50,50,50],[100,100,100],[150,50,200],[200,200,200],[250,300,400]] +k_list=[] +aug_amount = [30,150,300,400,600,950] + +# 在不同数据集量下训练最佳k值 +for i in range (0,len(amount_list)): + model = KNN() + X_train, X_test, Y_train, Y_test = generate(amount_list[i][0],amount_list[i][1],amount_list[i][2]) + k_list.append(model.fit(X_train, Y_train)) + +# 画图 +l1=plt.plot(aug_amount,k_list,'r--',label='Best-K-Value') +plt.title('The relationship between # elements and |K|') +plt.xlabel('Total # of elements') +plt.ylabel('K-value') +plt.legend() + +``` +![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/120033_088f8aa7_8823823.png "屏幕截图.png") + + +1. K取值与元素数量无关 +2. 最佳K会趋向于一个较小的值,所以在fit时考虑遍历[1,10],无需遍历更大的K(导致额外无用运算) + 3.2 不同K下的锯齿图 3.3 不同K下的acc \ No newline at end of file -- Gitee From 59ba14c2d14761e6d5ff2b323fb8ed9c73280a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 12:04:35 +0800 Subject: [PATCH 37/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index 2feaf97..d9e68d0 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -413,9 +413,7 @@ $$ -** -3. K值 -** +**3. K值 ** ***3.1 不同量下的best_k*** -- Gitee From 0bf9f950a569592a6b0f694632897248bef8fa1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 12:25:38 +0800 Subject: [PATCH 38/84] update assignment-1/submission/18340246016/README.md. --- assignment-1/submission/18340246016/README.md | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/assignment-1/submission/18340246016/README.md b/assignment-1/submission/18340246016/README.md index d9e68d0..c998960 100644 --- a/assignment-1/submission/18340246016/README.md +++ b/assignment-1/submission/18340246016/README.md @@ -446,5 +446,40 @@ plt.legend() 2. 最佳K会趋向于一个较小的值,所以在fit时考虑遍历[1,10],无需遍历更大的K(导致额外无用运算) -3.2 不同K下的锯齿图 -3.3 不同K下的acc \ No newline at end of file +**3.2 不同K下的acc** + + +``` +# 因为我实现的KNN函数没有K参数(学习最优K),这里采用SKlearn数据库中的KNeighborsClassifier来做本次探究 +from sklearn.datasets import load_iris +from sklearn.model_selection import train_test_split +from sklearn.neighbors import KNeighborsClassifier + +# 导入sklearn iris数据库并分类 +iris = load_iris() +X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size = 0.25, random_state = 33) + +# 在不同k值下计算accuracy +acc_list=[] + +for i in range (1,100): + + + knc = KNeighborsClassifier(n_neighbors=i) + knc.fit(X_train, y_train) + y_predict = knc.predict(X_test) + + acc_list.append(knc.score(X_test, y_test)) + +# 画图 +l1=plt.plot(range(1,100),acc_list,'green',label='Accuracy') +plt.title('The relationship between K-choice and Accuracy') +plt.xlabel('K-Value') +plt.ylabel('Accuracy') +plt.legend() + +``` +![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/122104_30809a7a_8823823.png "屏幕截图.png") + +1. 同3.1结论[2],最佳K的取值会聚焦于一个较小的值 +2. iris数据集大小为150,可以看到超过0.5*len 之后准确率锁定在50%(几乎约等于瞎猜) -- Gitee From 995af67ca45c3e02d0286696b32538e31fe08f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=9F=E7=84=95=E7=84=B6?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 12:27:33 +0800 Subject: [PATCH 39/84] update assignment-1/submission/18340246016/source.py. --- assignment-1/submission/18340246016/source.py | 68 +++++++++++++++++-- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/assignment-1/submission/18340246016/source.py b/assignment-1/submission/18340246016/source.py index ceb7e79..c43b0cc 100644 --- a/assignment-1/submission/18340246016/source.py +++ b/assignment-1/submission/18340246016/source.py @@ -1,6 +1,3 @@ -import numpy as np -import matplotlib.pyplot as plt - class KNN: def __init__(self): @@ -27,15 +24,14 @@ class KNN: mu = np.mean(train_data, axis=0) sigma = np.std(train_data, axis=0) train_data = (train_data - mu) / sigma - #train_data = train_data / np.sqrt(np.sum(train_data**2)) # 划分训练集/验证集 with rate =0.3 X_train, X_test, Y_train, Y_test = self.train_test_split(train_data,train_label,0.3) - # 对于不同的K[1-0.5*len(train)],计算验证集到训练集的欧氏距离 + # 对于不同的K[1-20],计算验证集到训练集的欧氏距离 best_k=0 k_candi=0; - for k in range(1,int(0.5*len(X_train))+1): + for k in range(1,20): true_couter=0 for test_counter in range(0,len(X_test)): @@ -67,6 +63,7 @@ class KNN: best_k = true_couter k_candi = k + # print(k_candi) self.k = k_candi self.train_data = train_data self.train_labels = train_label @@ -97,4 +94,61 @@ class KNN: test_label.append(result_list[np.argmax(result_list)]) return test_label - \ No newline at end of file + +def generate (amount_1,amount_2,amount_3): + + + mean = (2, 2) + cov = np.array([[1,0], [0, 1]]) + x = np.random.multivariate_normal(mean, cov, (amount_1,)) + + mean = (4, 6) + cov = np.array([[2, 0], [0, 2]]) + y = np.random.multivariate_normal(mean, cov, (amount_2,)) + + mean = (10, 10) + cov = np.array([[2,1],[1,3]]) + z = np.random.multivariate_normal(mean, cov, (amount_3,)) + + + data = np.concatenate([x,y,z]) + + label = np.concatenate([ + np.zeros((amount_1,),dtype=int), + np.ones((amount_2,),dtype=int), + np.ones((amount_3,),dtype=int)*2 + ]) + + return model.train_test_split(data,label,0.2) + + +def display(x,y): + type1_x = []; type1_y = [] + type2_x = []; type2_y = [] + type3_x = []; type3_y = [] + + plt.figure(figsize=(8,6)) + + for i in range(0,len(x)): + if(y[i]==0): + type1_x.append(x[i][0]) + type1_y.append(x[i][1]) + if(y[i]==1): + type2_x.append(x[i][0]) + type2_y.append(x[i][1]) + if(y[i]==2): + type3_x.append(x[i][0]) + type3_y.append(x[i][1]) + + fig = plt.figure(figsize = (10, 6)) + ax = fig.add_subplot(111) + + type1 = ax.scatter(type1_x, type1_y, s = 30, c = 'brown') + type2 = ax.scatter(type2_x, type2_y, s = 30, c = 'lime') + type3 = ax.scatter(type3_x, type3_y, s = 30, c = "darkviolet") + + + + ax.legend((type1, type2, type3), ("A", "B", "C"), loc = 0) + + plt.show() -- Gitee From 7c1648b7355ecf7f44b285f07427d8cef6e12476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 12:30:41 +0800 Subject: [PATCH 40/84] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20img?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-1/submission/18340246016/img/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-1/submission/18340246016/img/.keep diff --git a/assignment-1/submission/18340246016/img/.keep b/assignment-1/submission/18340246016/img/.keep new file mode 100644 index 0000000..e69de29 -- Gitee From 16c197ef049b9296b4e600b7879efa184489c336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 1 Apr 2021 12:33:18 +0800 Subject: [PATCH 41/84] readme.md's IMG --- .../18340246016/img/105433_e7ec4619_8823823.png | Bin 0 -> 28759 bytes .../18340246016/img/105459_56af4a90_8823823.png | Bin 0 -> 14691 bytes .../18340246016/img/111859_687c068b_8823823.png | Bin 0 -> 33266 bytes .../18340246016/img/111906_d0e2e134_8823823.png | Bin 0 -> 15637 bytes .../18340246016/img/112426_09535d36_8823823.png | Bin 0 -> 31102 bytes .../18340246016/img/112437_53a32eec_8823823.png | Bin 0 -> 15380 bytes .../18340246016/img/112759_754208e4_8823823.png | Bin 0 -> 28511 bytes .../18340246016/img/112810_ca9d4230_8823823.png | Bin 0 -> 14918 bytes .../18340246016/img/120033_088f8aa7_8823823.png | Bin 0 -> 14675 bytes .../18340246016/img/122104_30809a7a_8823823.png | Bin 0 -> 15150 bytes 10 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-1/submission/18340246016/img/105433_e7ec4619_8823823.png create mode 100644 assignment-1/submission/18340246016/img/105459_56af4a90_8823823.png create mode 100644 assignment-1/submission/18340246016/img/111859_687c068b_8823823.png create mode 100644 assignment-1/submission/18340246016/img/111906_d0e2e134_8823823.png create mode 100644 assignment-1/submission/18340246016/img/112426_09535d36_8823823.png create mode 100644 assignment-1/submission/18340246016/img/112437_53a32eec_8823823.png create mode 100644 assignment-1/submission/18340246016/img/112759_754208e4_8823823.png create mode 100644 assignment-1/submission/18340246016/img/112810_ca9d4230_8823823.png create mode 100644 assignment-1/submission/18340246016/img/120033_088f8aa7_8823823.png create mode 100644 assignment-1/submission/18340246016/img/122104_30809a7a_8823823.png diff --git a/assignment-1/submission/18340246016/img/105433_e7ec4619_8823823.png b/assignment-1/submission/18340246016/img/105433_e7ec4619_8823823.png new file mode 100644 index 0000000000000000000000000000000000000000..2b3ebe23a4c696d374084525296b704bc1e94461 GIT binary patch literal 28759 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 literal 0 HcmV?d00001 diff --git a/assignment-1/submission/18340246016/img/105459_56af4a90_8823823.png b/assignment-1/submission/18340246016/img/105459_56af4a90_8823823.png new file mode 100644 index 0000000000000000000000000000000000000000..8ecab29162d04ce0e20d91129786ace0133752dd GIT binary patch literal 14691 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�M*&d;K3q z50*!DmZ3cQ8nrWJEf*R+-1l>FjX@-HU}ulMkm8AZSlkpR%1sV!$ohDpKkN-{lJZLh z!om=LV~j{;F11vQ!%}t2uq;-0K2Jf984>S>>omgH&Wt?0;g%%cq=(V!b&F!Aj8C@L?D+J1h9Z7>ehcab407!gk$*_nn5jE$bwv*bQTv*tYc$wy|Vb+;qC ze*ujol+n!V{Nd**_tVqU7|uQET%#=FeQ#bFgE@%rTmIyDeyeCTBk|LEudsy-^UhRm z*OS9)oYZB~-J^fdlulq0-ss!cx#s%}ci5!)(gIPdfsv_Di9D2(%b~8Un&z|kNdZ;x zU3;N3pQmijiaKUT@lY6Rk#l=YNC&IPg(Vz~(#ym!ExH-4smCW&*4oK@v#vW_K78K) z+|xW+{7)?lpW)3Tb|WFp2~fSv8jy|ZRNPcJlE-X)U;(ogbWaDler}-(g6~NDvdF$` zC9auscqTun@LFU>0d^|mo&sj=JL>gnf8kVi)OiGUB3E~Q>o#()dvDD$i&PhhonXQa z6!aQWFK#%aJQf1elOBK^0FwVGe=}!`oM4~3nnd$gryoSiN`HZBv4lxP3UQB-H_-Wi5{x-&tK6u4#;&>sK* literal 0 HcmV?d00001 diff --git a/assignment-1/submission/18340246016/img/112426_09535d36_8823823.png b/assignment-1/submission/18340246016/img/112426_09535d36_8823823.png new file mode 100644 index 0000000000000000000000000000000000000000..a1db91fe434924aafbc734b235647d73fb4229dd GIT binary patch literal 31102 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 literal 0 HcmV?d00001 diff --git a/assignment-1/submission/18340246016/img/112437_53a32eec_8823823.png b/assignment-1/submission/18340246016/img/112437_53a32eec_8823823.png new file mode 100644 index 0000000000000000000000000000000000000000..7731028adc12f28c461efc7240b6e5fa95c12702 GIT binary patch literal 15380 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 literal 0 HcmV?d00001 diff --git a/assignment-1/submission/18340246016/img/112759_754208e4_8823823.png b/assignment-1/submission/18340246016/img/112759_754208e4_8823823.png new file mode 100644 index 0000000000000000000000000000000000000000..913e3801971de18d4f609181dad97957b03a142b GIT binary patch literal 28511 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%0AKg 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 literal 0 HcmV?d00001 diff --git a/assignment-1/submission/18340246016/img/122104_30809a7a_8823823.png b/assignment-1/submission/18340246016/img/122104_30809a7a_8823823.png new file mode 100644 index 0000000000000000000000000000000000000000..0343da404b4c87d03aebfde3016b60e6b55cb836 GIT binary patch literal 15150 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 Date: Thu, 1 Apr 2021 12:33:33 +0800 Subject: [PATCH 42/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-1/submission/18340246016/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-1/submission/18340246016/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 assignment-1/submission/18340246016/.keep diff --git a/assignment-1/submission/18340246016/.keep b/assignment-1/submission/18340246016/.keep deleted file mode 100644 index e69de29..0000000 -- Gitee From 795a640cda650617ac6fa0beffe0607878313908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 29 Apr 2021 15:57:02 +0800 Subject: [PATCH 43/84] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20assignment-2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-2/.keep diff --git a/assignment-2/.keep b/assignment-2/.keep new file mode 100644 index 0000000..e69de29 -- Gitee From 3fc83e9476532947c88166d34f20120fd2beb061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 29 Apr 2021 15:58:58 +0800 Subject: [PATCH 44/84] add assignment-2/numpy_fnn.py. --- assignment-2/numpy_fnn.py | 249 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 assignment-2/numpy_fnn.py diff --git a/assignment-2/numpy_fnn.py b/assignment-2/numpy_fnn.py new file mode 100644 index 0000000..7f48bcd --- /dev/null +++ b/assignment-2/numpy_fnn.py @@ -0,0 +1,249 @@ +import numpy as np + + +class NumpyOp: + + def __init__(self): + self.memory = {} + self.epsilon = 1e-12 + + +class Matmul(NumpyOp): + + def forward(self, x, W): + """ + x: shape(N, d) + w: shape(d, d') + """ + self.memory['x'] = x + self.memory['W'] = W + h = np.matmul(x, W) + return h + + def backward(self, grad_y): + """ + grad_y: shape(N, d') + """ + + #################### + # code 1 # + x = self.memory['x'] + W = self.memory['W'] + + grad_W = np.matmul(x.T,grad_y) + grad_x = np.matmul(grad_y,W.T) + #################### + + return grad_x, grad_W + + +class Relu(NumpyOp): + + def forward(self, x): + self.memory['x'] = x + return np.where(x > 0, x, np.zeros_like(x)) + + def backward(self, grad_y): + """ + grad_y: same shape as x + """ + + #################### + # code 2 # + x = self.memory['x'] + + grad_x = np.where(x > 0, 1, 0) + + grad_x = grad_x * grad_y + + #################### + + return grad_x + + +class Log(NumpyOp): + + def forward(self, x): + """ + x: shape(N, c) + """ + + out = np.log(x + self.epsilon) + self.memory['x'] = x + + return out + + def backward(self, grad_y): + """ + grad_y: same shape as x + """ + + #################### + # code 3 # + x = self.memory['x'] + + grad_x = (1/(x + self.epsilon)) + + grad_x = grad_x*grad_y + + + #################### + + return grad_x + + +class Softmax(NumpyOp): + """ + softmax over last dimension + """ + + def forward(self, x): + """ + x: shape(N, c) + """ + + #################### + # code 4 # + + out = np.array(x, copy="true") + + + result_list=[] + + for m in range(len(out)): + result_list.append(sum(np.exp(out[m]))) + + for m in range(len(out)): + for n in range(len(out[0])): + out[m][n]= np.exp(out[m][n]) / result_list[m] + + self.memory['x'] = x + + #################### + + return out + + + + def backward(self, grad_y): + + """ + grad_y: same shape as x + """ + + + + #################### + # code 5 # + + x = self.memory['x'] + softx = self.forward(x) + [n, m] = x.shape + out = [] + for i in range(n): + out.append([]) + for j in range(m): + out[i].append(0) + for k in range(m): + if j == k: + out[i][j] += (1 - softx[i][k]) * softx[i][k] * grad_y[i][k] + else: + out[i][j] += -softx[i][j] * softx[i][k] * grad_y[i][k] + grad_x = np.array(out) + + + + + #################### + + return grad_x + + +class NumpyLoss: + + def __init__(self): + self.target = None + + def get_loss(self, pred, target): + self.target = target + return (-pred * target).sum(axis=1).mean() + + def backward(self): + return -self.target / self.target.shape[0] + + +class NumpyModel: + def __init__(self): + self.W1 = np.random.normal(size=(28 * 28, 256)) + self.W2 = np.random.normal(size=(256, 64)) + self.W3 = np.random.normal(size=(64, 10)) + + # 以下算子会在 forward 和 backward 中使用 + self.matmul_1 = Matmul() + self.relu_1 = Relu() + self.matmul_2 = Matmul() + self.relu_2 = Relu() + self.matmul_3 = Matmul() + self.softmax = Softmax() + self.log = Log() + + # 以下变量需要在 backward 中更新。 softmax_grad, log_grad 等为算子反向传播的梯度( loss 关于算子输入的偏导) + self.x1_grad, self.W1_grad = None, None + self.relu_1_grad = None + self.x2_grad, self.W2_grad = None, None + self.relu_2_grad = None + self.x3_grad, self.W3_grad = None, None + self.softmax_grad = None + self.log_grad = None + + def forward(self, x): + x = x.reshape(-1, 28 * 28) + + #################### + # code 6 # + #x = torch.relu(torch.matmul(x, self.W1)) + x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) + + #x = torch.relu(torch.matmul(x, self.W2)) + x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) + + #x = torch.matmul(x, self.W3) + #x = torch.softmax(x, 1) + x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) + + #x = torch.log(x) + x = self.log.forward(x) + + #################### + + return x + + def backward(self, y): + + #################### + # code 7 # + + self.log_grad = self.log.backward(y) + + self.softmax_grad = self.softmax.backward(self.log_grad) + + self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) + + self.relu_2_grad = self.relu_2.backward(self.x3_grad) + + self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) + + self.relu_1_grad = self.relu_1.backward(self.x2_grad) + + self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) + + + + #################### + + pass + + def optimize(self, learning_rate): + self.W1 -= learning_rate * self.W1_grad + self.W2 -= learning_rate * self.W2_grad + self.W3 -= learning_rate * self.W3_grad \ No newline at end of file -- Gitee From 605dfaf5e9b9de94eee7594e1a15855caebc6a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Thu, 29 Apr 2021 16:00:33 +0800 Subject: [PATCH 45/84] add assignment-2/numpy_mnist.py. --- assignment-2/numpy_mnist.py | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 assignment-2/numpy_mnist.py diff --git a/assignment-2/numpy_mnist.py b/assignment-2/numpy_mnist.py new file mode 100644 index 0000000..833e5aa --- /dev/null +++ b/assignment-2/numpy_mnist.py @@ -0,0 +1,58 @@ +import numpy as np +from numpy_fnn import NumpyModel, NumpyLoss +from utils import download_mnist, batch, get_torch_initialization, plot_curve, one_hot + +def mini_batch(dataset, batch_size=128, numpy=False): + + data = [] + label = [] + for each in dataset: + data.append(np.array(each[0])) + label.append(each[1]) + + data = np.array(data) + label = np.array(label) + + res = [] + + + for start_idx in range(0, data.shape[0], batch_size): + end_idx = min(start_idx + batch_size, len(data)) + res.append((data[start_idx:end_idx],label[start_idx:end_idx])) + + return res + + +def numpy_run(): + train_dataset, test_dataset = download_mnist() + + model = NumpyModel() + numpy_loss = NumpyLoss() + model.W1, model.W2, model.W3 = get_torch_initialization() + + train_loss = [] + + epoch_number = 3 + learning_rate = 0.1 + + for epoch in range(epoch_number): + for x, y in mini_batch(train_dataset): + y = one_hot(y) + + y_pred = model.forward(x) + loss = numpy_loss.get_loss(y_pred, y) + + model.backward(numpy_loss.backward()) + model.optimize(learning_rate) + + train_loss.append(loss.item()) + + x, y = batch(test_dataset)[0] + accuracy = np.mean((model.forward(x).argmax(axis=1) == y)) + print('[{}] Accuracy: {:.4f}'.format(epoch, accuracy)) + + plot_curve(train_loss) + + +if __name__ == "__main__": + numpy_run() \ No newline at end of file -- Gitee From 139a2e496eebaf4051ab3676600d4228161ef71a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 10:01:53 +0800 Subject: [PATCH 46/84] add assignment-2. --- assignment-2/readme.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-2/readme.md diff --git a/assignment-2/readme.md b/assignment-2/readme.md new file mode 100644 index 0000000..e69de29 -- Gitee From d951453c2bba3cf53ab9c487f308ce4d5e9cb43d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 10:15:41 +0800 Subject: [PATCH 47/84] rename assignment-2/readme.md to assignment-2/README.md. --- assignment-2/README.md | 25 +++++++++++++++++++++++++ assignment-2/readme.md | 0 2 files changed, 25 insertions(+) create mode 100644 assignment-2/README.md delete mode 100644 assignment-2/readme.md diff --git a/assignment-2/README.md b/assignment-2/README.md new file mode 100644 index 0000000..274c633 --- /dev/null +++ b/assignment-2/README.md @@ -0,0 +1,25 @@ +**1. Mini-batch 函数的实现** + +``` +def mini_batch(dataset, batch_size=128, numpy=False): + +# 仿照batch函数分离data与label + data = [] + label = [] + for each in dataset: + data.append(np.array(each[0])) + label.append(each[1]) + + data = np.array(data) + label = np.array(label) + + + res = [] + +# 以batch_size为单位,从[0,len(data)]分割mini-batch + for start_idx in range(0, data.shape[0], batch_size): + end_idx = min(start_idx + batch_size, len(data)) + res.append((data[start_idx:end_idx],label[start_idx:end_idx])) + + return res +``` diff --git a/assignment-2/readme.md b/assignment-2/readme.md deleted file mode 100644 index e69de29..0000000 -- Gitee From e13104e97a34c3d66e9602020a90f47e2803d7a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 10:23:28 +0800 Subject: [PATCH 48/84] update assignment-2/README.md. --- assignment-2/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/assignment-2/README.md b/assignment-2/README.md index 274c633..3a44836 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -23,3 +23,10 @@ def mini_batch(dataset, batch_size=128, numpy=False): return res ``` + + **2. 模型的训练和测试** + +| Epoch | Batch_size | +| ---------------- | ------ | +| 3 | 16 | +| 10 | 128 | -- Gitee From 680ebe33e6b18eff82e227d4a98ae34f9d62212d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 10:26:24 +0800 Subject: [PATCH 49/84] update assignment-2/README.md. --- assignment-2/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/assignment-2/README.md b/assignment-2/README.md index 3a44836..0fe8ee5 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -30,3 +30,12 @@ def mini_batch(dataset, batch_size=128, numpy=False): | ---------------- | ------ | | 3 | 16 | | 10 | 128 | + + +* Epoch = 3 Batch_size=128 * + +[0] Accuracy: 0.9373 +[1] Accuracy: 0.9583 +[2] Accuracy: 0.9683 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/102618_2f8a1661_8823823.png "3-128.png") \ No newline at end of file -- Gitee From 41cd8450b1cf1796252abdb3261cc93934b64f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 10:26:53 +0800 Subject: [PATCH 50/84] update assignment-2/README.md. --- assignment-2/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assignment-2/README.md b/assignment-2/README.md index 0fe8ee5..cd9c6cf 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -32,10 +32,12 @@ def mini_batch(dataset, batch_size=128, numpy=False): | 10 | 128 | -* Epoch = 3 Batch_size=128 * +* Epoch = 3 Batch_size=128 [0] Accuracy: 0.9373 + [1] Accuracy: 0.9583 + [2] Accuracy: 0.9683 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/102618_2f8a1661_8823823.png "3-128.png") \ No newline at end of file -- Gitee From 8083ec87a9e58c3fb907d62403954677fde91bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 10:27:17 +0800 Subject: [PATCH 51/84] update assignment-2/README.md. --- assignment-2/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/assignment-2/README.md b/assignment-2/README.md index cd9c6cf..8fc9add 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -35,9 +35,7 @@ def mini_batch(dataset, batch_size=128, numpy=False): * Epoch = 3 Batch_size=128 [0] Accuracy: 0.9373 - [1] Accuracy: 0.9583 - [2] Accuracy: 0.9683 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/102618_2f8a1661_8823823.png "3-128.png") \ No newline at end of file -- Gitee From b38ba76f0f7c32a277dc7fb7441ee5c29b115fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 10:28:14 +0800 Subject: [PATCH 52/84] update assignment-2/README.md. --- assignment-2/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-2/README.md b/assignment-2/README.md index 8fc9add..d440643 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -34,8 +34,8 @@ def mini_batch(dataset, batch_size=128, numpy=False): * Epoch = 3 Batch_size=128 -[0] Accuracy: 0.9373 -[1] Accuracy: 0.9583 -[2] Accuracy: 0.9683 +
[0] Accuracy: 0.9373 +
[1] Accuracy: 0.9583 +
[2] Accuracy: 0.9683 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/102618_2f8a1661_8823823.png "3-128.png") \ No newline at end of file -- Gitee From b39c0b86cc07885bf8566476d7fcee7a30e4a086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 10:28:32 +0800 Subject: [PATCH 53/84] update assignment-2/README.md. --- assignment-2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-2/README.md b/assignment-2/README.md index d440643..4c7da37 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -34,7 +34,7 @@ def mini_batch(dataset, batch_size=128, numpy=False): * Epoch = 3 Batch_size=128 -
[0] Accuracy: 0.9373 +[0] Accuracy: 0.9373
[1] Accuracy: 0.9583
[2] Accuracy: 0.9683 -- Gitee From 800438d57751af2b14348f3685b3222d313c0b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 11:10:58 +0800 Subject: [PATCH 54/84] update assignment-2/README.md. --- assignment-2/README.md | 43 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/assignment-2/README.md b/assignment-2/README.md index 4c7da37..b95f42e 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -38,4 +38,45 @@ def mini_batch(dataset, batch_size=128, numpy=False):
[1] Accuracy: 0.9583
[2] Accuracy: 0.9683 -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/102618_2f8a1661_8823823.png "3-128.png") \ No newline at end of file +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/102618_2f8a1661_8823823.png "3-128.png") + + + +* Epoch = 3 Batch_size=16 + +[0] Accuracy: 0.9640 +
[1] Accuracy: 0.9676 +
[2] Accuracy: 0.9707 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/103502_131ca59f_8823823.png "3-16.png") + +* Epoch = 10 Batch_size=16 + +[0] Accuracy: 0.9602 +
[1] Accuracy: 0.9657 +
[2] Accuracy: 0.9741 +
[3] Accuracy: 0.9747 +
[4] Accuracy: 0.9701 +
[5] Accuracy: 0.9731 +
[6] Accuracy: 0.9760 +
[7] Accuracy: 0.9763 +
[8] Accuracy: 0.9760 +
[9] Accuracy: 0.9780 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/105531_82cafce0_8823823.png "10-16.png") + + +* Epoch = 10 Batch_size=128 + +[0] Accuracy: 0.9389 +
[1] Accuracy: 0.9585 +
[2] Accuracy: 0.9679 +
[3] Accuracy: 0.9706 +
[4] Accuracy: 0.9746 +
[5] Accuracy: 0.9760 +
[6] Accuracy: 0.9769 +
[7] Accuracy: 0.9777 +
[8] Accuracy: 0.9781 +
[9] Accuracy: 0.9781 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/111052_ddb4ecda_8823823.png "10-128.png") \ No newline at end of file -- Gitee From 54cf0081c52d2e22bff8236f8d6b53dca668aeb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 11:34:14 +0800 Subject: [PATCH 55/84] update assignment-2/README.md. --- assignment-2/README.md | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/assignment-2/README.md b/assignment-2/README.md index b95f42e..6d53862 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -26,6 +26,65 @@ def mini_batch(dataset, batch_size=128, numpy=False): **2. 模型的训练和测试** +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/113123_f204953a_8823823.png "processon.png") + +``` + # 前向传播过程 + def forward(self, x): + x = x.reshape(-1, 28 * 28) + + #################### + # code 6 # + + #x = torch.relu(torch.matmul(x, self.W1)) + # 模仿torch的relu(Matmul.(x,w1))操作,下同 + x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) + + #x = torch.relu(torch.matmul(x, self.W2)) + x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) + + #x = torch.matmul(x, self.W3) + #x = torch.softmax(x, 1) + x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) + + #x = torch.log(x) + x = self.log.forward(x) + + #################### + + return x + + # 反向传播过程 + def backward(self, y): + + #################### + # code 7 # + + self.log_grad = self.log.backward(y) + + self.softmax_grad = self.softmax.backward(self.log_grad) + + self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) + + self.relu_2_grad = self.relu_2.backward(self.x3_grad) + + self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) + + self.relu_1_grad = self.relu_1.backward(self.x2_grad) + + self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) + + + + #################### + + pass +``` + + + + + | Epoch | Batch_size | | ---------------- | ------ | | 3 | 16 | -- Gitee From d370041d49edc2d1cdc3cbf002d56681800b4723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 11:35:12 +0800 Subject: [PATCH 56/84] update assignment-2/README.md. --- assignment-2/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/assignment-2/README.md b/assignment-2/README.md index 6d53862..4fdfff2 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -138,4 +138,8 @@ def mini_batch(dataset, batch_size=128, numpy=False):
[8] Accuracy: 0.9781
[9] Accuracy: 0.9781 -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/111052_ddb4ecda_8823823.png "10-128.png") \ No newline at end of file +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/111052_ddb4ecda_8823823.png "10-128.png") + + + +*探究发现* -- Gitee From 8fe4b7b70e26b55dc69d2052324383855689605c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 11:38:53 +0800 Subject: [PATCH 57/84] update assignment-2/README.md. --- assignment-2/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assignment-2/README.md b/assignment-2/README.md index 4fdfff2..d1d1917 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -143,3 +143,5 @@ def mini_batch(dataset, batch_size=128, numpy=False): *探究发现* +1. mini-batch size太小的情况下,模型的波动率非常高,并不是对batch_size越细分模型的准确率就越高 +2. 从epoch的数量上来看,epoch的数量与模型accuracy有正相关性 \ No newline at end of file -- Gitee From 5240526a3b001b4f80dbf9fe573480a6f4e40e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 11:53:48 +0800 Subject: [PATCH 58/84] update assignment-2/README.md. --- assignment-2/README.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/assignment-2/README.md b/assignment-2/README.md index d1d1917..d5f6d85 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -144,4 +144,36 @@ def mini_batch(dataset, batch_size=128, numpy=False): *探究发现* 1. mini-batch size太小的情况下,模型的波动率非常高,并不是对batch_size越细分模型的准确率就越高 -2. 从epoch的数量上来看,epoch的数量与模型accuracy有正相关性 \ No newline at end of file +2. 从epoch的数量上来看,epoch的数量与模型accuracy有正相关性 + + + **3.Momentum 优化函数下的对比试验** + + +``` + # 利用momentum优化下的optimize函数 + def optimize(self, learning_rate): + + # 初始化V值 + v1=0 + v2=0 + v3=0 + mu=0.9 + + # momentum下的更新算法 + v1 = mu * v1 - learning_rate * self.W1_grad + self.W1 = self.W1 + v1 + + v2 = mu * v2 - learning_rate * self.W2_grad + self.W2 = self.W2 + v2 + + v3 = mu * v3 - learning_rate * self.W3_grad + self.W3 = self.W3 + v3 + + + #self.W1 -= learning_rate * self.W1_grad + # self.W2 -= learning_rate * self.W2_grad + #self.W3 -= learning_rate * self.W3_grad +``` + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/115301_1fa39f2b_8823823.png "屏幕截图.png") \ No newline at end of file -- Gitee From 8be1d39f9827cfc85a501ab780070051982f2fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Fri, 30 Apr 2021 11:59:36 +0800 Subject: [PATCH 59/84] update assignment-2/README.md. --- assignment-2/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/assignment-2/README.md b/assignment-2/README.md index d5f6d85..827aa9f 100644 --- a/assignment-2/README.md +++ b/assignment-2/README.md @@ -176,4 +176,8 @@ def mini_batch(dataset, batch_size=128, numpy=False): #self.W3 -= learning_rate * self.W3_grad ``` -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/115301_1fa39f2b_8823823.png "屏幕截图.png") \ No newline at end of file +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/115301_1fa39f2b_8823823.png "屏幕截图.png") + +1. 在我们的测试数据下,momentum与梯度下降模型准确率差异不大 +2. momentum模型主要用来解决全局最优与局部最优之间的差异,但在本测试集下不存在全局与局部的差异 +3. 理论上来说,当 momentum 动量越大时,其转换为势能的能量也就越大,就越有可能摆脱局部凹域的束缚,进入全局凹域 \ No newline at end of file -- Gitee From 4cb244d6c1341f69f47a7e0dc2ab86ef2640174b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:17:46 +0800 Subject: [PATCH 60/84] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20submission?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/submission/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-2/submission/.keep diff --git a/assignment-2/submission/.keep b/assignment-2/submission/.keep new file mode 100644 index 0000000..e69de29 -- Gitee From f0366413984247ee36e0c7df3f78f3ac11b98ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:19:16 +0800 Subject: [PATCH 61/84] add assignment-2/submission/README.md. --- assignment-2/submission/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-2/submission/README.md diff --git a/assignment-2/submission/README.md b/assignment-2/submission/README.md new file mode 100644 index 0000000..e69de29 -- Gitee From 2ade6e8912a269748871af147816a198e279ea27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:19:46 +0800 Subject: [PATCH 62/84] update assignment-2/submission/README.md. --- assignment-2/submission/README.md | 183 ++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/assignment-2/submission/README.md b/assignment-2/submission/README.md index e69de29..827aa9f 100644 --- a/assignment-2/submission/README.md +++ b/assignment-2/submission/README.md @@ -0,0 +1,183 @@ +**1. Mini-batch 函数的实现** + +``` +def mini_batch(dataset, batch_size=128, numpy=False): + +# 仿照batch函数分离data与label + data = [] + label = [] + for each in dataset: + data.append(np.array(each[0])) + label.append(each[1]) + + data = np.array(data) + label = np.array(label) + + + res = [] + +# 以batch_size为单位,从[0,len(data)]分割mini-batch + for start_idx in range(0, data.shape[0], batch_size): + end_idx = min(start_idx + batch_size, len(data)) + res.append((data[start_idx:end_idx],label[start_idx:end_idx])) + + return res +``` + + **2. 模型的训练和测试** + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/113123_f204953a_8823823.png "processon.png") + +``` + # 前向传播过程 + def forward(self, x): + x = x.reshape(-1, 28 * 28) + + #################### + # code 6 # + + #x = torch.relu(torch.matmul(x, self.W1)) + # 模仿torch的relu(Matmul.(x,w1))操作,下同 + x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) + + #x = torch.relu(torch.matmul(x, self.W2)) + x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) + + #x = torch.matmul(x, self.W3) + #x = torch.softmax(x, 1) + x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) + + #x = torch.log(x) + x = self.log.forward(x) + + #################### + + return x + + # 反向传播过程 + def backward(self, y): + + #################### + # code 7 # + + self.log_grad = self.log.backward(y) + + self.softmax_grad = self.softmax.backward(self.log_grad) + + self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) + + self.relu_2_grad = self.relu_2.backward(self.x3_grad) + + self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) + + self.relu_1_grad = self.relu_1.backward(self.x2_grad) + + self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) + + + + #################### + + pass +``` + + + + + +| Epoch | Batch_size | +| ---------------- | ------ | +| 3 | 16 | +| 10 | 128 | + + +* Epoch = 3 Batch_size=128 + +[0] Accuracy: 0.9373 +
[1] Accuracy: 0.9583 +
[2] Accuracy: 0.9683 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/102618_2f8a1661_8823823.png "3-128.png") + + + +* Epoch = 3 Batch_size=16 + +[0] Accuracy: 0.9640 +
[1] Accuracy: 0.9676 +
[2] Accuracy: 0.9707 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/103502_131ca59f_8823823.png "3-16.png") + +* Epoch = 10 Batch_size=16 + +[0] Accuracy: 0.9602 +
[1] Accuracy: 0.9657 +
[2] Accuracy: 0.9741 +
[3] Accuracy: 0.9747 +
[4] Accuracy: 0.9701 +
[5] Accuracy: 0.9731 +
[6] Accuracy: 0.9760 +
[7] Accuracy: 0.9763 +
[8] Accuracy: 0.9760 +
[9] Accuracy: 0.9780 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/105531_82cafce0_8823823.png "10-16.png") + + +* Epoch = 10 Batch_size=128 + +[0] Accuracy: 0.9389 +
[1] Accuracy: 0.9585 +
[2] Accuracy: 0.9679 +
[3] Accuracy: 0.9706 +
[4] Accuracy: 0.9746 +
[5] Accuracy: 0.9760 +
[6] Accuracy: 0.9769 +
[7] Accuracy: 0.9777 +
[8] Accuracy: 0.9781 +
[9] Accuracy: 0.9781 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/111052_ddb4ecda_8823823.png "10-128.png") + + + +*探究发现* +1. mini-batch size太小的情况下,模型的波动率非常高,并不是对batch_size越细分模型的准确率就越高 +2. 从epoch的数量上来看,epoch的数量与模型accuracy有正相关性 + + + **3.Momentum 优化函数下的对比试验** + + +``` + # 利用momentum优化下的optimize函数 + def optimize(self, learning_rate): + + # 初始化V值 + v1=0 + v2=0 + v3=0 + mu=0.9 + + # momentum下的更新算法 + v1 = mu * v1 - learning_rate * self.W1_grad + self.W1 = self.W1 + v1 + + v2 = mu * v2 - learning_rate * self.W2_grad + self.W2 = self.W2 + v2 + + v3 = mu * v3 - learning_rate * self.W3_grad + self.W3 = self.W3 + v3 + + + #self.W1 -= learning_rate * self.W1_grad + # self.W2 -= learning_rate * self.W2_grad + #self.W3 -= learning_rate * self.W3_grad +``` + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/115301_1fa39f2b_8823823.png "屏幕截图.png") + +1. 在我们的测试数据下,momentum与梯度下降模型准确率差异不大 +2. momentum模型主要用来解决全局最优与局部最优之间的差异,但在本测试集下不存在全局与局部的差异 +3. 理论上来说,当 momentum 动量越大时,其转换为势能的能量也就越大,就越有可能摆脱局部凹域的束缚,进入全局凹域 \ No newline at end of file -- Gitee From d31fadb39e915756efe8f197a7b8b2d19d217d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:20:31 +0800 Subject: [PATCH 63/84] add assignment-2/submission. --- .../submission/assignment-2/numpy_fnn.py | 249 ++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 assignment-2/submission/assignment-2/numpy_fnn.py diff --git a/assignment-2/submission/assignment-2/numpy_fnn.py b/assignment-2/submission/assignment-2/numpy_fnn.py new file mode 100644 index 0000000..7f48bcd --- /dev/null +++ b/assignment-2/submission/assignment-2/numpy_fnn.py @@ -0,0 +1,249 @@ +import numpy as np + + +class NumpyOp: + + def __init__(self): + self.memory = {} + self.epsilon = 1e-12 + + +class Matmul(NumpyOp): + + def forward(self, x, W): + """ + x: shape(N, d) + w: shape(d, d') + """ + self.memory['x'] = x + self.memory['W'] = W + h = np.matmul(x, W) + return h + + def backward(self, grad_y): + """ + grad_y: shape(N, d') + """ + + #################### + # code 1 # + x = self.memory['x'] + W = self.memory['W'] + + grad_W = np.matmul(x.T,grad_y) + grad_x = np.matmul(grad_y,W.T) + #################### + + return grad_x, grad_W + + +class Relu(NumpyOp): + + def forward(self, x): + self.memory['x'] = x + return np.where(x > 0, x, np.zeros_like(x)) + + def backward(self, grad_y): + """ + grad_y: same shape as x + """ + + #################### + # code 2 # + x = self.memory['x'] + + grad_x = np.where(x > 0, 1, 0) + + grad_x = grad_x * grad_y + + #################### + + return grad_x + + +class Log(NumpyOp): + + def forward(self, x): + """ + x: shape(N, c) + """ + + out = np.log(x + self.epsilon) + self.memory['x'] = x + + return out + + def backward(self, grad_y): + """ + grad_y: same shape as x + """ + + #################### + # code 3 # + x = self.memory['x'] + + grad_x = (1/(x + self.epsilon)) + + grad_x = grad_x*grad_y + + + #################### + + return grad_x + + +class Softmax(NumpyOp): + """ + softmax over last dimension + """ + + def forward(self, x): + """ + x: shape(N, c) + """ + + #################### + # code 4 # + + out = np.array(x, copy="true") + + + result_list=[] + + for m in range(len(out)): + result_list.append(sum(np.exp(out[m]))) + + for m in range(len(out)): + for n in range(len(out[0])): + out[m][n]= np.exp(out[m][n]) / result_list[m] + + self.memory['x'] = x + + #################### + + return out + + + + def backward(self, grad_y): + + """ + grad_y: same shape as x + """ + + + + #################### + # code 5 # + + x = self.memory['x'] + softx = self.forward(x) + [n, m] = x.shape + out = [] + for i in range(n): + out.append([]) + for j in range(m): + out[i].append(0) + for k in range(m): + if j == k: + out[i][j] += (1 - softx[i][k]) * softx[i][k] * grad_y[i][k] + else: + out[i][j] += -softx[i][j] * softx[i][k] * grad_y[i][k] + grad_x = np.array(out) + + + + + #################### + + return grad_x + + +class NumpyLoss: + + def __init__(self): + self.target = None + + def get_loss(self, pred, target): + self.target = target + return (-pred * target).sum(axis=1).mean() + + def backward(self): + return -self.target / self.target.shape[0] + + +class NumpyModel: + def __init__(self): + self.W1 = np.random.normal(size=(28 * 28, 256)) + self.W2 = np.random.normal(size=(256, 64)) + self.W3 = np.random.normal(size=(64, 10)) + + # 以下算子会在 forward 和 backward 中使用 + self.matmul_1 = Matmul() + self.relu_1 = Relu() + self.matmul_2 = Matmul() + self.relu_2 = Relu() + self.matmul_3 = Matmul() + self.softmax = Softmax() + self.log = Log() + + # 以下变量需要在 backward 中更新。 softmax_grad, log_grad 等为算子反向传播的梯度( loss 关于算子输入的偏导) + self.x1_grad, self.W1_grad = None, None + self.relu_1_grad = None + self.x2_grad, self.W2_grad = None, None + self.relu_2_grad = None + self.x3_grad, self.W3_grad = None, None + self.softmax_grad = None + self.log_grad = None + + def forward(self, x): + x = x.reshape(-1, 28 * 28) + + #################### + # code 6 # + #x = torch.relu(torch.matmul(x, self.W1)) + x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) + + #x = torch.relu(torch.matmul(x, self.W2)) + x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) + + #x = torch.matmul(x, self.W3) + #x = torch.softmax(x, 1) + x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) + + #x = torch.log(x) + x = self.log.forward(x) + + #################### + + return x + + def backward(self, y): + + #################### + # code 7 # + + self.log_grad = self.log.backward(y) + + self.softmax_grad = self.softmax.backward(self.log_grad) + + self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) + + self.relu_2_grad = self.relu_2.backward(self.x3_grad) + + self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) + + self.relu_1_grad = self.relu_1.backward(self.x2_grad) + + self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) + + + + #################### + + pass + + def optimize(self, learning_rate): + self.W1 -= learning_rate * self.W1_grad + self.W2 -= learning_rate * self.W2_grad + self.W3 -= learning_rate * self.W3_grad \ No newline at end of file -- Gitee From 6e49ac116d333d1a7927f79719dc2ae9e9aeb98e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:21:01 +0800 Subject: [PATCH 64/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/submission/assignment-2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../submission/assignment-2/numpy_fnn.py | 249 ------------------ 1 file changed, 249 deletions(-) delete mode 100644 assignment-2/submission/assignment-2/numpy_fnn.py diff --git a/assignment-2/submission/assignment-2/numpy_fnn.py b/assignment-2/submission/assignment-2/numpy_fnn.py deleted file mode 100644 index 7f48bcd..0000000 --- a/assignment-2/submission/assignment-2/numpy_fnn.py +++ /dev/null @@ -1,249 +0,0 @@ -import numpy as np - - -class NumpyOp: - - def __init__(self): - self.memory = {} - self.epsilon = 1e-12 - - -class Matmul(NumpyOp): - - def forward(self, x, W): - """ - x: shape(N, d) - w: shape(d, d') - """ - self.memory['x'] = x - self.memory['W'] = W - h = np.matmul(x, W) - return h - - def backward(self, grad_y): - """ - grad_y: shape(N, d') - """ - - #################### - # code 1 # - x = self.memory['x'] - W = self.memory['W'] - - grad_W = np.matmul(x.T,grad_y) - grad_x = np.matmul(grad_y,W.T) - #################### - - return grad_x, grad_W - - -class Relu(NumpyOp): - - def forward(self, x): - self.memory['x'] = x - return np.where(x > 0, x, np.zeros_like(x)) - - def backward(self, grad_y): - """ - grad_y: same shape as x - """ - - #################### - # code 2 # - x = self.memory['x'] - - grad_x = np.where(x > 0, 1, 0) - - grad_x = grad_x * grad_y - - #################### - - return grad_x - - -class Log(NumpyOp): - - def forward(self, x): - """ - x: shape(N, c) - """ - - out = np.log(x + self.epsilon) - self.memory['x'] = x - - return out - - def backward(self, grad_y): - """ - grad_y: same shape as x - """ - - #################### - # code 3 # - x = self.memory['x'] - - grad_x = (1/(x + self.epsilon)) - - grad_x = grad_x*grad_y - - - #################### - - return grad_x - - -class Softmax(NumpyOp): - """ - softmax over last dimension - """ - - def forward(self, x): - """ - x: shape(N, c) - """ - - #################### - # code 4 # - - out = np.array(x, copy="true") - - - result_list=[] - - for m in range(len(out)): - result_list.append(sum(np.exp(out[m]))) - - for m in range(len(out)): - for n in range(len(out[0])): - out[m][n]= np.exp(out[m][n]) / result_list[m] - - self.memory['x'] = x - - #################### - - return out - - - - def backward(self, grad_y): - - """ - grad_y: same shape as x - """ - - - - #################### - # code 5 # - - x = self.memory['x'] - softx = self.forward(x) - [n, m] = x.shape - out = [] - for i in range(n): - out.append([]) - for j in range(m): - out[i].append(0) - for k in range(m): - if j == k: - out[i][j] += (1 - softx[i][k]) * softx[i][k] * grad_y[i][k] - else: - out[i][j] += -softx[i][j] * softx[i][k] * grad_y[i][k] - grad_x = np.array(out) - - - - - #################### - - return grad_x - - -class NumpyLoss: - - def __init__(self): - self.target = None - - def get_loss(self, pred, target): - self.target = target - return (-pred * target).sum(axis=1).mean() - - def backward(self): - return -self.target / self.target.shape[0] - - -class NumpyModel: - def __init__(self): - self.W1 = np.random.normal(size=(28 * 28, 256)) - self.W2 = np.random.normal(size=(256, 64)) - self.W3 = np.random.normal(size=(64, 10)) - - # 以下算子会在 forward 和 backward 中使用 - self.matmul_1 = Matmul() - self.relu_1 = Relu() - self.matmul_2 = Matmul() - self.relu_2 = Relu() - self.matmul_3 = Matmul() - self.softmax = Softmax() - self.log = Log() - - # 以下变量需要在 backward 中更新。 softmax_grad, log_grad 等为算子反向传播的梯度( loss 关于算子输入的偏导) - self.x1_grad, self.W1_grad = None, None - self.relu_1_grad = None - self.x2_grad, self.W2_grad = None, None - self.relu_2_grad = None - self.x3_grad, self.W3_grad = None, None - self.softmax_grad = None - self.log_grad = None - - def forward(self, x): - x = x.reshape(-1, 28 * 28) - - #################### - # code 6 # - #x = torch.relu(torch.matmul(x, self.W1)) - x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) - - #x = torch.relu(torch.matmul(x, self.W2)) - x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) - - #x = torch.matmul(x, self.W3) - #x = torch.softmax(x, 1) - x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) - - #x = torch.log(x) - x = self.log.forward(x) - - #################### - - return x - - def backward(self, y): - - #################### - # code 7 # - - self.log_grad = self.log.backward(y) - - self.softmax_grad = self.softmax.backward(self.log_grad) - - self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) - - self.relu_2_grad = self.relu_2.backward(self.x3_grad) - - self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) - - self.relu_1_grad = self.relu_1.backward(self.x2_grad) - - self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) - - - - #################### - - pass - - def optimize(self, learning_rate): - self.W1 -= learning_rate * self.W1_grad - self.W2 -= learning_rate * self.W2_grad - self.W3 -= learning_rate * self.W3_grad \ No newline at end of file -- Gitee From 121ab91d1cd072097be024e26ac8d956b4e905a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:21:07 +0800 Subject: [PATCH 65/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/submission/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/submission/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 assignment-2/submission/.keep diff --git a/assignment-2/submission/.keep b/assignment-2/submission/.keep deleted file mode 100644 index e69de29..0000000 -- Gitee From 8ab7d290014888a75155928cc93dbb8857f6f4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:21:29 +0800 Subject: [PATCH 66/84] add assignment-2/submission/numpy_fnn.py. --- assignment-2/submission/numpy_fnn.py | 249 +++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 assignment-2/submission/numpy_fnn.py diff --git a/assignment-2/submission/numpy_fnn.py b/assignment-2/submission/numpy_fnn.py new file mode 100644 index 0000000..7f48bcd --- /dev/null +++ b/assignment-2/submission/numpy_fnn.py @@ -0,0 +1,249 @@ +import numpy as np + + +class NumpyOp: + + def __init__(self): + self.memory = {} + self.epsilon = 1e-12 + + +class Matmul(NumpyOp): + + def forward(self, x, W): + """ + x: shape(N, d) + w: shape(d, d') + """ + self.memory['x'] = x + self.memory['W'] = W + h = np.matmul(x, W) + return h + + def backward(self, grad_y): + """ + grad_y: shape(N, d') + """ + + #################### + # code 1 # + x = self.memory['x'] + W = self.memory['W'] + + grad_W = np.matmul(x.T,grad_y) + grad_x = np.matmul(grad_y,W.T) + #################### + + return grad_x, grad_W + + +class Relu(NumpyOp): + + def forward(self, x): + self.memory['x'] = x + return np.where(x > 0, x, np.zeros_like(x)) + + def backward(self, grad_y): + """ + grad_y: same shape as x + """ + + #################### + # code 2 # + x = self.memory['x'] + + grad_x = np.where(x > 0, 1, 0) + + grad_x = grad_x * grad_y + + #################### + + return grad_x + + +class Log(NumpyOp): + + def forward(self, x): + """ + x: shape(N, c) + """ + + out = np.log(x + self.epsilon) + self.memory['x'] = x + + return out + + def backward(self, grad_y): + """ + grad_y: same shape as x + """ + + #################### + # code 3 # + x = self.memory['x'] + + grad_x = (1/(x + self.epsilon)) + + grad_x = grad_x*grad_y + + + #################### + + return grad_x + + +class Softmax(NumpyOp): + """ + softmax over last dimension + """ + + def forward(self, x): + """ + x: shape(N, c) + """ + + #################### + # code 4 # + + out = np.array(x, copy="true") + + + result_list=[] + + for m in range(len(out)): + result_list.append(sum(np.exp(out[m]))) + + for m in range(len(out)): + for n in range(len(out[0])): + out[m][n]= np.exp(out[m][n]) / result_list[m] + + self.memory['x'] = x + + #################### + + return out + + + + def backward(self, grad_y): + + """ + grad_y: same shape as x + """ + + + + #################### + # code 5 # + + x = self.memory['x'] + softx = self.forward(x) + [n, m] = x.shape + out = [] + for i in range(n): + out.append([]) + for j in range(m): + out[i].append(0) + for k in range(m): + if j == k: + out[i][j] += (1 - softx[i][k]) * softx[i][k] * grad_y[i][k] + else: + out[i][j] += -softx[i][j] * softx[i][k] * grad_y[i][k] + grad_x = np.array(out) + + + + + #################### + + return grad_x + + +class NumpyLoss: + + def __init__(self): + self.target = None + + def get_loss(self, pred, target): + self.target = target + return (-pred * target).sum(axis=1).mean() + + def backward(self): + return -self.target / self.target.shape[0] + + +class NumpyModel: + def __init__(self): + self.W1 = np.random.normal(size=(28 * 28, 256)) + self.W2 = np.random.normal(size=(256, 64)) + self.W3 = np.random.normal(size=(64, 10)) + + # 以下算子会在 forward 和 backward 中使用 + self.matmul_1 = Matmul() + self.relu_1 = Relu() + self.matmul_2 = Matmul() + self.relu_2 = Relu() + self.matmul_3 = Matmul() + self.softmax = Softmax() + self.log = Log() + + # 以下变量需要在 backward 中更新。 softmax_grad, log_grad 等为算子反向传播的梯度( loss 关于算子输入的偏导) + self.x1_grad, self.W1_grad = None, None + self.relu_1_grad = None + self.x2_grad, self.W2_grad = None, None + self.relu_2_grad = None + self.x3_grad, self.W3_grad = None, None + self.softmax_grad = None + self.log_grad = None + + def forward(self, x): + x = x.reshape(-1, 28 * 28) + + #################### + # code 6 # + #x = torch.relu(torch.matmul(x, self.W1)) + x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) + + #x = torch.relu(torch.matmul(x, self.W2)) + x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) + + #x = torch.matmul(x, self.W3) + #x = torch.softmax(x, 1) + x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) + + #x = torch.log(x) + x = self.log.forward(x) + + #################### + + return x + + def backward(self, y): + + #################### + # code 7 # + + self.log_grad = self.log.backward(y) + + self.softmax_grad = self.softmax.backward(self.log_grad) + + self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) + + self.relu_2_grad = self.relu_2.backward(self.x3_grad) + + self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) + + self.relu_1_grad = self.relu_1.backward(self.x2_grad) + + self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) + + + + #################### + + pass + + def optimize(self, learning_rate): + self.W1 -= learning_rate * self.W1_grad + self.W2 -= learning_rate * self.W2_grad + self.W3 -= learning_rate * self.W3_grad \ No newline at end of file -- Gitee From cda6edb4f818cee09a27b21c5398b560ed89dbfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:21:56 +0800 Subject: [PATCH 67/84] add assignment-2/submission/numpy_mnist.py. --- assignment-2/submission/numpy_mnist.py | 58 ++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 assignment-2/submission/numpy_mnist.py diff --git a/assignment-2/submission/numpy_mnist.py b/assignment-2/submission/numpy_mnist.py new file mode 100644 index 0000000..833e5aa --- /dev/null +++ b/assignment-2/submission/numpy_mnist.py @@ -0,0 +1,58 @@ +import numpy as np +from numpy_fnn import NumpyModel, NumpyLoss +from utils import download_mnist, batch, get_torch_initialization, plot_curve, one_hot + +def mini_batch(dataset, batch_size=128, numpy=False): + + data = [] + label = [] + for each in dataset: + data.append(np.array(each[0])) + label.append(each[1]) + + data = np.array(data) + label = np.array(label) + + res = [] + + + for start_idx in range(0, data.shape[0], batch_size): + end_idx = min(start_idx + batch_size, len(data)) + res.append((data[start_idx:end_idx],label[start_idx:end_idx])) + + return res + + +def numpy_run(): + train_dataset, test_dataset = download_mnist() + + model = NumpyModel() + numpy_loss = NumpyLoss() + model.W1, model.W2, model.W3 = get_torch_initialization() + + train_loss = [] + + epoch_number = 3 + learning_rate = 0.1 + + for epoch in range(epoch_number): + for x, y in mini_batch(train_dataset): + y = one_hot(y) + + y_pred = model.forward(x) + loss = numpy_loss.get_loss(y_pred, y) + + model.backward(numpy_loss.backward()) + model.optimize(learning_rate) + + train_loss.append(loss.item()) + + x, y = batch(test_dataset)[0] + accuracy = np.mean((model.forward(x).argmax(axis=1) == y)) + print('[{}] Accuracy: {:.4f}'.format(epoch, accuracy)) + + plot_curve(train_loss) + + +if __name__ == "__main__": + numpy_run() \ No newline at end of file -- Gitee From d61dc27d2ca729a94196a033a62e287ac2f75326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:22:14 +0800 Subject: [PATCH 68/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 assignment-2/.keep diff --git a/assignment-2/.keep b/assignment-2/.keep deleted file mode 100644 index e69de29..0000000 -- Gitee From dae7f126db9b777f53fb38fab8ecfa74a039ca8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:22:45 +0800 Subject: [PATCH 69/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/README.md | 183 ----------------------------------------- 1 file changed, 183 deletions(-) delete mode 100644 assignment-2/README.md diff --git a/assignment-2/README.md b/assignment-2/README.md deleted file mode 100644 index 827aa9f..0000000 --- a/assignment-2/README.md +++ /dev/null @@ -1,183 +0,0 @@ -**1. Mini-batch 函数的实现** - -``` -def mini_batch(dataset, batch_size=128, numpy=False): - -# 仿照batch函数分离data与label - data = [] - label = [] - for each in dataset: - data.append(np.array(each[0])) - label.append(each[1]) - - data = np.array(data) - label = np.array(label) - - - res = [] - -# 以batch_size为单位,从[0,len(data)]分割mini-batch - for start_idx in range(0, data.shape[0], batch_size): - end_idx = min(start_idx + batch_size, len(data)) - res.append((data[start_idx:end_idx],label[start_idx:end_idx])) - - return res -``` - - **2. 模型的训练和测试** - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/113123_f204953a_8823823.png "processon.png") - -``` - # 前向传播过程 - def forward(self, x): - x = x.reshape(-1, 28 * 28) - - #################### - # code 6 # - - #x = torch.relu(torch.matmul(x, self.W1)) - # 模仿torch的relu(Matmul.(x,w1))操作,下同 - x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) - - #x = torch.relu(torch.matmul(x, self.W2)) - x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) - - #x = torch.matmul(x, self.W3) - #x = torch.softmax(x, 1) - x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) - - #x = torch.log(x) - x = self.log.forward(x) - - #################### - - return x - - # 反向传播过程 - def backward(self, y): - - #################### - # code 7 # - - self.log_grad = self.log.backward(y) - - self.softmax_grad = self.softmax.backward(self.log_grad) - - self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) - - self.relu_2_grad = self.relu_2.backward(self.x3_grad) - - self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) - - self.relu_1_grad = self.relu_1.backward(self.x2_grad) - - self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) - - - - #################### - - pass -``` - - - - - -| Epoch | Batch_size | -| ---------------- | ------ | -| 3 | 16 | -| 10 | 128 | - - -* Epoch = 3 Batch_size=128 - -[0] Accuracy: 0.9373 -
[1] Accuracy: 0.9583 -
[2] Accuracy: 0.9683 - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/102618_2f8a1661_8823823.png "3-128.png") - - - -* Epoch = 3 Batch_size=16 - -[0] Accuracy: 0.9640 -
[1] Accuracy: 0.9676 -
[2] Accuracy: 0.9707 - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/103502_131ca59f_8823823.png "3-16.png") - -* Epoch = 10 Batch_size=16 - -[0] Accuracy: 0.9602 -
[1] Accuracy: 0.9657 -
[2] Accuracy: 0.9741 -
[3] Accuracy: 0.9747 -
[4] Accuracy: 0.9701 -
[5] Accuracy: 0.9731 -
[6] Accuracy: 0.9760 -
[7] Accuracy: 0.9763 -
[8] Accuracy: 0.9760 -
[9] Accuracy: 0.9780 - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/105531_82cafce0_8823823.png "10-16.png") - - -* Epoch = 10 Batch_size=128 - -[0] Accuracy: 0.9389 -
[1] Accuracy: 0.9585 -
[2] Accuracy: 0.9679 -
[3] Accuracy: 0.9706 -
[4] Accuracy: 0.9746 -
[5] Accuracy: 0.9760 -
[6] Accuracy: 0.9769 -
[7] Accuracy: 0.9777 -
[8] Accuracy: 0.9781 -
[9] Accuracy: 0.9781 - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/111052_ddb4ecda_8823823.png "10-128.png") - - - -*探究发现* -1. mini-batch size太小的情况下,模型的波动率非常高,并不是对batch_size越细分模型的准确率就越高 -2. 从epoch的数量上来看,epoch的数量与模型accuracy有正相关性 - - - **3.Momentum 优化函数下的对比试验** - - -``` - # 利用momentum优化下的optimize函数 - def optimize(self, learning_rate): - - # 初始化V值 - v1=0 - v2=0 - v3=0 - mu=0.9 - - # momentum下的更新算法 - v1 = mu * v1 - learning_rate * self.W1_grad - self.W1 = self.W1 + v1 - - v2 = mu * v2 - learning_rate * self.W2_grad - self.W2 = self.W2 + v2 - - v3 = mu * v3 - learning_rate * self.W3_grad - self.W3 = self.W3 + v3 - - - #self.W1 -= learning_rate * self.W1_grad - # self.W2 -= learning_rate * self.W2_grad - #self.W3 -= learning_rate * self.W3_grad -``` - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/115301_1fa39f2b_8823823.png "屏幕截图.png") - -1. 在我们的测试数据下,momentum与梯度下降模型准确率差异不大 -2. momentum模型主要用来解决全局最优与局部最优之间的差异,但在本测试集下不存在全局与局部的差异 -3. 理论上来说,当 momentum 动量越大时,其转换为势能的能量也就越大,就越有可能摆脱局部凹域的束缚,进入全局凹域 \ No newline at end of file -- Gitee From 9cb49c85bc07a789ad43b8a390cec684f2383dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:22:53 +0800 Subject: [PATCH 70/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/numpy=5Ffnn.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/numpy_fnn.py | 249 -------------------------------------- 1 file changed, 249 deletions(-) delete mode 100644 assignment-2/numpy_fnn.py diff --git a/assignment-2/numpy_fnn.py b/assignment-2/numpy_fnn.py deleted file mode 100644 index 7f48bcd..0000000 --- a/assignment-2/numpy_fnn.py +++ /dev/null @@ -1,249 +0,0 @@ -import numpy as np - - -class NumpyOp: - - def __init__(self): - self.memory = {} - self.epsilon = 1e-12 - - -class Matmul(NumpyOp): - - def forward(self, x, W): - """ - x: shape(N, d) - w: shape(d, d') - """ - self.memory['x'] = x - self.memory['W'] = W - h = np.matmul(x, W) - return h - - def backward(self, grad_y): - """ - grad_y: shape(N, d') - """ - - #################### - # code 1 # - x = self.memory['x'] - W = self.memory['W'] - - grad_W = np.matmul(x.T,grad_y) - grad_x = np.matmul(grad_y,W.T) - #################### - - return grad_x, grad_W - - -class Relu(NumpyOp): - - def forward(self, x): - self.memory['x'] = x - return np.where(x > 0, x, np.zeros_like(x)) - - def backward(self, grad_y): - """ - grad_y: same shape as x - """ - - #################### - # code 2 # - x = self.memory['x'] - - grad_x = np.where(x > 0, 1, 0) - - grad_x = grad_x * grad_y - - #################### - - return grad_x - - -class Log(NumpyOp): - - def forward(self, x): - """ - x: shape(N, c) - """ - - out = np.log(x + self.epsilon) - self.memory['x'] = x - - return out - - def backward(self, grad_y): - """ - grad_y: same shape as x - """ - - #################### - # code 3 # - x = self.memory['x'] - - grad_x = (1/(x + self.epsilon)) - - grad_x = grad_x*grad_y - - - #################### - - return grad_x - - -class Softmax(NumpyOp): - """ - softmax over last dimension - """ - - def forward(self, x): - """ - x: shape(N, c) - """ - - #################### - # code 4 # - - out = np.array(x, copy="true") - - - result_list=[] - - for m in range(len(out)): - result_list.append(sum(np.exp(out[m]))) - - for m in range(len(out)): - for n in range(len(out[0])): - out[m][n]= np.exp(out[m][n]) / result_list[m] - - self.memory['x'] = x - - #################### - - return out - - - - def backward(self, grad_y): - - """ - grad_y: same shape as x - """ - - - - #################### - # code 5 # - - x = self.memory['x'] - softx = self.forward(x) - [n, m] = x.shape - out = [] - for i in range(n): - out.append([]) - for j in range(m): - out[i].append(0) - for k in range(m): - if j == k: - out[i][j] += (1 - softx[i][k]) * softx[i][k] * grad_y[i][k] - else: - out[i][j] += -softx[i][j] * softx[i][k] * grad_y[i][k] - grad_x = np.array(out) - - - - - #################### - - return grad_x - - -class NumpyLoss: - - def __init__(self): - self.target = None - - def get_loss(self, pred, target): - self.target = target - return (-pred * target).sum(axis=1).mean() - - def backward(self): - return -self.target / self.target.shape[0] - - -class NumpyModel: - def __init__(self): - self.W1 = np.random.normal(size=(28 * 28, 256)) - self.W2 = np.random.normal(size=(256, 64)) - self.W3 = np.random.normal(size=(64, 10)) - - # 以下算子会在 forward 和 backward 中使用 - self.matmul_1 = Matmul() - self.relu_1 = Relu() - self.matmul_2 = Matmul() - self.relu_2 = Relu() - self.matmul_3 = Matmul() - self.softmax = Softmax() - self.log = Log() - - # 以下变量需要在 backward 中更新。 softmax_grad, log_grad 等为算子反向传播的梯度( loss 关于算子输入的偏导) - self.x1_grad, self.W1_grad = None, None - self.relu_1_grad = None - self.x2_grad, self.W2_grad = None, None - self.relu_2_grad = None - self.x3_grad, self.W3_grad = None, None - self.softmax_grad = None - self.log_grad = None - - def forward(self, x): - x = x.reshape(-1, 28 * 28) - - #################### - # code 6 # - #x = torch.relu(torch.matmul(x, self.W1)) - x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) - - #x = torch.relu(torch.matmul(x, self.W2)) - x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) - - #x = torch.matmul(x, self.W3) - #x = torch.softmax(x, 1) - x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) - - #x = torch.log(x) - x = self.log.forward(x) - - #################### - - return x - - def backward(self, y): - - #################### - # code 7 # - - self.log_grad = self.log.backward(y) - - self.softmax_grad = self.softmax.backward(self.log_grad) - - self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) - - self.relu_2_grad = self.relu_2.backward(self.x3_grad) - - self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) - - self.relu_1_grad = self.relu_1.backward(self.x2_grad) - - self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) - - - - #################### - - pass - - def optimize(self, learning_rate): - self.W1 -= learning_rate * self.W1_grad - self.W2 -= learning_rate * self.W2_grad - self.W3 -= learning_rate * self.W3_grad \ No newline at end of file -- Gitee From acbf2200229d4e565447acbf88b4fd69ccd3cea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:23:07 +0800 Subject: [PATCH 71/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/numpy=5Fmnist.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/numpy_mnist.py | 58 ------------------------------------- 1 file changed, 58 deletions(-) delete mode 100644 assignment-2/numpy_mnist.py diff --git a/assignment-2/numpy_mnist.py b/assignment-2/numpy_mnist.py deleted file mode 100644 index 833e5aa..0000000 --- a/assignment-2/numpy_mnist.py +++ /dev/null @@ -1,58 +0,0 @@ -import numpy as np -from numpy_fnn import NumpyModel, NumpyLoss -from utils import download_mnist, batch, get_torch_initialization, plot_curve, one_hot - -def mini_batch(dataset, batch_size=128, numpy=False): - - data = [] - label = [] - for each in dataset: - data.append(np.array(each[0])) - label.append(each[1]) - - data = np.array(data) - label = np.array(label) - - res = [] - - - for start_idx in range(0, data.shape[0], batch_size): - end_idx = min(start_idx + batch_size, len(data)) - res.append((data[start_idx:end_idx],label[start_idx:end_idx])) - - return res - - -def numpy_run(): - train_dataset, test_dataset = download_mnist() - - model = NumpyModel() - numpy_loss = NumpyLoss() - model.W1, model.W2, model.W3 = get_torch_initialization() - - train_loss = [] - - epoch_number = 3 - learning_rate = 0.1 - - for epoch in range(epoch_number): - for x, y in mini_batch(train_dataset): - y = one_hot(y) - - y_pred = model.forward(x) - loss = numpy_loss.get_loss(y_pred, y) - - model.backward(numpy_loss.backward()) - model.optimize(learning_rate) - - train_loss.append(loss.item()) - - x, y = batch(test_dataset)[0] - accuracy = np.mean((model.forward(x).argmax(axis=1) == y)) - print('[{}] Accuracy: {:.4f}'.format(epoch, accuracy)) - - plot_curve(train_loss) - - -if __name__ == "__main__": - numpy_run() \ No newline at end of file -- Gitee From 4c08c606bcf6b4920e85efc4207735ffdb22f00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:23:18 +0800 Subject: [PATCH 72/84] =?UTF-8?q?=E6=96=B0=E5=BB=BA=2018340246016?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/submission/18340246016/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-2/submission/18340246016/.keep diff --git a/assignment-2/submission/18340246016/.keep b/assignment-2/submission/18340246016/.keep new file mode 100644 index 0000000..e69de29 -- Gitee From eba8f7486ce326563afca56f95914c6c4385490f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:25:00 +0800 Subject: [PATCH 73/84] add assignment-2/submission/18340246016/README.md. --- assignment-2/submission/18340246016/README.md | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 assignment-2/submission/18340246016/README.md diff --git a/assignment-2/submission/18340246016/README.md b/assignment-2/submission/18340246016/README.md new file mode 100644 index 0000000..be11b1d --- /dev/null +++ b/assignment-2/submission/18340246016/README.md @@ -0,0 +1,183 @@ +**1. Mini-batch 函数的实现** + +``` +def mini_batch(dataset, batch_size=128, numpy=False): + +# 仿照batch函数分离data与label + data = [] + label = [] + for each in dataset: + data.append(np.array(each[0])) + label.append(each[1]) + + data = np.array(data) + label = np.array(label) + + + res = [] + +# 以batch_size为单位,从[0,len(data)]分割mini-batch + for start_idx in range(0, data.shape[0], batch_size): + end_idx = min(start_idx + batch_size, len(data)) + res.append((data[start_idx:end_idx],label[start_idx:end_idx])) + + return res +``` + + **2. 模型的训练和测试** + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/113123_f204953a_8823823.png "processon.png") + +``` + # 前向传播过程 + def forward(self, x): + x = x.reshape(-1, 28 * 28) + + #################### + # code 6 # + + #x = torch.relu(torch.matmul(x, self.W1)) + # 模仿torch的relu(Matmul.(x,w1))操作,下同 + x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) + + #x = torch.relu(torch.matmul(x, self.W2)) + x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) + + #x = torch.matmul(x, self.W3) + #x = torch.softmax(x, 1) + x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) + + #x = torch.log(x) + x = self.log.forward(x) + + #################### + + return x + + # 反向传播过程 + def backward(self, y): + + #################### + # code 7 # + + self.log_grad = self.log.backward(y) + + self.softmax_grad = self.softmax.backward(self.log_grad) + + self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) + + self.relu_2_grad = self.relu_2.backward(self.x3_grad) + + self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) + + self.relu_1_grad = self.relu_1.backward(self.x2_grad) + + self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) + + + + #################### + + pass +``` + + + + + +| Epoch | Batch_size | +| ---------------- | ------ | +| 3 | 16 | +| 10 | 128 | + + +* Epoch = 3 Batch_size=128 + +[0] Accuracy: 0.9373 +
[1] Accuracy: 0.9583 +
[2] Accuracy: 0.9683 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/102618_2f8a1661_8823823.png "3-128.png") + + + +* Epoch = 3 Batch_size=16 + +[0] Accuracy: 0.9640 +
[1] Accuracy: 0.9676 +
[2] Accuracy: 0.9707 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/103502_131ca59f_8823823.png "3-16.png") + +* Epoch = 10 Batch_size=16 + +[0] Accuracy: 0.9602 +
[1] Accuracy: 0.9657 +
[2] Accuracy: 0.9741 +
[3] Accuracy: 0.9747 +
[4] Accuracy: 0.9701 +
[5] Accuracy: 0.9731 +
[6] Accuracy: 0.9760 +
[7] Accuracy: 0.9763 +
[8] Accuracy: 0.9760 +
[9] Accuracy: 0.9780 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/105531_82cafce0_8823823.png "10-16.png") + + +* Epoch = 10 Batch_size=128 + +[0] Accuracy: 0.9389 +
[1] Accuracy: 0.9585 +
[2] Accuracy: 0.9679 +
[3] Accuracy: 0.9706 +
[4] Accuracy: 0.9746 +
[5] Accuracy: 0.9760 +
[6] Accuracy: 0.9769 +
[7] Accuracy: 0.9777 +
[8] Accuracy: 0.9781 +
[9] Accuracy: 0.9781 + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/111052_ddb4ecda_8823823.png "10-128.png") + + + +*探究发现* +1. mini-batch size太小的情况下,模型的波动率非常高,并不是对batch_size越细分模型的准确率就越高 +2. 从epoch的数量上来看,epoch的数量与模型accuracy有正相关性 + + + **3.Momentum 优化函数下的对比试验** + + +``` + # 利用momentum优化下的optimize函数 + def optimize(self, learning_rate): + + # 初始化V值 + v1=0 + v2=0 + v3=0 + mu=0.9 + + # momentum下的更新算法 + v1 = mu * v1 - learning_rate * self.W1_grad + self.W1 = self.W1 + v1 + + v2 = mu * v2 - learning_rate * self.W2_grad + self.W2 = self.W2 + v2 + + v3 = mu * v3 - learning_rate * self.W3_grad + self.W3 = self.W3 + v3 + + + #self.W1 -= learning_rate * self.W1_grad + # self.W2 -= learning_rate * self.W2_grad + #self.W3 -= learning_rate * self.W3_grad +``` + +![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/115301_1fa39f2b_8823823.png "屏幕截图.png") + +1. 在我们的测试数据下,momentum与梯度下降模型准确率差异不大 +2. momentum模型主要用来解决全局最优与局部最优之间的差异,但在本测试集下不存在全局与局部的差异 +3. 理论上来说,当 momentum 动量越大时,其转换为势能的能量也就越大,就越有可能摆脱局部凹域的束缚,进入全局凹域 \ No newline at end of file -- Gitee From b302284b2cf17d7a85c049e032b02d3da57dad0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:25:30 +0800 Subject: [PATCH 74/84] add assignment-2/submission/18340246016/assignment-2/submission/numpy_fnn.py. --- .../assignment-2/submission/numpy_fnn.py | 249 ++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 assignment-2/submission/18340246016/assignment-2/submission/numpy_fnn.py diff --git a/assignment-2/submission/18340246016/assignment-2/submission/numpy_fnn.py b/assignment-2/submission/18340246016/assignment-2/submission/numpy_fnn.py new file mode 100644 index 0000000..7f48bcd --- /dev/null +++ b/assignment-2/submission/18340246016/assignment-2/submission/numpy_fnn.py @@ -0,0 +1,249 @@ +import numpy as np + + +class NumpyOp: + + def __init__(self): + self.memory = {} + self.epsilon = 1e-12 + + +class Matmul(NumpyOp): + + def forward(self, x, W): + """ + x: shape(N, d) + w: shape(d, d') + """ + self.memory['x'] = x + self.memory['W'] = W + h = np.matmul(x, W) + return h + + def backward(self, grad_y): + """ + grad_y: shape(N, d') + """ + + #################### + # code 1 # + x = self.memory['x'] + W = self.memory['W'] + + grad_W = np.matmul(x.T,grad_y) + grad_x = np.matmul(grad_y,W.T) + #################### + + return grad_x, grad_W + + +class Relu(NumpyOp): + + def forward(self, x): + self.memory['x'] = x + return np.where(x > 0, x, np.zeros_like(x)) + + def backward(self, grad_y): + """ + grad_y: same shape as x + """ + + #################### + # code 2 # + x = self.memory['x'] + + grad_x = np.where(x > 0, 1, 0) + + grad_x = grad_x * grad_y + + #################### + + return grad_x + + +class Log(NumpyOp): + + def forward(self, x): + """ + x: shape(N, c) + """ + + out = np.log(x + self.epsilon) + self.memory['x'] = x + + return out + + def backward(self, grad_y): + """ + grad_y: same shape as x + """ + + #################### + # code 3 # + x = self.memory['x'] + + grad_x = (1/(x + self.epsilon)) + + grad_x = grad_x*grad_y + + + #################### + + return grad_x + + +class Softmax(NumpyOp): + """ + softmax over last dimension + """ + + def forward(self, x): + """ + x: shape(N, c) + """ + + #################### + # code 4 # + + out = np.array(x, copy="true") + + + result_list=[] + + for m in range(len(out)): + result_list.append(sum(np.exp(out[m]))) + + for m in range(len(out)): + for n in range(len(out[0])): + out[m][n]= np.exp(out[m][n]) / result_list[m] + + self.memory['x'] = x + + #################### + + return out + + + + def backward(self, grad_y): + + """ + grad_y: same shape as x + """ + + + + #################### + # code 5 # + + x = self.memory['x'] + softx = self.forward(x) + [n, m] = x.shape + out = [] + for i in range(n): + out.append([]) + for j in range(m): + out[i].append(0) + for k in range(m): + if j == k: + out[i][j] += (1 - softx[i][k]) * softx[i][k] * grad_y[i][k] + else: + out[i][j] += -softx[i][j] * softx[i][k] * grad_y[i][k] + grad_x = np.array(out) + + + + + #################### + + return grad_x + + +class NumpyLoss: + + def __init__(self): + self.target = None + + def get_loss(self, pred, target): + self.target = target + return (-pred * target).sum(axis=1).mean() + + def backward(self): + return -self.target / self.target.shape[0] + + +class NumpyModel: + def __init__(self): + self.W1 = np.random.normal(size=(28 * 28, 256)) + self.W2 = np.random.normal(size=(256, 64)) + self.W3 = np.random.normal(size=(64, 10)) + + # 以下算子会在 forward 和 backward 中使用 + self.matmul_1 = Matmul() + self.relu_1 = Relu() + self.matmul_2 = Matmul() + self.relu_2 = Relu() + self.matmul_3 = Matmul() + self.softmax = Softmax() + self.log = Log() + + # 以下变量需要在 backward 中更新。 softmax_grad, log_grad 等为算子反向传播的梯度( loss 关于算子输入的偏导) + self.x1_grad, self.W1_grad = None, None + self.relu_1_grad = None + self.x2_grad, self.W2_grad = None, None + self.relu_2_grad = None + self.x3_grad, self.W3_grad = None, None + self.softmax_grad = None + self.log_grad = None + + def forward(self, x): + x = x.reshape(-1, 28 * 28) + + #################### + # code 6 # + #x = torch.relu(torch.matmul(x, self.W1)) + x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) + + #x = torch.relu(torch.matmul(x, self.W2)) + x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) + + #x = torch.matmul(x, self.W3) + #x = torch.softmax(x, 1) + x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) + + #x = torch.log(x) + x = self.log.forward(x) + + #################### + + return x + + def backward(self, y): + + #################### + # code 7 # + + self.log_grad = self.log.backward(y) + + self.softmax_grad = self.softmax.backward(self.log_grad) + + self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) + + self.relu_2_grad = self.relu_2.backward(self.x3_grad) + + self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) + + self.relu_1_grad = self.relu_1.backward(self.x2_grad) + + self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) + + + + #################### + + pass + + def optimize(self, learning_rate): + self.W1 -= learning_rate * self.W1_grad + self.W2 -= learning_rate * self.W2_grad + self.W3 -= learning_rate * self.W3_grad \ No newline at end of file -- Gitee From 8a602e23c34830acabd2c7d4a661dbb143a7cf2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:25:55 +0800 Subject: [PATCH 75/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/submission/18340246016/assignment-2/submission?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment-2/submission/numpy_fnn.py | 249 ------------------ 1 file changed, 249 deletions(-) delete mode 100644 assignment-2/submission/18340246016/assignment-2/submission/numpy_fnn.py diff --git a/assignment-2/submission/18340246016/assignment-2/submission/numpy_fnn.py b/assignment-2/submission/18340246016/assignment-2/submission/numpy_fnn.py deleted file mode 100644 index 7f48bcd..0000000 --- a/assignment-2/submission/18340246016/assignment-2/submission/numpy_fnn.py +++ /dev/null @@ -1,249 +0,0 @@ -import numpy as np - - -class NumpyOp: - - def __init__(self): - self.memory = {} - self.epsilon = 1e-12 - - -class Matmul(NumpyOp): - - def forward(self, x, W): - """ - x: shape(N, d) - w: shape(d, d') - """ - self.memory['x'] = x - self.memory['W'] = W - h = np.matmul(x, W) - return h - - def backward(self, grad_y): - """ - grad_y: shape(N, d') - """ - - #################### - # code 1 # - x = self.memory['x'] - W = self.memory['W'] - - grad_W = np.matmul(x.T,grad_y) - grad_x = np.matmul(grad_y,W.T) - #################### - - return grad_x, grad_W - - -class Relu(NumpyOp): - - def forward(self, x): - self.memory['x'] = x - return np.where(x > 0, x, np.zeros_like(x)) - - def backward(self, grad_y): - """ - grad_y: same shape as x - """ - - #################### - # code 2 # - x = self.memory['x'] - - grad_x = np.where(x > 0, 1, 0) - - grad_x = grad_x * grad_y - - #################### - - return grad_x - - -class Log(NumpyOp): - - def forward(self, x): - """ - x: shape(N, c) - """ - - out = np.log(x + self.epsilon) - self.memory['x'] = x - - return out - - def backward(self, grad_y): - """ - grad_y: same shape as x - """ - - #################### - # code 3 # - x = self.memory['x'] - - grad_x = (1/(x + self.epsilon)) - - grad_x = grad_x*grad_y - - - #################### - - return grad_x - - -class Softmax(NumpyOp): - """ - softmax over last dimension - """ - - def forward(self, x): - """ - x: shape(N, c) - """ - - #################### - # code 4 # - - out = np.array(x, copy="true") - - - result_list=[] - - for m in range(len(out)): - result_list.append(sum(np.exp(out[m]))) - - for m in range(len(out)): - for n in range(len(out[0])): - out[m][n]= np.exp(out[m][n]) / result_list[m] - - self.memory['x'] = x - - #################### - - return out - - - - def backward(self, grad_y): - - """ - grad_y: same shape as x - """ - - - - #################### - # code 5 # - - x = self.memory['x'] - softx = self.forward(x) - [n, m] = x.shape - out = [] - for i in range(n): - out.append([]) - for j in range(m): - out[i].append(0) - for k in range(m): - if j == k: - out[i][j] += (1 - softx[i][k]) * softx[i][k] * grad_y[i][k] - else: - out[i][j] += -softx[i][j] * softx[i][k] * grad_y[i][k] - grad_x = np.array(out) - - - - - #################### - - return grad_x - - -class NumpyLoss: - - def __init__(self): - self.target = None - - def get_loss(self, pred, target): - self.target = target - return (-pred * target).sum(axis=1).mean() - - def backward(self): - return -self.target / self.target.shape[0] - - -class NumpyModel: - def __init__(self): - self.W1 = np.random.normal(size=(28 * 28, 256)) - self.W2 = np.random.normal(size=(256, 64)) - self.W3 = np.random.normal(size=(64, 10)) - - # 以下算子会在 forward 和 backward 中使用 - self.matmul_1 = Matmul() - self.relu_1 = Relu() - self.matmul_2 = Matmul() - self.relu_2 = Relu() - self.matmul_3 = Matmul() - self.softmax = Softmax() - self.log = Log() - - # 以下变量需要在 backward 中更新。 softmax_grad, log_grad 等为算子反向传播的梯度( loss 关于算子输入的偏导) - self.x1_grad, self.W1_grad = None, None - self.relu_1_grad = None - self.x2_grad, self.W2_grad = None, None - self.relu_2_grad = None - self.x3_grad, self.W3_grad = None, None - self.softmax_grad = None - self.log_grad = None - - def forward(self, x): - x = x.reshape(-1, 28 * 28) - - #################### - # code 6 # - #x = torch.relu(torch.matmul(x, self.W1)) - x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) - - #x = torch.relu(torch.matmul(x, self.W2)) - x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) - - #x = torch.matmul(x, self.W3) - #x = torch.softmax(x, 1) - x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) - - #x = torch.log(x) - x = self.log.forward(x) - - #################### - - return x - - def backward(self, y): - - #################### - # code 7 # - - self.log_grad = self.log.backward(y) - - self.softmax_grad = self.softmax.backward(self.log_grad) - - self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) - - self.relu_2_grad = self.relu_2.backward(self.x3_grad) - - self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) - - self.relu_1_grad = self.relu_1.backward(self.x2_grad) - - self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) - - - - #################### - - pass - - def optimize(self, learning_rate): - self.W1 -= learning_rate * self.W1_grad - self.W2 -= learning_rate * self.W2_grad - self.W3 -= learning_rate * self.W3_grad \ No newline at end of file -- Gitee From 126872f63e45f7b5762f6902d8b9cd3496daaef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:26:01 +0800 Subject: [PATCH 76/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/submission/18340246016/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/submission/18340246016/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 assignment-2/submission/18340246016/.keep diff --git a/assignment-2/submission/18340246016/.keep b/assignment-2/submission/18340246016/.keep deleted file mode 100644 index e69de29..0000000 -- Gitee From 264545a4b530857590fb9539428b57c50b6949a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:26:18 +0800 Subject: [PATCH 77/84] add assignment-2/submission/18340246016/numpy_mnist.py. --- .../submission/18340246016/numpy_mnist.py | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 assignment-2/submission/18340246016/numpy_mnist.py diff --git a/assignment-2/submission/18340246016/numpy_mnist.py b/assignment-2/submission/18340246016/numpy_mnist.py new file mode 100644 index 0000000..833e5aa --- /dev/null +++ b/assignment-2/submission/18340246016/numpy_mnist.py @@ -0,0 +1,58 @@ +import numpy as np +from numpy_fnn import NumpyModel, NumpyLoss +from utils import download_mnist, batch, get_torch_initialization, plot_curve, one_hot + +def mini_batch(dataset, batch_size=128, numpy=False): + + data = [] + label = [] + for each in dataset: + data.append(np.array(each[0])) + label.append(each[1]) + + data = np.array(data) + label = np.array(label) + + res = [] + + + for start_idx in range(0, data.shape[0], batch_size): + end_idx = min(start_idx + batch_size, len(data)) + res.append((data[start_idx:end_idx],label[start_idx:end_idx])) + + return res + + +def numpy_run(): + train_dataset, test_dataset = download_mnist() + + model = NumpyModel() + numpy_loss = NumpyLoss() + model.W1, model.W2, model.W3 = get_torch_initialization() + + train_loss = [] + + epoch_number = 3 + learning_rate = 0.1 + + for epoch in range(epoch_number): + for x, y in mini_batch(train_dataset): + y = one_hot(y) + + y_pred = model.forward(x) + loss = numpy_loss.get_loss(y_pred, y) + + model.backward(numpy_loss.backward()) + model.optimize(learning_rate) + + train_loss.append(loss.item()) + + x, y = batch(test_dataset)[0] + accuracy = np.mean((model.forward(x).argmax(axis=1) == y)) + print('[{}] Accuracy: {:.4f}'.format(epoch, accuracy)) + + plot_curve(train_loss) + + +if __name__ == "__main__": + numpy_run() \ No newline at end of file -- Gitee From 0dbb52ed31d3b95a5918474aad2d9e3105bd1743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:26:44 +0800 Subject: [PATCH 78/84] add assignment-2/submission/18340246016/numpy_fnn.py. --- .../submission/18340246016/numpy_fnn.py | 249 ++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 assignment-2/submission/18340246016/numpy_fnn.py diff --git a/assignment-2/submission/18340246016/numpy_fnn.py b/assignment-2/submission/18340246016/numpy_fnn.py new file mode 100644 index 0000000..7f48bcd --- /dev/null +++ b/assignment-2/submission/18340246016/numpy_fnn.py @@ -0,0 +1,249 @@ +import numpy as np + + +class NumpyOp: + + def __init__(self): + self.memory = {} + self.epsilon = 1e-12 + + +class Matmul(NumpyOp): + + def forward(self, x, W): + """ + x: shape(N, d) + w: shape(d, d') + """ + self.memory['x'] = x + self.memory['W'] = W + h = np.matmul(x, W) + return h + + def backward(self, grad_y): + """ + grad_y: shape(N, d') + """ + + #################### + # code 1 # + x = self.memory['x'] + W = self.memory['W'] + + grad_W = np.matmul(x.T,grad_y) + grad_x = np.matmul(grad_y,W.T) + #################### + + return grad_x, grad_W + + +class Relu(NumpyOp): + + def forward(self, x): + self.memory['x'] = x + return np.where(x > 0, x, np.zeros_like(x)) + + def backward(self, grad_y): + """ + grad_y: same shape as x + """ + + #################### + # code 2 # + x = self.memory['x'] + + grad_x = np.where(x > 0, 1, 0) + + grad_x = grad_x * grad_y + + #################### + + return grad_x + + +class Log(NumpyOp): + + def forward(self, x): + """ + x: shape(N, c) + """ + + out = np.log(x + self.epsilon) + self.memory['x'] = x + + return out + + def backward(self, grad_y): + """ + grad_y: same shape as x + """ + + #################### + # code 3 # + x = self.memory['x'] + + grad_x = (1/(x + self.epsilon)) + + grad_x = grad_x*grad_y + + + #################### + + return grad_x + + +class Softmax(NumpyOp): + """ + softmax over last dimension + """ + + def forward(self, x): + """ + x: shape(N, c) + """ + + #################### + # code 4 # + + out = np.array(x, copy="true") + + + result_list=[] + + for m in range(len(out)): + result_list.append(sum(np.exp(out[m]))) + + for m in range(len(out)): + for n in range(len(out[0])): + out[m][n]= np.exp(out[m][n]) / result_list[m] + + self.memory['x'] = x + + #################### + + return out + + + + def backward(self, grad_y): + + """ + grad_y: same shape as x + """ + + + + #################### + # code 5 # + + x = self.memory['x'] + softx = self.forward(x) + [n, m] = x.shape + out = [] + for i in range(n): + out.append([]) + for j in range(m): + out[i].append(0) + for k in range(m): + if j == k: + out[i][j] += (1 - softx[i][k]) * softx[i][k] * grad_y[i][k] + else: + out[i][j] += -softx[i][j] * softx[i][k] * grad_y[i][k] + grad_x = np.array(out) + + + + + #################### + + return grad_x + + +class NumpyLoss: + + def __init__(self): + self.target = None + + def get_loss(self, pred, target): + self.target = target + return (-pred * target).sum(axis=1).mean() + + def backward(self): + return -self.target / self.target.shape[0] + + +class NumpyModel: + def __init__(self): + self.W1 = np.random.normal(size=(28 * 28, 256)) + self.W2 = np.random.normal(size=(256, 64)) + self.W3 = np.random.normal(size=(64, 10)) + + # 以下算子会在 forward 和 backward 中使用 + self.matmul_1 = Matmul() + self.relu_1 = Relu() + self.matmul_2 = Matmul() + self.relu_2 = Relu() + self.matmul_3 = Matmul() + self.softmax = Softmax() + self.log = Log() + + # 以下变量需要在 backward 中更新。 softmax_grad, log_grad 等为算子反向传播的梯度( loss 关于算子输入的偏导) + self.x1_grad, self.W1_grad = None, None + self.relu_1_grad = None + self.x2_grad, self.W2_grad = None, None + self.relu_2_grad = None + self.x3_grad, self.W3_grad = None, None + self.softmax_grad = None + self.log_grad = None + + def forward(self, x): + x = x.reshape(-1, 28 * 28) + + #################### + # code 6 # + #x = torch.relu(torch.matmul(x, self.W1)) + x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) + + #x = torch.relu(torch.matmul(x, self.W2)) + x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) + + #x = torch.matmul(x, self.W3) + #x = torch.softmax(x, 1) + x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) + + #x = torch.log(x) + x = self.log.forward(x) + + #################### + + return x + + def backward(self, y): + + #################### + # code 7 # + + self.log_grad = self.log.backward(y) + + self.softmax_grad = self.softmax.backward(self.log_grad) + + self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) + + self.relu_2_grad = self.relu_2.backward(self.x3_grad) + + self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) + + self.relu_1_grad = self.relu_1.backward(self.x2_grad) + + self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) + + + + #################### + + pass + + def optimize(self, learning_rate): + self.W1 -= learning_rate * self.W1_grad + self.W2 -= learning_rate * self.W2_grad + self.W3 -= learning_rate * self.W3_grad \ No newline at end of file -- Gitee From ef4e29e453691647681aa3d4077982661733d508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:26:55 +0800 Subject: [PATCH 79/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/submission/README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/submission/README.md | 183 ------------------------------ 1 file changed, 183 deletions(-) delete mode 100644 assignment-2/submission/README.md diff --git a/assignment-2/submission/README.md b/assignment-2/submission/README.md deleted file mode 100644 index 827aa9f..0000000 --- a/assignment-2/submission/README.md +++ /dev/null @@ -1,183 +0,0 @@ -**1. Mini-batch 函数的实现** - -``` -def mini_batch(dataset, batch_size=128, numpy=False): - -# 仿照batch函数分离data与label - data = [] - label = [] - for each in dataset: - data.append(np.array(each[0])) - label.append(each[1]) - - data = np.array(data) - label = np.array(label) - - - res = [] - -# 以batch_size为单位,从[0,len(data)]分割mini-batch - for start_idx in range(0, data.shape[0], batch_size): - end_idx = min(start_idx + batch_size, len(data)) - res.append((data[start_idx:end_idx],label[start_idx:end_idx])) - - return res -``` - - **2. 模型的训练和测试** - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/113123_f204953a_8823823.png "processon.png") - -``` - # 前向传播过程 - def forward(self, x): - x = x.reshape(-1, 28 * 28) - - #################### - # code 6 # - - #x = torch.relu(torch.matmul(x, self.W1)) - # 模仿torch的relu(Matmul.(x,w1))操作,下同 - x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) - - #x = torch.relu(torch.matmul(x, self.W2)) - x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) - - #x = torch.matmul(x, self.W3) - #x = torch.softmax(x, 1) - x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) - - #x = torch.log(x) - x = self.log.forward(x) - - #################### - - return x - - # 反向传播过程 - def backward(self, y): - - #################### - # code 7 # - - self.log_grad = self.log.backward(y) - - self.softmax_grad = self.softmax.backward(self.log_grad) - - self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) - - self.relu_2_grad = self.relu_2.backward(self.x3_grad) - - self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) - - self.relu_1_grad = self.relu_1.backward(self.x2_grad) - - self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) - - - - #################### - - pass -``` - - - - - -| Epoch | Batch_size | -| ---------------- | ------ | -| 3 | 16 | -| 10 | 128 | - - -* Epoch = 3 Batch_size=128 - -[0] Accuracy: 0.9373 -
[1] Accuracy: 0.9583 -
[2] Accuracy: 0.9683 - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/102618_2f8a1661_8823823.png "3-128.png") - - - -* Epoch = 3 Batch_size=16 - -[0] Accuracy: 0.9640 -
[1] Accuracy: 0.9676 -
[2] Accuracy: 0.9707 - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/103502_131ca59f_8823823.png "3-16.png") - -* Epoch = 10 Batch_size=16 - -[0] Accuracy: 0.9602 -
[1] Accuracy: 0.9657 -
[2] Accuracy: 0.9741 -
[3] Accuracy: 0.9747 -
[4] Accuracy: 0.9701 -
[5] Accuracy: 0.9731 -
[6] Accuracy: 0.9760 -
[7] Accuracy: 0.9763 -
[8] Accuracy: 0.9760 -
[9] Accuracy: 0.9780 - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/105531_82cafce0_8823823.png "10-16.png") - - -* Epoch = 10 Batch_size=128 - -[0] Accuracy: 0.9389 -
[1] Accuracy: 0.9585 -
[2] Accuracy: 0.9679 -
[3] Accuracy: 0.9706 -
[4] Accuracy: 0.9746 -
[5] Accuracy: 0.9760 -
[6] Accuracy: 0.9769 -
[7] Accuracy: 0.9777 -
[8] Accuracy: 0.9781 -
[9] Accuracy: 0.9781 - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/111052_ddb4ecda_8823823.png "10-128.png") - - - -*探究发现* -1. mini-batch size太小的情况下,模型的波动率非常高,并不是对batch_size越细分模型的准确率就越高 -2. 从epoch的数量上来看,epoch的数量与模型accuracy有正相关性 - - - **3.Momentum 优化函数下的对比试验** - - -``` - # 利用momentum优化下的optimize函数 - def optimize(self, learning_rate): - - # 初始化V值 - v1=0 - v2=0 - v3=0 - mu=0.9 - - # momentum下的更新算法 - v1 = mu * v1 - learning_rate * self.W1_grad - self.W1 = self.W1 + v1 - - v2 = mu * v2 - learning_rate * self.W2_grad - self.W2 = self.W2 + v2 - - v3 = mu * v3 - learning_rate * self.W3_grad - self.W3 = self.W3 + v3 - - - #self.W1 -= learning_rate * self.W1_grad - # self.W2 -= learning_rate * self.W2_grad - #self.W3 -= learning_rate * self.W3_grad -``` - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0430/115301_1fa39f2b_8823823.png "屏幕截图.png") - -1. 在我们的测试数据下,momentum与梯度下降模型准确率差异不大 -2. momentum模型主要用来解决全局最优与局部最优之间的差异,但在本测试集下不存在全局与局部的差异 -3. 理论上来说,当 momentum 动量越大时,其转换为势能的能量也就越大,就越有可能摆脱局部凹域的束缚,进入全局凹域 \ No newline at end of file -- Gitee From 7c63abea7400a9d3414b647fec383c3acc354f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:27:01 +0800 Subject: [PATCH 80/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/submission/numpy=5Ffnn.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/submission/numpy_fnn.py | 249 --------------------------- 1 file changed, 249 deletions(-) delete mode 100644 assignment-2/submission/numpy_fnn.py diff --git a/assignment-2/submission/numpy_fnn.py b/assignment-2/submission/numpy_fnn.py deleted file mode 100644 index 7f48bcd..0000000 --- a/assignment-2/submission/numpy_fnn.py +++ /dev/null @@ -1,249 +0,0 @@ -import numpy as np - - -class NumpyOp: - - def __init__(self): - self.memory = {} - self.epsilon = 1e-12 - - -class Matmul(NumpyOp): - - def forward(self, x, W): - """ - x: shape(N, d) - w: shape(d, d') - """ - self.memory['x'] = x - self.memory['W'] = W - h = np.matmul(x, W) - return h - - def backward(self, grad_y): - """ - grad_y: shape(N, d') - """ - - #################### - # code 1 # - x = self.memory['x'] - W = self.memory['W'] - - grad_W = np.matmul(x.T,grad_y) - grad_x = np.matmul(grad_y,W.T) - #################### - - return grad_x, grad_W - - -class Relu(NumpyOp): - - def forward(self, x): - self.memory['x'] = x - return np.where(x > 0, x, np.zeros_like(x)) - - def backward(self, grad_y): - """ - grad_y: same shape as x - """ - - #################### - # code 2 # - x = self.memory['x'] - - grad_x = np.where(x > 0, 1, 0) - - grad_x = grad_x * grad_y - - #################### - - return grad_x - - -class Log(NumpyOp): - - def forward(self, x): - """ - x: shape(N, c) - """ - - out = np.log(x + self.epsilon) - self.memory['x'] = x - - return out - - def backward(self, grad_y): - """ - grad_y: same shape as x - """ - - #################### - # code 3 # - x = self.memory['x'] - - grad_x = (1/(x + self.epsilon)) - - grad_x = grad_x*grad_y - - - #################### - - return grad_x - - -class Softmax(NumpyOp): - """ - softmax over last dimension - """ - - def forward(self, x): - """ - x: shape(N, c) - """ - - #################### - # code 4 # - - out = np.array(x, copy="true") - - - result_list=[] - - for m in range(len(out)): - result_list.append(sum(np.exp(out[m]))) - - for m in range(len(out)): - for n in range(len(out[0])): - out[m][n]= np.exp(out[m][n]) / result_list[m] - - self.memory['x'] = x - - #################### - - return out - - - - def backward(self, grad_y): - - """ - grad_y: same shape as x - """ - - - - #################### - # code 5 # - - x = self.memory['x'] - softx = self.forward(x) - [n, m] = x.shape - out = [] - for i in range(n): - out.append([]) - for j in range(m): - out[i].append(0) - for k in range(m): - if j == k: - out[i][j] += (1 - softx[i][k]) * softx[i][k] * grad_y[i][k] - else: - out[i][j] += -softx[i][j] * softx[i][k] * grad_y[i][k] - grad_x = np.array(out) - - - - - #################### - - return grad_x - - -class NumpyLoss: - - def __init__(self): - self.target = None - - def get_loss(self, pred, target): - self.target = target - return (-pred * target).sum(axis=1).mean() - - def backward(self): - return -self.target / self.target.shape[0] - - -class NumpyModel: - def __init__(self): - self.W1 = np.random.normal(size=(28 * 28, 256)) - self.W2 = np.random.normal(size=(256, 64)) - self.W3 = np.random.normal(size=(64, 10)) - - # 以下算子会在 forward 和 backward 中使用 - self.matmul_1 = Matmul() - self.relu_1 = Relu() - self.matmul_2 = Matmul() - self.relu_2 = Relu() - self.matmul_3 = Matmul() - self.softmax = Softmax() - self.log = Log() - - # 以下变量需要在 backward 中更新。 softmax_grad, log_grad 等为算子反向传播的梯度( loss 关于算子输入的偏导) - self.x1_grad, self.W1_grad = None, None - self.relu_1_grad = None - self.x2_grad, self.W2_grad = None, None - self.relu_2_grad = None - self.x3_grad, self.W3_grad = None, None - self.softmax_grad = None - self.log_grad = None - - def forward(self, x): - x = x.reshape(-1, 28 * 28) - - #################### - # code 6 # - #x = torch.relu(torch.matmul(x, self.W1)) - x = self.relu_1.forward(self.matmul_1.forward(x,self.W1)) - - #x = torch.relu(torch.matmul(x, self.W2)) - x = self.relu_2.forward(self.matmul_2.forward(x,self.W2)) - - #x = torch.matmul(x, self.W3) - #x = torch.softmax(x, 1) - x = self.softmax.forward(self.matmul_3.forward(x,self.W3)) - - #x = torch.log(x) - x = self.log.forward(x) - - #################### - - return x - - def backward(self, y): - - #################### - # code 7 # - - self.log_grad = self.log.backward(y) - - self.softmax_grad = self.softmax.backward(self.log_grad) - - self.x3_grad, self.W3_grad = self.matmul_3.backward(self.softmax_grad) - - self.relu_2_grad = self.relu_2.backward(self.x3_grad) - - self.x2_grad, self.W2_grad = self.matmul_2.backward(self.relu_2_grad) - - self.relu_1_grad = self.relu_1.backward(self.x2_grad) - - self.x1_grad, self.W1_grad = self.matmul_1.backward(self.relu_1_grad) - - - - #################### - - pass - - def optimize(self, learning_rate): - self.W1 -= learning_rate * self.W1_grad - self.W2 -= learning_rate * self.W2_grad - self.W3 -= learning_rate * self.W3_grad \ No newline at end of file -- Gitee From 2bb30db8c563d399d70196dfa9484349a30248f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:27:07 +0800 Subject: [PATCH 81/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/submission/numpy=5Fmnist.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/submission/numpy_mnist.py | 58 -------------------------- 1 file changed, 58 deletions(-) delete mode 100644 assignment-2/submission/numpy_mnist.py diff --git a/assignment-2/submission/numpy_mnist.py b/assignment-2/submission/numpy_mnist.py deleted file mode 100644 index 833e5aa..0000000 --- a/assignment-2/submission/numpy_mnist.py +++ /dev/null @@ -1,58 +0,0 @@ -import numpy as np -from numpy_fnn import NumpyModel, NumpyLoss -from utils import download_mnist, batch, get_torch_initialization, plot_curve, one_hot - -def mini_batch(dataset, batch_size=128, numpy=False): - - data = [] - label = [] - for each in dataset: - data.append(np.array(each[0])) - label.append(each[1]) - - data = np.array(data) - label = np.array(label) - - res = [] - - - for start_idx in range(0, data.shape[0], batch_size): - end_idx = min(start_idx + batch_size, len(data)) - res.append((data[start_idx:end_idx],label[start_idx:end_idx])) - - return res - - -def numpy_run(): - train_dataset, test_dataset = download_mnist() - - model = NumpyModel() - numpy_loss = NumpyLoss() - model.W1, model.W2, model.W3 = get_torch_initialization() - - train_loss = [] - - epoch_number = 3 - learning_rate = 0.1 - - for epoch in range(epoch_number): - for x, y in mini_batch(train_dataset): - y = one_hot(y) - - y_pred = model.forward(x) - loss = numpy_loss.get_loss(y_pred, y) - - model.backward(numpy_loss.backward()) - model.optimize(learning_rate) - - train_loss.append(loss.item()) - - x, y = batch(test_dataset)[0] - accuracy = np.mean((model.forward(x).argmax(axis=1) == y)) - print('[{}] Accuracy: {:.4f}'.format(epoch, accuracy)) - - plot_curve(train_loss) - - -if __name__ == "__main__": - numpy_run() \ No newline at end of file -- Gitee From 4cc5d1548a24d00aaae7731be6d7dbada0bdbe56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:27:37 +0800 Subject: [PATCH 82/84] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20img?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/submission/18340246016/img/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-2/submission/18340246016/img/.keep diff --git a/assignment-2/submission/18340246016/img/.keep b/assignment-2/submission/18340246016/img/.keep new file mode 100644 index 0000000..e69de29 -- Gitee From c57f0a7828175f549b47b5e2967e1504aaf2b8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E5=87=AF=E4=B9=90?= <8823823+y3sm1r@user.noreply.gitee.com> Date: Sun, 2 May 2021 09:28:17 +0800 Subject: [PATCH 83/84] upload img --- .../submission/18340246016/img/10-128.png | Bin 0 -> 12376 bytes .../submission/18340246016/img/10-16.png | Bin 0 -> 12200 bytes .../submission/18340246016/img/3-128.png | Bin 0 -> 15189 bytes .../submission/18340246016/img/3-16.png | Bin 0 -> 12056 bytes .../submission/18340246016/img/momentum.png | Bin 0 -> 20051 bytes .../submission/18340246016/img/processon.png | Bin 0 -> 15211 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 assignment-2/submission/18340246016/img/10-128.png create mode 100644 assignment-2/submission/18340246016/img/10-16.png create mode 100644 assignment-2/submission/18340246016/img/3-128.png create mode 100644 assignment-2/submission/18340246016/img/3-16.png create mode 100644 assignment-2/submission/18340246016/img/momentum.png create mode 100644 assignment-2/submission/18340246016/img/processon.png diff --git a/assignment-2/submission/18340246016/img/10-128.png b/assignment-2/submission/18340246016/img/10-128.png new file mode 100644 index 0000000000000000000000000000000000000000..62352ed1838be0f2b7ded908e7cf94416690e663 GIT binary patch literal 12376 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 pf-+J#0Ohg}MR_&3Y8kW8{|zOYF`fVb literal 0 HcmV?d00001 diff --git a/assignment-2/submission/18340246016/img/3-16.png b/assignment-2/submission/18340246016/img/3-16.png new file mode 100644 index 0000000000000000000000000000000000000000..e85d4d2d4c3cc2d62bcfd80dd2199c0ff26dcc85 GIT binary patch literal 12056 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 literal 0 HcmV?d00001 diff --git a/assignment-2/submission/18340246016/img/momentum.png b/assignment-2/submission/18340246016/img/momentum.png new file mode 100644 index 0000000000000000000000000000000000000000..f1f3afdf95cb49bd4f84f7c2bfb68fdbd13ddde3 GIT binary patch literal 20051 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 literal 0 HcmV?d00001 diff --git a/assignment-2/submission/18340246016/img/processon.png b/assignment-2/submission/18340246016/img/processon.png new file mode 100644 index 0000000000000000000000000000000000000000..0b41c289c3621142bc38c400ba1a566f6945f523 GIT binary patch literal 15211 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 Date: Sun, 2 May 2021 09:28:31 +0800 Subject: [PATCH 84/84] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20as?= =?UTF-8?q?signment-2/submission/18340246016/img/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-2/submission/18340246016/img/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 assignment-2/submission/18340246016/img/.keep diff --git a/assignment-2/submission/18340246016/img/.keep b/assignment-2/submission/18340246016/img/.keep deleted file mode 100644 index e69de29..0000000 -- Gitee