昇思25天学习打卡营第1天 | 初探“孢子”-MindSpore

基本了解

何为孢子(MindSpore)

昇思MindSpore是一个全场景深度学习框架,旨在实现易开发、高效执行、全场景统一部署三大目标。
其中,易开发表现为API友好、调试难度低;高效执行包括计算效率、数据预处理效率和分布式训练效率;全场景则指框架同时支持云、边缘以及端侧场景。
我总结如下几个优点:

  • 易用性:MindSpore 框架的 API 设计简洁明了,易于学习和使用。
  • 性能:MindSpore 框架在昇腾 AI 处理器上具有出色的性能表现
  • 灵活性:MindSpore 框架支持多种编程语言和硬件平台,具有很强的灵活性。

其设计理念包括:

  • 支持全场景统一部署
  • 提供Python编程范式,简化AI编程
  • 提供动态图和静态图统一的编码方式
  • 采用AI和科学计算融合编程,使用户聚焦于模型算法的数学原生表达
  • 分布式训练原生

层次结构:
MindSpore API

华子的 AI 布局

昇腾AI全栈如下图所示:

昇腾全栈
下面简单介绍每个模块的作用以及分别对标的对象:

  • 昇腾应用使能:华为各大产品线基于MindSpore提供的AI平台或服务能力。对标各类 AI 产品,如盘古大模型(to B)与 ChatGPT(to C)
  • MindSpore:支持端、边、云独立的和协同的统一训练和推理框架。对标 pytorch 和 tensorflow 等主流开源框架
  • CANN:昇腾芯片使能、驱动层。对标英伟达 CUDA + CuDNN
  • 计算资源:昇腾系列化IP、芯片和服务器。对标 GPU 和各类计算卡

注:这里说的“对标”二字可能不太准确,但是大概就是那个意思

入门初探

处理数据集

MindSpore提供基于Pipeline的数据引擎,通过数据集(Dataset)和数据变换(Transforms)实现高效的数据预处理。
MNIST数据集目录结构如下:

MNIST_Data
└── train
├── train-images-idx3-ubyte (60000个训练图片)
├── train-labels-idx1-ubyte (60000个训练标签)
└── test
├── t10k-images-idx3-ubyte (10000个测试图片)
├── t10k-labels-idx1-ubyte (10000个测试标签)

数据下载完成后,获得数据集对象。

train_dataset = MnistDataset('MNIST_Data/train')
test_dataset = MnistDataset('MNIST_Data/test')

打印数据集中包含的数据列名,用于dataset的预处理。

MindSpore的dataset使用数据处理流水线(Data Processing Pipeline),需指定map、batch、shuffle等操作。这里我们使用map对图像数据及标签进行变换处理,然后将处理好的数据集打包为大小为64的batch。

def datapipe(dataset, batch_size):
    image_transforms = [
        vision.Rescale(1.0 / 255.0, 0),
        vision.Normalize(mean=(0.1307,), std=(0.3081,)),
        vision.HWC2CHW()
    ]
    label_transform = transforms.TypeCast(mindspore.int32)

    dataset = dataset.map(image_transforms, 'image')
    dataset = dataset.map(label_transform, 'label')
    dataset = dataset.batch(batch_size)
    return dataset
    
# Map vision transforms and batch dataset
train_dataset = datapipe(train_dataset, 64)
test_dataset = datapipe(test_dataset, 64)

迭代访问,查看数据和标签的shape和datatype。

for image, label in test_dataset.create_tuple_iterator():
    print(f"Shape of image [N, C, H, W]: {image.shape} {image.dtype}")
    print(f"Shape of label: {label.shape} {label.dtype}")
    break
#或
for data in test_dataset.create_dict_iterator():
    print(f"Shape of image [N, C, H, W]: {data['image'].shape} {data['image'].dtype}")
    print(f"Shape of label: {data['label'].shape} {data['label'].dtype}")
    break

输出:
Shape of image [N, C, H, W]: (64, 1, 28, 28) Float32
Shape of label: (64,) Int32

网络构建

mindspore.nn类是构建所有网络的基类,也是网络的基本单元。当用户需要自定义网络时,可以继承nn.Cell类,并重写__init__方法和construct方法。__init__包含所有网络层的定义,construct中包含数据(Tensor)的变换过程。

# Define model
class Network(nn.Cell):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.dense_relu_sequential = nn.SequentialCell(
            nn.Dense(28*28, 512),
            nn.ReLU(),
            nn.Dense(512, 512),
            nn.ReLU(),
            nn.Dense(512, 10)
        )

    def construct(self, x):
        x = self.flatten(x)
        logits = self.dense_relu_sequential(x)
        return logits

model = Network()
print(model)

在这里插入图片描述

模型训练

在模型训练中,一个完整的训练过程(step)需要实现以下三步:

  1. 正向计算:模型预测结果(logits),并与正确标签(label)求预测损失(loss)。
  2. 反向传播:利用自动微分机制,自动求模型参数(parameters)对于loss的梯度(gradients)。
  3. 参数优化:将梯度更新到参数上。

MindSpore使用函数式自动微分机制,因此针对上述步骤需要实现:

  1. 定义正向计算函数。
  2. 使用value_and_grad通过函数变换获得梯度计算函数。
  3. 定义训练函数,使用set_train设置为训练模式,执行正向计算、反向传播和参数优化。
# Instantiate loss function and optimizer
loss_fn = nn.CrossEntropyLoss()
optimizer = nn.SGD(model.trainable_params(), 1e-2)

# 1. Define forward function
def forward_fn(data, label):
    logits = model(data)
    loss = loss_fn(logits, label)
    return loss, logits

# 2. Get gradient function
grad_fn = mindspore.value_and_grad(forward_fn, None, optimizer.parameters, has_aux=True)

# 3. Define function of one-step training
def train_step(data, label):
    (loss, _), grads = grad_fn(data, label)
    optimizer(grads)
    return loss

def train(model, dataset):
    size = dataset.get_dataset_size()
    model.set_train()
    for batch, (data, label) in enumerate(dataset.create_tuple_iterator()):
        loss = train_step(data, label)

        if batch % 100 == 0:
            loss, current = loss.asnumpy(), batch
            print(f"loss: {loss:>7f}  [{current:>3d}/{size:>3d}]")

训练过程需多次迭代数据集,一次完整的迭代称为一轮(epoch)。在每一轮,遍历训练集进行训练,结束后使用测试集进行预测。打印每一轮的loss值和预测准确率(Accuracy),可以看到loss在不断下降,Accuracy在不断提高。

epochs = 3
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train(model, train_dataset)
    test(model, test_dataset, loss_fn)
print("Done!")
import time
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), 'youlianzhong')

在这里插入图片描述
查看 npu 训练时运行状态的命令:

watch -n 0.1 npu-smi info

和 nvdia-smi 有点像。

我发现训练的时候 npu 并不能满载运行训练速度有点慢,不知道是不是数据量太小了,数据在加载的时候也比较慢。

保存和加载模型

保存模型参数

# Save checkpoint
mindspore.save_checkpoint(model, "model.ckpt")
print("Saved Model to model.ckpt")

加载保存的权重分为两步:

  1. 重新实例化模型对象,构造模型。
  2. 加载模型参数,并将其加载至模型上。
# Instantiate a random initialized model
model = Network()
# Load checkpoint and load parameter to model
param_dict = mindspore.load_checkpoint("model.ckpt")
param_not_load, _ = mindspore.load_param_into_net(model, param_dict)
print(param_not_load)

param_not_load是未被加载的参数列表,为空时代表所有参数均加载成功。

预测推理:

model.set_train(False)
for data, label in test_dataset:
    pred = model(data)
    predicted = pred.argmax(1)
    print(f'Predicted: "{predicted[:10]}", Actual: "{label[:10]}"')
    break

输出:
Predicted: “[1 3 1 4 4 7 6 3 3 7]”, Actual: “[1 3 1 4 4 7 6 3 3 7]”

<think>嗯,用户想绘制一个包含管理员、系统配置、保安、考勤、绩效、任务、地点、设备这些实体的ER图。首先,我需要理清每个实体的属性和它们之间的关系。管理员和系统配置之间应该是一对多的关系,因为一个管理员可能管理多个配置。保安可能和考勤、绩效、任务有关联。考勤和绩效可能需要记录保安的工作情况,所以可能是保安与考勤、绩效之间的一对多关系。任务可能涉及多个保安和多个地点,所以任务和保安之间是多对多,任务和地点也是一样。设备可能属于某个地点,所以地点和设备是一对多。系统配置由管理员管理,这个关系需要明确。然后,是否需要考虑绩效如何与任务或考勤关联?比如绩效可能基于考勤记录和任务完成情况。另外,设备可能有维护任务,是否需要和设备关联?可能保安负责某些设备,或者设备属于地点。需要确认用户的具体业务逻辑,但根据现有信息,先按照常见情况设计。使用工具的话,Navicat可以生成ER图,但需要先创建表结构,设置外键。可能需要检查是否有遗漏的关系,比如任务和设备是否有联系,或者绩效是否与其他实体有关联。引用中提到多对多关系需要用中间表处理,比如保安任务和任务地点之间的中间表。导出ER图时要注意去掉中文注释,确保SQL正确性。最后,用户可能需要步骤指导,比如创建实体、确定关系、使用工具绘制、验证导出等。需要参考引用中的ER图绘制方法和注意事项。</think>### 如何绘制包含多实体的关系型ER图? #### 步骤1:**明确实体及其属性** 根据需求定义以下实体及核心属性: 1. **管理员**:管理员ID(主键)、姓名、权限等级 2. **系统配置**:配置ID(主键)、参数名称、参数值 3. **保安**:保安ID(主键)、姓名、所属部门 4. **考勤**:考勤ID(主键)、打卡时间、考勤状态 5. **绩效**:绩效ID(主键)、评分日期、综合评分 6. **任务**:任务ID(主键)、任务名称、执行状态 7. **地点**:地点ID(主键)、位置名称、区域编号 8. **设备**:设备ID(主键)、设备类型、维护记录 #### 步骤2:**定义实体间关系** 1. **管理员 ↔ 系统配置** - 1:n(一个管理员管理多个系统配置) - 外键:系统配置表中添加`管理员ID`字段 2. **保安 ↔ 考勤/绩效** - 保安与考勤:1:n(一个保安有多次考勤记录) - 保安与绩效:1:n(一个保安对应多条绩效评分) - 外键:考勤表和绩效表中添加`保安ID`字段 3. **保安 ↔ 任务** - n:m(多个保安执行多个任务) - 需创建中间表`保安任务`,包含`保安ID`和`任务ID` 4. **任务 ↔ 地点** - n:m(任务可能涉及多个地点) - 需创建中间表`任务地点`,包含`任务ID`和`地点ID` 5. **地点 ↔ 设备** - 1:n(一个地点包含多个设备) - 外键:设备表中添加`地点ID` #### 步骤3:**使用工具绘制ER图** 推荐使用Navicat或MySQL Workbench: 1. **创建表结构**:根据上述实体和关系设计数据库表 2. **添加外键约束**:通过工具设置关联关系(如管理员ID关联系统配置) 3. **生成ER图**:Navicat中右键数据库选择“逆向数据库到模型”[^3] 4. **调整布局**:手动优化实体位置,明确多对多关系(如任务与地点) #### 步骤4:**验证与导出** 1. **检查关系**:确保外键正确映射,删除冗余字段 2. **导出ER图**:保存为PNG或PDF格式,注意去掉表名中文注释[^4] 3. **生成SQL脚本**:用于后续部署到测试服务器 --- ### ER图示例(逻辑结构) ```plaintext 管理员 (1) ———— 管理 ———— (n) 系统配置 保安 (1) ———— 关联 ———— (n) 考勤 保安 (1) ———— 关联 ———— (n) 绩效 保安 (n) ———— 保安任务 ———— (m) 任务 任务 (n) ———— 任务地点 ———— (m) 地点 地点 (1) ———— 包含 ———— (n) 设备 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

樱花穿过千岛湖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值