1 YOLOv5网络
1 YOLOv5网络
1 YOLOv5网络
图源:https://zhuanlan.zhihu.com/p/172121380
2 OpenVINO?工具套件介绍
2 OpenVINO?工具套件介绍
3 重新训练YOLOv5
3.1 下载YOLOv5代码和权重文件
git clone https://github.com/ultralytics/yolov5
3.2 数据集准备
3.3 重新训练YOLOv5
3.3.1 修改参数
nc:需要识别的类别 anchors:YOLOv5默认自适应anchors计算,也可以自定义通过k-means算法计算
3.3.2 训练YOLOv5
python train.py --data 数据集路径/data.yaml --cfg models/yolov5s.yaml --weights '' --batch-size 64 --epochs 100
注:训练命令行的参数含义可参考:https://docs.ultralytics.com,比如batch size、epochs可以根据训练设备自行调整
3.3.3 YOLOv5 Demo检测
python detect.py --weight runs/exp6/weights/best.pt --source 数据集路径/test/images/1288126-10255706714jpg_jpg.rf.95f7324cbfd48e0386e0660b5e932223.jpg
输入图像:
4 模型转换 (YOLOv5—>OpenVINO?工具套件)
4 模型转换 (YOLOv5—>OpenVINO?工具套件)
Ubuntu 18.04 OpenVINO?工具套件 2021.03
4.1 .pt 权重文件 —> ONNX 权重文件
4.1.1 安装ONNX
pip install onnx
4.1.2 ONNX转换
torch.onnx.export(model, img, f, verbose=False, opset_version=10, input_names=['images'],
output_names=['classes', 'boxes'] if y is None else ['output'])
python models/export.py --weights runs/exp6/weights/best.pt --img 640 --batch 1
Netron在线可视化:https://netron.app/ Netron github:https://github.com/lutzroeder/netron
4.2 ONNX 权重文件 —> IR 文件(.bin和.xml)
4.2.1 安装OpenVINO?工具套件
wget https://apt.repos.intel.com/openvino/2021/GPG-PUB-KEY-INTEL-OPENVINO-2021
apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2021
apt-key list
touch /etc/apt/sources.list.d/intel-openvino-2021.list
echo "deb https://apt.repos.intel.com/openvino/2021 all main" >> /etc/apt/sources.list.d/intel-openvino-2021.list
apt update
sudo apt-cache search intel-openvino-dev-ubuntu18
apt install intel-openvino-dev-ubuntu18-2021.3.394
4.2.2 OpenVINO?工具套件转换
source /opt/intel/openvino_2021/bin/setupvars.sh
python /opt/intel/openvino_2021/deployment_tools/model_optimizer/mo.py --input_model runs/exp6/weights/best.onnx --model_name yolov5s_best -s 255 --reverse_input_channels --output Conv_487,Conv_471,Conv_455
关于命令行的参数用法,更多细节可参考:https://docs.openvinotoolkit.org/cn/latest/openvino_docs_MO_DG_prepare_model_convert_model_Converting_Model_General.html
5
使用OpenVINO?工具套件进行推理部署
5.1 安装Python版的OpenVINO?工具套件
pip install openvino
5.2 OpenVINO?工具套件实测
def letterbox(img, size=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True):# Resize image to a 32-pixel-multiple rectangle https://github.com/ultralytics/yolov3/issues/232 shape = img.shape[:2] # current shape [height, width] w, h = size# Scale ratio (new / old) r = min(h / shape[0], w / shape[1])if not scaleup: # only scale down, do not scale up (for better test mAP) r = min(r, 1.0)# Compute padding ratio = r, r # width, height ratios new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) dw, dh = w - new_unpad[0], h - new_unpad[1] # wh paddingif auto: # minimum rectangle dw, dh = np.mod(dw, 64), np.mod(dh, 64) # wh paddingelif scaleFill: # stretch dw, dh = 0.0, 0.0 new_unpad = (w, h) ratio = w / shape[1], h / shape[0] # width, height ratios dw /= 2 # divide padding into 2 sides dh /= 2if shape[::-1] != new_unpad: # resize img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR) top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border top2, bottom2, left2, right2 = 0, 0, 0, 0if img.shape[0] != h: top2 = (h - img.shape[0])//2 bottom2 = top2 img = cv2.copyMakeBorder(img, top2, bottom2, left2, right2, cv2.BORDER_CONSTANT, value=color) # add borderelif img.shape[1] != w: left2 = (w - img.shape[1])//2 right2 = left2 img = cv2.copyMakeBorder(img, top2, bottom2, left2, right2, cv2.BORDER_CONSTANT, value=color) # add borderreturn img
def parse_yolo_region(blob, resized_image_shape, original_im_shape, params, threshold):
# ------------------------------------------ Validating output parameters ------------------------------------------
out_blob_n, out_blob_c, out_blob_h, out_blob_w = blob.shape
predictions = 1.0/(1.0+np.exp(-blob))
assert out_blob_w == out_blob_h, "Invalid size of output blob. It sould be in NCHW layout and height should " \
"be equal to width. Current height = {}, current width = {}" \
"".format(out_blob_h, out_blob_w)
# ------------------------------------------ Extracting layer parameters -------------------------------------------
orig_im_h, orig_im_w = original_im_shape
resized_image_h, resized_image_w = resized_image_shape
objects = list()
side_square = params.side * params.side
# ------------------------------------------- Parsing YOLO Region output -------------------------------------------
bbox_size = int(out_blob_c/params.num) #4+1+num_classes
for row, col, n in np.ndindex(params.side, params.side, params.num):
bbox = predictions[0, n*bbox_size:(n+1)*bbox_size, row, col]
x, y, width, height, object_probability = bbox[:5]
class_probabilities = bbox[5:]
if object_probability < threshold:
continue
x = (2*x - 0.5 + col)*(resized_image_w/out_blob_w)
y = (2*y - 0.5 + row)*(resized_image_h/out_blob_h)
if int(resized_image_w/out_blob_w) == 8 & int(resized_image_h/out_blob_h) == 8: #80x80,
idx = 0
elif int(resized_image_w/out_blob_w) == 16 & int(resized_image_h/out_blob_h) == 16: #40x40
idx = 1
elif int(resized_image_w/out_blob_w) == 32 & int(resized_image_h/out_blob_h) == 32: # 20x20
idx = 2
width = (2*width)**2* params.anchors[idx * 6 + 2 * n]
height = (2*height)**2 * params.anchors[idx * 6 + 2 * n + 1]
class_id = np.argmax(class_probabilities)
confidence = object_probability
objects.append(scale_bbox(x=x, y=y, height=height, width=width, class_id=class_id, confidence=confidence,
im_h=orig_im_h, im_w=orig_im_w, resized_im_h=resized_image_h, resized_im_w=resized_image_w))
return objects
def scale_bbox(x, y, height, width, class_id, confidence, im_h, im_w, resized_im_h=640, resized_im_w=640):
gain = min(resized_im_w / im_w, resized_im_h / im_h) # gain = old / new
pad = (resized_im_w - im_w * gain) / 2, (resized_im_h - im_h * gain) / 2 # wh padding
x = int((x - pad[0])/gain)
y = int((y - pad[1])/gain)
w = int(width/gain)
h = int(height/gain)
xmin = max(0, int(x - w / 2))
ymin = max(0, int(y - h / 2))
xmax = min(im_w, int(xmin + w))
ymax = min(im_h, int(ymin + h))
# Method item() used here to convert NumPy types to native types for compatibility with functions, which don't
# support Numpy types (e.g., cv2.rectangle doesn't support int64 in color parameter)
return dict(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, class_id=class_id.item(), confidence=confidence.item())
[ INFO ] Creating Inference Engine... [ INFO ] Loading network files: yolov5/yolov5s_best.xml yolov5/yolov5s_best.bin yolov5_demo.py:233: DeprecationWarning: Reading network using constructor is deprecated. Please, use IECore.read_network() method instead net = IENetwork(model=model_xml, weights=model_bin) Traceback (most recent call last): File "yolov5_demo.py", line 414, in <module> sys.exit(main() or 0) File "yolov5_demo.py", line 238, in main not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers] AttributeError: 'openvino.inference_engine.ie_api.IENetwork' object has no attribute 'layers'
out_blob = out_blob.reshape(net.layers[layer_name].out_data[0].shape) layer_params = YoloParams(net.layers[layer_name].params, out_blob.shape[2])
out_blob = out_blob.reshape(net.outputs[layer_name].shape)
params = [x._get_attributes() for x in function.get_ordered_ops() if x.get_friendly_name() == layer_name][0]
layer_params = YoloParams(params, out_blob.shape[2])
function = ng.function_from_cnn(net)
python yolov5_demo.py -m yolov5/yolov5s_best.xml test.mp4
本文暂时没有评论,来添加一个吧(●'◡'●)