cs231n assignment 1

20210804 - 20210808。

总结

建立模型的步骤:

  • __init__(self);在注释中约定模型的参数超参数。
  • 写出【loss function】,loss():要给出regularization_strength,如果给出label y就返回gradient。
  • 用stochastic gradient descent写出train()
  • 写出predict()

训练模型的步骤:

  • 得到train、validation、predict的X和y,顺便得到它们的维度;
  • 设置一堆超参数,开始训练,试出来哪些超参数更好。

矩阵求微分:

\[AB=C
\\
\frac{\part l}{\part B}=A^T\frac{\part l}{\part C}
\\
\frac{\part l}{\part A}=\frac{\part l}{\part C}B^T
\]

其中\(A^T\)就是\((\frac{\part C}{\part B})^T\),也就是\(\frac{\part l}{\part B}=(\frac{\part C}{\part B})^T\frac{\part l}{\part C}\)​;

\(B^T\)​就是\((\frac{\part C}{\part A})^T\)​,也就是\(\frac{\part l}{\part A}=\frac{\part l}{\part C}(\frac{\part C}{\part A})^T\)​​,是链式法则。

KNN

思想

k是一个超参数。对于新给出的一个数据,找到离它【距离】最近的k个样本,用 这k个样本中数目最多的类别 来预测 这个数据的类别。

距离:L1距离/Manhattan距离,L2距离/Euclidean距离。

(L1距离与选择的坐标轴有关,而转动坐标轴对L2距离没有影响。因此如果坐标轴有特殊的意义,可以考虑L1距离,否则L2距离更自然一些。)

cross-validation

一般做法:我们会把数据分成3组:train,validation,test。在validation上试出最合适的超参数,然后我们就用这一组超参数对应的模型了。

交叉验证:把test拿出来,然后把其余的分成若干组。对于一组超参数,把每一组都拿出来做一次validation(用其余组训练模型),然后对模型在各个validation上的表现取平均值,根据这个平均值选超参数。

在小数据集上是有用的,但在深度学习中不常用。

编程细节

# 神仙高效矢量化代码
dists[i, j] = np.sqrt(np.sum(np.square(X[i] - self.X_train[j]))) # np是万能的 dists[i, :] = np.sqrt(np.sum(np.square(X[i] - self.X_train), axis = 1)) # 进阶版,axis=1: :::::: -> :,0::::::: -> ...... dists = np.sqrt(
np.sum(X**2, axis = 1, keepdims = True)
+ np.sum(self.X_train**2, axis = 1, keepdims = True).T
- 2*np.dot(X, self.X_train.T)
) # 一次得到!更高更妙的广播操作,keepdims用来保持二维特性
max_index = np.argsort(dists[i]) # argsort返回的是数组值从小到大的索引值
maxdir = {} # this is a dictionary
sy = set(closest_y) # make it become set
for s in sy:
maxdir[s] = closest_y.count(s)
y_pred[i] = int(max(maxdir, key = maxdir.get)) # 字典返回value最大的key
# Frobenius norm 可以用来检验两个矩阵是否相同
# 就是所有的difference平方和开根号
# 换句话说,把矩阵变成向量再求euclidean距离
difference = np.linalg.norm(dists - dists_one, ord='fro')
print('Difference was: %f' % (difference, ))
if difference < 0.001:
print('Good! The distance matrices are the same')
else:
print('Uh-oh! The distance matrices are different')

SVM

思想

线性分类器:

\[f(x,W)=Wx+b
\]

x是3072*1的图片(列向量),W是10*3072的权重矩阵,b是10*1的bias列向量。

最后我们得到一个10*1的列向量,其中【第i行的元素】就是【W第i行】和【x】的内积(再加一个bias),内积即相似程度。W的第i行可以被看成与类别i对应的pattern。

代码中的预处理

  • 算出mean,然后把每个数据都减去mean;
  • 直接把mean作为bias,svm只对W进行优化。

multi-class svm loss

\[L_i=\sum_{j\ne y_i}
\left \{
\begin{array}{ll}
0, & if~s_{y_{i}} \ge s_j+1 \\
s_j-s_{y_{i}}+1, & otherwise\\
\end{array}
\right.
\\
=\sum_{j\ne y_i}max(0,s_j-s_{y_{i}}+1)
\]

我们看除正确类别外的9个类别的得分:如果正确类别的得分高于该错误类别得分,高于它一个安全的bound(此处为1),loss是0,否则loss是【错误类别得分+bound-正确类别】。

正则项

\[L(W)=\frac{1}{N}\sum_{i=1}^n{L_i(f(x_i,W),y_i)}+\lambda R(W)
\]

λ是正则化强度。就是鼓励更简洁的模型,penalize the complexity of the model。

L2 regularization:\(R(W)=\sum_k \sum_l W_{k,l}^2\)​​。所有数的平方和。

L1 regularization:\(R(W)=\sum_k \sum_l |W_{k,l}|\)​。所有数的绝对值和。

编程细节

# numpy真是魔法
mask = range(num_training, num_training + num_validation)
X_val = X_train[mask]

如果【正确类别得分没有高于错误类别一个安全的bound】,求梯度的时候不仅要错误类别分数降低,还要正确类别分数升高。

# W是3072*10,X是100*3072

scores = X.dot(W)
correct_class_score = scores[np.arange(num_train),y]
scores_to_calc = scores - correct_class_score.reshape(-1, 1) + 1.
# 想让矩阵变成只有一列(行数不知道多少),通过mat.reshape(-1,1)
# 也就是所有分数减去正确分数再加1
scores_to_calc[scores_to_calc <= 0] = 0
loss = np.sum(scores) / num_train - 1 # 减去正确类别 scores_to_calc[scores_to_calc > 0] = 1
mask = np.array(scores_to_calc) # 数组深复制
mask[np.arange(num_train), y] = -np.sum(scores_to_calc, axis = 1) # 有多少个+1超过bound的错误类别分数,正确类别的loss梯度就要减多少次
dW = X.T.dot(mask) / num_train # Add regularization to the loss.
loss += reg * np.sum(W * W)
dW += 2 * reg * W

梯度下降法,是沿loss负梯度的方向向下走,所以是W -= learning_rage * grad

softmax

思想

softmax的loss function是这样的:

我们认为P是一个概率。给出样本\(x_i\),判断其类别为k的概率:

\[P(Y=k|X=x_i)=\frac{e^{s_k}}{\sum_j e^{s_j}}
\]

就是【类别k得分的exp】比上【各个类别得分的exp之和】。

损失函数就是【-log正确类别概率】,概率=1时loss=0,概率=0时loss=正无穷。

\[L_i=-logP(Y=y_i|X=x_i)
\]

编程细节

X_train = np.reshape(X_train, (X_train.shape[0], -1))
# reshape,保留第一个维度,剩下全压缩到一个维度(-1)
X_train = np.hstack([X_train, np.ones((X_train.shape[0], 1))])
# hstack,就是把两个矩阵水平靠着放在一起
# 等价于np.concatenate([ndarray数组], axis=1)

要想用np广播,就要在np.sum()的时候加上keepdims=True

two layers net

思想

linear score function:

\[f=Wx+b
\]

2-layer Neural Network:

\[f=W_2max(W_1x,0)
\\
f=W_2max(W_1x+b_1,0)+b_2
\]

非线性运算(如这里的max)很重要,否则线性堆叠在一起还是线性。

forward pass:先算h,再算s,再算loss。

backward pass:求loss的微分,先算dscore,再算db2、dW2、dh,通过dh再算dW1和db1。

epoch是什么

一个epoch表示把所有数据送入模型训练一遍的过程。

minibatch是为了算gradient快一些。

iterations_per_epoch = max(num_train / batch_size, 1),就是说我们要iterate几次才能完成一个epoch。

完成一个epoch之后,我们把learning_rate调低,learning_rate *= learning_rate_decay

编程细节

算loss的时候算的是N个example的mean,并且别忘了加regularization term。

算gradient的时候也别忘了加上正则项。

y_pred = np.argsort(self.loss(X),axis = 1)[:,-1]
# argsort把元素从小到大排序,给我们排序好的下标。我们要得分最大的,因此[:,-1]

feathers

思想

feather engineering。

DL基础:cs231n assignment 1的更多相关文章

  1. DL基础:cs231n assignment 2

    cs231n assignment 2 20210913 - 20211005. 目录 cs231n assignment 2 fully-connected nets 基本思想 编程细节 复习mul ...

  2. Java基础-赋值运算符Assignment Operators与条件运算符Condition Operators

    Java基础-赋值运算符Assignment Operators与条件运算符Condition Operators 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.赋值运算符 表 ...

  3. DL基础补全计划(二)---Softmax回归及示例(Pytorch,交叉熵损失)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  4. DL基础补全计划(三)---模型选择、欠拟合、过拟合

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  5. DL基础补全计划(一)---线性回归及示例(Pytorch,平方损失)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  6. DL基础补全计划(五)---数值稳定性及参数初始化(梯度消失、梯度爆炸)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  7. DL基础补全计划(六)---卷积和池化

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  8. 【DL基础】GridSearch网格搜索

    前言 参考 1. 调参必备---GridSearch网格搜索: 完

  9. 普通程序员如何转向AI方向

    眼下,人工智能已经成为越来越火的一个方向.普通程序员,如何转向人工智能方向,是知乎上的一个问题.本文是我对此问题的一个回答的归档版.相比原回答有所内容增加. 一. 目的 本文的目的是给出一个简单的,平 ...

随机推荐

  1. 2021.06.12【NOIP提高B组】模拟 总结

    T1 题目大意:有 \(n\) 个点,到点 \(i\) 可以获得 \(A_i\) ,同时消耗 \(B_i\) 若当前价值小于 \(B_i\) 则不能到,问从 \(P\) 开始,任一点结束后的最大值. ...

  2. 用一个性能提升了666倍的小案例说明在TiDB中正确使用索引的重要性

    背景 最近在给一个物流系统做TiDB POC测试,这个系统是基于MySQL开发的,本次投入测试的业务数据大概10个库约900张表,最大单表6千多万行. 这个规模不算大,测试数据以及库表结构是用Dump ...

  3. 入坑KeePass(三)安全设置完后后留存

    1.文件> 数据库设置 > 安全 迭代次数改成500000 2.工具 > 选项 2.1.安全 2.2.策略 2.3.集成 2.4高级

  4. 安装gitlab客户端

    1. 下载客户端软件包 https://pan.baidu.com/disk/home#/category?type=6&vmode=list 安装顺序: Git-2.13.3-64-bit. ...

  5. 配置svn,httpd启动报错 Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.

    查看httpd的状态,发现80端口被占用,因为我的nginx的80端口. systemctl status httpd.service  解决: 把Apache的端口该成别的端口 vi /etc/ht ...

  6. nginx启动失败/报错(bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket...permissions) nginx启动失败

    出现这个问题是因为80端口被占用了 1.cmd输入命令netstat -aon|findstr "80" 2..查看80端口 16356对应的任务 输入命令 tasklist|fi ...

  7. NC16561 [NOIP2012]国王的游戏

    NC16561 [NOIP2012]国王的游戏 题目 题目描述 恰逢 H 国国庆,国王邀请 \(n\) 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上 ...

  8. Min-max 容斥与 kth 容斥

    期望的线性性: \[E(x+y)=E(x)+E(y) \] 证明: \[E(x+y)=\sum_i \sum_j(i+j)*P(i=x,j=y) \] \[=\sum_i\sum_ji*P(i=x,j ...

  9. Mybatis整合第三方缓存

    1) 为了提高扩展性.MyBatis定义了缓存接口Cache.我们可以通过实现Cache接口来自定义二级缓存 2) EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点. 3) 整合 ...

  10. java---数组(重点概念)

    一.什么是数组 程序=算法+数据结构 数据结构:把数据按照某种特定的结构保存,设计一个合理的数据是解决问题的关键: 数组:是一种用于存储多个相同类型数据类型 的存储模型: 数组的特定结构:相同类型组成 ...