目标检测和跟踪对于资源受限的嵌入式系统来说是具有挑战性的任务。尽管这些任务是人工智能领域中计算量最大的任务之一,但它们在嵌入式设备上只能使用有限的计算和内存资源。与此同时,这种资源受限的实现通常需要满足额外的苛刻要求,如实时响应、高吞吐量性能和可靠的推理精度。SkyNet是一种硬件高效的神经网络,为嵌入式系统提供最先进的检测精度和速度。SkyNet没有遵循常见的自上而下的紧凑深度神经网络(DNN)设计流程,而是提供了一种自下而上的DNN设计方法,从一开始就全面理解硬件约束,以提供硬件高效的DNN。SkyNet的有效性通过在第56届IEEE/ACM设计自动化会议(DAC-SDC)的低功耗目标检测系统设计竞赛中获胜得到了证明,SkyNet显著优于其他100多名竞争对手:它在TX2嵌入式GPU上实现了0.731的交并比(IoU)和67.33帧每秒(FPS);在Ultra96嵌入式FPGA上实现了0.716的IoU和25.05 FPS。SkyNet的评估还扩展到了GOT-10K,这是一个最近的大规模高多样性通用对象跟踪基准。对于使用ResNet-50作为骨干网络的最先进目标跟踪器SiamRPN++和SiamMask,使用SkyNet作为骨干DNN的实现在一台1080Ti GPU上运行时,速度分别提高了1.60倍和1.73倍,并且在参数大小上小了37.20倍,显著改善了内存和存储占用。
在前文中:
《SkyNet:一种用于嵌入式系统目标检测和跟踪的硬件高效方法》
我们通过对作者研究内容的学习了解了SkyNet的相关内容,这里本文的主要目的是想要基于SkyNet目标检测模型来进行对应的应用实践测试分析,对其推理时间效率进行分析。
首先加载模型:
def load_net(fname, net):
with h5py.File(fname, 'r') as h5f:
for k, v in net.state_dict().items():
try:
param = torch.from_numpy(np.asarray(h5f[k]))
except KeyError:
pass
# print("no value")
else:
v.copy_(param)
之后进行加载:
modeltype = "SkyNet()"
weightfile = "dac.weights"
model = eval(modeltype)
region_loss = model.loss
load_net(weightfile, model)
之后划分设定网格:
grid_x = (
torch.linspace(0, w - 1, w)
.repeat(h, 1)
.repeat(batch_size * num_anchors, 1, 1)
.view(batch_size * num_anchors * h * w)
)
grid_y = (
torch.linspace(0, h - 1, h)
.repeat(w, 1)
.t()
.repeat(batch_size * num_anchors, 1, 1)
.view(batch_size * num_anchors * h * w)
)
计算锚框数据:
anchor_w = (
torch.Tensor(anchors)
.view(num_anchors, anchor_step)
.index_select(1, torch.LongTensor([0]))
)
anchor_h = (
torch.Tensor(anchors)
.view(num_anchors, anchor_step)
.index_select(1, torch.LongTensor([1]))
)
之后是构建数据处理流程:
trans = transforms.Compose(
[
transforms.ToTensor(),
transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.25, 0.25, 0.25]),
]
)
单张图像推理实现:
def single(pic="test.jpg"):
global width, height, video
img = cv2.imread(pic)
width, height = img.shape[1], img.shape[0]
resImg = inference(img)
save_path = pic.split("/")[-1].split(".")[0] + "_result.jpg"
cv2.imwrite(save_path, resImg)
批处理测试:
def batchTest(dataDir="samples/"):
count = 0
start = time.time()
for one_pic in os.listdir(dataDir):
one_path = dataDir + one_pic
print("Loading Image: ", one_path)
single(pic=one_path)
count += 1
end = time.time()
delta = end - start
avg = delta / count
print("TimeConsume: ", delta)
print("AvgTimeConsume: ", avg)
随机选取构建的图像用于模型测试:
在我本地的PC机上面进行推理测试,测试结果输出如下所示:
大概每张图像66ms的时间消耗,速度是蛮快的。
接下来简单看下实例推理效果:
感兴趣的话也可以自行动手实践下,这里我主要是结合前文论文的阅读实践做了一些基础性的尝试分析。