前年年前做一个手机移动端图像识别项目的时候,
先后尝试了mxnet,thnets,caffe,tensorflow.
当时的情况是,mxnet内存管理奇差,内存经常由于模型运算分配不足,app挂掉。
后来调研了下caffe发现也很不友好。
最后发现thnets相对比较轻巧,
经过算法调优之后,性能还不错,
特别是在ios下启用了Accelerate加速库。
后来tensorflow快速发展,就切到tensorflow上了。
最近看了下thnets,作者 mvitez 看来不怎么上心了。
至今为止,改进的不多。
thnets的移动端样例代码,可以参考:
https://github.com/e-lab/apps-iOs
https://github.com/e-lab/apps-android
有一段时间nnpack加速库起来了,就想着把thnets给patch一下nnpack.
但是由于项目太赶,没那个时间去做。
后来也因为切换到tensorflow上了。
thnets就被雪藏了。
向作者提交了两个建议,1,改用stb_image加载图片 2, 支持windows平台
这个两个工作,我都做了。
作者合了1。
2 我关闭了。几天前去看历史记录,作者当时问我关闭的原因,我没回。
真正的原因是。。。thnets被我遗忘了,而windows 版本的存在意义并不大。
今天稍微花了点时间,在windows写个thnets的demo样例,给有需要的网友~
项目地址:
https://github.com/cpuimage/thnets
代码示例见:demo.c
#include <string.h> #include <stdlib.h> #include <stdio.h> #include "thnets.h" // http://cpuimage.cnblogs.com/ THNETWORK * net; char * labels[] = { "lamp"," bottle"," watch"," pen"," grass"," shoe"," wall"," chair"," mug"," fork"," table"," book"," tablet"," bookcase"," pencil"," door"," face"," ceiling"," sofa"," bicycle"," aluminum - can"," window"," road"," stairs"," floor"," painting"," toy"," remote"," computer"," plant"," television"," dog"," laptop"," microwave"," cat"," tree"," knife"," car"," motorcycle"," person"," cup"," sidewalk"," telephone"," spoon"," hand"," sofabed" }; int main(int argc, char ** argv) { img_t image = { 0 }; //test.jpg char * pic_file = argv[1]; //model char * model_path = argv[2]; int dropclassifier = 0; loadimage(pic_file, &image); THInit(); printf("init_thnets."); net = THLoadNetwork(model_path); if (net) { THUseSpatialConvolutionMM(net, 2); if (dropclassifier == 1) { if (net->net->modules[net->net->nelem - 1].type == MT_SoftMax) net->net->nelem--; if (net->net->modules[net->net->nelem - 1].type == MT_Linear) net->net->nelem--; if (net->net->modules[net->net->nelem - 1].type == MT_View) net->net->nelem--; } } else { printf("Shiiiiit went down."); return -1; } float * percentages = 0; int outwidth, outheight; if (!net) { return 0; } int i = 0; int nbatch = 1; unsigned char *bitmaps[256]; for (i = 0; i < nbatch; i++) bitmaps[i] = image.bitmap; int size = THProcessImages(net, bitmaps, nbatch, image.width, image.height, image.cp * image.width, &percentages, &outwidth, &outheight, 0); for (i = 0; i < nbatch; i++) if (bitmaps[i]) free(bitmaps[i]); if (percentages) { float max[3] = { 0 }; int maxPos[3] = { 0 }; for (int j = 0; j < size; j++) { if (percentages[j] > max[0]) { maxPos[0] = j; max[0] = percentages[j]; } else if (percentages[j] > max[1]) { maxPos[1] = j; max[1] = percentages[j]; } else if (percentages[j] > max[2]) { maxPos[2] = j; max[2] = percentages[j]; } } for (int index = 0; index < 3; index += 1) { const float predictionValue = max[index]; if (predictionValue > 0.05f) { printf(" %f %s ", predictionValue, labels[maxPos[index] % size]); } } free(percentages); } getchar(); }
采用vs编译的话,需要下载openblas:
https://jaist.dl.sourceforge.net/project/openblas/v0.2.19/
lib库链接文件:libopenblas.dll.a 即可编译。
附带的模型 来自e-lab的项目。
示例输出得分最高并且高于0.05的三个结果。
示例图片:test.jpg
示例模型: model
对应的标签,见代码或模型文件夹下的categories.txt
以上,待有精力再对thnets进行性能调优。
对于前向传播而言,最好的代码学习资料莫过于:darknet
https://github.com/pjreddie/darknet
darknet 代码写得十分耐看,逻辑清晰。
darknet+nnpack:
https://github.com/digitalbrain79/darknet-nnpack
若有其他相关问题或者需求也可以邮件联系俺探讨。
邮箱地址是:
gaozhihan@vip.qq.com