昇思25天学习打卡营第6天|函数式自动微分

今天是参加昇思25天学习打卡营的第6天,学习的内容是“网络构建”和“函数式自动微分”,这里做一个简单的分享。

1.简介

今天学习的内容是如何构建神经网络以及掌握函数式自动微分相关的知识

(1)神经网络模型是由神经网络层和Tensor操作构成,mindspore.nn提供常见神经网络层的实现,也是本节学习的主要内容。
(2)神经网络的训练主要使用反向传播算法,模型预测值(logits)与正确标签(label)送入损失函数(loss function)获得loss,然后进行反向传播计算,求得梯度(gradients),最终更新至模型参数(parameters)。自动微分能够计算可导函数在某点处的导数值,是反向传播算法的一般化。自动微分主要解决的问题是将一个复杂的数学运算分解为一系列简单的基本运算,该功能对用户屏蔽了大量的求导细节和过程,大大降低了框架的使用门槛。

2.网络构建

## 2.1定义网络

mindspore中的模型的定义主要基于nn.Cell类来实现。示例代码如下:

#定义网络
class Network(nn.Cell):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.dense_relu_sequential = nn.SequentialCell(
            nn.Dense(28*28, 512, weight_init="normal", bias_init="zeros"),
            nn.ReLU(),
            nn.Dense(512, 512, weight_init="normal", bias_init="zeros"),
            nn.ReLU(),
            nn.Dense(512, 10, weight_init="normal", bias_init="zeros")
        )

    def construct(self, x):
        x = self.flatten(x)
        logits = self.dense_relu_sequential(x)
        return logits
#创建网络
model = Network()
print(model)

#计算随机数据的预测值
X = ops.ones((1, 28, 28), mindspore.float32)
logits = model(X)
# print logits
logits

#定义nn.Softmax层实例来获得预测概率
pred_probab = nn.Softmax(axis=1)(logits)
y_pred = pred_probab.argmax(1)
print(f"Predicted class: {y_pred}")

2.2.模型层的细节

(1)实例化nn.Flatten层,将28x28的2D张量转换为784大小的连续数组。

(2)nn.Dense为全连接层,其使用权重和偏差对输入进行线性变换。

(3)nn.ReLU层给网络中加入非线性的激活函数,帮助神经网络学习各种复杂的特征。

(4)nn.SequentialCell是一个有序的Cell容器。输入Tensor将按照定义的顺序通过所有Cell。

(5)最后使用nn.Softmax将神经网络最后一个全连接层返回的logits的值缩放为[0, 1],表示每个类别的预测概率。axis指定的维度数值和为1。

网络内部神经网络层具有权重参数和偏置参数(如nn.Dense),这些参数会在训练过程中不断进行优化,可通过 model.parameters_and_names() 来获取参数名及对应的参数详情。

#查看模型参数
print(f"Model structure: {model}\n\n")

for name, param in model.parameters_and_names():
    print(f"Layer: {name}\nSize: {param.shape}\nValues : {param[:2]} \n")

3.函数式自动微分

MindSpore使用函数式自动微分的设计理念,提供更接近于数学语义的自动微分接口gradvalue_and_grad

## 3.1函数与计算图

计算图是用图论语言表示数学函数的一种方式,也是深度学习框架表达神经网络模型的统一方法。

参考的计算图,构造计算函数,可以用来计算的损失值。损失值为预测值和计算值之间的偏离程度

#计算函数示例
def function(x, y, w, b):
    z = ops.matmul(x, w) + b
    loss = ops.binary_cross_entropy_with_logits(z, y, ops.ones_like(z), ops.ones_like(z))
    return loss

3.2微分函数与梯度计算

3.2.1微分函数与梯度计算

为了优化模型参数,需要求参数对loss值得导数,此时主要通过mindspore.grad函数来获得function的微分函数

计算代码为:

grad_fn = mindspore.grad(function, (2, 3))
# 第一个参数是待求导的函数
# 第二个是的求导输入位置的索引

#根据微分函数可以计算wb对应的梯度
grads = grad_fn(x, y, w, b)

3.2.2 Stop Gradient

通常情况下,求导时会求loss对参数的导数,因此函数的输出只有loss一项。当我们希望函数输出多项时,微分函数会求所有输出项对参数的导数。此时如果想实现对某个输出项的梯度截断,或消除某个Tensor对梯度的影响,需要用到Stop Gradient操作。

示例代码

#Stop Gradient
def function_stop_gradient(x, y, w, b):
    z = ops.matmul(x, w) + b
    loss = ops.binary_cross_entropy_with_logits(z, y, ops.ones_like(z), ops.ones_like(z))
    return loss, ops.stop_gradient(z)

grad_fn = mindspore.grad(function_stop_gradient, (2, 3))
grads = grad_fn(x, y, w, b)
print(grads)

3.3.3 Auxiliary data

Auxiliary data意为辅助数据,是函数除第一个输出项外的其他输出。通常我们会将函数的loss设置为函数的第一个输出,其他的输出即为辅助数据。

gradvalue_and_grad提供has_aux参数,当其设置为True时,可以自动实现前文手动添加stop_gradient的功能,满足返回辅助数据的同时不影响梯度计算的效果

示例代码

grad_fn = mindspore.grad(function_with_logits, (2, 3), has_aux=True)
grads, (z,) = grad_fn(x, y, w, b)
print(grads, z)

3.3 神经网络梯度计算

利用自动微分函数就可以很方便的实现反向传播。 核心代码示例

# Define model
class Network(nn.Cell):
    def __init__(self):
        super().__init__()
        self.w = w
        self.b = b

    def construct(self, x):
        z = ops.matmul(x, self.w) + self.b
        return z
# Instantiate model
model = Network()
# Instantiate loss function
loss_fn = nn.BCEWithLogitsLoss()

# Define forward function
def forward_fn(x, y):
    z = model(x)
    loss = loss_fn(z, y)
    return loss

#利用函数式自动微分实现反向传播
grad_fn = mindspore.value_and_grad(forward_fn, None, weights=model.trainable_params())

loss, grads = grad_fn(x, y)
print(grads)

4.小结

从模型构建开始,就开始接触神经网络模型相关的核心知识了。今天的内容是主要介绍了模型的构成,以及函数式自动微分。实际上涉及的理论概念是较多的,例如像神经网络、全连接层、损失函数、梯度、激活函数等,如果之前没有接触过相关的内容,就还需要查看一些相关基础概念的介绍。

通过网络构建、函数式自动微分的学习,那么接下来就可以尝试进行模型的训练了。

以上是第6天的学习内容,附上今日打卡记录:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值