奇奇怪怪的知识增加了——那些神经网络中出现的问题
看完了视频课,做完了练习题,开始实战,啊这啥情况,啊这又是啥情况,啊这老师没教过啊,啊这论文没写过啊,没错,奇奇怪怪的问题开始出现了。其实这并不奇怪,神经网络嘛,老黑盒了。那么就来看看神经网络中论文不会写,但你却会遇到的奇怪问题吧。本文不定期更新,全看我自己遇到了哪些新的乐子。
数据与损失函数(过拟合)
拟合模型最大的特点是,从外部没有办法直接把需求传递给模型,模型只会也只能通过数据和损失函数,换句话说,模型并不是真正按着设计者的要求去做的,这是人类思维与计算机思维的区别,以分类模型为例,假设有以下两个图片样本做为训练集 该样本的标签为A 该样本的标签为B
那么问题是 这个测试样本的标签是什么呢? 有兴趣的可以从人类的角度去观察一下猜猜,但这道题的答案是——都可以 这就是问题所在了,首先,区分A和B两个样本的方法有很多,这是因为样本中总是包含不同的特征,例如,A样本可以看出是在室外,可以看出是蓝色的,可以看出车头对着右,B样本可以看出是在室内,可以看出是黄色的,可以看出车头冲着我们,那再看看这个测试样本,场景是在室外,与A相同,蓝色的,与A相同,车头冲着我们,与B相同,显然,从人类的角度来看,根据分类的标准不同,测试样本被分为A和B的可能性都是有的,可能有人会觉得,测试样本与A样本有两种特征相同,与B只有一种特征相同,那不是应该更倾向于A么,很遗憾,首先这里我们是以人类的角度去考虑的,模型的关注点与我们未必相同,其次,如果模型发现某种特征可以区分开数据,一般来说就不会再去学习新的特征了,这点常见于GAN的模式崩溃——如果你希望模型生成猫和狗的图片,生成器生成猫的图片后发现判别器通过了,那么后面生成的有可能就全是猫,反之亦然。 所以说,所谓的数据和损失函数,实际上都是以区分开标签为目的的,换句话说,我们没有办法告诉模型我想让你确认的特征是什么,我们最多能说我想让你作区分,至于特征是什么,你自己看着办吧,也就是说,数据光有数量是不够的,还要有区分度,也就是有质量,各种类型的样本数量均衡是同样的道理。那如果数据不够怎么办呢,首先就应该考虑人为破坏某些不相干的特征,这点常用于数据增强,比如我不想让你识别车头方向,那我把图像翻转了,不想让你识别长度,那我把图像拉伸压缩,不想让你识别车体的形状,那我把图像裁剪再乱拼起来,不想让你识别颜色,那我把图像灰化了,这些都是可以的。如果你的数据是爬来的,就应该注意,别对着一个地方使劲儿爬,比如想训练文本生成,你去知乎爬,训练出来模型张嘴就“人在美国刚下飞机”,去网易云爬,训练出来模型张嘴就“有的人8岁就死了80岁才埋”,倾向性都很明显,放在现实里典型的人传人现象,小丑的演员把自己扔精神病院呆久了人不是也疯了么。但如果你在各个网站爬,那样本就会相对均匀,模型能学到的东西也更多。
损失函数在某个位置急剧反弹(学习率调整)
这个问题比较偏工程,论文里没法说。这种情况在分类问题里比较少见,但是在输出序列的模型里经常见到。这种现象出现的原因是当输出为序列时,模型需要顾及的问题会远比输出几个点多,这种情况下轻微的参数变动就可能导致连锁反应,在刚开始训练时,你完全可以这样来节省时间 然后训练了一段时间后就 显然,半面墙的情况,你照一面墙的力道去训练,砸过界了 那这种情况怎么办呢,我说上句你接下句 前方收费站
这种情况也很好解决,在合适的时候降低学习率就行了,问题就在于这个合适的时候,首先我一说到降低学习率,估计大家首先会想到的就是学习率衰减torch.optim.lr_scheduler.StepLR 但实际情况是这东西并没有想象中好用,因为我们在训练之前并不知道“收费站”具体在哪,就算知道了,这种提前设置就相当于让你在开车的时候给一脚油门,然后精准地停在收费站前,显然这并不容易,大部分时候要么停早了还得补,要么就直接冲卡了,那这种时候怎么办呢?这里个人的建议是,首先设置一个函数,在循环外计算一定范围内的损失函数变化,周期性地条件语句作为检查点,当该函数下降时,周期性地保存模型,这个周期具体多久可以看个人情况,我个人是设置在每次迭代后;然后人为观察,当发现损失函数出现异常反弹(设置了训练过程中显示损失函数)或在资源管理器里发现模型已经有相当长的时间没有保存(没设置训练过程中显示,不过一般情况下应该都会设置吧。。。)时手动终止训练,然后人工降低学习率,读取模型继续训练。如果需要append记录损失函数变化趋势时,请同样周期性保存负责记录的数组,在读取模型时读取该数组继续训练。
暂时先写这么多了,后面遇到啥奇怪的情况继续写,有时候感觉做工程也是件挺有趣的事吧,能遇到各种奇奇怪怪的问题。
|