【MindSpore】【深度学习Step by Step】(1-3)深度学习框架

深度学习框架

回顾

首先,我们来回顾一下前两节我们做了什么。

在第一节,我们建立了一个线性数据集,将其打包进行批量计算;通过加权求和的方式,建立了一个线性网络;使用平方误差作为损失函数;通过梯度下降的方式进行反向传播,使线性网络收敛。
在第二节,我们使用Mnist数据集,将其打包进行批量计算;使用了Softmax非线性网络;使用交叉熵作为损失函数;通过梯度下降的方式进行反向传播,使非线性网络收敛。

可以注意到,在两种方式中,我们的操作都有共同的成分,比如打开数据集、设置网络格式、选择误差函数、选择网络训练方法等。不可忽视的是,在前两节中,我们都采用手动求导的方法,进行梯度下降的操作,需要用户熟练掌握微积分。

但实际上,哪怕不是数学家或者信息学家,也能很好地使用深度学习,因为这些东西,深度学习框架都会自动帮我们处理,很多时候,我们需要做的,仅仅只是数据标注,以及超参数的调整而已,哪怕我们对模型的细节一无所知,也可以将其作为一个工具进行使用,这也是调参侠的由来。

下面,我们依照第二节,来了解一下MindSpore是如何为我们实现模型的训练的。

选择超参数

在这里,我们选择批处理量为256, 学习率为0.0001,训练轮次为10轮。

    batch_size, lr, num_epochs = 256, 0.0001, 10

加载数据集

在上一节中,我们使用mindvision.classification.dataset中的Mnist可以获取Mnist的数据集。同时,它也可以直接作为MindSpore框架的数据集,使用

    dataset_train = Mnist(path='/shareData/mindspore-dataset/Mnist', split="train",
                          batch_size=batch_size, repeat_num=1, shuffle=True,
                          download=False, resize=28).run()
    dataset_test = Mnist(path='/shareData/mindspore-dataset/Mnist', split="test",
                         batch_size=batch_size, repeat_num=1, shuffle=True,
                         download=False, resize=28).run()

即可将其作为MindSpore的标准数据集输入。

但如果我们要使用我们自己定义的方式加载数据,则需要进行一定的处理。

比如说我们要使用第二节自定义的load_mnist函数,首先要定义一个迭代器来输出数据与标签的值

def synthetic_data(features, labels):
    for i in range(len(labels)):
        yield features[i]/255, labels[i]

要自定义数据集,我们需要引用mindspore.dataset

import mindspore.dataset as ds

下面的代码,第二行,我们使用了上述的迭代器;第三行,利用mindspore.dataset.GeneratorDataset来建立MindSpore可接受的数据集;第四行与第五行,我们对其进行格式转换;第七行,我们以一个batchsize的大小将其打包。

def data_iter(features, labels, batch_size):
    data_gen = synthetic_data(features, labels)
    data = ds.GeneratorDataset(tuple(data_gen), ['image', 'label'], shuffle=True)
    data = data.map(operations=[TypeCast(ms.dtype.float32)])
    data = data.map(operations=[TypeCast(ms.dtype.int32)],
                    input_columns='label')
    data = data.batch(batch_size)
    return data

使用下面的代码,即可将我们自建的数据集转换为MindSpore的格式。

    features_t, labels_t = load_mnist('/shareData/mindspore-dataset/Mnist/train')
    features_v, labels_v = load_mnist('/shareData/mindspore-dataset/Mnist/test', split='t10k')

    dataset_train = data_iter(features_t, labels_t, batch_size)
    dataset_valid = data_iter(features_v, labels_v, batch_size)

设置网络

在MindSpore中,我们的线性网络是nn.Dense(其实是全连接层),其计算方式为

y = a c t i v a t i o n ( W X T + B ) y = activation(WX^T+B) y=activation(WXT+B)

其中,activation可以是线性的,可以是非线性的,默认为线性的激活函数。

在官方的文档中,可以看到函数的说明:

mindspore.nn.Dense(in_channels, out_channels, weight_init='normal', bias_init='zeros', has_bias=True, activation=None)

其中,in_channels为输入的通道数,out_channels为输出的通道数,weight_init权重为初始化的方式(默认为高斯分布),bias_init为偏置的初始化方式(默认为0),has_bias为是否设置偏置,actitvation是上述提到的激活函数。

如果我们使用官方的数据集,可以使用下面的方式建立神经网络。

    net = nn.SequentialCell(
        nn.Flatten(),
        nn.Dense(28*28, 10),
    )

使用我们自定义的数据集,只需要下面的方式即可。

    net = nn.Dense(28*28, 10)

设置损失函数

设置Softmax输出层的交叉熵损失函数非常简单,只需要一句话:

    loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')

设置优化器

现在,我们不需要手动求导来获得梯度了。我们可以直接使用SGD优化器,可以自动进行优化。

    opti = nn.SGD(net.trainable_params(), learning_rate=lr)

回调函数

回调函数是在训练过程中会被调用的函数,在之后的章节中会详细说明(下面的函数在util.callback文件中)。

def get_accuracy(network, datasets):
    metric = nn.Accuracy('classification')
    for x, y in datasets:
        y_hat = network(x)
        metric.update(y_hat, y)
    return metric.eval()
def get_loss(network, loss_f, dataset):
    loss = 0
    for x, y in dataset:
        y_hat = network(x)
        loss += loss_f(y_hat, y)
    return loss
class AccuracyMonitor(ms.Callback):
    def __init__(self, valid_data):
        self.valid_data = valid_data

    def on_train_epoch_end(self, run_context):
        """Called after each epoch finished."""

        callback_params = run_context.original_args()

        cur_epoch_num = callback_params.cur_epoch_num
        epoch_num = callback_params.epoch_num

        network = callback_params.network

        train_data = callback_params.train_dataset

        train_accu = get_accuracy(network, train_data)
        valid_accu = get_accuracy(network, self.valid_data)

        loss = get_loss(network, callback_params.loss_fn, train_data)
        loss /= callback_params.batch_num

        print(f'epoch:[{cur_epoch_num}/{epoch_num}] Loss:{loss} Train Accuracy:{train_accu} Valid Accuracy:{valid_accu}')

训练模型

在MindSpore提供模型训练的高阶API,使用以下的短短两行代码即可进行训练。

    model = ms.Model(net, loss_fn=loss, optimizer=opti, metrics={'acc'})

    model.train(num_epochs, dataset_train, callbacks=[AccuracyMonitor(dataset_valid)])

输出结果

epoch:[1/10] Loss:2.2774138 Train Accuracy:0.14748333333333333 Valid Accuracy:0.155
epoch:[2/10] Loss:2.252627 Train Accuracy:0.19975 Valid Accuracy:0.2083
epoch:[3/10] Loss:2.2284462 Train Accuracy:0.2749666666666667 Valid Accuracy:0.2841
epoch:[4/10] Loss:2.2046874 Train Accuracy:0.3722666666666667 Valid Accuracy:0.3815
epoch:[5/10] Loss:2.1814284 Train Accuracy:0.46326666666666666 Valid Accuracy:0.4711
epoch:[6/10] Loss:2.1586423 Train Accuracy:0.5326166666666666 Valid Accuracy:0.5395
epoch:[7/10] Loss:2.136246 Train Accuracy:0.58175 Valid Accuracy:0.588
epoch:[8/10] Loss:2.11424 Train Accuracy:0.6151666666666666 Valid Accuracy:0.6216
epoch:[9/10] Loss:2.0927134 Train Accuracy:0.6402666666666667 Valid Accuracy:0.6477
epoch:[10/10] Loss:2.071551 Train Accuracy:0.6594166666666667 Valid Accuracy:0.669
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
今年的华为开发者大会 HDC 2020 上,除了**昇腾、鲲鹏等自研芯片硬件平台**之外,最令人期待的就是**深度学习框架 MindSpore 的开源**了。今天上午,华为 MindSpore **首席科学家陈雷**在活动中宣布这款产品正式开源,我们终于可以在开放平台上一睹它的真面目。 本文是根据机器之心报道的MindSpore 的开源介绍而整理的.md笔记 作为一款支持**端、边、云独立/协同的统一训练和推理框架,华为希望通过这款完整的软件堆栈,实现**一次性算子开发、一致的开发和调试体验**,以此帮助开发者实现**一次开发,应用在所有设备上平滑迁移**的能力。 三大创新能力:新编程范式,执行模式和协作方式 由**自动微分、自动并行、数据处理**等功能构成 开发算法即代码、运行高效、部署态灵活**的**特点**, 三层核心:从下往上分别是**后端运行时、计算图引擎及前端表示层**。 最大特点:采用了业界最新的 **Source-to-Source 自动微分**,它能**利用编译器及编程语言的底层技术**,进一步**优化以支持更好的微分表达**。主流深度学习框架中主要有**三种自动微分技术,才用的不是静态计算图、动态计算图,而是基于**源码**转换:该技术源以**函数式编程框架**为基础,以**即时编译(JIT)**的方式**在<u>中间表达</u>(编译过程中程序的表达形式)上做自动微分变换**,支持**<u>复杂控制流场景、高阶函数和闭包</u>**。 MindSpore 主要概念就是张量、算子、单元和模型 其代码有两个比较突出的亮点:计算图的调整,动态图与静态图可以一行代码切换;自动并行特性,我们写的串行代码,只需要多加一行就能完成自动并行。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值