ModelArts平台打卡体验活动-使用mindspore自定义数据集搭建CNN实现猫狗分类
在体验活动中我快速上手了mindspore,实现了数字分类,其结果如下:

在体验了这一过程后我想要自己动手用mindspore实现一个猫狗分类的任务,用到的神经网络是卷积神经网络,在这一过程中我遇到的难点主要是数据的加载和处理,下文会介绍我这个任务的整个实现过程,以及踩到的坑,重点在于数据的加载和处理。
首先mindspore包含了很多图像数据集,很多可以直接用它封装好的函数,不需要自己创建,但是对于自己特定的任务还是需要自己创建的,首先就是设定训练集和验证集的路径,然后用dataset的一个方法GeneratorDataset就可以创建数据集了,这个比较简单,掌握一些OS库的基本操作就可以,对于文本文件的读取可以用mindspore封装好的LineReader方法,可以很方便的读取文本信息。下面是我的代码(数据集附在附件中):
class MyDataset():
def __init__(self,path,dir):
self.reader=LineReader(path)
self.dir=dir
def __getitem__(self,index):
line=self.reader.readline(int(index+1))
line=line.split(' ')
filepath=os.path.join(self.dir,line[0])
label=int(line[1])
image=Image.open(filepath)
# image = np.array(image) # 转为 NumPy 数组
return image,label
def __len__(self):
return self.reader.len()
def close(self):
self.reader.close()
path1='data/train.txt'
path2='data/val.txt'
dir='data'
trainset=ds.GeneratorDataset(source=MyDataset(path1,dir),column_names=['image','label'])
print(trainset.get_col_names())
valset=ds.GeneratorDataset(source=MyDataset(path2,dir),column_names=['image','label'])
这里有个坑是readline的index需要是整型,但是在后面用迭代方法的时候好像会传一个float进去,所以这里要把它强制转换成int类型
接着就是对于数据的处理,主要是对于transforms_list的设计,这里会涉及到对于图片数据的一系列操作,如图片裁剪,数据类型转换,还有归一化等等
下面是我的代码:
from mindspore.dataset.vision import Inter
from mindspore.dataset.transforms import TypeCast
from mindspore.dataset import vision
import mindspore.dataset.vision.c_transforms as C
from mindspore import dataset
定义转换操作
transforms_list = [
vision.Resize([150, 150]),
vision.ToTensor(),将数据转成Tensor后图片会从HWC转成CHW,所以下面要用false
vision.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], is_hwc=False)
]
trainset = trainset.map(operations=transforms_list, input_columns=['image'])
trainset = trainset.batch(32)用batch处理
类型转换
transform_label = TypeCast(mindspore.int32)标签要转成int32类型
trainset = trainset.map(operations=transform_label, input_columns=["label"])
验证集的转换
transforms_list1 = [
vision.Resize([150, 150]),
vision.ToTensor(),
vision.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], is_hwc=False)
]
valset = valset.map(operations=transforms_list1, input_columns=['image'])
valset = valset.batch(32)
类型转换
transform_label1 = TypeCast(mindspore.int32)
valset = valset.map(operations=transform_label1, input_columns=["label"])
这里需要注意的是他的这些卷积,池化,以及各种层都需要先实例化,并确定参数,然后在construct中实现网络的处理流程。
接着是训练和验证逻辑的实现,mindspore中是把这两个过程封装成了一个对象,类似于一个修饰器?他可以返回前向传播的计算值和梯度,然后把梯度传入优化器实现反向传播,接下来就是训练和验证的流程编写,并开始训练,我的代码如下:
from mindspore import ops
import mindspore
Instantiate loss function and optimizer
loss_fn = ops.nll_loss()
optimizer = nn.SGD(model.trainable_params(), 1e-2)
def forward_fn(image, label):
logits = model(image)
loss = ops.nll_loss(logits, label)
return loss, logits
grad_fn = mindspore.value_and_grad(forward_fn, None, optimizer.parameters, has_aux=True)这就是上面提到的那个对象
print(grad_fn)
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, (image, label) in enumerate(dataset.create_tuple_iterator()):训练流程,迭代随机访问训练集中的图片
loss = train_step(image, label)
if batch % 100 == 0:
loss, current = loss.asnumpy(), batch
print(f"loss: {loss:>7f} [{current:>3d}/{size:>3d}]")可视化训练进程
def test(model, dataset):
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 += ops.nll_loss(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")
训练代码
epochs = 60
for t in range(epochs):
print(f"Epoch {t+1}\n-------------------------------")
train(model, trainset)
test(model, valset)
print("Done!")
我一共训练了60个epoch,最后一次在验证集上的结果如下:

接着是模型保存,代码如下:
mindspore.save_checkpoint(model, "model.ckpt")
print("Saved Model to model.ckpt")
最后是加载模型权重并执行推理,代码如下:
加载权重
model = CNN()
param_dict = mindspore.load_checkpoint("model.ckpt")
param_not_load, _ = mindspore.load_param_into_net(model, param_dict)
print(param_not_load)
推理
model.set_train(False)
for image, label in valset:
pred = model(image)
predicted = pred.argmax(1)
print(f'Predicted: "{predicted[:10]}", Actual: "{label[:10]}"')
break
推理结果如下:

0表示小猫,1表示小狗,所有数据预测正确。
总结下来,mindspore是一个集成度高的深度学习框架, 我这种小白都可以快速上手实现自定义数据集的训练,大家也快去试试吧!!!!
昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链
更多推荐

所有评论(0)