昇思25天学习打卡训练营|day1-快速入门
收藏回复举报
昇思25天学习打卡训练营|day1-快速入门
发表于2024-06-20 01:31:49
0 查看

Question 1

  1. 什么是mindspore,和CANN的区别?
  2. mindspore和pytorch的区别?在模型各个环节的代码对比是怎么样的?
  3. 初体验是什么感觉?



  • 备注
  • 本案例使用的pytorch代码引用于知乎Dr.Sun的文章-MINST手写数据集训练



Detail

浅浅看下CANN版本

true


  • 使用的是7.0.0版本

cd /usr/local/Ascend/ascend-toolkit/latest/
vim version.cfg

true


导入库操作


import mindspore
from mindspore import nn
from mindspore.dataset import vision, transforms
from mindspore.dataset import MnistDataset

  • pytorch

import torch
from torch import nn, optim
from torch.autograd import Variable
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

数据集,验证集的下载,设置


# Download data from open datasets
from download import download

url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/" \
      "notebook/datasets/MNIST_Data.zip"
path = download(url, "./", kind="zip", replace=True)

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

  • pytorch

train_dataset = datasets.MNIST(root='./data', train=True, transform=data_tf, download=True) 
#训练集数据
test_dataset = datasets.MNIST(root='./data', train=False, transform=data_tf)                
#测试集数据

train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

数据集的预处理


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)

  • pytorch

batch_size = 64         #分批参数
learning_rate = 0.02    #学习率
# 数据预处理。transforms.ToTensor()将图片转换成PyTorch中处理的对象Tensor,并且进行标准化(数据在0~1之间)
# transforms.Normalize()做归一化。它进行了减均值,再除以标准差。两个参数分别是均值和标准差
# transforms.Compose()函数将各种预处理的操作组合到了一起

data_tf = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize([0.5], [0.5])
     ])

网络构建


# 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)

  • pytorch

class CNN(nn.Module):#定义卷积神经网络
    def __init__(self):
        super(CNN, self).__init__()
        self.layer1 = nn.Sequential(#卷积
            nn.Conv2d(1, 25, kernel_size=3),#输入通道,输出通道,卷积核
            nn.BatchNorm2d(25),#参数为输出通道数
            nn.ReLU(inplace=True)#线性整流
        )
        self.layer2 = nn.Sequential(#池化
            nn.MaxPool2d(kernel_size=2, stride=2)
        )
        self.layer3 = nn.Sequential(#卷积
            nn.Conv2d(25, 50, kernel_size=3),
            nn.BatchNorm2d(50),
            nn.ReLU(inplace=True)
        )
        self.layer4 = nn.Sequential(#池化
            nn.MaxPool2d(kernel_size=2, stride=2)
        )
        self.fc = nn.Sequential(
            nn.Linear(50 * 5 * 5, 1024),
            nn.ReLU(inplace=True),
            nn.Linear(1024, 128),
            nn.ReLU(inplace=True),
            nn.Linear(128, 10)
        )

    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x

模型训练


# 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}]")

  • pytorch

# 选择模型
model = cnn.CNN()
if torch.cuda.is_available():
    model = model.cuda()
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()#常用于多分类问题的交叉熵
optimizer = optim.SGD(model.parameters(), lr=learning_rate)

# 训练模型
epoch = 0
# 从训练集读取数据,开始迭代
for data in train_loader:
    img, label = data
    if torch.cuda.is_available():
        img = img.cuda()
        label = label.cuda()
    else:
        img = Variable(img)
        label = Variable(label)

    out = model(img)
    loss = criterion(out, label)    #计算损失函数值
    print_loss = loss.data.item()
    optimizer.zero_grad()   #将梯度归零
    loss.backward()         #反向传播计算得到每个参数的梯度值
    optimizer.step()        #通过梯度下降执行一步参数更新
    
    epoch+=1
    
    if epoch%50 == 0:       #输出进度
        print('epoch: {}, loss: {:.4}'.format(epoch, loss.data.item()))

模型评估


def test(model, dataset, loss_fn):
    num_batches = dataset.get_dataset_size()
    model.set_train(False)
    total, test_loss, correct = 0, 0, 0
    for data, label in dataset.create_tuple_iterator():
        pred = model(data)
        total += len(data)
        test_loss += loss_fn(pred, label).asnumpy()
        correct += (pred.argmax(1) == label).asnumpy().sum()
    test_loss /= num_batches
    correct /= total
    print(f"Test: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

  • pytorch

# 模型评估
model.eval()
eval_loss = 0
eval_acc = 0
for data in test_loader:
    img, label = data
    img = Variable(img)
    if torch.cuda.is_available():       #CPU or GPU
        img = img.cuda()
        label = label.cuda()
    out = model(img)
    loss = criterion(out, label)
    eval_loss += loss.data.item()*label.size(0)
    _, pred = torch.max(out, 1)         
    #pred为一个tensor,里面是一组预测可能性最大的数,实际为下标,但在这里下标刚好与数匹配
    num_correct = (pred == label).sum() 
    #按理说bool型不能接sum,但当pred和label是tensor格式时会得到一个tensor且只有一个值为前两者相等的值得个数,刚好统计了正确的预测数
    print('pred',pred)
    print('label',label)
    eval_acc += num_correct.item()
print('Test Loss: {:.6f}, Acc: {:.6f}'.format(      #输出模型评估参数总损失和正确率
    eval_loss / (len(test_dataset)),
    eval_acc / (len(test_dataset))
))

模型保存


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

  • pytorch

torch.save(model, 'CNN_for_MNIST.pth')

模型重加载


# 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)

  • pytorch

model  = torch.load('CNN_for_MNIST.pth')

最终运行结果签字

true


  • 这里要提一下,由于time.time得到的时间戳比当前时间要少8个小时
  • 所以这里要在操作PDF基础上代码加上28800,小tips

import time 
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()+28800)),'williammyq')

true


心得

  1. 初体验与Pytorch用法基本一致,在某些部分代码可能会更加精简
  2. 整体框架,思维方式与pytroch 几乎一致
  3. 我觉得不论哪种AI架构,方向以及应用更加重要,框架只是手段,实现了什么才是目的

本帖最后由 匿名用户 于 2024/06/20 15:34:29 编辑

我要发帖子