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上的表现取平均值,根据这个平均值选超参数。

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

编程细节

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

编程细节

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

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

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

编程细节

  1. X_train = np.reshape(X_train, (X_train.shape[0], -1))
  2. # reshape,保留第一个维度,剩下全压缩到一个维度(-1)
  1. X_train = np.hstack([X_train, np.ones((X_train.shape[0], 1))])
  2. # hstack,就是把两个矩阵水平靠着放在一起
  3. # 等价于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的时候也别忘了加上正则项。

  1. y_pred = np.argsort(self.loss(X),axis = 1)[:,-1]
  2. # 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. php7.1 安装amqp扩展

    在php开发中使用rabbitmq消息队列时,需要安装PHP扩展amqp,安装步骤如下: 直接使用pecl进行amqp扩展的安装, /usr/local/php/bin/pecl install am ...

  2. python基础中遇到的问题(TypeError: unhashable type: 'list')

    d20220330 #false >>> l=[{i:i+1} for i in [1,2,3]] >>> l [{1: 2}, {2: 3}, {3: 4}] & ...

  3. 左右手切换工具xmouse v1.2版本发布

    Xmouse 方便的切换鼠标左右键,因为功能非常简单,所以支持.net framework 2.0及以上 windows环境就可以了,目前已测试win7.win10可用. 关于为什么做这么个东西,那是 ...

  4. 重学ES系列之变量的作用范围

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. React技巧之发出http请求

    原文链接:https://bobbyhadz.com/blog/react-send-request-on-click 作者:Borislav Hadzhiev 正文从这开始~ 总览 在React中, ...

  6. 配置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 ...

  7. 飞鱼CRM

    直接放干货吧,今日头条飞鱼CRM的PHP调用方法,点我跳转. 很简单的两个方法,加密时重要的是有一个空格,必须要有,这个也是坑了我很长时间的一个坑. 接下来具体说一下飞鱼CRM系统接口加密的方法. & ...

  8. 全国30m精度二级分类土地利用数据

    ​数据下载链接:数据下载链接 引言 全国土地利用数据产品是以Landsat TM/ETM/OLI遥感影像为主要数据源,经过影像融合.几何校正.图像增强与拼接等处理后,通过人机交互目视解译的方法,将全国 ...

  9. 【python基础】第19回 多层,有参装饰器 递归 二分法

    本章内容概要 1. 多层装饰器 2. 有参装饰器 3. 递归函数 4. 算法(二分法) 本章内容详解 1. 多层装饰器 1.1 什么是多层装饰器 多层装饰器是从下往上依次执行,需要注意的是,被装饰的函 ...

  10. 基于 Github Actions 自动部署 Hexo 博客

    前言 前不久使用了 Hexo 搭建独立博客,我是部署在我的腾讯云轻量应用服务器上的,每次都需要 hexo deploy 然后打包.上传.解压和刷新 CDN,非常麻烦.我的服务器配置也不高 2C2G 无 ...