这一篇主要介绍如何用训练好的weights进行进一步量化。目的是使float32->float16,训练好后的weights数据是float32形式的,而将weights量化可以在较小精度损失代价下,减小模型的一半大小,达到精简,轻量化模型的目的。
上接用darknet训练自己的模型:https://blog.csdn.net/m0_48941999/article/details/108563544
本文环境配置:
- python3.8
- tensorflow=2.4.0
- Mac Catalina/ubuntu16.04
tiny-yolov2-mask结构图:
实现过程:
借助github项目利用之前训练的weigths和cfg,先直接运行
一、直接运行
1.将weights转化为h5
原网络weights:
python3 tools/model_converter/convert.py cfg/yolov2-tiny-voc.cfg weights/yolov2-tiny-voc.weights weights/yolov2-tiny-voc.h5
训练后的weights:
python3 tools/model_converter/convert.py cfg/yolov2-tiny-voc_mask.cfg weights/yolov2-tiny-voc_final.weights weights/yolov2-tiny_mask.h5
2.执行
yolov2-tiny原始网络执行:
python3 yolo.py --model_type=tiny_yolo2_darknet --weights_path=weights/yolov2-tiny-voc.h5 --anchors_path=configs/yolo2-tiny-voc_anchors.txt --classes_path=configs/voc_classes.txt --image
使用训练后weights:
图像测试:
python3 yolo.py --model_type=tiny_yolo2_darknet --weights_path=weights/yolov2-tiny_mask.h5 --anchors_path=weights/yolov2-tiny_mask_anchors.txt --classes_path=configs/mask_detect.txt --image
image测试:
/keras-YOLOv3-model-set-master/example/dog.jpg
视频测试:
python3 yolo.py --model_type=tiny_yolo2_darknet --weights_path=logs/000/ep040-loss43.354-val_loss43.060-mAP68.551.h5 --anchors_path=weights/yolov2-tiny_mask_anchors.txt --classes_path=configs/mask_detect.txt --input='0'
二、量化为float16:
借助TFlite工具库,先转为float32的tflite形式,再量化为float16形式。
PS:如果用的keras模型,需要tensorflow2.0以上
#yolo_model.summary()
#print('*' * 100)
converter = tf.lite.TFLiteConverter.from_keras_model(yolo_model)
tflite_model = converter.convert()
#路径可以自定义更改
tflite_models_dir = pathlib.Path("/keras-YOLOv3-model-set-master/mask_tflite_models/")
tflite_models_dir.mkdir(exist_ok=True, parents=True)
tflite_model_file = tflite_models_dir / "orign_model.tflite"
tflite_model_file.write_bytes(tflite_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float16]
tflite_fp16_model = converter.convert()
tflite_model_fp16_file = tflite_models_dir / "orign_model_quant_f16.tflite"
tflite_model_fp16_file.write_bytes(tflite_fp16_model)
tflite2npy
npy是numpy存储二进制数组的一种格式。
如果需要转换为npy格式可以直接使用netron工具,但只能导出每一层convd的npy。
参考【4】,如果要生成整个网络的npy文件:
#合并文件
with open('/Users/apple/Downloads/all_convd_weights.npy','wb') as f:
for p in path:
arr = np.load(p)
print(arr)
np.save(f,arr)
#读取文件数组验证是否正确
with open('/Users/apple/Downloads/all_convd_weights.npy','rb') as f:
for p in path:
arr = np.load(p)
arr2 = np.load(f)
print('*'*100)
print(p)
print((arr == arr2).all())
print(arr)
print('&'*100)
print(arr2)
三、训练
数据处理:
python3 voc_annotation.py --dataset_path=/home/lixq/darknet/scripts/VOCdevkit --output_path=/home/lixq/keras-YOLOv3-model-set-master/others
数据增强
# random resize image and crop|padding to target size
#随机调整图像大小,裁剪|填充到目标大小
image, padding_size, padding_offset = random_resize_crop_pad(image, target_size=model_input_size)
# random horizontal flip image
#随机水平翻转图像
image, horizontal_flip = random_horizontal_flip(image)
# random adjust brightness
#随机调整亮度
image = random_brightness(image)
# random adjust color level
#随机调整颜色级别
image = random_chroma(image)
# random adjust contrast
#随机调整对比度
image = random_contrast(image)
# random adjust sharpness
#随机调整锐度
image = random_sharpness(image)
# random convert image to grayscale
#随机转换图像灰度
image = random_grayscale(image)
# random vertical flip image
#随机垂直翻转图像
image, vertical_flip = random_vertical_flip(image)
运行:
暂时不能运行的:
python3 train.py --model_type=tiny_yolo2_darknet --anchors_path=weights/yolov2-tiny_mask_anchors.txt --weights_path=/home/lixq/darknet/darknet19_448.conv.23 --annotation_file=others/2020_train.txt --classes_path=configs/mask_detect.txt --eval_online --save_eval_checkpoint
能够成功运行的:
python3 train.py --model_type=tiny_yolo2_darknet --anchors_path=weights/yolov2-tiny_mask_anchors.txt --weights_path=weights/mask_2_model.h5 --annotation_file=others/2020_train.txt --val_annotation_file=others/2020_val.txt --classes_path=configs/mask_detect.txt --batch_size=64 --total_epoch=150 --data_shuffle --eval_online --save_eval_checkpoint
python3 yolo.py --model_type=tiny_yolo2_darknet --weights_path=weights/mask_2_model.h5 --anchors_path=weights/yolov2-tiny_mask_anchors.txt --classes_path=configs/mask_detect.txt --image
python3 yolo.py --model_type=tiny_yolo2_darknet --weights_path=logs/000/ep060-loss2.194-val_loss2.055-mAP64.231.h5 --anchors_path=weights/yolov2-tiny_mask_anchors.txt --classes_path=configs/mask_detect.txt --model_image_size=416x416 --dump_model --output_model_file=weights/mask_2_model.h5
评估:
python3 eval.py --model_path=weights/yolov2-tiny_mask.h5 --anchors_path=weights/yolov2-tiny_mask_anchors.txt --classes_path=configs/mask_detect.txt --model_image_size=416x416 --eval_type=VOC --iou_threshold=0.5 --conf_threshold=0.1 --annotation_file=others/2020_test.txt --save_result
玄学调参:
1.当出现一张照片有太多的bbox时,考虑置信率太低
eval.py中conf_threshold修改为0.1
训练及测试结果
数据集:一共10666张;包含人脸和口罩。
训练和测试时采用了2000-10666:一共8667张
训练集:6828
测试集:1839
第一次训练:c语言darknet网络: 具体结果result_1
五、其他
查找文件
find ./ name 文件名
在项目中一般使用虚拟环境:
python下载virtualenv
网上帖子比较多。
如果路径配置有问题,可以在每次使用前输入
source virtualenvwrapper.sh
然后制定python版本创建虚拟环境
查看gpu使用情况:
nvidia-smi
参考资料: