脑肿瘤数据集分类任务
本次任务是针对脑肿瘤数据集进行分类操作,分类是指对于输入,离散地输出对应输出的预测种类,分类任务是基本的计算机视觉任务之一,实现分类任务有助于我们对计算机视觉和机器学习包括神经网络有更深的理解。
PS:个人更喜欢终端,所以大部分命令都基于终端。
1. 数据预览与预处理
- 数据共有四类约7000张图片,类别为:胶质瘤、脑膜瘤、垂体瘤和无肿瘤,将数据解压,解压后会有Testing和Training两个文件夹
- 数据预处理:
将数据集进行划分,在终端中执行get_dataset.py脚本,便会在文件夹下生成对应的trian.txt和val.txt文件,终端中输入python get_dataset.py
,注意脚本中的路径需要你自己单独配置,预处理脚本分析:
最后获得类似下面格式的结果,主要是train.txt和val.txt,第一列是文件名,第二列是类别# 设置路径 training_root = '/home/aistudio/data/data156301/Brain_Tumor_MRI_Dataset/Training' train_txt = '/home/aistudio/data/data156301/Brain_Tumor_MRI_Dataset/train.txt' # 获取文件夹名称,准备遍历 training_classes = os.listdir(training_root) class_index = 0 # 打开文件读写 f_train = open(train_txt, 'w') for trainig_class in training_classes: dir_path = os.path.join(training_root, trainig_class) img_list = glob.glob(os.path.join(dir_path, '*')) father_paths = dir_path.split('/') while True: if father_paths[len(father_paths) - 1] == '': del father_paths[len(father_paths) - 1] else: break father_path = father_paths[len(father_paths) - 3] + '/' \ + father_paths[len(father_paths) - 2] + '/' + father_paths[len(father_paths) - 1] # 写入txt for img_path in img_list: # 将文件名和类别写入txt中 file_content = father_paths[len(father_paths) - 1] + '/' + os.path.basename(img_path) + ' ' + str(class_index) + '\n' f_train.write(file_content) class_index += 1 f_train.close()
pituitary/Tr-pi_0824.jpg 0
pituitary/Tr-pi_0114.jpg 0
pituitary/Tr-pi_0075.jpg 0
pituitary/Tr-pi_0983.jpg 0
pituitary/Tr-pi_0432.jpg 0
pituitary/Tr-pi_0813.jpg 0
···
2. 基于paddleclas的分类任务
- clone 项目:终端中执行
git clone https://gitee.com/paddlepaddle/PaddleClas.git
- 修改配置
这里已resnet18为例,路径为/home/aistudio/work/PaddleClas/ppcls/configs/ImageNet/ResNet/ResNet18.yaml
- 训练参数
eval_interval: 1 # eval间隔 epochs: 120 # 训练总轮数
- 修改
image_shape: [3, 512, 512]
这里是数据集的真实图片大小 - 修改
class_num: 4
为数据集的类别数,这里脑肿瘤是4分类 - 在
DataLoader
修改training_root, val_root, train_txt, val_txt
,两个root填写数据集的training和testing路径,两个txt使用我们脚本生成的txt
- 训练参数
3. 训练
终端输入python tools/train.py -c ./ppcls/configs/ImageNet/ResNet/ResNet18.yaml
,开始训练:
最开始阶段的top1比较低,但随着训练的增多,top1精确率会慢慢上升:
第一轮:
[2022/12/11 20:43:06] ppcls INFO: [Train][Epoch 1/120][Iter: 0/90]lr(PiecewiseDecay): 0.10000000, top1: 0.18750, CELoss: 1.49461, loss: 1.49461, batch_cost: 3.20558s, reader_cost: 1.02573, ips: 19.96520 samples/s, eta: 9:37:00
[2022/12/11 20:43:07] ppcls INFO: [Train][Epoch 1/120][Iter: 10/90]lr(PiecewiseDecay): 0.10000000, top1: 0.36222, CELoss: 2.18129, loss: 2.18129, batch_cost: 0.10000s, reader_cost: 0.00034, ips: 640.01205 samples/s, eta: 0:17:58
[2022/12/11 20:43:09] ppcls INFO: [Train][Epoch 1/120][Iter: 20/90]lr(PiecewiseDecay): 0.10000000, top1: 0.37128, CELoss: 1.86246, loss: 1.86246, batch_cost: 0.14999s, reader_cost: 0.03558, ips: 426.68123 samples/s, eta: 0:26:56
[2022/12/11 20:43:11] ppcls INFO: [Train][Epoch 1/120][Iter: 30/90]lr(PiecewiseDecay): 0.10000000, top1: 0.36946, CELoss: 3.59353, loss: 3.59353, batch_cost: 0.16220s, reader_cost: 0.05393, ips: 394.58220 samples/s, eta: 0:29:06
[2022/12/11 20:43:12] ppcls INFO: [Train][Epoch 1/120][Iter: 40/90]lr(PiecewiseDecay): 0.10000000, top1: 0.36966, CELoss: 3.11498, loss: 3.11498, batch_cost: 0.16385s, reader_cost: 0.05825, ips: 390.61025 samples/s, eta: 0:29:22
在第65轮的时候,我们的top1精确率已经可以到0.9以上了
[2022/12/11 21:06:43] ppcls INFO: [Train][Epoch 65/120][Iter: 60/90]lr(PiecewiseDecay): 0.00100000, top1: 0.93494, CELoss: 0.17916, loss: 0.17916, batch_cost: 0.18562s, reader_cost: 0.07280, ips: 344.79572 samples/s, eta: 0:15:24
[2022/12/11 21:06:45] ppcls INFO: [Train][Epoch 65/120][Iter: 70/90]lr(PiecewiseDecay): 0.00100000, top1: 0.93398, CELoss: 0.18150, loss: 0.18150, batch_cost: 0.18325s, reader_cost: 0.07136, ips: 349.25658 samples/s, eta: 0:15:10
[2022/12/11 21:06:47] ppcls INFO: [Train][Epoch 65/120][Iter: 80/90]lr(PiecewiseDecay): 0.00100000, top1: 0.93519, CELoss: 0.17985, loss: 0.17985, batch_cost: 0.18413s, reader_cost: 0.07091, ips: 347.58699 samples/s, eta: 0:15:13
在最后120轮的时候,通过日志可以发现,分类准确率已经接近0.97了:
[2022/12/11 21:26:42] ppcls INFO: [Train][Epoch 120/120][Iter: 80/90]lr(PiecewiseDecay): 0.00010000, top1: 0.93364, CELoss: 0.16817, loss: 0.16817, batch_cost: 0.18678s, reader_cost: 0.07453, ips: 342.63999 samples/s, eta: 0:00:01
[2022/12/11 21:26:43] ppcls INFO: [Train][Epoch 120/120][Avg]top1: 0.93435, CELoss: 0.16738, loss: 0.16738
[2022/12/11 21:26:44] ppcls INFO: [Eval][Epoch 120][Iter: 0/21]CELoss: 0.03871, loss: 0.03871, top1: 0.98438, batch_cost: 0.98946s, reader_cost: 0.91152, ips: 64.68195 images/sec
[2022/12/11 21:26:45] ppcls INFO: [Eval][Epoch 120][Iter: 10/21]CELoss: 0.12364, loss: 0.12364, top1: 0.95597, batch_cost: 0.13568s, reader_cost: 0.08472, ips: 471.69756 images/sec
[2022/12/11 21:26:47] ppcls INFO: [Eval][Epoch 120][Iter: 20/21]CELoss: 0.01761, loss: 0.01761, top1: 0.96796, batch_cost: 0.12692s, reader_cost: 0.08135, ips: 244.25635 images/sec
[2022/12/11 21:26:47] ppcls INFO: [Eval][Epoch 120][Avg]CELoss: 0.09605, loss: 0.09605, top1: 0.96796
[2022/12/11 21:26:47] ppcls INFO: [Eval][Epoch 120][best metric: 0.970251739025116]
4. 结果获取
在之前推理使用的yaml文件中,我们的路径是./output
,我这里是针对Paddle项目的,所以路径在Paddle项目下的output里面,文件夹里面存储了训练的结果
推理的时候,需要先准备好对应的数据和标签,修改yaml中的class_id_map_file
,然后使用终端
python3 tools/infer.py -c ./ppcls/configs/ImageNet/ResNet/ResNet18.yaml -o Infer.infer_imgs=xxxxx.jpg -o Global.pretrained_model=/home/aistudio/work/PaddleClas/output/ResNet18/latest
,记得修改文件名和路径
最后返回推理的结果,结合后面的label_names,发现输出的结果是无肿瘤,符合我们的预期
W1204 20:16:06.956899 16161 gpu_resources.cc:91] device: 0, cuDNN Version: 8.2.
[{'class_ids': [1, 2, 3, 0], 'scores': [0.99947, 0.00053, 0.0, 0.0], 'file_name': 'xxxxx.jpg', 'label_names': ['notumor', 'meningioma', 'glioma', 'pituitary']}]
5. 任务总结
本次任务针对脑肿瘤的胶质瘤、脑膜瘤、垂体瘤和无肿瘤四种类别进行确定,对于分类任务,主要包含以下几个步骤:
- 数据预处理,包括数据获取、数据筛选、数据整合,最终的目标是将数据整理成我们想要的样子。
- 网络设计,包括网络选择或修改以及损失函数、学习率等方法或参数的选择和设置,针对我们的任务设计出更好的网络。
- 网络的部署,部署包括几个方面,可以直接在PC上基于python/c++等语言的部署,或者基于linux等嵌入式平台的部署,在嵌入式平台上的部署可能会涉及到模型的转换、部分程序的重写和调优等。
完成上述步骤,一个任务就算初步结束了,通过脑肿瘤数据集分类任务,我对整个深度学习落地有了更为清晰的认知,通过paddlecla套件,我们可以快速准确的完成任务,提高了我们的开发效率和动手能力。
此文章为搬运
原项目链接