统一 Caffe 网络结构#
from pathlib import Path
from google.protobuf import text_format
import caffe_pb2 as pb2
temp_dir = Path(".temp")
temp_dir.mkdir(exist_ok=True)
处理 in-place 层#
from caffe_utils import _rebuild_layers
该函数用于处理 Caffe 网络中的 in-place 层,解决因输入输出绑定(in-place)导致的名称冲突问题。
具体来说,当某层的输入(bottom)和输出(top)名称相同时(即 in-place 层),需要将其 top 改为层名称(pl.name),并通过映射表 changed_top_dict 动态更新其他层的 bottom,确保后续层引用正确。
text = """
name: "MyNetwork"
layer {
name: "input_layer"
type: "Input"
top: "input"
input_param { shape { dim: 1 dim: 3 dim: 224 dim: 224 } }
}
layer {
name: "conv1"
type: "Convolution"
bottom: "input"
top: "conv1_out"
}
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1_out"
top: "conv1_out" # 这是 in-place 操作,输入输出名称相同
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1_out" # 依赖原始名称 "conv1_out"
top: "pool1_out"
}
""".strip()
为什么需要这样的处理?
避免名称冲突:原 in-place 层的输入输出绑定会导致后续层无法正确引用输出名称(如 pool1 无法找到 "conv1_out")。
兼容性需求:部分框架(如 PyTorch、TensorFlow)不支持 Caffe 的原生 in-place 机制,需显式修改名称以保证结构清晰。
统一输入节点表示#
替换数字名称#
from caffe_utils import convert_num_to_name
text = """
name: "替换数字名称"
layer {
name: "data"
type: "Input"
top: "181"
input_param {
shape {
dim: 1
dim: 3
dim: 224
dim: 224
}
}
}
layer {
name: "Relu_1"
type: "ReLU"
bottom: "181"
top: "182"
}
layer {
name: "PRelu_2"
type: "PReLU"
bottom: "182"
top: "183"
}
""".strip()
predict_net = text_format.Merge(text, pb2.NetParameter())
predict_net = convert_num_to_name(predict_net)
predict_net
name: "替换数字名称"
layer {
name: "data"
type: "Input"
top: "data"
input_param {
shape {
dim: 1
dim: 3
dim: 224
dim: 224
}
}
}
layer {
name: "Relu_1"
type: "ReLU"
bottom: "data"
top: "Relu_1"
}
layer {
name: "PRelu_2"
type: "PReLU"
bottom: "Relu_1"
top: "PRelu_2"
}
统一 caffe 结构#
from caffe_utils import unity_struct
predict_net = text_format.Merge(text, pb2.NetParameter())
predict_net = unity_struct(predict_net)
predict_net
name: "替换数字名称"
layer {
name: "data"
type: "Input"
top: "data"
input_param {
shape {
dim: 1
dim: 3
dim: 224
dim: 224
}
}
}
layer {
name: "Relu_1"
type: "ReLU"
bottom: "data"
top: "Relu_1"
}
layer {
name: "PRelu_2"
type: "PReLU"
bottom: "Relu_1"
top: "PRelu_2"
}