在深度学习推理应用阶段,涉及到提速,绕不开一个关键词“预热”。
在其他地方的“预热”,预先加热到指定的温度。通常指预习准备做某一样事时,为此做好准备。
而在深度学习推理应用阶段涉及的预热通常是指GPU预热,GPU在不用的时候是低功耗状态,它会把有些高性能的功能暂时关闭或降低性能,这时候如果把模型放上面处理,能明显感觉到有点慢,甚至从点击程序运行以后要等个几秒钟才出结果,因为这个阶段GPU要完成很多初始化工作【当然了,这也和显卡好坏有关系】。
接下来的Demo案例主要是呈现预热与否的运行时间差异
首先呈现的是未经预热的第一次测试
未经预热的第二次测试
未经预热的第三次测试
预热后第一次应用
预热后第二次应用
预热后第N次应用
Demo案例预热方式仅采用部分内存释放与否的方式进行测试,仅为展示效果
附上C#UI代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ViewControl;
using HalconDotNet;
using System.Reflection.Emit;
using static System.Net.Mime.MediaTypeNames;
namespace DeepLearningTest1
{
public partial class Form1 : Form
{
HalconView HW; //dll调用
public static DeepLearning Dl = new DeepLearning();//类调用
//全局变量
HObject HIMage = new HObject();
HTuple hv_DLDataset = new HTuple(), hv_DLPreprocessParam = new HTuple();
HTuple hv_DLModelHandle = new HTuple(), hv_ImageFiles = new HTuple();
public Form1()
{
InitializeComponent();
HW = new HalconView();
HW.HWindowControl.BackColor = Color.White;
splitContainer1.Panel1.Controls.Add(HW);
HW.Dock = DockStyle.Fill;
}
/// <summary>
/// 加载图片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog openFileDialog = new OpenFileDialog();
//openFileDialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
openFileDialog.Filter = "图片文件(*.bmp;*.jpg;*.gif;*.png;*.tiff;*.tif)|*.bmp;*.jpg;*.gif;*.png;*.tiff;*.tif";
openFileDialog.RestoreDirectory = true;
openFileDialog.FilterIndex = 1;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
label3.Text = openFileDialog.FileName;
HOperatorSet.ReadImage(out HIMage, label3.Text);
HW.DispImage(HIMage, true);
}
}
catch (Exception ex)
{
MessageBox.Show("加载图片失败 " + ex.ToString());
}
}
/// <summary>
/// 模型预热
/// </summary>
Detect detectResult = new Detect();
private Detect detectTest(HObject Hobj, string mode)
{
detectResult = new Detect();
HObject ho_Image = new HObject(); ;
HTuple hv_WindowDict = new HTuple(), hv_Index = new HTuple();
HTuple hv_SampleIndex = new HTuple(), hv_DLSampleBatch = new HTuple();
HTuple hv_DLResult = new HTuple(), hv_ClaID = new HTuple();
HTuple hv_ClassSorce = new HTuple(), hv_ClassName = new HTuple();
HTuple hv_ID = new HTuple(), hv_Sorce = new HTuple(), hv_N = new HTuple();
HOperatorSet.GenEmptyObj(out ho_Image);
try
{
HTuple t = new HTuple(), t1 = new HTuple(), T = new HTuple();
hv_DLDataset.Dispose();
HOperatorSet.ReadDict("E:/Halcon数据/测量程序/深度学习/1109/xin1109.hdict",
new HTuple(), new HTuple(), out hv_DLDataset);
hv_DLPreprocessParam.Dispose();
HOperatorSet.ReadDict("E:/Halcon数据/测量程序/深度学习/xin110900/训练-241109-153815/dl_preprocess_param.hdict",
new HTuple(), new HTuple(), out hv_DLPreprocessParam);
hv_DLModelHandle.Dispose();
HOperatorSet.ReadDlModel("E:/Halcon数据/测量程序/深度学习/xin110900/训练-241109-153815/best_model.hdl",
out hv_DLModelHandle);
ho_Image.Dispose();
ho_Image = Hobj;
HW.DispImage(ho_Image, true);
hv_DLSampleBatch.Dispose();
Dl.gen_dl_samples_from_images(ho_Image, out hv_DLSampleBatch);
Dl.preprocess_dl_samples(hv_DLSampleBatch, hv_DLPreprocessParam);
HOperatorSet.CountSeconds(out t);
hv_DLResult.Dispose();
HOperatorSet.ApplyDlModel(hv_DLModelHandle, hv_DLSampleBatch, new HTuple(),
out hv_DLResult);
HOperatorSet.CountSeconds(out t1);
T = t1 - t;
label11.Text = T.ToString();
hv_ClaID.Dispose();
HOperatorSet.GetDictTuple(hv_DLResult, "classification_class_ids", out hv_ClaID);
hv_ClassSorce.Dispose();
HOperatorSet.GetDictTuple(hv_DLResult, "classification_confidences", out hv_ClassSorce);
hv_ClassName.Dispose();
HOperatorSet.GetDictTuple(hv_DLResult, "classification_class_names", out hv_ClassName);
hv_ID.Dispose();
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
hv_ID = hv_ClaID.TupleSelect(
0);
}
hv_Sorce.Dispose();
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
hv_Sorce = hv_ClassSorce.TupleSelect(
0);
}
label1.Text = hv_Sorce.ToString();
hv_N.Dispose();
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
hv_N = hv_ClassName.TupleSelect(
0);
}
label2.Text = hv_N.ToString();
}
catch
{
detectResult = new Detect();
detectResult.finishJudge_CCD2 = false;
}
ho_Image.Dispose();
hv_WindowDict.Dispose();
hv_Index.Dispose();
hv_SampleIndex.Dispose();
hv_DLSampleBatch.Dispose();
hv_DLResult.Dispose();
hv_ClaID.Dispose();
hv_ClassSorce.Dispose();
hv_ClassName.Dispose();
hv_ID.Dispose();
hv_Sorce.Dispose();
hv_N.Dispose();
return detectResult;
}
/// <summary>
/// 图片检测
/// </summary>
/// <param name="Hobj"></param>
/// <param name="mode"></param>
/// <returns></returns>
private Detect detectTest1(HObject Hobj, string mode)
{
detectResult = new Detect();
HObject ho_Image = new HObject(); ;
HTuple hv_WindowDict = new HTuple(), hv_Index = new HTuple();
HTuple hv_SampleIndex = new HTuple(), hv_DLSampleBatch = new HTuple();
HTuple hv_DLResult = new HTuple(), hv_ClaID = new HTuple();
HTuple hv_ClassSorce = new HTuple(), hv_ClassName = new HTuple();
HTuple hv_ID = new HTuple(), hv_Sorce = new HTuple(), hv_N = new HTuple();
HOperatorSet.GenEmptyObj(out ho_Image);
try
{
HTuple t = new HTuple(), t1 = new HTuple(), T = new HTuple();
ho_Image.Dispose();
ho_Image = Hobj;
HW.DispImage(ho_Image, true);
hv_DLSampleBatch.Dispose();
Dl.gen_dl_samples_from_images(ho_Image, out hv_DLSampleBatch);
Dl.preprocess_dl_samples(hv_DLSampleBatch, hv_DLPreprocessParam);
HOperatorSet.CountSeconds(out t);
hv_DLResult.Dispose();
HOperatorSet.ApplyDlModel(hv_DLModelHandle, hv_DLSampleBatch, new HTuple(),
out hv_DLResult);
HOperatorSet.CountSeconds(out t1);
T = t1 - t;
label13.Text = T.ToString();
hv_ClaID.Dispose();
HOperatorSet.GetDictTuple(hv_DLResult, "classification_class_ids", out hv_ClaID);
hv_ClassSorce.Dispose();
HOperatorSet.GetDictTuple(hv_DLResult, "classification_confidences", out hv_ClassSorce);
hv_ClassName.Dispose();
HOperatorSet.GetDictTuple(hv_DLResult, "classification_class_names", out hv_ClassName);
hv_ID.Dispose();
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
hv_ID = hv_ClaID.TupleSelect(
0);
}
hv_Sorce.Dispose();
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
hv_Sorce = hv_ClassSorce.TupleSelect(
0);
}
label21.Text = hv_Sorce.ToString();
hv_N.Dispose();
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
hv_N = hv_ClassName.TupleSelect(
0);
}
label20.Text = hv_N.ToString();
}
catch
{
detectResult = new Detect();
detectResult.finishJudge_CCD2 = false;
}
ho_Image.Dispose();
hv_WindowDict.Dispose();
hv_Index.Dispose();
hv_SampleIndex.Dispose();
hv_DLSampleBatch.Dispose();
hv_DLResult.Dispose();
hv_ClaID.Dispose();
hv_ClassSorce.Dispose();
hv_ClassName.Dispose();
hv_ID.Dispose();
hv_Sorce.Dispose();
hv_N.Dispose();
return detectResult;
}
/// <summary>
/// 模型预热
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
if (!HIMage.IsInitialized()) { MessageBox.Show("图片为空"); return; }
Detect detectTemp = new Detect();
HTuple t = new HTuple(), t1 = new HTuple(), T = new HTuple();
HOperatorSet.CountSeconds(out t);
detectTemp = detectTest(HIMage, "test");
HOperatorSet.CountSeconds(out t1);
T = t1 - t;
label7.Text = T.ToString();
}
/// <summary>
/// 图片检测
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
if (!HIMage.IsInitialized()) { MessageBox.Show("图片为空"); return; }
Detect detectTemp = new Detect();
HTuple t = new HTuple(), t1 = new HTuple(), T = new HTuple();
HOperatorSet.CountSeconds(out t);
detectTemp = detectTest1(HIMage, "test");
HOperatorSet.CountSeconds(out t1);
T = t1 - t;
label17.Text = T.ToString();
}
}
}