这是对此问题的扩展,讨论如何在训练前将现有权重添加到模型中。
我想使用现有权重,但我的最终层输出为50而不是1000(因为该网络被训练用于分类1000个项目)。从之前的帖子中,通过更改输出层的名称,我能够添加权重。但随后我意识到有其他层依赖于这个最终层。以下是VGG网络的一个片段:
layer { name: "loss3/classifier" type: "InnerProduct" bottom: "pool5/7x7_s1" top: "loss3/classifier" param { lr_mult: 1 decay_mult: 1 } param { lr_mult: 2 decay_mult: 0 } inner_product_param { num_output: 50 weight_filler { type: "xavier" } bias_filler { type: "constant" value: 0 } } } layer { name: "loss3/loss3" type: "SoftmaxWithLoss" bottom: "loss3/classifier" bottom: "label" top: "loss3/loss3" loss_weight: 1 } layer { name: "loss3/top-1" type: "Accuracy" bottom: "loss3/classifier" bottom: "label" top: "loss3/top-1" include { phase: TEST } } layer { name: "loss3/top-5" type: "Accuracy" bottom: "loss3/classifier" bottom: "label" top: "loss3/top-5" include { phase: TEST } accuracy_param { top_k: 5 } }
我的问题是:
-
“bottom”和“top”参数到底是什么?
-
我是否需要更改后续两个层中“loss3/classifier”的名称?
回答:
这是一个相当基础的问题。我强烈建议你查看一些文档和基本的Caffe教程,以掌握Caffe的基础知识。这个教程可以作为一个很好的起点。
深度网络有一个底层图,描述了从网络输入到预测输出的数据“流动”。你问题中附带的片段描述了这样一个图。
每个层代表“数据路径”上的一个“处理单元”:它的输入是"bottom"
blob(s),层将其处理后的数据输出为"top"
blobs。
因此,如果你有一个层
layer { name: "loss3/classifier" type: "InnerProduct" bottom: "pool5/7x7_s1" top: "loss3/classifier" ...}
那么这个层执行一个"InnerProduct"
操作(由层的type
定义)。它对输入blob "pool5/7x7_s1"
(定义为bottom
)执行操作,并将结果输出到blob "loss3/classifier"
(定义为top
blob)。这个层的可学习参数(权重和偏置)由Caffe使用层的名称"loss3/classifier"
存储和访问。
因此,如果你将层的名称更改为"loss3/classifier_50"
,不更改top
,你将获得预期的效果:Caffe不会复制该层的权重,但会保持该层的输出与其他层相连。
顺便说一下,
你确定你在使用VGG网络吗?这个prototxt看起来像是GoogLeNet架构…
请注意,AlexNet、VGG和GoogLeNet是三种相当不同的网络。