发表于2024-06-20 01:31:49
0 查看
Question 1
- 什么是mindspore,和CANN的区别?
- mindspore和pytorch的区别?在模型各个环节的代码对比是怎么样的?
- 初体验是什么感觉?
- 备注
- 本案例使用的pytorch代码引用于知乎Dr.Sun的文章-MINST手写数据集训练
Detail
浅浅看下CANN版本


导入库操作
数据集,验证集的下载,设置
数据集的预处理
网络构建
模型训练
模型评估
模型保存
模型重加载
最终运行结果签字

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

心得
- 初体验与Pytorch用法基本一致,在某些部分代码可能会更加精简
- 整体框架,思维方式与pytroch 几乎一致
- 我觉得不论哪种AI架构,方向以及应用更加重要,框架只是手段,实现了什么才是目的
本帖最后由 匿名用户 于 2024/06/20 15:34:29 编辑
Question 1
Detail
浅浅看下CANN版本
导入库操作
数据集,验证集的下载,设置
# 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')数据集的预处理
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)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)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}]")# 选择模型 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")# 模型评估 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")模型重加载
# 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)model = torch.load('CNN_for_MNIST.pth')最终运行结果签字
import time print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()+28800)),'williammyq')心得