现有的 网络参数 初始化 方法
全零初始化
网络参数初始化方法 最粗暴的 莫过于 全零初始化 。顾名思义,所有参数全部初始化为0。想法很好,简便省事儿,还可使得初始化全零时参数的期望与网络稳定时参数的期望一致为0。
But,参数全为0,那么同层网络中,所有神经元的输出必然相同。而相同的输出,意味着。。梯度更新完全一样。。。那模型还训练个卵。。。。
随机初始化
于是最常用的就是 随机初始化 。通过一套机制来随机生成参数填充。
在 tensorflow 中具体体现在指定 initializer
为 tf.contrib.layers.xavier_initializer_conv2d()
,例如:
weights = tf.get_variable(name="weights", shape=[2, 2, in_channel, out_channel],
initializer=tf.contrib.layers.xavier_initializer_conv2d())
数据敏感初始化
当然,还有一些偏门左道的初始化方法,比如 数据敏感的 参数初始化 方式 ,即根据自身任务数据集个性化定制的参数初始化方式。
症结
但这些参数初始化方法都是建立在对各网络层 一视同仁 的基础上,用同一套简单机制去填喂初始参数。
那么,有没有 “因材施教式” 的 参数初始化 办法 呢?
思考
初始化后的深度学习模型的训练就像一个婴孩。在训练过程中,各网络层 总数不变,但在梯度下降的 引导 下,不断 分化 成各种 功能层 。各功能层 协作 ,使得模型成熟而强大。
纵观生物界,同一物种的分化基本都遵循一定规律。那么神经网络这种 “生物”,相信也 必然 有它的 分化规律,正亟待各位大佬们去发现和总结。
解决方法
在 思考: 神经网络层 的 功能识别 一文中,我提出了 对 神经网络层 进行 功能识别 这么一个idea。那么这个idea自然也可以延伸到 改进 现有的 网络参数初始化 方法 上来。
首先,对现有的经典网络结构进行 各 神经网络层 功能识别 。
其次,将得到的识别结果进行 数据对比和分析 ,总结出规律。(例如得到下表这种效果)
对应层的深度范围 | 颜色 | 边缘 | 纹理 | 肢干 | 整体 |
---|---|---|---|---|---|
约前20% | ⋆ ⋆⋆⋆ | ⋆ | |||
20%~40% | ⋆ | ⋆⋆⋆ | ⋆ | ||
40%~60% | ⋆ | ⋆⋆⋆ | ⋆ | ||
60%~80% | ⋆ | ⋆⋆⋆ | ⋆ | ||
80%~100% | ⋆ | ⋆⋆⋆⋆ |
在表中可大致看出各深度范围的网络层 可能对应的大概功能(但是实际情况中,网络结构部件千变万化,肯定不是仅仅考虑“深度”这么一个变量。这边只是用最简单的网络结构举个例子)
最后,将不同深度范围的网络层,在初始化阶段“分而(初始)化之” 。即 分别 初始化 为该部分对应的 模板滤波器集 。节省 后期 分化 任务量,从而在初始化的时候就赢在起跑线。
对优点和缺点的预估
可能的优点
可以预见的是,初始化阶段使用该新方法,加快 收敛速度 是一定的,毕竟赢在了起跑线。
可能的缺点
会不会比随机初始化方法更容易陷入过拟合,这个我就不敢肯定了。需要在具体问题上再具体分析。
写在最后
一言以蔽之:不直接拿成熟模型来迁移学习,只参照了人家的套路。
一点拙见,可以一试。等最近几个月忙完,我打算找个时间看看能不能亲手实现之。