Datawhale X 李宏毅苹果书 AI夏令营 Task03:机器学习框架&实践攻略
机器学习框架
Training Data:
(
x
1
,
y
^
1
)
,
(
x
2
,
y
^
2
)
,
.
.
.
,
(
x
N
,
y
^
N
)
{(x^1, \hat{y}^1), (x^2, \hat{y}^2), ..., (x^N, \hat{y}^N)}
(x1,y^1),(x2,y^2),...,(xN,y^N)
Training:
f
u
n
c
t
i
o
n
w
i
t
h
u
n
k
n
o
w
n
,
y
=
f
θ
(
x
)
→
d
e
f
i
n
e
l
o
s
s
,
L
(
θ
)
→
o
p
t
i
m
i
z
a
t
i
o
n
,
θ
∗
=
a
r
g
m
i
n
θ
L
function \quad with \quad unknown, y = f_\theta (x) \rightarrow define \quad loss, L(\theta) \rightarrow optimization, \theta^* = arg min_\theta L
functionwithunknown,y=fθ(x)→defineloss,L(θ)→optimization,θ∗=argminθL
Testing Data:
x
N
+
1
,
x
N
+
2
,
.
.
.
,
x
N
+
M
{x^{N + 1}, x^{N+2}, ..., x^{N+M}}
xN+1,xN+2,...,xN+M
之后使用:
U
s
e
y
=
f
θ
∗
(
x
)
t
o
l
a
b
e
l
t
h
e
t
e
s
t
i
n
g
d
a
t
a
Use \quad y = f_{\theta^*}(x) \quad to \quad label \quad the \quad testing \quad data
Usey=fθ∗(x)tolabelthetestingdata
得到:
y
N
+
1
,
y
N
+
2
,
.
.
.
,
y
N
+
M
y^{N+1}, y^{N+2}, ..., y^{N+M}
yN+1,yN+2,...,yN+M
继续优化指导:
模型偏差
模型太小,即使找到该模型的极限Loss,也没什么用,因为模型自身可解释性太差。只能重新设计Model:
可以关联更多特征,深度学习增加网络深度等
优化问题
梯度下降,步长不合适,很容易只达到局部最优解,而非真正最优解
判断是Model问题还是优化问题的方法是:
左边并不能直接判断是Overfitting,因为如果再训练集中56层依旧很差,则说明优化有问题,这里的建议就是
- 在面对新问题时,可以先跑一些深度较低的网络,或者用支持向量机等简单的模型进行测试
- 然后再进行深的model的训练,如果在深的model的Loss还不如浅的model的Loss,就需要其他优化方式
过拟合
一定是Training Data的Loss小,而Testing Data的Loss大才是过拟合,而不能直接看Testing Data就直接判断。正常情况下,比较有弹性的Model就容易出现Overfitting的问题
解决方法则是:
- 最简单的方法,增加训练资料
- 数据增强(data augmentation),例如图片训练集上进行图片旋转,裁切,遮罩,反色等
- 或者,给模型增加限制
- 给模型比较少的参数。如果是深度学习的话,就给它比较少的神经元的数量,本来每层一千个神经元,改成一百个神经元之类的,或者让模型共用参数,可以让一些参数有一样的数值。**全连接网络(fully-connected network)其实是一个比较有灵活性的架构,而卷积神经网络(Convolutional Neural Network,CNN)**是一个比较有限制的架构。CNN 是一种比较没有灵活性的模型,其是针对图像的特性来限制模型的灵活性。所以全连接神经网络,可以找出来的函数所形成的集合其实是比较大的,CNN 所找出来的函数,它形成的集合其实是比较小的,其实包含在全连接网络里面的,但是就是因为CNN 给了,比较大的限制,所以 CNN 在图像上,反而会做得比较好,这个之后都还会再提到
- 用比较少的特征,本来给 3 天的数据,改成用给两天的数据,其实结果就好了一些
- 还有别的方法,比如早停(early stopping)、正则化(regularization)和丢弃法(dropoutmethod)
但也不能限制太多,太多训练出来的东西偏差依旧很大
交叉验证
交叉验证就是,将训练集再拆分成俩部分,一部分称为训练集(training set),一部分是验证集(validation set)。比如 90% 的数据作为训练集,有 10% 的数据作为验证集。在训练集上训练出来的模型会使用验证集来衡量它们的分数,根据验证集上面的分数去挑选结果,再把这个结果上传到 Kaggle 上面得到的公开分数。在挑分数的时候,是用验证集来挑模型,所以公开测试集分数就可以反映私人测试集的分数。但假设这个循环做太多次,根据公开测试集上的结果调整模型太多次,就又有可能在公开测试集上面过拟合,在私人测试集上面得到差的结果。
根据过去的经验,就在公开排行榜上排前几名的,往往私人测试集很容易就不好。而我们挑选的时候,就是用验证损失,最小的直接挑就好了,不要管公开测试集的结果。理想上就用验证集挑就好,有过比较好的**基线(baseline)**算法以后,就不要再去动它了,就可以避免在测试集上面过拟合。
但是这边会有一个问题,如果随机分验证集,可能会分得不好,分到很奇怪的验证集,会导致结果很差,如果有这个担心的话,可以用 k 折交叉验证(k-foldcross validation)。
k 折交叉验证就是先把训练集切成 k 等份。在这个例子,训练集被切成 3 等份,切完以后,拿其中一份当作验证集,另外两份当训练集,这件事情要重复 3 次。即第一份第 2 份当训练,第 3 份当验证;第一份第 3 份当训练,第 2 份当验证;第一份当验证,第 2 份第 3 份当训练。
接下来有 3 个模型,不知道哪一个是好的。把这 3 个模型,在这 3 个设置下,在这 3 个训练跟验证的数据集上面,通通跑过一次,把这 3 个模型,在这 3 种情况的结果都平均起来,把每个模型的这3种情况的结果,都平均起来,再看看谁结果最好。假设模型1结果最好,3折交叉验证得出的结果是模型1最好。再把模型1用在全部训练集上,训练出来的模型再用再训练集上面即可
不匹配
不匹配和过拟合不同,一般过拟合金可以用增加数据来克服。但是不匹配是指训练集跟测试集的分布不同,再增加训练集几乎没有帮助。我的理解是训练集和测试集看似问题相同,实则差别很大,导致其实两个问题相对独立,训练后对测试集的任务几乎毫无帮助。
增加数据来克服。但是不匹配是指训练集跟测试集的分布不同,再增加训练集几乎没有帮助。我的理解是训练集和测试集看似问题相同,实则差别很大,导致其实两个问题相对独立,训练后对测试集的任务几乎毫无帮助。