上篇直接就上了一个示例神经网络,尽管我代码每一行都注释了,因为格式对齐问题,可能看起来还是费劲,我在多说几句Pytorch的优化的思路,说白了本质上和传统的机器学习没区别,准备数据-定义模型-定义损失函数-使用数据反复训练这个模型,直到损失函数的误差值小于一定的值即可。
变量和参数位置的转换
这里最难理解的就是就是函数变量的转换,我们在正常数学里面学的函数变量是各个坐标或维度的值,值我们是不知道的,知道的是各个项的系数,也就是说我常规处理方法是模型确定的,我们只要给模型输入然后产出一个值就是我们所有获取的,过程比较确定,而现在正好反过来了,我们有了大量大维度数据了,但是怎么产生这些数据的模型我们不知道,也就是说我们需要找到个模型,寻找之前常规函数群中的系数,我们常规是通过系数来确定数据,现在是通过数据来确定系数,使函数群可以完美的解释这些数据,最最初我们就是逻辑回归,聚类、等方法,现在呢,我采用神经网络模型。
上一篇体会我也说了,什么是神经网络,一句话,就是一个函数变换器,给一组输入最后给出一个输出。关键是组成神经网络的基础运算单元都是线性函数然后外包一个非线性的变换函数,这些非线性的便函函数的形式又不是特别复杂,在导数的形式上有容易计算的特点,多个这类单元的组合显然就可以完成复杂的非线性数据的拟合。
目标函数
目标函数-听起来类,我的理解就是损失函数,实际的采样输出值和原始输入经过神经网络预测的值的差值函数,当然这个差值的计算函数的表现形式可以自己定义成自己喜欢的或者使用系统标准的。我们梯度的反向传播就是计算这个差值函数对各个节点的系数梯度,本质上就是这个函数对各个节点系数的导数,当然这里系数往往是个矩阵。最后反向求导计算完的也是一个系数的梯度矩阵。
损失函数的形式:可以参见 https://blog.csdn.net/zhangxb35/article/details/72464152
优化和训练
这是什么东西?说白了就是计算向真实值考虑的各个系数跟新的策略,可能你会和我开始学习一样,直接减或加梯度不就行了,那么麻烦干嘛,直接加减梯度数学模型没问题,但是实际的操作过程中会有问题,我们想一下,这个模型是怎么来的,是数据真实的模型吗?不是,是我们自己倒腾的,是不是能够反映这些数据的规律,真不知道,这个时候怎么办,和我们通常人处理问题一样,知道方向了,小步前进,想想我们人在处理位置问题的时候,是不是在知道解决问题的大方向的时候是不是变着花样试着怎么解决问题最合适?优化器的原理就是这个,这些方法是拍脑袋想出来的?不是,大量实践总结出来的,
回想一下我们人类解决问题过程是一次解决问题吗?尤其是针对未知的问题,显然不是,我们可能会经过N轮的尝试,最终才能找到解决问题的方案,同样,我们建立的神经网络的目的是在已知的数据中找适合的参数的模型,显然一次肯定不能找到最优的参数配置,这就需要根据上一次的结果多跑几次,然后才能得到想要的模型,等等,真能得到完美契合的模型吗?有些问题可以,有些问题,呵呵了,显然不能,和我们通常解决问题一样,最靠近真实解就行了,那么神经网络训练就是目标函数的差值小于某个规定的值即可。这种就是训练
常见的优化方法如下:
# SGD 就是随机梯度下降
opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
# momentum 动量加速,在SGD函数里指定momentum的值即可
opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
# RMSprop 指定参数alpha
opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
# Adam 参数betas=(0.9, 0.99)
opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
可以参见:https://ptorch.com/news/54.html
学习效率
等等呢,学习效率什么鬼?就是你每次决定走多大,梯度知道了,是不是真实按照梯度值走,这就是学习效率,和我们人类解决问题一样,我知道一步跨过去就可以到达目的地,但是,现在位置真的可以一步到达目的吗?想想我们出去旅游,我们和黄山风景区之间直线距离就是320公里,我直接按照这个320公里的方向走?肯定行不通,那么怎么办,我们先朝着黄山的方向按照既定的策略走一小部分,这一小部分针对一下子到黄山来说就是个学习效率,也就是说,我不一下子到目的地,我先按照选定的策略方向走目前可以明确知道的,等走完了,在考虑下一步的行动。等等,我仅仅是打个比方。