神经网络:强大的线性模型拓展
1. 神经网络概述
神经网络(Neural Networks,NNs)是大众熟知的机器学习技术之一,其科幻感十足的名称,尤其是随着“深度学习”一词的出现,更具吸引力。它在图像分类应用中备受青睐,如人脸识别。然而,要想用好神经网络并非易事,存在诸多问题:
- “黑盒”操作,内部运行机制不透明。
- 需调整的超参数众多。
- 容易过拟合。
- 计算时间可能较长,处理大数据时可能需要大量内存,运行数小时甚至数天。
- 存在收敛问题。
神经网络受人类思维生物学启发,在二分类问题中,预测变量作为神经元输入,输出 1 或 0,1 表示神经元激活,对应类别 1。它由多个隐藏层组成,前一层神经元输出作为下一层输入,直至最终输出层。节点和单元与神经元同义。后来该方法得到推广,使用输出不限于 1 和 0 的激活函数,并允许后层向前层反馈。
神经网络通常包含输入层、输出层和一个或多个隐藏层。输入层在最左侧,输出层在最右侧,中间为隐藏层。层与层之间,前一层输出作为下一层输入。回归问题输出通常是单个数字,c 类分类问题输出 c 个数字。输入通过线性模型处理,输出通过激活函数处理,激活函数类似于支持向量机(SVM)中的核函数,用于处理非线性关系。例如在图 11 - 1 中,使用的激活函数是逻辑函数 a(t) = 1/[1 + exp(−t)]。
线性组合的系数(权重)计算,在回归问题中,本质是最小化预测误差平方和;在分类问题中,选择权重以最小化总体误分类率或其变体。
2. 复杂基础设施上的工作
qeNeural() 是构建神经网络的函数,属于 qe
系列。qe
系列函数主要是包装器,为各种机器学习算法提供统一、便捷的用户界面。qeNeural() 的大致工作流程如下:
- qeNeural() 包装 regtools() 函数 krsFit()。
- krsFit() 包装 R keras 包中用于神经网络的多个函数。
- R keras 包包装 R tensorflow 包。
- R tensorflow 包包装同名的 Python 包。
- tensorflow 很多部分用 C 语言编写,且依赖 reticulate() 函数在 R 和 Python 间进行翻译。
设置时需注意软件的“双语”性质,例如即使在神经网络运行前调用 set.seed(),每次运行结果仍可能有差异,因为 Python 有自己的随机数生成器。可参考 RStudio 网站获取特定平台的帮助。
3. 示例:脊椎数据
若要拟合模型并进行预测,可指定不使用保留集以充分利用数据进行预测。以下是具体代码:
z <- vert[1,-7] # 排除要预测的 "Y"
nnout <- qeNeural(vert,'V7',holdout=NULL)
拟合过程是迭代的,每次迭代或周期都会给出报告,周期数是超参数。例如,预测与数据中第一个患者相似,但 V2 为 18 而非 22.55 的患者类别:
z$V2 <- 18
predict(nnout,z)
预测结果为类别 “DH”。
4. 神经网络超参数
神经网络库以超参数众多而闻名,qeNeural() 函数设计时尽量减少超参数数量,其调用形式如下:
qeNeural(data,yName,
hidden=c(100,100),
nEpoch=30,
acts=rep("relu", length(hidden)),
learnRate=0.001,
conv = NULL, xShape = NULL,
holdout=floor(min(1000,0.1*nrow(data)))
)
各参数含义如下:
| 参数 | 含义 |
| ---- | ---- |
| hidden | 指定隐藏层数量和每层单元数量(各层数量可不相同),默认表示两个隐藏层,每层 100 个单元。若向量中的数字为小数,表示丢弃率。 |
| nEpoch | 指定周期数。 |
| acts | 为每个隐藏层指定激活函数。 |
| learnRate | 与梯度提升中的学习率类似。 |
| conv, xShape | 用于图像分类设置的参数。 |
这些参数主要用于控制偏差 - 方差权衡(如 hidden、nEpoch)和处理收敛问题(如 nEpoch、acts、learnRate)。值得注意的是,在大多数迭代算法中,迭代次数越多越好,但在神经网络中,过多迭代可能导致过拟合。
5. 激活函数
若每层仅输入和输出线性函数,最终组合仍为线性函数。为处理非线性关系,在每层输出处使用激活函数 a(t)。多年来,关于激活函数的选择存在争议,原则上任何非线性函数都可行,但会出现一些问题,尤其是重要的收敛问题。
例如,当曲线在最小值附近有较浅低谷时,即使学习率较大,也可能导致许多迭代进展甚微,这就是梯度消失问题;若曲线在最小值附近很陡峭,则可能出现梯度爆炸问题,即使很小的学习率也会产生严重影响。
目前,神经网络用户常用的激活函数是修正线性单元(Rectified Linear Unit,ReLU):f(x) 在 x < 0 时为 0,x ≥ 0 时等于 x。
6. 正则化
神经网络容易过拟合,因为许多网络有数千甚至数百万个权重。权重本质上是线性回归系数,总权重数相当于特征数量 p,因此需要降低该值。
6.1 L1 和 L2 正则化
由于神经网络通常最小化平方和,可应用惩罚项来减小解的大小,类似于岭回归和 LASSO。在 LASSO 中,ℓ1 惩罚倾向于产生稀疏解,多数系数为 0。但在神经网络中,由于使用非线性激活函数,可能无法达到此效果。不过,ℓ1 和 ℓ2 仍能缩小权重,在一定程度上实现降维。
6.2 丢弃法正则化
若权重为 0,在网络图中对应链接会被移除。丢弃法直接移除部分链接或节点,例如丢弃率为 0.2 时,随机临时移除给定层 20% 的链接。
7. 示例:跌倒检测数据
以跌倒检测数据为例,进行超参数组合的网格搜索。
pars <- list(hidden=c('5,5','25,25','100,100','100,0.2,100,0.2',
'100,0.5,100,0.5','250,0.5,250,0.5'),
learnRate=c(0.0001,0.0005,0.001,0.005))
ftout <- qeFT(fd,'ACTIVITY','qeNeural',pars=pars,nTst=250,nXval=25)
结果如下:
| hidden | learnRate | meanAcc | CI | bonfCI |
| ---- | ---- | ---- | ---- | ---- |
| 100,100 | 5e - 03 | 0.53256 | 0.5437322 | 0.5519608 |
| 100,0.2,100,0.2 | 5e - 03 | 0.55896 | 0.5669100 | 0.5727654 |
|… |… |… |… |… |
从结果可以看出,尝试不同超参数值效果显著,最小准确率与最大准确率差距较大。同时,学习率较小效果往往较差,过小的学习率不仅会减慢收敛速度,还可能使算法陷入局部最小值。此外,在本次实验中,较小的丢弃率似乎能产生更好的结果。
8. 收敛问题
配置神经网络分析以实现良好收敛通常具有挑战性,可能遇到“破钟问题”,即无论输入如何,网络都预测相同值,或者出现 “nan”(非数字)输出,这可能是由于梯度消失问题导致代码尝试除以 0。以下是一些解决收敛问题的方法:
-
数据缩放
:使用 R 的 scale() 函数或将数据映射到 [0,1] 区间,qeNeural() 软件中已内置缩放功能。
-
调整学习率
:学习率影响收敛速度和结果。
-
更改激活函数
:尝试斜率更陡或更缓的激活函数,例如 a(t) = 1/(1 + exp(−2t)) 在 t = 0 附近比普通逻辑函数更陡。
-
提前停止
:在神经网络中,过多迭代可能导致收敛到较差解,因此可采用提前停止策略。
-
动量
:将最后几次步长组合,下一步长设为最后几次的加权平均值,近期步长权重更大。此超参数在 qeNeural() 中不可用,但可通过 keras 包直接访问。
回归应用由于 Y 无界,可能比分类应用更易出现收敛问题。
9. 与多项式回归的紧密关系
多项式回归是特征为多项式形式的线性模型,例如二次模型中,除了人的身高和年龄特征外,还包括身高和年龄的平方以及交叉项(身高 × 年龄)。在支持向量机中,也会出现多项式核。
神经网络本质上也在进行多项式回归。例如,若激活函数为平方函数 t²,隐藏层中每个节点对输入进行线性组合后输出其平方,隐藏层输出为输入的二次多项式;若有第二个隐藏层,其输出为四次多项式。若激活函数本身为多项式,后续层会产生更高次多项式。
常用激活函数如双曲正切函数 tanh(t) 有泰勒级数展开,可近似为多项式回归;ReLU 虽无泰勒级数展开,但也可进行多项式逼近。
然而,对于大数据集,直接使用多项式回归计算不可行,因为调用 lm() 或 glm() 时会有大量多项式项,导致内存问题。神经网络通过迭代寻找最小二乘解,虽可能有收敛问题,但内存使用较少。通过尝试不同超参数组合,仍可能获得较好结果,并且在某些问题上找到合适的神经网络拟合后,可通过微调应用于相关问题(迁移学习)。
10. 神经网络中的偏差与方差
通常将隐藏层数量称为网络深度,每层单元数量称为宽度。深度与宽度平方的乘积越大,网络的权重或参数越多。如前文所述,模型参数越多,方差越大,偏差越小。
从与多项式回归的关系来看,神经网络中隐藏层数量越多,多项式回归近似的次数越高,多项式回归模型次数越高,偏差越小但方差越大。因此,设计神经网络架构时,必须考虑偏差 - 方差权衡。
11. 总结与建议
近年来,神经网络在机器学习“革命”中发挥了重要作用,在某些应用中取得显著成功。但它也存在计算成本高(部分情况运行数小时甚至数天)和收敛问题等挑战。
此外,机器学习社区普遍认为,神经网络对表格数据(存储在数据框中的数据)效果不佳。建议将神经网络保留用于图像识别和自然语言处理等应用。
12. 神经网络架构设计要点
在设计神经网络架构时,需要综合考虑多个因素,以平衡偏差和方差,提高模型性能。以下是一些关键要点:
-
深度与宽度的选择
:增加隐藏层数量(深度)和每层单元数量(宽度)会增加模型复杂度,降低偏差,但可能导致方差增大。应根据数据集大小和问题复杂度合理选择。例如,对于简单问题和小数据集,较浅和较窄的网络可能就足够;对于复杂问题和大数据集,可能需要更深更宽的网络。
-
超参数调整
:如前文所述,超参数对模型性能有重要影响。可以通过网格搜索、随机搜索等方法,尝试不同的超参数组合,找到最优解。例如,在跌倒检测数据示例中,通过调整隐藏层结构、学习率和丢弃率等超参数,显著提高了模型准确率。
-
激活函数选择
:不同的激活函数适用于不同的场景。ReLU 因其简单高效,在大多数情况下是一个不错的选择,但在某些情况下,其他激活函数可能更合适。例如,在处理梯度消失问题时,可以尝试使用 Leaky ReLU 等改进版本的激活函数。
13. 神经网络的应用领域
神经网络在多个领域取得了广泛的应用,以下是一些主要领域:
| 应用领域 | 具体应用 |
| ---- | ---- |
| 图像识别 | 人脸识别、物体检测、图像分类等。例如,在安防领域,人脸识别技术用于门禁系统和监控摄像头,提高安全性。 |
| 自然语言处理 | 机器翻译、情感分析、文本生成等。例如,谷歌翻译使用神经网络技术实现了高质量的多语言翻译。 |
| 语音识别 | 语音助手、语音指令识别等。例如,苹果的 Siri 和亚马逊的 Alexa 都是基于神经网络的语音识别技术。 |
| 金融领域 | 风险评估、股票预测、信用评分等。例如,银行使用神经网络模型评估客户的信用风险,决定是否发放贷款。 |
| 医疗领域 | 疾病诊断、医学图像分析等。例如,通过分析医学影像(如 X 光、CT 扫描),神经网络可以帮助医生更准确地诊断疾病。 |
14. 神经网络的未来发展趋势
随着技术的不断进步,神经网络将继续发展和演变。以下是一些可能的未来发展趋势:
-
模型轻量化
:为了在移动设备和嵌入式系统上运行神经网络,需要开发更轻量级的模型。这将涉及到模型压缩、剪枝和量化等技术,以减少模型的参数数量和计算量。
-
强化学习与神经网络的结合
:强化学习是一种通过与环境交互来学习最优策略的方法。将强化学习与神经网络相结合,可以解决更复杂的决策问题,如自动驾驶和机器人控制。
-
可解释性研究
:由于神经网络通常被视为“黑盒”模型,其决策过程难以解释。未来的研究将致力于提高神经网络的可解释性,使人们能够更好地理解模型的决策依据。
-
跨领域应用
:神经网络将在更多领域得到应用,如农业、能源、交通等。通过将神经网络技术与这些领域的专业知识相结合,可以解决更多实际问题。
15. 总结
神经网络作为一种强大的机器学习技术,在许多领域取得了显著的成功。然而,它也面临着一些挑战,如计算成本高、收敛问题和过拟合等。在使用神经网络时,需要合理设计架构,调整超参数,选择合适的激活函数和正则化方法,以提高模型性能。
同时,我们也应该关注神经网络的未来发展趋势,不断探索新的应用领域和技术方法。通过不断学习和实践,我们可以更好地掌握神经网络技术,为解决实际问题提供更有效的解决方案。
总之,神经网络是一个充满潜力和挑战的领域,值得我们深入研究和探索。希望本文能够帮助读者更好地理解神经网络的原理、应用和发展趋势,为进一步学习和实践提供参考。
超级会员免费看

被折叠的 条评论
为什么被折叠?



