深度学习——第7章 项目实战:自己动手写一个神经网络模型

这篇具有很好参考价值的文章主要介绍了深度学习——第7章 项目实战:自己动手写一个神经网络模型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第7章 项目实战:自己动手写一个神经网络模型

目录

7.1 导入数据集

7.2 定义神经网络输入层、隐藏层、输出层神经元个数

7.3 网络参数W和b初始化

7.4 正向传播过程

7.5 损失函数

7.6 反向传播过程

7.7 网络参数更新

7.8 搭建整个神经网络模型

7.9 模型训练

7.10 模型预测

7.11 隐藏层神经元个数对分类效果的影响

上一课主要介绍了最简单的二层神经网络模型,详细推导其正向传播过程和反向传播过程,对整个神经网络的模型结构和数学理论推导过程有了清晰的认识和掌握。

本章将带大家使用Python搭建一个神经网络模型来解决实际的分类问题。

7.1 导入数据集

为了简化操作,我们直接构造一批数据集。

import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline

r = np.random.randn(200)*0.8
x1 = np.linspace(-3, 1, 200)
x2 = np.linspace(-1, 3, 200)
y1 = x1*x1 + 2*x1 - 2 + r
y2 = -x2*x2 + 2*x2 + 2 + r

X = np.hstack(([x1, y1],[x2, y2]))                     # 输入样本 X,维度:2 x 400
Y = np.hstack((np.zeros((1,200)),np.ones((1,200))))    # 输出标签 Y

输入样本X的特征维度为2,样本个数为400,输出标签Y包含0和1类别各200个。

将数据集在二维平面上显示。

plt.scatter(X[0, :], X[1, :], c=np.squeeze(Y), s=40, cmap=plt.cm.Spectral);
plt.show()

深度学习——第7章 项目实战:自己动手写一个神经网络模型,深度学习,深度学习,神经网络,人工智能,机器学习,python,cnn
从正负样本的分布来看,使用简单的逻辑回归进行分类效果肯定不会太好,因为数据集不是线性可分的。下面,我将带大家一步一步搭建一个简单的神经网络模型来解决这个分类问题。

7.2 定义神经网络输入层、隐藏层、输出层神经元个数

我们使用的简单神经网络,只包含一层隐藏层。首先,我们需要定义神经网络输入层、隐藏层、输出层的神经元个数。

深度学习——第7章 项目实战:自己动手写一个神经网络模型,深度学习,深度学习,神经网络,人工智能,机器学习,python,cnn

m = X.shape[1]      # 样本个数
n_x = X.shape[0]    # 输入层神经元个数
n_h = 3             # 隐藏层神经元个数
n_y = Y.shape[0]    # 输出层神经元个数

7.3 网络参数W和b初始化

在上一篇中我们说过神经网络模型在开始训练时需要对各层权重系数W和常数项b进行初始化赋值。

初始化赋值时,b一般全部初始化为0即可,但是W不能全部初始化为0。

初始化代码如下:

W1 = np.random.randn(n_h,n_x)*0.01
b1 = np.zeros((n_h,1))
W2 = np.random.randn(n_y,n_h)*0.01
b2 = np.zeros((n_y,1))
    
assert (W1.shape == (n_h, n_x))
assert (b1.shape == (n_h, 1))
assert (W2.shape == (n_y, n_h))
assert (b2.shape == (n_y, 1))
    
parameters = {"W1": W1,
              "b1": b1,
              "W2": W2,
              "b2": b2}

其中,assert语句对向量或者数组维度进行判断。如果与给定的维度不同,则程序在此处停止运行。assert的灵活使用可以帮助我们及时检查神经网络模型中参数的维度是否正确。

7.4 正向传播过程

正向传播过程,包含了 Z [ 1 ] Z^{[1]} Z[1] A [ 1 ] A^{[1]} A[1] Z [ 2 ] Z^{[2]} Z[2] A [ 2 ] A^{[2]} A[2]的计算,根据上一篇的详细推导结果:

Z [ 1 ] = W [ 1 ] X + b [ 1 ] Z^{[1]}=W^{[1]}X+b^{[1]} Z[1]=W[1]X+b[1]

A [ 1 ] = g ( Z [ 1 ] ) A^{[1]}=g\left(Z^{[1]}\right) A[1]=g(Z[1])

Z [ 2 ] = W [ 2 ] A [ 1 ] + b [ 2 ] Z^{[2]}=W^{[2]} A^{[1]}+b^{[2]} Z[2]=W[2]A[1]+b[2]

A [ 2 ] = g ( Z [ 2 ] ) A^{[2]}=g\left(Z^{[2]}\right) A[2]=g(Z[2])

其中,隐藏层的激活函数 g ( ⋅ ) g(\cdot) g()选择使用tanh函数,输出层的激活函数 g ( ⋅ ) g(\cdot) g()选择使用sigmoid函数。

定义 sigmoid 函数:

def sigmoid(x):
    """
    Compute the sigmoid of x
    """
    s = 1/(1+np.exp(-x))
    return s

定义正向传播过程:

def forward_propagation(X, parameters):

    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]
    
    Z1 = np.dot(W1,X) + b1
    A1 = np.tanh(Z1)
    Z2 = np.dot(W2,A1) + b2
    A2 = sigmoid(Z2)
    
    assert(A2.shape == (1, X.shape[1]))
    
    cache = {"Z1": Z1,
             "A1": A1,
             "Z2": Z2,
             "A2": A2}
    
    return A2, cache

7.5 损失函数

m m m个样本的损失函数为:

J = − 1 m ∑ i = 1 m y ( i ) l o g y ^ ( i ) + ( 1 − y ( i ) ) l o g ( 1 − y ^ ( i ) ) J=-\frac{1}{m}\sum_{i=1}^my^{(i)}log\hat y^{(i)}+(1-y^{(i)})log(1-\hat y^{(i)}) J=m1i=1my(i)logy^(i)+(1y(i))log(1y^(i))

def compute_cost(A2, Y, parameters):
    
    m = Y.shape[1] # number of example

    # 计算交叉熵损失函数
    logprobs = np.multiply(np.log(A2),Y)+np.multiply(np.log(1-A2),(1-Y))
    cost = - 1/m * np.sum(logprobs)
    
    cost = np.squeeze(cost)     
    
    return cost

7.6 反向传播过程

反向传播过程需要计算损失函数 J J J对各个变量$A^{[2]} , , Z^{[2]} , , W{[2]}$,$b{[2]} , , A{[1]}$,$Z{[1]} , , W{[1]}$,$b{[1]} $的偏导数。根据上一篇的详细推导结果:

d Z [ 2 ] = A [ 2 ] − Y dZ^{[2]}=A^{[2]}-Y dZ[2]=A[2]Y

d W [ 2 ] = 1 m d Z [ 2 ] A [ 1 ] T dW^{[2]}=\frac1mdZ^{[2]}A^{[1]T} dW[2]=m1dZ[2]A[1]T

d b [ 2 ] = 1 m n p . s u m ( d Z [ 2 ] , a x i s = 1 ) db^{[2]}=\frac1mnp.sum(dZ^{[2]},axis=1) db[2]=m1np.sum(dZ[2],axis=1)

d Z [ 1 ] = W [ 2 ] T d Z [ 2 ] ∗ g ′ ( Z [ 1 ] ) dZ^{[1]}=W^{[2]T}dZ^{[2]}\ast g'(Z^{[1]}) dZ[1]=W[2]TdZ[2]g(Z[1])

d W [ 1 ] = 1 m d Z [ 1 ] X T dW^{[1]}=\frac1mdZ^{[1]}X^T dW[1]=m1dZ[1]XT

d b [ 1 ] = 1 m n p . s u m ( d Z [ 1 ] , a x i s = 1 ) db^{[1]}=\frac1mnp.sum(dZ^{[1]},axis=1) db[1]=m1np.sum(dZ[1],axis=1)

反向传播函数定义为:

def backward_propagation(parameters, cache, X, Y):
    
    m = X.shape[1]
    
    W1 = parameters["W1"]
    W2 = parameters["W2"]
        
    A1 = cache["A1"]
    A2 = cache["A2"]
    
    # 反向求导
    dZ2 = A2 - Y
    dW2 = 1/m*np.dot(dZ2,A1.T)
    db2 = 1/m*np.sum(dZ2,axis=1,keepdims=True)
    dZ1 = np.dot(W2.T,dZ2)*(1 - np.power(A1, 2))
    dW1 = 1/m*np.dot(dZ1,X.T)
    db1 = 1/m*np.sum(dZ1,axis=1,keepdims=True)
    
    # 存储各个梯度值
    grads = {"dW1": dW1,
             "db1": db1,
             "dW2": dW2,
             "db2": db2}
    
    return grads

7.7 网络参数更新

根据梯度下降算法,对网络参数W和b进行更新,并将新的网络参数存储在字典里。

def update_parameters(parameters, grads, learning_rate = 1.5):

    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]
    
    dW1 = grads["dW1"]
    db1 = grads["db1"]
    dW2 = grads["dW2"]
    db2 = grads["db2"]
    
    W1 = W1 - learning_rate*dW1
    b1 = b1 - learning_rate*db1
    W2 = W2 - learning_rate*dW2
    b2 = b2 - learning_rate*db2
    
    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}
    
    return parameters

7.8 搭建整个神经网络模型

各个模块已经写好,接下来要做的就是将各个模块组合起来,搭建整个神经网络模型。

def nn_model(X, Y, n_h = 3, num_iterations = 10000, print_cost=False):
    
    m = X.shape[1]      # 样本个数
    n_x = X.shape[0]    # 输入层神经元个数
    n_y = Y.shape[0]    # 输出层神经元个数
    
    W1 = np.random.randn(n_h,n_x)*0.01
    b1 = np.zeros((n_h,1))
    W2 = np.random.randn(n_y,n_h)*0.01
    b2 = np.zeros((n_y,1))
    
    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}

    # 迭代训练
    J = []     # 存储损失函数
    for i in range(0, num_iterations):

        A2, cache = forward_propagation(X, parameters)            # 正向传播
        cost = compute_cost(A2, Y, parameters)                    # 计算损失函数
        grads = backward_propagation(parameters, cache, X, Y)     # 反向传播
        parameters = update_parameters(parameters, grads)         # 更新权重
        J.append(cost)
        # 每隔 1000 次训练,打印 cost
        if print_cost and i % 1000 == 0:
            print ("Cost after iteration %i: %f" %(i, cost))

    return parameters

7.9 模型训练

接下来,就可以使用样本数据,对模型进行训练。

parameters = nn_model(X, Y, n_h = 3, num_iterations = 10000, print_cost=True)

输出结果:

Cost after iteration 0: 0.693201
Cost after iteration 1000: 0.061391
Cost after iteration 2000: 0.038519
Cost after iteration 3000: 0.039222
Cost after iteration 4000: 0.038911
Cost after iteration 5000: 0.038509
Cost after iteration 6000: 0.038056
Cost after iteration 7000: 0.037663
Cost after iteration 8000: 0.037349
Cost after iteration 9000: 0.037094

7.10 模型预测

模型搭建完毕之后,就可以使用训练好的模型对新样本进行预测。

def predict(parameters, X):
    
    A2, cache = forward_propagation(X, parameters)
    #predictions = A2 > 0.5
    predictions = np.zeros_like(A2)
    predictions[A2 > 0.5] = 1
    
    return predictions
y_pred = predict(parameters,X)
accuracy = np.mean(y_pred == Y)
print(accuracy)

输出结果:

0.9875

得到的预测准确率达到了98.25%。

最后,为了更直观地查看分类曲线和分类效果,我们绘制分类界限。

def plot_decision_boundary(model, X, y):

    x_min, x_max = X[0, :].min() - 1, X[0, :].max() + 1
    y_min, y_max = X[1, :].min() - 1, X[1, :].max() + 1
    h = 0.01

    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

    Z = model(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)

    plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
    plt.ylabel('x2')
    plt.xlabel('x1')
    plt.scatter(X[0, :], X[1, :], c=np.squeeze(y), cmap=plt.cm.Spectral)
plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y)
plt.title("Decision Boundary, hidden layers = 3")
plt.show()

输出结果:
深度学习——第7章 项目实战:自己动手写一个神经网络模型,深度学习,深度学习,神经网络,人工智能,机器学习,python,cnn

7.11 隐藏层神经元个数对分类效果的影响

下面,分别设置隐藏层神经元个数n_h = 2、3、4、6,看看分类效果如何。

# n_h = 2
parameters = nn_model(X, Y, n_h = 2, num_iterations = 10000, print_cost=True)
y_pred = predict(parameters,X)
accuracy = np.mean(y_pred == Y)
print(accuracy)
plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y)
plt.title("Decision Boundary, hidden layers = 2")
plt.show()

输出结果:
深度学习——第7章 项目实战:自己动手写一个神经网络模型,深度学习,深度学习,神经网络,人工智能,机器学习,python,cnn
当n_h = 2时,测得准确率为88.25%。

深度学习——第7章 项目实战:自己动手写一个神经网络模型,深度学习,深度学习,神经网络,人工智能,机器学习,python,cnn
当n_h = 4时,测得准确率为98.5%。

深度学习——第7章 项目实战:自己动手写一个神经网络模型,深度学习,深度学习,神经网络,人工智能,机器学习,python,cnn
可见,当n_4 = 4时,分类准确率最高。一般情况下,神经元个数越多,模型的分类准确率越高。但是,根据问题的复杂程度,一味地增加神经元个数不一定总会提高准确率,准确率可能会达到饱和状态。另外,神经元个数过多也容易造成过拟合。实际应用中,神经元个数一般可以通过交叉验证选择最佳个数。文章来源地址https://www.toymoban.com/news/detail-794868.html

到了这里,关于深度学习——第7章 项目实战:自己动手写一个神经网络模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 李沐《动手学深度学习》线性神经网络 线性回归

    李沐《动手学深度学习》预备知识 张量操作及数据处理 李沐《动手学深度学习》预备知识 线性代数及微积分 教材:李沐《动手学深度学习》 线性回归基于的 假设 : 假设自变量和因变量之间的关系是线性的,这里通常允许包含观测值的一些噪声; 假设任何噪声都比较正常

    2024年01月21日
    浏览(92)
  • 《动手学深度学习》学习笔记 第9章 现代循环神经网络

    书籍链接: 动手学深度学习 笔记是从第四章开始,前面三章为基础知识,有需要的可以自己去看看 关于本系列笔记: 书里为了让读者更好的理解,有大篇幅的描述性的文字,内容很多,笔记只保留主要内容,同时也是对之前知识的查漏补缺 《动手学深度学习》学习笔记 第

    2024年01月18日
    浏览(51)
  • 动手学深度学习—卷积神经网络(原理解释+代码详解)

    多层感知机对图像处理是百万维度,模型不可实现。 如果要在图片中找到某个物体,寻找方法应该和物体位置无关。 适合 计算机视觉 的神经网络架构: 平移不变性 :不管检测对象出现在图像中的哪个位置,神经网络前几层应该对相同图像区域有相似的反应。 局部性 :神

    2024年02月14日
    浏览(50)
  • 动手学深度学习-pytorch版本(二):线性神经网络

    参考引用 动手学深度学习 神经网络的整个训练过程,包括: 定义简单的神经网络架构、数据处理、指定损失函数和如何训练模型 。经典统计学习技术中的 线性回归 和 softmax 回归 可以视为线性神经网络 1.1 线性回归 回归 (regression) 是能为一个或多个自变量与因变量之间关系建

    2024年02月12日
    浏览(47)
  • 项目实战解析:基于深度学习搭建卷积神经网络模型算法,实现图像识别分类

    随着人工智能的不断发展,深度学习这门技术也越来越重要,很多人都开启了学习机器学习,本文将通过项目开发实例,带领大家从零开始设计实现一款基于深度学习的图像识别算法。 学习本章内容, 你需要掌握以下基础知识: Python 基础语法 计算机视觉库(OpenCV) 深度学习

    2024年02月03日
    浏览(59)
  • 《动手学深度学习 Pytorch版》 9.4 双向循环神经网络

    之前的序列学习中假设的目标是在给定观测的情况下对下一个输出进行建模,然而也存在需要后文预测前文的情况。 数学推导太复杂了,略。 双向循环神经网络(bidirectional RNNs)添加了反向传递信息的隐藏层,以便更灵活地处理此类信息。 前向和反向隐状态的更新如下:

    2024年02月07日
    浏览(43)
  • 精华整理几十个Python数据科学、机器学习、深度学习、神经网络、人工智能方面的核心库以及详细使用实战案例,轻松几行代码训练自己的专有人工智能模型

    精华整理几十个Python数据科学、机器学习、深度学习、神经网络、人工智能方面的核心库以及详细使用实战案例,轻松几行代码训练自己的专有人工智能模型。 机器学习 人工智能的核心,是使计算机具有智能的根本途径。机器学习专注于算法,允许机器学习而不需要编程,

    2024年01月25日
    浏览(71)
  • 【AI】《动手学-深度学习-PyTorch版》笔记(十七):卷积神经网络入门

    我们在前面学习的多层感知机中,已经认识了全链接层,缺点很明显,在稍微大点的网络模型中,参数成指数级别增长。参数量很快就达到数十亿,这样的量级几乎无法计算。为此科学家们想出一个减少参数的方法:卷积。 从全链接层到卷积的推论,使用如下两个原则: 平

    2024年02月13日
    浏览(59)
  • 十 动手学深度学习v2 ——卷积神经网络之NiN + GoogLeNet

    NiN块使用卷积层加两个1x1卷积层 后者对每个像素增加了非线性性 NiN使用全局平均池化层来替代VGG和AlexNet中的全连接层 不容易过拟合,更少的参数个数 Inception块由四条并行路径组成。 前三条路径使用窗口大小为1x1、3x3和5x5的卷积层,从不同空间大小中提取信息。 中间的两条

    2024年02月09日
    浏览(59)
  • 【AI】《动手学-深度学习-PyTorch版》笔记(十八):卷积神经网络模型

    发布时间:1989年 模型目的:识别手写数字 1.3.1 相关函数原型 1)nn.Conv2d:卷积层

    2024年02月13日
    浏览(73)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包