最笨的方法
caffe
caffe是深度学习框架(c++实现了底层,填入参数即可实现深度学习算法),搭建时考虑了表达性(?)、速度(学习其优化方法)和模块化(模块化的思想与面向对象的思想是相通的?代码重用,代码封装,提供接口)。
网站提供了caffe实现的训练好的图片分类器,提交图片后按可能性从高到低给出5种识别结果。
why caffe?
expressive architecture: 定义模型和迭代训练的绝大部分工作通过文档定义,给layer和训练参数赋值即可,省略了网络代码实现过程,鼓励研究者和开发者把精力用在应用和对模型结构的创新上。对GPU和CPU的选用通过设置一个flag值完成。
extensible code: caffe搭建起来后,在github上很多人fork参与了代码开发,使得整体的模型(如layer的完备性)和优化(速度上)都达到了很高的水平。
speed:目前实现了卷积网络的最快框架(为什么比别人都快?有什么秘籍?)
Documentation
caffe tutorial(介绍philosophy,architecture,usage)
1.philosophy
模型解剖--nets,layers,blobs
深度网络,就是一连串前后连接的层构成的,处理数据的模型。caffe就是通过layer-by-layer搭建网络,网络输入data,输出loss,反向传回残差(神经网络进行参数优化的方法),layer负责计算,blob负责数据存储(标准数组),solver配置网络参数的优化参数和decouple modeling(给参数初始化防止????????)
blob
blob provides synchronization capability between CPU & GPU(??????????), a N-dim array stored in C-contiguous fashion(?????????)存储和传递信息的unified memory interface(?????????)(data,weight,diff)
blob conceal the computational and mental overhead of mixed GPU/CPU operation by synchronizing from the CPU host to GPU device as needed. Memory on the host and and device is allocated on demand for efficient memory usage(?????????????)
data存储是n*k*h*w,row-major(岂不就是一个一维数组?)
batch processing有更好的吞吐量(一次处理内存不够,一次整一个太慢?还有什么别的弊端?一个batch传进来之后具体如何传导,单个传还是同时?)
可以不用conv层单纯用innerproduct层搭建传统的多层神经网络,输入是一维向量,blob用二维,(N,D),n为batch size,d为向量维数。
对于custom data(?)要自己做数据输入的准备工作,完成之后,剩下的工作交给模块化的layer。
blobs stores 2 chunks ofmemories(?),data and diff(??权重呢)
这些数值可能会存在cpu也可能会存在gpu中(什么搞法?)
blob类中的访问方法:
const Dtype* cpu_data() const; const函数,不对访问的值做修改,不能调用非const函数,返回data常量指针,不能通过指针改变其指向的Dtype值
Dtype* mutable_cpu_data(); 返回data指针,可通过指针修改data
blob用了一个syncedMem类在cpu和gpu之间做数据同步(how?blob自己就是类,就是保持两遍数据相同?)。不要把调一次后返回的指针存起来,每次用都现调,方便syncedMem操作(调用时会给syncedMem类信号?反正const call返回的是常量指针,const 指针可存,mutable做现调给syncedMem发信号也可?)
(就是说,数据是在gpu和cpu内混合计算,程序看着按需取用内存,但不用考虑gpu和cpu上的数据同步?)gpu可用时,data从磁盘到blob(内存中,gpu也算内存?)in CPU code(????),call a device kernal做gpu计算,忽略低层细节(gpu和cpu之间数据拷贝和同步的细节???)。如果从头到尾的layer计算都在gpu中实现,那么数据就一直在gpu中,cpu中没有(去cpu中访问数据的同时数据会被拷贝到cpu中???call cpu_data()时给syncedMem信号,他完成数据从gpu到cpu的拷贝,然后返回cpu中数据的指针??)
layer computation and connections
当前出现的state-of-the-art模型中有的layer全都实现了。conv,pooling,inner product,relu,sigmoid,normlize,load data,loss(softmax,hinge)。
bottom输入,top输出。
每个layer必要的三种计算:
setup:在model初始化的同时初始化,initialize这个layer and its connections(how?就是把prototxt里面的参数取出来赋给layer类里面的基本变量???)
forward:给定的input和参数,计算outputs给top
backward:对于有参数的层(没有参数的层跳过直线传递,caffe已经实现了,看残差传到pooling层时如何处理?算出来的存起来,不直接更新参数?layer另取blob做top和bottom还是在原来的bottom和blob上做覆盖?应该是覆盖吧,也没用了,耗内存,blob肯定是内存中的)
forward和backward都同时实现了cpu和gpu模式,更快,尽管有data transfer cost(传输,tranform是转换)
要开发自己的layer,就是(setup,forward,backward,类中函数成员?)
forward,做任务,backward,通过残差学习任务。
net begin:data layer从磁盘中读入数据,end:loss layer计算残差。
模型初始化:Net::init() net类???在类外部定义成员函数时用init,为什么这么调用????
init()实现
1.创建blob和layer搭起整个DAG(实例化类得到对象,如果blob在这里固定,每个layer都有bottom对象和layer对象,那么反向传diff时对data做覆盖????)
2.call layer的setup(得到layer对象后用layer.setup()???????对layer对象赋值)
其他:检查网络正确性(有没有环????)打印进度信息
模型初始化实例了layer和blob,给layer赋从prorotxt里面读取的值,(blob没法赋值因为没有开始计算只能占位,topshape干什么????),blob占位,确定layer之间的连接关系(how???ip<-data,ip->ip,前者为layer名,此信息说明了ip层和mnist层的连接,但干什么?)lr和wd读取,初始化完成时计算了需要的内存。
此过程无需考虑cpu和gpu实现(为什么有考虑的可能????)caffe::mode()和caffe::set_mode()有何区别?????前面说的混合在一起算机动分配内存又是怎么回事?
模型定义:.prototxt
训练好的模型:.caffemodel(是.binaryproto文件,可执行文件,c++写出来的程序,编译连接生成了可执行文件,里面是caffe源码编译生成的目标文件再链接得到的可执行指令文件,why proto?)
forward and backward
Net::forward() Net::backward() carry out the respective passes(??????????????????)
Layer::forward Layer::backward() 执行计算
每个layer都有forward_{cpu,gpu}和backward_{cpu,gpu}(和上面那个又怎么区分????????????)
loss
一般用softmax,输出top blob是个标量(提到的empty在代码里面可能会看到相应的内容)
loss是一个batch所有样本的loss均值,用这个batch对参数做一次更新,那么一个batch的sample是一起计算的,参数与batch大小无关,那么data blob 的n=batch size * kernal数??
有的网络不止用一个layer产生loss,这种时候可以给layer产生的loss加权重。

浙公网安备 33010602011771号