CMU10414-hw0
overview
hw0 简单回顾了机器学习的基础,看了 lec01-03 就可以开始完成。本人为 0基础 机器学习选手,花了不少时间熟悉矩阵运算和一些 python 的矩阵操作。hw0 是进入开发needle
前的热身,并不算难。关于计算梯度等的求导过程,在 lec 中会简单过一遍,最后直接使用简化后的公式即可( Kotlin说这样hacky 一点,因为没有人会在实际的计算过程中使用严格的求导过程)。
环境
作业的检测平台使用 colab,作为非会员,经常会断线。每次断线重连可能需要重新配置环境:(插入代码块并运行)
- 挂载
google drive
1
2from google.colab import drive
drive.mount('/content/drive') - 进入工作路径(假设drive中已经有文件夹)
1
%cd /content/drive/MyDrive/10714/hw0
- 下载必要依赖:
1
2
3!pip3 install --upgrade --no-deps git+https://github.com/dlsyscourse/mugrade.git
!pip3 install pybind11
!pip3 install numdifftools
add
1 |
|
parse_mnist
手动解析 mnist 数据集:
1 |
|
softmax loss
1 |
|
我们需要熟悉一下numpy
的一些基本操作:
np.exp
对 ndarray 中每一个元素计算指数函数np.sum
对 ndarray 进行求和,axis=1
代表对行求和np.log
对 ndarray 每个元素取自然对数Z.shape[0]
表示 Z 的行数,1为列数np.arange(t)
生成一个 0 到 t-1 的数组
softmax regression epoch
我们将X(m,n)、y(m) 按照 batch size 划分为多个 batch (m / batch_size 个),利用简化后的梯度计算公式来计算下降梯度
更新公式:theta := theta - lr * grad
lr 为学习率,aka 步长
1 |
|
(离大谱了,有人可以想到 -=
和 = -
的区别?)
注意在 python 中,后者相当于重新创建了一个新的 theta
并修改,和我们预期的原地修改不一样!!
这里学到的 ndarray 操作:
X.T
:得到 ndarray 的矩阵转置keepdims=True
:可以保留原来的维度,比如:1
2
3
4
5
6# before
([1,2],
[3,4])
# after
([3,3],
[7,7])np.zeros()
:创造指定形状的零矩阵@
:该运算符可以用来进行矩阵乘法,注意区分*
对于两个矩阵是每个相同位置的元素相乘
nn_epoch
利用反向传播的简化公式,更新参数 W1 W2(即神经网络的layer)
1 |
|
ReLU
函数:ReLU(x) = max(0, x)
,是这里的非线性因素
softmax regression epoch in cpp
要求我们使用 cpp 实现 Softmax 回归,小批量梯度下降,和上面的一样
1 |
|
result
使用 mnist作为训练数据,平台为 colab
python 版本的 softmax regression classifier
Epoch | Train Loss | Train Err | Test Loss | Test Err |
---|---|---|---|---|
0 | 0.35134 | 0.10182 | 0.33588 | 0.09400 |
1 | 0.32142 | 0.09268 | 0.31086 | 0.08730 |
2 | 0.30802 | 0.08795 | 0.30097 | 0.08550 |
3 | 0.29987 | 0.08532 | 0.29558 | 0.08370 |
4 | 0.29415 | 0.08323 | 0.29215 | 0.08230 |
5 | 0.28981 | 0.08182 | 0.28973 | 0.08090 |
6 | 0.28633 | 0.08085 | 0.28793 | 0.08080 |
7 | 0.28345 | 0.07997 | 0.28651 | 0.08040 |
8 | 0.28100 | 0.07923 | 0.28537 | 0.08010 |
9 | 0.27887 | 0.07847 | 0.28442 | 0.07970 |
python 版本的神经网络:可以看到Test Err
显然低于前者,说明我们引入的非线性因素,的确显著提高了分辨的正确率。
Epoch | Train Loss | Train Err | Test Loss | Test Err |
---|---|---|---|---|
0 | 0.15324 | 0.04697 | 0.16305 | 0.04920 |
1 | 0.09854 | 0.02923 | 0.11604 | 0.03660 |
2 | 0.07434 | 0.02167 | 0.09790 | 0.03160 |
3 | 0.05947 | 0.01713 | 0.08773 | 0.02890 |
4 | 0.04826 | 0.01355 | 0.08048 | 0.02610 |
5 | 0.04048 | 0.01093 | 0.07690 | 0.02390 |
6 | 0.03476 | 0.00895 | 0.07435 | 0.02320 |
7 | 0.03026 | 0.00777 | 0.07256 | 0.02290 |
8 | 0.02664 | 0.00650 | 0.07137 | 0.02200 |
9 | 0.02355 | 0.00560 | 0.07004 | 0.02130 |
10 | 0.02099 | 0.00463 | 0.06890 | 0.02080 |
11 | 0.01908 | 0.00392 | 0.06852 | 0.02070 |
12 | 0.01720 | 0.00322 | 0.06801 | 0.02070 |
13 | 0.01561 | 0.00275 | 0.06746 | 0.02110 |
14 | 0.01422 | 0.00238 | 0.06691 | 0.02070 |
15 | 0.01297 | 0.00212 | 0.06644 | 0.02040 |
16 | 0.01188 | 0.00178 | 0.06617 | 0.02030 |
17 | 0.01085 | 0.00142 | 0.06560 | 0.01980 |
18 | 0.01005 | 0.00122 | 0.06527 | 0.01900 |
19 | 0.00921 | 0.00105 | 0.06492 | 0.01900 |
c++版本的 softmax regression classifier
Epoch | Train Loss | Train Err | Test Loss | Test Err |
---|---|---|---|---|
0 | 0.35134 | 0.10182 | 0.33588 | 0.09400 |
1 | 0.32142 | 0.09270 | 0.31086 | 0.08730 |
2 | 0.30803 | 0.08795 | 0.30097 | 0.08550 |
3 | 0.29987 | 0.08532 | 0.29559 | 0.08370 |
4 | 0.29415 | 0.08323 | 0.29215 | 0.08230 |
5 | 0.28981 | 0.08182 | 0.28973 | 0.08090 |
6 | 0.28633 | 0.08083 | 0.28793 | 0.08080 |
7 | 0.28345 | 0.07997 | 0.28651 | 0.08040 |
8 | 0.28100 | 0.07925 | 0.28537 | 0.08010 |
9 | 0.27887 | 0.07847 | 0.28442 | 0.07970 |
move on !