IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 【MindSpore】【深度学习Step by Step】(1-1)线性神经网络 -> 正文阅读

[人工智能]【MindSpore】【深度学习Step by Step】(1-1)线性神经网络

深度学习Step by Step

写在前面

本教程是有关深度学习的入门教程,基于一个国产的人工智能引擎,mindspore,主要参考了《深度学习》以及《动手学深度学习》,使用MindSpore实现了《动手学深度学习》中很多有用的练习,可以作为深度学习以及MindSpore的入门教程。

阅读本教程需要有一定的Python基础。

你可以访问这个连接进行下载MindSpore:https://www.mindspore.cn/install。

所有代码可以在仓库中获取。

线性神经网络

在历史上,神经网络有三次浪潮,其一是随着控制论的发展,奠定了神经网络的基本结构(感知机);第二次是联结主义的发展,使用了反向传播;深度学习则是近十几年发展而来,主要的代表有卷积神经网络等。

下面通过numpy来实现线性回归,以介绍深度学习的基本知识。

产生数据

假设有一个线性生成器,以下式产生数值,其实W与B是未知的矩阵,N是高斯分布的噪声

Y = W X T + B + N Y = W X^T + B + N Y=WXT+B+N

我们通过下面这个程序来生成n个数据,并添加均值为0,方差为0.01的噪声。

def synthetic_data(w, b, n):
    x = np.random.normal(0, 1, (n, 1))
    y = np.matmul(x, w) + b
    # add noise
    y += np.random.normal(0, 0.01, y.shape)
    return x, y

线性网络

我们要通过数据来估计出W与B的取值,使用线性网络

y ^ = w ^ x T + b ^ \hat y = \hat w x^T + \hat b y^?=w^xT+b^

可以通过下面这个式子来实现

def linreg(x, w, b):
    return np.matmul(w, x.T) + b

损失函数

我们需要评估我们与目标函数之间的误差,并称这个函数为损失函数。在这里,我们采用平方误差(也叫L2损失)来衡量我们的预测函数与目标函数之间的差距。注意到我们对目标函数的 X X X B B B都是未知的,所以我们只能在给定 X X X的条件下,确定预测函数输出的 y ^ \hat y y^?与目标函数输出的真实 y y y之间的差距,即

L o s s ( y , y ^ ) = ( y ^ ? y ) 2 2 Loss(y, \hat y) = \frac{(\hat y - y)^2}2 Loss(y,y^?)=2(y^??y)2?

上式需要除二是因为求导后的表达式更简洁。我们通过下面的程序实现:

def squared_loss(y_hat, y):
    return np.square(y_hat - y)/2

批量计算

我们通过来打乱数据,提高计算速度。

以下是实现的代码,首先,我们要产生一组索引,通过np.random.shuffle将其打乱,然后以batch_size为一个批次,用np.mat生成将一系列矩阵作为索引,最后通过yield返回数据。

def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    np.random.shuffle(indices)
    for i in range(0, num_examples, batch_size):
        batch_indices = np.mat(indices[i:min(i + batch_size, num_examples)])
        yield features[batch_indices, :], labels[:, batch_indices]

优化器

梯度

我们初始化设置的 W W W是高斯分布的, B B B为0,可以想到,当我们输入一个 X X X,此时线性网络的输出结果 y ^ \hat y y^?与真实值之间存在有较大的差距,所以我们需要通过某种方法来更新 W W W B B B

作为线性函数时,我们很容易想到使用最小二乘法来计算最佳的 W W W B B B,但最小二乘法并不是什么时候都能够使用的。在深度学习中,我们由远及近,通过计算梯度的方式,来更新网络的参数。

什么是梯度呢?用一个简单的例子,比如有个函数, y = 1 2 x 2 y=\frac 1 2 x^2 y=21?x2,我们要寻找x值的最小值,虽然从数学上我们能很容易地知道该函数的最小值是0,但假设我们现在还不知道,如何寻找该函数的最小值呢?根据微积分,加入我们有一个点 x 0 x_0 x0?,我们将其带入函数中求导,得到 y ′ = x 0 y'=x_0 y=x0?,如果 x 0 > 0 x_0>0 x0?>0,则 y ′ > 0 y'>0 y>0,此时往 y ′ y' y减小的方向(即 ? y ′ -y' ?y方向)更新 x 0 x_0 x0?,就有希望达到极小值;如果 x 0 < 0 x_0<0 x0?<0,则 y ′ < 0 y'<0 y<0,此时往 y ′ y' y增大的方向(即 ? y ′ -y' ?y方向)更新 x 0 x_0 x0?,就有希望达到极小值。从上面的例子看出,不管如何,往导数方向相反的方向,就有可能找到函数的极小值。

梯度,则是一元函数导数的推广,即对多元函数来说,梯度方向是函数值增长的方向;而梯度的反方向,有可能能够找到函数的极小值。

链式法则

对多元函数来说,可以链式法则进行求导。

反向传播

我们将由数据 x x x得到 y ^ \hat y y^?的过程,称为正向传播,此时我们可以计算出梯度。根据得到的梯度,反向更新网络的参数,该过程被称为反向传播。

随机梯度下降(SGD)

我们要使 y ^ → y \hat y \to y y^?y,等价于使损失函数最小化,也就是对损失函数求 W W W B B B的梯度,来更新 W W W B B B的权重。

所以,我们根据以下式子来更新线性函数的 W W W B B B

w ^ ? l r ? ? L o s s ? w ^ → w ^ \hat w - lr * \frac{\partial Loss}{\partial \hat w} \to \hat w w^?lr??w^?Loss?w^

b ^ ? l r ? ? L o s s ? b ^ → b ^ \hat b - lr * \frac{\partial Loss}{\partial \hat b} \to \hat b b^?lr??b^?Loss?b^

式中的 l r lr lr是学习率,目的是将梯度的大小进行缩放,避免以太大的范围更新权限。

首先我们来计算一下 W W W B B B的梯度,根据损失函数,将 y ^ \hat y y^?代入,有

L o s s ( y , x , b ) = ( w ^ × x + b ^ ? y ) 2 2 Loss(y, x, b) = \frac{(\hat w \times x + \hat b - y)^2}2 Loss(y,x,b)=2(w^×x+b^?y)2?

如果我们对他求导,可以得到以下两个式子

? L o s s ? w ^ = ( w ^ × x + b ^ ? y ) × x = ( y ^ ? y ) × x \frac{\partial Loss}{\partial \hat w}= (\hat w \times x + \hat b - y)\times x = (\hat y - y)\times x ?w^?Loss?=(w^×x+b^?y)×x=(y^??y)×x

? L o s s ? b ^ = w ^ × x + b ^ ? y ) = ( y ^ ? y ) \frac{\partial Loss}{\partial \hat b} = \hat w \times x + \hat b - y) = (\hat y - y) ?b^?Loss?=w^×x+b^?y)=(y^??y)

我们通过下面的代码实现上述的过程。

def linreg_sgd(w, b, x, y, lr, batch_size):
    # manual calculate the gradient of squared loss
    y_hat = linreg(x.squeeze(axis=0), w, b)
    grad_w = (y_hat - y.squeeze(axis=0))*x.squeeze(axis=0)
    grad_b = (y_hat - y.squeeze(axis=0))
    grad_b = grad_b.sum(axis=1)
    new_w = w-lr*grad_w/batch_size
    new_b = b-lr*grad_b/batch_size
    return new_w, new_b

原理上,我们要在所有的样本中计算出梯度再进行更新,但现在我们只计算了一个batch size样本的梯度就对网络参数进行了更新,这个batch size样本的选择具有一定的随机性,所以称为随机梯度下降。

程序逻辑

首先,我们设置真实的分布

    true_w = np.mat([2, -3.4])
    true_b = np.array([4.2])

然后,生成1000个样本数据

    features, labels = synthetic_data(true_w, true_b, 1000)

设置批量为10,学习率0.03,训练三轮,

    batch_size = 10
    lr = 0.03
    epochs = 3

以均值为0,方差为0.01设置需要训练的w,以0设置b。

    w = np.random.normal(0, 0.01, (1, 2))
    b = np.zeros((1, 1))
    print(f'Initial w={w}, b={b}')

设置网络为线性网络,损失函数为平方差函数。

    net = linreg
    loss = squared_loss

最后一步,输入数据,获取梯度,更新 w w w b b b的值,计算损失函数。

    for epoch in range(epochs):
        for x, y in data_iter(batch_size, features, labels):
            w, b = linreg_sgd(w, b, x, y, lr, batch_size)
        train_loss = loss(net(features, w, b), labels)
        print(f'In epoch {epoch + 1}, loss is {float(train_loss.mean()):f}')

最后我们可以得到估计的 w w w b b b

    print(f'estimate w is {w}, b is {b}')
    print(f'estimate error is that w is {w-true_w} and b is {b-true_b}')

实现结果

以下是程序的输出结果

Initial w=[[-0.0204044 -0.0061789]], b=[[0.]]
In epoch 1, loss is 0.035662
In epoch 2, loss is 0.000127
In epoch 3, loss is 0.000049
estimate w is [[ 1.9999425  -3.39916696]], b is [[4.19945344]]
estimate error is that w is [[-5.74996689e-05  8.33035609e-04]] and b is [[-0.00054656]]

(2022年10月15日更新)

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:33:43  更:2022-10-17 12:38:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 3:28:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计