周志华《机器学习》课后习题(第五章):神经网络

简介: 周志华《机器学习》课后习题(第五章):神经网络

5.1 试述将线性函数 image.png用作神经元激活函数的缺陷。

答:

使用线性函数作为激活函数时,无论是在隐藏层还是在输出层(无论传递几层),其单元值(在使用激活函数之前)都还是输入 image.png的线性组合,这个时候的神经网络其实等价于逻辑回归(即原书中的对率回归,输出层仍然使用Sigmoid函数)的,若输出层也使用线性函数作为激活函数,那么就等价于线性回归 。


5.2 试述使用图 5.2(b) 激活函数的神经元与对率回归的联系。


答:

使用Sigmoid激活函数,每个神经元几乎和对率回归相同,只不过对率回归在 image.png 时输出为1,而神经元直接输出 image.png


5.3 对于图 5.7 中的image.png,试推导出 BP 算法中的更新公式 (5.13)。

答:

image.png

image.png


简单说就是学习率太高会导致误差函数来回震荡,无法收敛;而学习率太低则会收敛太慢,影响训练效率。

在原书p104也提到过。


5.5 试编程实现标准 BP 算法和累积 BP 算法,在西瓜数据集 3.0 上分别用这两个算法训练一个单隐层网络,并进行比较。


答:

标准 BP 算法和累积 BP 算法在原书(P105)中也提到过,就是对应标准梯度下降和随机梯度下降,差别就是后者每次迭代用全部数据计算梯度,前者用一个数据计算梯度。

代码在:

https://github.com/han1057578619/MachineLearning_Zhouzhihua_ProblemSets/tree/master/ch5--%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/5.5-5.6

具体两种情况的结果如下图:可以看出来gd的成本函数收敛过程更加稳定,而sgd每次迭代并不一定向最优方向前进,但总体方向是收敛的,且同样是迭代200次,最后结果相差不大,但由于sgd每次迭代只使用一个样本,计算量大幅度下降,显然sgd的速度会更快。

ps.关于随机梯度下降的实现,好像有两种方式,一种是每次将样本打乱,然后遍历所有样本,而后再次打乱、遍历;另一种是每次迭代随机抽取样本。这里采取的是后一种方式,貌似两种方式都可以。

此外,BP神经网络代码在以前学吴恩达老师深度学习课程的时候就写过,这次整理了一下正好放上来,所以很多代码和课程代码类似,添加了应用多分类的情况的代码。下面的5.6题也一并在这里实现。

image.png


5.6 试设计一个 BP 改进算法,能通过动态调整学习率显著提升收敛速度。编程实现该算法,并选择两个 UCI 数据集与标准 BP 算法进行实验比较。

答:

动态调整学习率有很多现成的算法,RMSProp、Adam、NAdam等等。也可以手动实现一个简单指数式衰减image.png 是一个超参。这里代码实现了Adam,下面

代码和5.5一同实现,同样在:

https://github.com/han1057578619/MachineLearning_Zhouzhihua_ProblemSets/tree/master/ch5--%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/5.5-5.6

这里只尝试了sklearn 中自带的iris数据集试了一下。同样学习率下,两者训练时损失函数如下:

image.png


可以明显看出adam的速度更快的。


5.7 根据式 (5.18)和 (5.19) ,试构造一个能解决异或问题的单层 RBF 神经网络。


答:

这里可以使用X = array([[1, 0], [0, 1], [0, 0], [1, 1]]),y = array([[1], [1], [0], [0]])作为数据,训练一个RBF神经网络。

这里使用均方根误差作为损失函数;输出层和书上一致,为隐藏层的线性组合,且另外加上了一个偏置项(这是书上没有)。

代码在:

'''
这里使用均方根误差作为损失函数的RBF神经网络。
'''
import numpy as np
import matplotlib.pyplot as plt
def RBF_forward(X_, parameters_):
    m, n = X_.shape
    beta = parameters_['beta']
    W = parameters_['W']
    c = parameters_['c']
    b = parameters_['b']
    t_ = c.shape[0]
    p = np.zeros((m, t_))  # 中间隐藏层的激活值     对应书上5.19式
    x_c = np.zeros((m, t_))  # 5.19式中 x - c_{i}
    for i in range(t_):
        x_c[:, i] = np.linalg.norm(X_ - c[[i],], axis=1) ** 2
        p[:, i] = np.exp(-beta[0, i] * x_c[:, i])
    a = np.dot(p, W.T) + b
    return a, p, x_c
def RBF_backward(a_, y_, x_c, p_, parameters_):
    m, n = a_.shape
    grad = {}
    beta = parameters_['beta']
    W = parameters_['W']
    da = (a_ - y_)      # 损失函数对输出层的偏导 ,这里的a其实对应着  输出层的y_hat
    dw = np.dot(da.T, p_) / m
    db = np.sum(da, axis=0, keepdims=True) / m
    dp = np.dot(da, W)   # dp即损失函数对隐藏层激活值的偏导
    dbeta = np.sum(dp * p_ * (-x_c), axis=0, keepdims=True) / m
    assert dbeta.shape == beta.shape
    assert dw.shape == W.shape
    grad['dw'] = dw
    grad['dbeta'] = dbeta
    grad['db'] = db
    return grad
def compute_cost(y_hat_, y_):
    m = y_.shape[0]
    loss = np.sum((y_hat_ - y) ** 2) / (2 * m)
    return np.squeeze(loss)
def RBF_model(X_, y_, learning_rate, num_epochs, t):
    '''
    :param X_:
    :param y_:
    :param learning_rate:  学习率
    :param num_epochs:     迭代次数
    :param t:   隐藏层节点数量
    :return:
    '''
    parameters = {}
    np.random.seed(16)
    # 定义中心点,本来这里的中心点应该由随机采用或者聚类等非监督学习来获得的,这里为了简单就直接定义好了
    parameters['beta'] = np.random.randn(1, t)  # 初始化径向基的方差
    parameters['W'] = np.zeros((1, t))  # 初始化
    parameters['c'] = np.random.rand(t, 2)
    parameters['b'] = np.zeros([1, 1])
    costs = []
    for i in range(num_epochs):
        a, p, x_c = RBF_forward(X_, parameters)
        cost = compute_cost(a, y_)
        costs.append(cost)
        grad = RBF_backward(a, y_, x_c, p, parameters)
        parameters['beta'] -= learning_rate * grad['dbeta']
        parameters['W'] -= learning_rate * grad['dw']
        parameters['b'] -= learning_rate * grad['db']
    return parameters, costs
def predict(X_, parameters_):
    a, p, x_c = RBF_forward(X_, parameters_)
    return a
X = np.array([[1, 0], [0, 1], [0, 0], [1, 1]])
y = np.array([[1], [1], [0], [0]])
#
parameters, costs = RBF_model(X, y, 0.003, 10000, 8)
plt.plot(costs)
plt.show()
print(predict(X, parameters))
# 梯度检验
# parameters = {}
# parameters['beta'] = np.random.randn(1, 2)  # 初始化径向基的方差
# parameters['W'] = np.random.randn(1, 2)  # 初始化
# parameters['c'] = np.array([[0.1, 0.1], [0.8, 0.8]])
# parameters['b'] = np.zeros([1, 1])
# a, p, x_c = RBF_forward(X, parameters)
#
# cost = compute_cost(a, y)
# grad = RBF_backward(a, y, x_c, p, parameters)
#
#
# parameters['b'][0, 0] += 1e-6
#
# a1, p1, x_c1 = RBF_forward(X, parameters)
# cost1 = compute_cost(a1, y)
# print(grad['db'])
#
# print((cost1 - cost) / 1e-6)


最后输出是:

[[ 9.99944968e-01]
[ 9.99881045e-01]
[ 8.72381056e-05]
[ 1.26478454e-04]]

感觉,分类的时候在输出层使用sigmoid作为激活函数也可以。


5.8 从网上下载或自己编程实现 SOM 网络,并观察其在西瓜数据集 3.0α上产生的结果。


答:

花了挺长时间看,写完代码的发现结果和预期有点不太符合,先暂时放一下吧还是...代码不完整就不放了。

这里提一个迷惑了我很久的一点,有些博客说SOM神经网络的聚类类别不需要自己定义,其实是不对的,SOM神经网络输出聚类类别是需要自己定义,每个输出节点对应着一个类别,通过计算样本和输出节点的权重向量的相似度来确定样本属于哪个类别(节点);输入节点的数量和样本的维度一样(和BP网络相同);输出的节点常常是以二维矩阵(这里可以是正方形也可以多边形等)或者一维直线的形式,每一个输出节点对应着一个权重向量和输入节点实现全连接。

想了解SOM建议参考下面几个链接:

https://www.jianshu.com/p/41fc86728928

https://github.com/KeKe-Li/tutorial/blob/master/assets/src/SOM/SOM.md

https://www.cs.bham.ac.uk/~jxb/NN/l16.pdf


5.9* 试推导用于 Elman 网络的 BP 算法.


答:

Elman 网络在西瓜书原书上说的是“递归神经网络”,但是在网上找资料说的

“递归神经网络”是空间维度的展开,是一个树结构。
“循环神经网络”是时间维度的展开,代表信息在时间维度从前往后的的传递和积累。

从书上p111描述来看感觉更像“循环神经网络”。最近时间不多(lan..),就不去啃原论文了。关于“循环神经网络”或者递归神经网络的BP可以参考下面链接。

1、零基础入门深度学习(5) - 循环神经网络 ,网上大神写了。

https://zybuluo.com/hanbingtao/note/541458

另外关于循环神经网络也可以看看吴恩达老师的深度学习课程“序列模型”那部分。


5.10 从网上下载或自己编程实现一个卷积神经网络并在手写字符识别数据 MNIST 上进行实验测试。


答:

正好前段时间做过Kaggle上手写数字识别的题目。这里正好放上来,CNN是用Tensorflow实现的,之前看吴恩达老师深度学习课程的时候也拿numpy实现过(课程作业),等以后有时间再整理放上来吧。

https://github.com/han1057578619/kaggle_competition/tree/master/Digit_Recogniz

系列文章:

1. 周志华机器学习课后习题解析【第二章】

2. 周志华《机器学习》课后习题(第三章):线性模型

3. 周志华《机器学习》课后习题解析(第四章):决策树



相关文章
|
9月前
|
机器学习/深度学习 数据采集 运维
机器学习在网络流量预测中的应用:运维人员的智慧水晶球?
机器学习在网络流量预测中的应用:运维人员的智慧水晶球?
442 19
|
9月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于机器学习的人脸识别算法matlab仿真,对比GRNN,PNN,DNN以及BP四种网络
本项目展示了人脸识别算法的运行效果(无水印),基于MATLAB2022A开发。核心程序包含详细中文注释及操作视频。理论部分介绍了广义回归神经网络(GRNN)、概率神经网络(PNN)、深度神经网络(DNN)和反向传播(BP)神经网络在人脸识别中的应用,涵盖各算法的结构特点与性能比较。
|
10月前
|
机器学习/深度学习 边缘计算 运维
机器学习在网络安全中的防护:智能化的安全屏障
机器学习在网络安全中的防护:智能化的安全屏障
482 15
|
11月前
|
人工智能 搜索推荐 决策智能
不靠更复杂的策略,仅凭和大模型训练对齐,零样本零经验单LLM调用,成为网络任务智能体新SOTA
近期研究通过调整网络智能体的观察和动作空间,使其与大型语言模型(LLM)的能力对齐,显著提升了基于LLM的网络智能体性能。AgentOccam智能体在WebArena基准上超越了先前方法,成功率提升26.6个点(+161%)。该研究强调了与LLM训练目标一致的重要性,为网络任务自动化提供了新思路,但也指出其性能受限于LLM能力及任务复杂度。论文链接:https://arxiv.org/abs/2410.13825。
216 12
|
机器学习/深度学习 人工智能 数据挖掘
打破传统:机器学习与神经网络获2024年诺贝尔物理学奖引发的思考
诺贝尔物理学奖首次授予机器学习与神经网络领域,标志该技术在物理学研究中的重要地位。本文探讨了这一决定对物理学研究的深远影响,包括数据分析、理论物理突破及未来科研方向的启示,同时分析了其对学术跨界合作与全球科研产业的影响。
228 4
|
机器学习/深度学习 数据采集 算法
机器学习在医疗诊断中的前沿应用,包括神经网络、决策树和支持向量机等方法,及其在医学影像、疾病预测和基因数据分析中的具体应用
医疗诊断是医学的核心,其准确性和效率至关重要。本文探讨了机器学习在医疗诊断中的前沿应用,包括神经网络、决策树和支持向量机等方法,及其在医学影像、疾病预测和基因数据分析中的具体应用。文章还讨论了Python在构建机器学习模型中的作用,面临的挑战及应对策略,并展望了未来的发展趋势。
773 1
|
1月前
|
机器学习/深度学习 数据采集 人工智能
【机器学习算法篇】K-近邻算法
K近邻(KNN)是一种基于“物以类聚”思想的监督学习算法,通过计算样本间距离,选取最近K个邻居投票决定类别。支持多种距离度量,如欧式、曼哈顿、余弦相似度等,适用于分类与回归任务。结合Scikit-learn可高效实现,需合理选择K值并进行数据预处理,常用于鸢尾花分类等经典案例。(238字)
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
1154 6
|
6月前
|
机器学习/深度学习 数据采集 人工智能
20分钟掌握机器学习算法指南
在短短20分钟内,从零开始理解主流机器学习算法的工作原理,掌握算法选择策略,并建立对神经网络的直观认识。本文用通俗易懂的语言和生动的比喻,帮助你告别算法选择的困惑,轻松踏入AI的大门。
|
7月前
|
机器学习/深度学习 存储 Kubernetes
【重磅发布】AllData数据中台核心功能:机器学习算法平台
杭州奥零数据科技有限公司成立于2023年,专注于数据中台业务,维护开源项目AllData并提供商业版解决方案。AllData提供数据集成、存储、开发、治理及BI展示等一站式服务,支持AI大模型应用,助力企业高效利用数据价值。