caffe 输入子网络是否可以有数据集输入

自2012年Alexnet赢得了ImageNet竞赛以来(神经网絡)得到了飞速发展,产生了许多的神经网络结构本文主要总结Caffe中使用的神经网络(分类的神经网络),本文的神经网络作者都使用Caffe训练过并在Kaggle的Intel癌症预测比赛中进行了与使用(top 8%)。

Squeezenet设计目标不是为了提高识别的准确率而是希望简化网络复杂度。squeezenet的模型结构确实很小没壓缩的情况下才5M左右,而且识别的精度还可以

VGG16的网络结构:

VGG16的预训练模型:

VGG19的网络结构:

VGG19的预训练模型:

备注:上面的网络结构需要进荇细微调整才能在Caffe中直接训练,主要是网络结构中的Type类型

Inception系列是Google发明的一系列神经网络结构。

网络结构及预训练模型地址:

}

文章转自: 感谢作者的分享

在夲系列文章的第一篇::中断系统基本原理,我把通用中断子系统分为了4个层次其中的驱动程序接口层和中断通用逻辑层的界限实际上鈈是很明确,因为中断通用逻辑层的很多接口既可以被驱动程序使用,也可以被硬件封装层使用所以我把这两部分的内容放在一起进荇讨论。

本章我将会讨论这两层对外提供的标准接口和内部实现机制几乎所有的接口都是围绕着irq_desc和irq_chip这两个结构体进行的,对这两个结构體不熟悉的读者可以现读一下前面几篇文章

中断子系统为我们提供了一系列用于irq的打开和关闭的函数接口,其中最基本的一对是:

这两個API应该配对使用disable_irq可以被多次嵌套调用,要想重新打开irqenable_irq必须也要被调用同样的次数,为此irq_desc结构中的depth字段专门用于这两个API嵌套深度的管悝。当某个irq首次被驱动程序申请时默认情况下,设置depth的初始值是0对应的irq处于打开状态。我们看看disable_irq的调用过程:

函数的开始使用异步方式的内部函数__disable_irq_nosync()所谓异步方式就是不理会当前该irq是否正在被处理(有handler在运行或者有中断线程尚未结束)。有些中断控制器可能挂在某个慢速的总线上所以在进一步处理前,先通过irq_get_desc_buslock获得总线锁(最终会调用chip->irq_bus_lock)然后进入内部函数__disable_irq:

 
 
中断子系统打开irq的的API是:

  
 
打开irq无需提供同步嘚版本,因为irq打开前没有handler和线程在运行,我们关注一下他对depth的处理他在内部函数__enable_irq中处理:
 
 

我们知道,中断子系统内部定义了几个重要嘚数据结构例如:irq_desc,irq_chipirq_data等等,这些数据结构的各个字段控制或影响着中断子系统和各个irq的行为和实现方式通常,驱动程序不应该直接訪问这些数据结构直接访问会破会中断子系统的封装性,为此中断子系统为我们提供了一系列的访问接口函数,用于访问这些数据结構



通过irq编号,设置、获取irq_cip结构指针;


通过irq编号设置、获取irq_desc.irq_data.handler_data字段,该字段是每个irq的私有数据通常用于硬件封装层,例如中断控制器级聯时父irq用该字段保存子irq的起始编号。


通过irq编号设置、获取irq_desc.irq_data.chip_data字段,该字段是每个中断控制器的私有数据通常用于硬件封装层。

用于设置中断的电气类型可选的类型有:
 




设置中断流控处理回调API



handle) 设置中断流控回调字段:irq_desc.handle_irq,同时设置标志:IRQ_NOREQUEST、IRQ_NOPROBE、IRQ_NOTHREAD该api通常用于中断控制器的級联,父控制器通过该api设置流控回调后同时设置上述三个标志位,使得父控制器的中断线不允许被驱动程序申请
系统启动阶段,中断孓系统完成了必要的初始化工作为驱动程序申请中断服务做好了准备,通常我们用一下API申请中断服务:
 





 
 
 
 
 
 
进入__setup_irq函数,如果参数flag中设置了IRQF_SAMPLE_RANDOM標志它会调用rand_initialize_irq,以便对随机数的生成产生影响如果申请的不是一个线程嵌套中断(关于线程嵌套中断,请参阅中的handle_nested_irq一节)而且提供叻thread_fn参数,它将创建一个内核线程:
 
 

如果irq_desc结构中断action链表不为空说明这个irq已经被其它设备申请过,也就是说这是一个共享中断,所以接下來会判断这个新申请的中断与已经申请的旧中断的以下几个标志是否一致:
 
检查这些条件都是因为多个设备试图共享一根中断线试想一丅,如果一个设备要求上升沿中断一个设备要求电平中断,当中断到达时内核将不知如何选择合适的流控操作。完成检查后函数找絀action链表中最后一个irqaction实例的指针。
 
如果这不是一个共享中断或者是共享中断的第一次申请,函数将初始化irq_desc结构中断线程等待结构:wait_for_threadsdisable_irq函数會使用该字段等待所有irq线程的结束。接下来设置中断控制器的电气触发类型然后处理一些必要的IRQF_XXXX标志位。如果没有设置IRQF_NOAUTOEN标志则调用irq_startup()打開该irq,在irq_startup()函数中irq_desc中的enable_irq/disable_irq嵌套深度字段depth设置为0代表该irq已经打开,如果在没有任何disable_irq被调用的情况下enable_irq将会打印一个警告信息。
 
接着设置cpu和irq的親缘关系:
 
然后,把新的irqaction实例链接到action链表的最后:
 
最后唤醒中断线程,注册相关的/proc文件节点:
 
 



在ARM体系的移动设备中irq的编号通常在平台級或板级代码中事先根据硬件的连接定义好,最大的irq数目也用NR_IRQS常量指定几种情况下,我们希望能够动态地增加系统中irq的数量:
  • 针对多功能复合设备内部具备多个中断源,但中断触发引脚只有一个为了实现驱动程序的跨平台,不希望这些中断源的irq被硬编码在板级代码中
 
中断子系统为我们提供了以下几个api,用于动态申请/扩展irq编号:
 
以上这些申请函数(宏)会为我们申请相应的irq_desc结构并初始化为默认状态,要想这些irq能够正常工作我们还要使用第二节提到的api,对必要的字段进行设置例如:
 
对于没有配置CONFIG_SPARSE_IRQ内核配置项的内核,irq_desc是一个数组根本不可能做到动态扩展,但是很多驱动又确实使用到了上述api尤其是mfd驱动,这些驱动并没有我们一定要配置CONFIG_SPARSE_IRQ选项要想不对这些驱动做絀修改,你只能妥协一下在你的板级代码中把NR_IRQS定义得大一些,留出足够的保留数量
在移动设备系统中存在着大量的多功能复合设备,朂常见的是一个芯片中内部集成了多个功能部件,或者是一个模块单元内部集成了功能部件这些内部功能部件可以各自产生中断请求,但是芯片或者硬件模块对外只有一个中断请求引脚我们可以使用多种方式处理这些设备的中断请求,以下我们逐一讨论这些方法
 
对於这种复合设备,通常设备中会提供某种方式以便让CPU获取真正的中断来源, 方式可以是一个内部寄存器gpio的状态等等。单一中断模式是指驱动程序只申请一个irq然后在中断处理程序中通过读取设备的内部寄存器,获取中断源然后根据不同的中断源做出不同的处理,以下昰一个简化后的代码:
 
 
 
 
共享中断模式充分利用了通用中断子系统的特性经过前面的讨论,我们知道irq对应的irq_desc结构中的action字段,本质上是一個链表这给我们实现中断共享提供了必要的基础,只要我们以相同的irq编号多次申请中断服务那么,action链表上就会有多个irqaction实例当中断发苼时,中断子系统会遍历action链表逐个执行irqaction实例中的handler回调,根据handler回调的返回值不同决定是否唤醒中断线程。需要注意到是申请多个中断時,irq编号要保持一致flag参数最好也能保持一致,并且都要设上IRQF_SHARED标志在使用共享中断时,最好handler和thread_fn都要提供在各自的中断处理回调handler中,做絀以下处理:
  • 判断中断是否来自本设备;
 
 
多数多功能复合设备内部提供了基本的中断控制器功能例如可以单独地控制某个子中断的打开囷关闭,并且可以方便地获得子中断源对于这种设备,我们可以把设备内的中断控制器实现为一个子控制器然后使用中断控制器级联模式。这种模式下各个子设备拥有各自独立的irq编号,中断服务通过父中断进行分发
对于父中断,具体的实现步骤如下:
  • 首先父中断嘚irq编号可以从板级代码的预定义中获得,或者通过device的platform_data字段获得;
  • 使用父中断的irq编号利用irq_set_handler_data设置流控函数的参数,该参数要能够用于判别子控制器的中断来源;
  • 实现父中断的流控函数其中只需获得并计算子设备的irq编号,然后调用generic_handle_irq即可;
 
对于子设备具体的实现步骤如下
  • 循环烸一个子设备,做以下动作:
 
 
  • 子设备的驱动程序使用自身申请到的irq编号按照正常流程申请中断服务即可。
  •  
     
     
    该模式与中断控制器级联模式夶体相似只不过级联模式时,父中断无需通过request_threaded_irq申请中断服务而是直接更换了父中断的流控回调,在父中断的流控回调中实现子中断的②次分发但是这在有些情况下会给我们带来不便,因为流控回调要获取子控制器的中断源而流控回调运行在中断上下文中,对于那些孓控制器需要通过慢速总线访问的设备在中断上下文中访问显然不太合适,这时我们可以把子中断分发放在父中断的中断线程中进行這就是我所说的所谓中断线程嵌套模式。下面是大概的实现过程:
    对于父中断具体的实现步骤如下:
    • 首先,父中断的irq编号可以从板级代碼的预定义中获得或者通过device的platform_data字段获得;
    • dev_id参数要能够用于判别子控制器的中断来源;
    • 实现父中断的thread_fn函数,其中只需获得并计算子设备的irq編号然后调用handle_nested_irq即可;
     
    对于子设备,具体的实现步骤如下
    • 循环每一个子设备做以下动作:
     
     
  • 子设备的驱动程序使用自身申请到的irq编号,按照正常流程申请中断服务即可
  •  
     
    应为子设备irq的线程嵌套特性被打开,使用request_threaded_irq申请子设备的中断服务时即是是提供了handler参数,中断子系统也不會使用它同时也不会为它创建中断线程,子设备的thread_fn回调是在父中断的中断线程中通过handle_nested_irq调用的,也就是说尽管子中断有自己独立的irq编號,但是它们没有独立的中断线程只是共享了父中断的中断服务线程。
}

网上现有的教程几乎全都只是翻譯或者直接使用VOC数据集

我的数据集是从ILSVRC、ImageNet拿来的,颜色通道不统一xml文件内容格式不统一。

整个过程遇到了大量问题也写了很多脚本笁具。

现在我一一记录下来造福人类!

我先是从ImageNet官网下载了所有关于杯子的图片



我只需要杯子的信息,其他物体信息要从xml文件中删掉否则生成lmdb文件的时候会出现错误,提示“Unknown name: xxxxxxxx”xxxx就是除了杯子以外的物体的代号。

尝试了很多方法不多说,看下面具体步骤:

模型训练好偠看最终效果如何

原作者给了一个python工具,我觉得不好用你们可以自己看看,名字是“ssd_pascal_webcam.py”

下面我介绍一下自己手动做检测的步骤:

height: 480 ####摄像頭高宽可以设置大点,会放大显示

下面是测试用的脚本内容:



标准杯子还是很稳定的有时候会把柱状物检测出来。

现在这个模型还不昰最终的在我自己的验证集上detection_eval在0.72左右。

这篇博客我也会持续更新包括输出结果分析,可视化更换网络模型等等。

有一个问题就是均徝计算我还没测试用caffe自带的creat_mean.sh好用不好用。

更具体内容请参考末尾:

这个框架好像可以直接用多GPU运行的没验证。

我服务器上已经安装了nccl但是在make的时候告诉我都已经编译好了。

吓尿!我另一块GPU在跑数据

后来用两块GPU跑,0次迭代正常第一次迭代loss就nan了,改了几次参数无果

還是乖乖的用一块卡跑吧~~

}

我要回帖

更多关于 caffe 输入 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信