Todo:手动实现ANN
手动实现ANN对mushroom进行有毒/无毒的分类
ANN架构
Mushroom_loader:trainning_data/testing_data/validation_data
Step1:读入数据
要把非数值信息转化为数值信息,将每一个转换成维度进行one-hot编码吗?
keras classification;
Step2:基本模型建立
Network课本
Step3:优化
- 计算梯度的方法
- keras
参数的选择与调整:
如何选择神经网络中的超参数?
- 学习速率$\eta$
- 规范化参数$\lambda$
- 隐藏层的个数/神经元的个数
- 学习的回合epoch
- 不同输出的编码方式
- Cost function的形式
- 权重初始化方法
设置超参数的宽泛策略:寻找参数的方法
超参数设置的推荐:
Relu神经元/sigmoid神经元/tanh神经元
交叉验证
如何将原来特征中的非数值信息转化成数值信息,我原来想的是都拆开看。。。
将字母标签转换为数值标签。
这里的蘑菇分类源有22个特征,使用sklearn的preprocessing库函数可以将字母标签转换为数值标签。
sklearn库函数原型的实现可以参照github代码。
但我感觉这个地方没有必要也写源代码啊.
拆分tr_d, va_d, te_d:train_test_split:
采用基于train_data/valid_data/test_data的基本Hold_Out方法
第一次构建神经网络,按照书上最简单的代码构建:
结果:
实验参数使用课本Network1的神经网络架构:
net.SGD(train_data, 30, 10, 3.0, test_data=test_data)
net = Network([22, 30, 2])
net.SGD(train_data, 30, 10, 3.0, test_data=test_data)
net = Network([22, 100, 2])
net.SGD(train_data, 30, 10, 100.0, test_data=test_data)
net = Network([22, 100, 2])
![截屏2020-06-18下午2.02.38](/Users/chixinning/Library/Application Support/typora-user-images/截屏2020-06-18下午2.02.38.png)
net.SGD(train_data, 30, 10, 100.0, test_data=test_data)
net = Network([22, 30, 2])
net = Network([22,30, 2])
net.SGD(train_data, 30, 10, 1, test_data=test_data)
我的妈,试了一下就1了…
我又反复测试了几次,发现学习速率为1的时候,确实正确率可以提到很高。
更改神经网络的架构,使用交叉熵损失函数(Gituhub上的Network2)
疑问:为什么我没有train_test_split我train的性能下降?
也就是说,我如果选择固定的样本训练,而不是随机的样本训练结果不好。
在书上代码中什么是train什么是test?
如果提供“test_data”,则在每个epoch之后,将根据测试数据对网络进行评估,并打印出部分进度。这对跟踪进度很有用,但会大大减慢速度
论好好看书的重要性!
Network1 without Validation!
用Valid_data衡量超参数的选择效果。为了防止我们过度拟合于test_data!
在之前描述 MNIST 数据时,它分成了 60,000 个训练图像和 10,000 个 测试图像。这是官方的 MNIST 的描述。
实际上,我们将用稍微不同的方法对数据进行划分。我 们将测试集保持原样,但是将 60,000 个图像的 MNIST 训练集分成两个部分:一部分 50,000 个 图像,我们将用来训练我们的神经网络,和一个单独的 10,000 个图像的验证集。在本章中我们 不使用验证数据,但是在本书的后面我们将会发现它对于解决如何去设置某些神经网络中的超 参数是很有用的 —— 例如学习速率等,这些参数不被我们的学习算法直接选择。
Network2的改进
Network2与Network1的区别:
- 交叉熵损失函数
- 正则化
- 更好的权重的初始化的值
Same problem again
这个evaluate函数的具体语法形式每次都会很出问题,啊。
2020.6.23科二挂后更新:return 一个np.max。。。
估计是python版本的原因吧
下面这个参数是目前最好的训练参数
我还优化啥?这不就测试完了吗。。。
这valid_data都成了….
看看能不能编,编的我调了很多参的样子…
感觉对于源代码具体逻辑和epoch还不是很理解。
Network2
第三章的代码中使用的为
- sigmoid函数和交叉熵损失函数的组合。
- sigmoid函数和传统的loss函数(2-范数距离,平方损失函数)
- Softmax输出函数和对数似然函数(不重叠饭勒问题)
- Softmax函数的反向传播
规范化与过拟合
epoch比较多,容易Overfitting
分类准确率在测试集上的可视化表现:
在Network1上感受一下过拟合的问题:
过拟合
检测
检测过度拟合的明显方法是:跟踪测试数据集合上的准确率随训练变化的情况。
valid_data的作用: 提前停止的策略:
在每个epoch的最后都计算在valid_data上的分类准确率,一旦分类准确率已经饱和就停止训练
提前停止的更多或更少的激进策略。
防止过拟合
增加训练样本的数量
降低网络规模
Regularization:
Regularization:
权重衰减:$L_2$规范化
增加一个额外的项(规范化项)到代价函数上。
$L_2$正则化的形式:
$\frac{\lambda}{2n}\sum_ww^2$
带正则化项修正后的函数:
$C=C_0+L_2$
正则化项参数$\lambda$的选择:不包含偏置。
规范化当作一种寻找小的权重和最小化原始代价的函数之间的折中。
小的权重和原始化代价之间的折中由超参数$\lambda$来控制。$\lambda$越小,就偏向于最小化原始代价函数
$\lambda$越大,就偏向于小的权重
为什么正则化项的效果不好呢?
正则化项是我们希望离0近一些,可是我们调参的过程中,一般都是从小参数加大的,所以使用正则化的手段和early Stopping做的事情是很接近的。
$L_1Regularization$
$sgn(x)=\begin{cases}x&&x>0\-x&&x<0\end{cases}$
用$L_1$正则化项比较sparse.
当我终于把python scaler改好以后,发现这个参数很明显的时候100个epoch都没有拟合,可是对比
可以看出来lmbda这个参数的影响。
Network2类型的测试
发现lambda参数的影响巨大。
而且自身在train_data上的拟合效果也不好。
lambda为0时,交叉熵的影响比较好。
Network的损失函数,这里交叉熵损失函数的性能不如二次代价函数的效果好。
对于二次代价函数,也是lambda=0/lambda=1时正确率到1的时间不同。
总结:network([22,30,2]),SGD[train_data,epoch=30,$\eta=1$,mini_batch_size=10]的拟合效果比较好。
555我终于也做出来图了!
比较没有加入正则化项时的超参数的调整
虽然是train_test_split但是在测试的时候也只测试了一次。
Epoch=20
Epoch=25
Epoch=30
–
检测过拟合:波动迭代上升
探究是large_weight_initializer和default_weight_initializer.
太明显了,正则化项不能太大,因为这里样本又比较小…
短暂总结:batch_size不明朗,epoch=30绝对正确率1,
正则化lambda太大会影响学习效果。
关于什么时候停止Train,即什么时候确定epoch的大小:
下图是TestingData上的测试值
下图是TrainingData上的测试值
跑一下400Epoch
TestingSet
TrainingSet
当参数调整的好的时候,Total Loss应该逐渐减小。
应该停在TestingSet的Loss最小的时候。但不知道testingSet的error在哪,故需要ValidationData。
跑一下400Epoch尝试一下:
testingSet
###TrainSet
50Epoch
Testing Data
TrainingData:
感觉从图所示,考虑EarlyStop还是35比较好?
35Epoch
TestingData
TrainingData
Epoch=100
TestingData
Epoch=40
epoch=38
Regularization
重新定义我们要去MINIMIZE的LOSS Function
添加一个正则化项。
正则化项一般不考虑bias项,添加正则化项的目的是为了让函数更加平滑。
DropOut(最后一点儿,不知道代码是否可以复现)
防止过拟合的三种方法:
- 正则化
- 认为增加训练样本
- Dropout:弃权记住在训练大规模深度网络时尤其有用。
Network3卷积神经网络的代码,使用了机器学习库了…到时候写一下自己也进行尝试了8。
代码调参部分Over。
开始编报告了。