1、 ncnn 支持的 onnx 算子
ncnn 并不能支持所有的onnx算,从 onnx2ncnn.cpp 源码中找出了其支持的 onnx 算子:
Constant,Dropout,BatchNormalization,BiasGelu,Clip,Conv,ConvTranspose,EmbedLayerNormalization,Gemm,GroupNorm,GRU,InstanceNormalization,LayerNorm,LSTM,MatMul,MultiHeadAttention,Pad,PRelu,Reshape,Resize,RNNSkipLayerNormalization,Slice,Upsample,adaptive_avg_pool2d,adaptive_max_pool2d,AveragePool,MaxPool .............
太多了,这里就不意义列举了。可以看到不支持 argmax 算子,当然不支持的算子还有很多,这里只谈论一种,后续不断的增加。
2、实现argmax函数
这里使用 ncnn::Mat 实现了 onnx 的 argmax 函数,其中要求 batch_size 为1,如果需要支持不为1的情况请自行修改代码,也就是在通道的 for 循环外再增加一个 batch 的循环,因为这里固定了只读取第0个 batch 的数据,通过遍历对比,得到每一个通道的最大值记录在maxVal中。
// batch = 1
void OnnxArgmax2Ncnn(const ncnn::Mat &cnMat, std::vector<float> argMax_data_, std::vector<float> argMax_idx_)
{
struct timeval start, end;
float time_use;
float tempMax;
int tempIndex;
std::cout << cnMat.c << cnMat.h <<