【Paddle打比赛】烟火云霓虹灯识别
通过使用PaddleClas图像分类套件MobileNetV3网络,手把手半小时教会您完成烟火云霓虹灯识别比赛模型训练、预测、结果提交。
一、山东省第三届数据应用创新创业大赛【烟火云雾识别】
山东省第三届数据应用创新创业大赛主赛场以“协同创新 强省惠民”为主题,加快推动公共数据资源开发利用,充分释放公共数据资源的经济价值和社会价值,集聚数据应用相关企业、团队、爱好者,打造一批具有创新性的数据产品、数据服务,促进发挥数据“优政、惠民、兴业”作用。本赛题是其中 生态环境部分中的一项。
随着公共安全需求的发展,在森林防火和城市消防需求下。对于火灾的防范以和及时发现的需求越来越强烈。现有的烟火识别算法在实际应用中效果较差,主要原因在于需要在复杂场景下准确分辨出烟雾与云雾的区别,火焰与城市霓虹灯等干扰的区别。
烟火云雾识别竞赛地址: http://data.sd.gov.cn/cmpt/cmptDetail.html?id=61
1.任务
本次比赛将提供烟火云雾以及城市霓虹灯的标注数据,需要选手在各种复杂干扰项下准确定位出烟火云雾的位置,并降低误报率和漏报率。比赛分为初赛和复赛,初赛和复赛分别为不同的任务。
初赛任务:初赛将提供城市霓虹灯、火焰、烟雾、云四个类别的图片数据集,每张图片只会出现一个类别目标,需要选手建立分类识别模型,检测出每张图片的类别。
2.数据集
训练集为774张图片,A榜测试集为200张图片。训练集包含images文件夹和train.csv文件。其中train.csv具体字段含义如下:
3.评分指标
初赛: Precision=图片label预测正确的数量 / 所有图片的数量
二、环境准备
主要分为以下几步:
- 一是安装PaddlePaddle-GPU(AI Studio平台已自带)
- 二是下载并安装PaddleClas图像分类套件
具体操作如下:
# git下载PaddleClas源码
!git clone https://gitee.com/paddlepaddle/PaddleClas.git --depth=1
Cloning into 'PaddleClas'...
remote: Enumerating objects: 1037, done.[K
remote: Counting objects: 100% (1037/1037), done.[K
remote: Compressing objects: 100% (918/918), done.[K
remote: Total 1037 (delta 331), reused 478 (delta 95), pack-reused 0[K
Receiving objects: 100% (1037/1037), 59.94 MiB | 3.57 MiB/s, done.
Resolving deltas: 100% (331/331), done.
Checking connectivity... done.
%cd ~/PaddleClas
# 更新pip
!pip install -U pip
# 安装依赖
!pip install -r requirements.txt
# 本地安装paddleclas
!pip install -e ./
三、数据准备
主要有以下几步
- 一是解压缩数据
- 二是查看数据分布情况
- 三是划分train、eval数据集
- 四是制作数据标签待用
1.解压缩数据
# 解压缩数据集
!unzip -qoa data/data124756/省厅-视频赛场-烟火云霓虹灯识别-算法赛-初赛A榜.zip
# 重命名目录
!mv '省厅-视频赛场-烟火云霓虹灯识别-算法赛-初赛A榜' mydata
# 查看数据
%cd ~
!head -n5 mydata/train/train.csv
/home/aistudio
# 查看图片
from PIL import Image
img=Image.open('mydata/train/images/tr-768.jpg')
# 查看尺寸
print(img.size)
img
(440, 587)
2.查看数据分布情况
通过分析可见,烟最少,云最多,大致均衡,
- 2 223
- 1 200
- 3 194
- 0 157
%cd ~
from matplotlib import pyplot as plt
import pandas as pd
from sklearn.utils import shuffle
# 读取数据
data=pd.read_csv('mydata/train/train.csv')
# 统计数据分布
print(data['label'].value_counts())
# 打乱数据集
data=shuffle(data)
print(len(data))
data.head()
/home/aistudio
2 223
1 200
3 194
0 157
Name: label, dtype: int64
774
image_name | label | |
---|---|---|
474 | tr-204.jpg | 2 |
562 | tr-83.jpg | 2 |
678 | tr-622.jpg | 3 |
590 | tr-534.jpg | 3 |
426 | tr-161.jpg | 2 |
data['label'].value_counts().plot(kind="bar")
<matplotlib.axes._subplots.AxesSubplot at 0x7fc620bee910>
3.数据集划分
# 划分train、eval数据集并保存
test=data.iloc[0:int(0.2*len(data))]
train=data.iloc[int(0.2*len(data))-1:-1]
print(train.shape)
print(test.shape)
test.to_csv('mydata/train/test.txt', index=None, header=None, sep=' ')
train.to_csv('mydata/train/train.txt', index=None, header=None, sep=' ')
(620, 2)
(154, 2)
4.生成label列表
手动生成label_list.txt,需要注意的是,使用writefile魔法时,第一行必须是 %%writefile
,否则会报错。
%%writefile mydata/train/label_list.txt
0 烟
1 火
2 云
3 霓虹灯
Writing mydata/train/label_list.txt
四、模型训练
网络选择轻量级 MobileNetV3 ,可快速进行验证。
以 PaddleClas/ppcls/configs/ImageNet/MobileNetV3/MobileNetV3_large_x1_25.yaml
为基础进行修改配置
1.全局参数
# global configs
Global:
# 恢复训练点
checkpoints: null
# 预训练模型地址
pretrained_model: null
# 输出地址
output_dir: ./output/
# gpu等选择
device: gpu
# 模型保存间隔
save_interval: 1
# 是否再训练时进行eval
eval_during_train: True
# 评估间隔
eval_interval: 10
# 训练轮数设置
epochs: 360
print_batch_step: 10
# 是否启用visualdl可视化训练
use_visualdl: False
# used for static mode and model export
image_shape: [3, 224, 224]
save_inference_dir: ./inference
2.网络配置
# model architecture
Arch:
#网络配置
name: MobileNetV3_large_x1_25
# 分类数量
class_num: 4
# loss function config for traing/eval process
Loss:
Train:
- CELoss:
weight: 1.0
epsilon: 0.1
Eval:
- CELoss:
weight: 1.0
Optimizer:
name: Momentum
momentum: 0.9
lr:
name: Cosine
#学习率,可适当更爱
learning_rate: 0.01
warmup_epoch: 50
regularizer:
name: 'L2'
coeff: 0.00004
3.数据集配置
# data loader for train and eval
DataLoader:
Train:
# 训练数据集配置
dataset:
name: ImageNetDataset
image_root: /home/aistudio/mydata/train/images
cls_label_path: /home/aistudio/mydata/train/train.txt
# 数据增强配置
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- RandCropImage:
size: 224
- RandFlipImage:
flip_code: 1
- RandAugment:
num_layers: 2
magnitude: 5
- NormalizeImage:
scale: 1.0/255.0
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
order: ''
- RandomErasing:
EPSILON: 0.5
sl: 0.02
sh: 0.4
r1: 0.3
mean: [0., 0., 0.]
- Cutout:
n_holes: 1
length: 112
sampler:
name: DistributedBatchSampler
# 训练 单次 数量 配置
batch_size: 512
drop_last: False
shuffle: True
loader:
num_workers: 4
use_shared_memory: True
Eval:
dataset:
name: ImageNetDataset
image_root: /home/aistudio/mydata/train/images
cls_label_path: /home/aistudio/mydata/train/test.txt
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- RandCropImage:
size: 224
- RandFlipImage:
flip_code: 1
- NormalizeImage:
scale: 1.0/255.0
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
order: ''
sampler:
name: DistributedBatchSampler
batch_size: 512
drop_last: False
shuffle: True
loader:
num_workers: 4
use_shared_memory: True
Infer:
infer_imgs: docs/images/whl/demo.jpg
batch_size: 10
transforms:
- DecodeImage:
to_rgb: True
channel_first: False
- ResizeImage:
resize_short: 256
- CropImage:
size: 224
- NormalizeImage:
scale: 1.0/255.0
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
order: ''
- ToCHWImage:
PostProcess:
name: Topk
topk: 3
# 标签配置
class_id_map_file: /home/aistudio/mydata/train/label_list.txt
Metric:
Train:
- TopkAcc:
topk: [1, 3]
Eval:
- TopkAcc:
topk: [1, 3]
4.注意事项
- 一是开始学习率不要太大,不然loss会NaN
- 二是Topk根据情况设置,例如分类为4,用Topk5就不合适了
- 三是数据增强需要注意顺序及参数
# 覆盖配置
!cp -r ~//MobileNetV3_large_x1_25.yaml PaddleClas/ppcls/configs/ImageNet/MobileNetV3/MobileNetV3_large_x1_25.yaml
5.开始训练
%cd ~/PaddleClas/
!python3 tools/train.py \
# 训练配置文件设置
-c ./ppcls/configs/ImageNet/MobileNetV3/MobileNetV3_large_x1_25.yaml \
# 训练输出目录配置
-o Global.output_dir="output_Fireworks_cloud_neon_lamp" \
-o Arch.pretrained=True
日志输出:
[2022/01/07 22:13:48] root INFO: Already save model in output_Fireworks_cloud_neon_lamp/MobileNetV3_large_x1_25/epoch_1
[2022/01/07 22:13:48] root INFO: Already save model in output_Fireworks_cloud_neon_lamp/MobileNetV3_large_x1_25/latest
[2022/01/07 22:13:54] root INFO: [Train][Epoch 2/360][Iter: 0/2]lr: 0.00030, top1: 0.16406, top3: 0.68945, CELoss: 1.62538, loss: 1.62538, batch_cost: 4.31696s, reader_cost: 3.72142, ips: 118.60189 images/sec, eta: 0:51:39
[2022/01/07 22:13:55] root INFO: [Train][Epoch 2/360][Avg]top1: 0.17903, top3: 0.70484, CELoss: 1.61036, loss: 1.61036
[2022/01/07 22:13:55] root INFO: Already save model in output_Fireworks_cloud_neon_lamp/MobileNetV3_large_x1_25/epoch_2
[2022/01/07 22:13:55] root INFO: Already save model in output_Fireworks_cloud_neon_lamp/MobileNetV3_large_x1_25/latest
[2022/01/07 22:14:02] root INFO: [Train][Epoch 3/360][Iter: 0/2]lr: 0.00050, top1: 0.20508, top3: 0.71875, CELoss: 1.59324, loss: 1.59324, batch_cost: 3.94291s, reader_cost: 3.36189, ips: 129.85339 images/sec, eta: 0:47:03
五、评估训练模型
%cd ~/PaddleClas/
!python tools/eval.py \
-c ./ppcls/configs/ImageNet/MobileNetV3/MobileNetV3_large_x1_25.yaml \
-o Global.pretrained_model=./output_Fireworks_cloud_neon_lamp/MobileNetV3_large_x1_25/best_model
六、预测
1.导处静态模型
根据配置save_inference_dir: ./inference
导出到 inference 目录
!python3 tools/export_model.py \
-c ./ppcls/configs/ImageNet/MobileNetV3/MobileNetV3_large_x1_25.yaml \
-o Global.pretrained_model=./output_Fireworks_cloud_neon_lamp/MobileNetV3_large_x1_25/best_model
2.修改预测脚本
修改 PaddleClas/deploy\python/predict_cls.py
,添加输出到文件代码
# 拷贝已经修改好的脚本, 覆盖git下的默认脚本
!cp -r ~/predict_cls.py ~/PaddleClas/deploy/python/predict_cls.py
修改 PaddleClas/deploy\python/predict_cls.py
def main(config):
cls_predictor = ClsPredictor(config)
image_list = get_image_list(config["Global"]["infer_imgs"])
batch_imgs = []
batch_names = []
cnt = 0
# 新建保存文件
f=open('/home/aistudio/result.txt', 'w')
# 写入表头
f.write('image_name' +','+ 'label'+'\n')
for idx, img_path in enumerate(image_list):
img = cv2.imread(img_path)
if img is None:
logger.warning(
"Image file failed to read and has been skipped. The path: {}".
format(img_path))
else:
img = img[:, :, ::-1]
batch_imgs.append(img)
img_name = os.path.basename(img_path)
batch_names.append(img_name)
cnt += 1
if cnt % config["Global"]["batch_size"] == 0 or (idx + 1
) == len(image_list):
if len(batch_imgs) == 0:
continue
batch_results = cls_predictor.predict(batch_imgs)
for number, result_dict in enumerate(batch_results):
filename = batch_names[number]
clas_ids = result_dict["class_ids"]
scores_str = "[{}]".format(", ".join("{:.2f}".format(
r) for r in result_dict["scores"]))
label_names = result_dict["label_names"]
print("{}:\tclass id(s): {}, score(s): {}, label_name(s): {}".
format(filename, clas_ids, scores_str, label_names))
# 写入预测数据
f.write(filename +','+ str(clas_ids[0])+'\n')
batch_imgs = []
batch_names = []
f.close()
if cls_predictor.benchmark:
cls_predictor.auto_logger.report()
return
3.开始预测
%cd /home/aistudio/PaddleClas/deploy
!python3 python/predict_cls.py \
# 使用生成的配置
-c configs/inference_cls.yaml \
# 设置要预测的图片目录
-o Global.infer_imgs=/home/aistudio/mydata/test-A榜/images \
# 设置静态模型
-o Global.inference_model_dir=../inference/ \
# 取消标签(比赛用数字标签,而不是真实数值)
-o PostProcess.Topk.class_id_map_file=None
日志输出
e-A1194.jpg: class id(s): [3, 2, 0, 1], score(s): [0.94, 0.03, 0.02, 0.01], label_name(s): []
te-A2804.jpg: class id(s): [1, 3, 0, 2], score(s): [0.87, 0.08, 0.03, 0.02], label_name(s): []
te-A4245.jpg: class id(s): [2, 3, 1, 0], score(s): [0.88, 0.06, 0.04, 0.01], label_name(s): []
te-A4660.jpg: class id(s): [2, 3, 0, 1], score(s): [0.59, 0.28, 0.07, 0.06], label_name(s): []
te-A4742.jpg: class id(s): [0, 3, 2, 1], score(s): [0.77, 0.12, 0.06, 0.05], label_name(s): []
te-B1132.jpg: class id(s): [3, 2, 0, 1], score(s): [0.93, 0.04, 0.02, 0.01], label_name(s): []
te-B1517.jpg: class id(s): [2, 1, 0, 3], score(s): [0.58, 0.18, 0.12, 0.11], label_name(s): []
te-B1575.jpg: class id(s): [0, 1, 3, 2], score(s): [0.86, 0.08, 0.04, 0.02], label_name(s): []
# 查看预测结果
! head -n10 ~/result.txt
image_name,label
te-A1194.jpg,3
te-A2804.jpg,1
te-A4245.jpg,2
te-A4660.jpg,2
te-A4742.jpg,0
te-B1132.jpg,3
te-B1517.jpg,2
te-B1575.jpg,0
te-B1587.jpg,1
pg,3
te-B1517.jpg,2
te-B1575.jpg,0
te-B1587.jpg,1
七、提交结果
提交生成的result.txt文件,即可得到分数。
这样就完成比赛啦,大家可以选择精度更高的更先进的模型配置、使用数据增强手段来提分了。
更多推荐
所有评论(0)