PS: 本文默认已学习CS231N相关课程并掌握相关知识。
dropout的相关原理本文不再描述,详情请见Dropout (neural networks)
那么我们怎么实现dropout呢?假设我们有 \(n\) 个神经元,每个神经元输出 \(m\) 维向量。那么,我们就随机生成一个 \(n\) 维向量,并按一定比例将值设为0(随机失活)。
|
|
PS: 本文默认已学习CS231N相关课程并掌握相关知识。
dropout的相关原理本文不再描述,详情请见Dropout (neural networks)
那么我们怎么实现dropout呢?假设我们有 \(n\) 个神经元,每个神经元输出 \(m\) 维向量。那么,我们就随机生成一个 \(n\) 维向量,并按一定比例将值设为0(随机失活)。
|
|
本来想自己写一篇博客,但是看到一篇写的特别好的,转载于此~
PS: 本文默认已学习CS231N相关课程并掌握相关知识。
Softmax的实验部分跟SVM非常相似,所以本文就简单求下 \(loss\) 和 \(grad\)
Softmax的 \(loss function\) 定义为
\[ L = - \frac{1}{m}\sum_{i=1}^{m}\ln{\frac{e^{(X[i]*W)[y[i]]}}{\sum_{i=1}^{C}{e^{(X[i]*W)[j]}}}} \]
接下来我们求 \(grad\)
\[ dW[:, l] = {\begin{cases} -X[i] + {\frac{e^{(X[i]*W)[l]}}{\sum_{i=1}^{C}{e^{(X[i]*W)[j]}}}} * X[i], & l = y[i] \\ {\frac{e^{(X[i]*W)[l]}}{\sum_{i=1}^{C}{e^{(X[i]*W)[j]}}}} * X[i], & l \neq y[i] \\ \end{cases} } \]
PS: 本文默认已学习CS231N相关课程并掌握相关知识。
SVM的实验部分分为以下内容:
MultiClass SVM的方程为
\[ f(x) = x * W \]
其中, \(x\) 为 \(1*k\), W为 \(k*C\) ( \(C\) 是label种类)
\(loss function\) 定义为
\[ L = \frac{1}{m}\sum_{i=1}^{m}{\sum_{j \neq y[i]}{max{(0, f(X[i])[j] - f(X[i])[y[i]] + 1)}}}\]
实验中已经帮我们实现了 \(loss function\) ,接下来我们要做的就是计算 \(grad\) 。众所周知,\(grad = \frac{\partial L}{\partial W}\) 。 \(loss function\) 只是简单的相加,所以我们考虑每一项不为0的组成部分对导数的贡献。
\[\begin{align} dW[:, l] & = \frac{\partial (f(X[i])[j] - f(X[i])[y[i]] + 1)}{\partial W[:, l]} \\ & = {\begin{cases} X[i], & l = j \\ -X[i], & l = y[i] \\ 0, & other \\ \end{cases} } \end{align}\]这样,我们就求出了 \(dW\) 。
首先我们要从数据中随机获取 \(batch\_size\) 样本(使用numpy.randomchoice),然后用这些数据进行一轮迭代,获得grad,再进行下降。
SVM模型有各种不同的参数。我们用多重循环,得到每种参数的组合的train accuracy和val accuracy,并记录最好的。(比较简单暴力)
PS: 本文默认已学习CS231N相关课程并掌握相关知识。
KNN的实验部分主要分为3大块内容:
接下来我们对这三部分进行探究
实验中分别让我们用two-loops, one-loop和no-loop计算距离。
假设我们的训练集规模为 $ n * k $, 测试集规模为 $ m * k $, 那么计算距离的方法如下:
\[ dists[i][j] = \sqrt{\sum_{l=1}^k(test[i][l] - train[j][l])^2} \]
其中,dists为$ m * n $的矩阵
那么,two-loops的计算方法就呼之欲出了,就是对两个$ k $维向量计算距离:
|
|
现在,我们考虑下one-loop的算法。对于测试集中每一个数据,都要与训练集中每个数据计算距离。其实我们可以利用numpy的broadcast,对每个测试集中的数据计算他到所有训练集数据的距离:
|
|
接下来,我们考虑no-loop的做法,这就需要用到一些矩阵运算的知识。我们将平方项展开:
\[\begin{align} dists[i][j] & = \sqrt{\sum_{l=1}^k(test[i][l] - train[j][l])^2} \\ & = \sqrt{\sum_{l=1}^k(test[i][l]^2 - 2 * test[i][l] * train[j][l] + train[j][l]^2)} \\ & = \sqrt{- 2 * \sum_{l=1}^k{test[i][l] * train[j][l]} + \sum_{l=1}^k{test[i][l]^2} + \sum_{l=1}^k{train[j][l]^2}} \end{align}\]在这里我们注意到, \({\sum_{l=1}^{k}{test[i][l] * train[j][l]}}\) 就是 \(test * train^T\) , 而 \(\sum_{l=1}^k{test[i][l]^2}\) 和 \(\sum_{l=1}^k{train[j][l]^2}\) 只是对矩阵中的 \(k\) 维向量求平方和,可以用numpy实现。代码如下:
|
|
在得到dists矩阵后,我们就可以计算测试集中每个样本的label。KNN算法就是获得距离样本最近的K个点,然后将这K个点中出现最多的label作为样本label:
|
|
交叉验证最主要的工作在于数据集的划分,实验中提供了np.array_split作为参考。实验中用了5-floder交叉验证。我们使用np.vstack将其他四份数据合在一起作为训练集,剩下一份作为验证集。