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

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

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. 周志华《机器学习》课后习题解析(第四章):决策树



相关文章
|
18天前
|
机器学习/深度学习 人工智能 数据挖掘
打破传统:机器学习与神经网络获2024年诺贝尔物理学奖引发的思考
诺贝尔物理学奖首次授予机器学习与神经网络领域,标志该技术在物理学研究中的重要地位。本文探讨了这一决定对物理学研究的深远影响,包括数据分析、理论物理突破及未来科研方向的启示,同时分析了其对学术跨界合作与全球科研产业的影响。
47 4
|
18天前
|
机器学习/深度学习 数据采集 算法
机器学习在医疗诊断中的前沿应用,包括神经网络、决策树和支持向量机等方法,及其在医学影像、疾病预测和基因数据分析中的具体应用
医疗诊断是医学的核心,其准确性和效率至关重要。本文探讨了机器学习在医疗诊断中的前沿应用,包括神经网络、决策树和支持向量机等方法,及其在医学影像、疾病预测和基因数据分析中的具体应用。文章还讨论了Python在构建机器学习模型中的作用,面临的挑战及应对策略,并展望了未来的发展趋势。
56 1
|
22天前
|
机器学习/深度学习 自然语言处理 算法
深入理解机器学习算法:从线性回归到神经网络
深入理解机器学习算法:从线性回归到神经网络
|
1月前
|
机器学习/深度学习 人工智能 安全
人工智能与机器学习在网络安全中的应用
人工智能与机器学习在网络安全中的应用
57 0
|
2月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
71 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
3月前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
117 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
3月前
|
机器学习/深度学习 安全 网络安全
利用机器学习优化网络安全威胁检测
【9月更文挑战第20天】在数字时代,网络安全成为企业和个人面临的重大挑战。传统的安全措施往往无法有效应对日益复杂的网络攻击手段。本文将探讨如何通过机器学习技术来提升威胁检测的效率和准确性,旨在为读者提供一种创新的视角,以理解和实施机器学习在网络安全中的应用,从而更好地保护数据和系统免受侵害。
|
2月前
|
机器学习/深度学习 人工智能 算法
#如何看待诺贝尔物理学奖颁给了机器学习与神经网络?#
2024年诺贝尔物理学奖首次颁发给机器学习与神经网络领域的研究者,标志着这一技术对物理学及多领域应用的深远影响。机器学习和神经网络不仅在生产、金融、医疗等行业展现出高效实用性,还在物理学研究中发挥了重要作用,如数据分析、模型优化和物理量预测等,促进了物理学与人工智能的深度融合与发展。
33 0
|
2月前
|
机器学习/深度学习 算法
【机器学习】揭秘反向传播:深度学习中神经网络训练的奥秘
【机器学习】揭秘反向传播:深度学习中神经网络训练的奥秘
|
2月前
|
机器学习/深度学习 人工智能 算法
【人工智能】人工智能的历史发展与机器学习和神经网络
【人工智能】人工智能的历史发展与机器学习和神经网络
72 0