caffe:使用固定的预定义内核(过滤器)进行卷积
caffe: convolution with a fix predifined kernel (filter)
我对具有固定预定义矩阵的卷积感兴趣,而不是拥有可学习的过滤器;例如 sobel 过滤器:
所以,我将 learning = 0(所以它是固定的)设置为:
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param { lr_mult: 0 decay_mult: 0 }
convolution_param {
num_output: 10
kernel_size: 3 # filter is 3x3
stride: 2
weight_filler {
type: ??}
}
}
现在,我不知道如何将矩阵信息提供给conv层。有任何想法吗?我认为它应该转到 weight_filler,但是如何呢?
还有一个问题:num_output 必须与 bottom 的(此处数据通道 = 10)通道大小相同吗?我可以设置 num_output 另一个号码吗?如果是,会发生什么,这意味着什么?
如何将权重初始化为特定值?
您可以使用 net_surgery
在 python 中加载您的 untrained/un-initialized 网络,然后将您想要的特定权重分配给过滤器,保存网络,并与权重一起使用你想要这个特定的图层。
如何设置num_output
和其他conv_params
?
这是个好问题:你有一个形状为 b
x10
xh
xw
的输入 blob,你想应用一个 3
x3
过滤每个通道并得到一个新的过滤 b
x10
xh
xw
。如果你只设置num_output: 10
,过滤器的形状将是10
x10
x3
x3
,即10个形状为[=的过滤器14=]x3
x3
- 这 不是 想要的。您需要 3
x3
过滤器。
为此,您需要查看 group
conv_param。将 group: 10
与 num_output: 10
一起设置(假设输入 c=10)将为您提供您想要的,权重形状将为 10
x1
x3
x 3
.
在pythoncaffe接口中,caffe.Net
对象通过加载.prototxt
文件实例化,它定义了网络架构。您可以使用具有以下属性的 caffe.Net
对象来访问网络上的各种信息。
blob_loss_weights
:按层名称索引的网络 blob 损失权重的 OrderedDict(从下到上,即输入到输出)
blobs
:按层名称索引的网络 blob 的 OrderedDict(从下到上,即输入到输出)
bottom_names
:全网下名
inputs
:输入到这个网络
layer_dict
:按层名称索引的网络层的 OrderedDict(从下到上,即输入到输出)
layers
:caffe._caffe.LayerVec
- 其元素是网络中 caffe.Layer
个对象的列表,caffe.Layer
个类有 blobs
层参数内存字段和 type
层类型(例如卷积、数据等)
outputs
:来自这个网络的输出
params
:按名称索引的网络参数的OrderedDict(从下到上,即输入到输出);每个都是多个 blob 的列表(例如,权重和偏差)
top_names
: 网络中的所有顶级人物
您可以使用 caffe.Net.params
访问层的可学习参数,并使用 caffe.Net.layer_dict
访问层信息。
caffe.Net.params
是有序字典,其中键是层名称,值是参数(例如权重和偏差)的斑点,在卷积层的情况下,首先blob 的元素是 weiht,blob 的第二个元素是 bias:
caffe.Net.params['layer_name'][0]
: 体重
caffe.Net.params['layer_name'][1]
:偏差
请注意,访问 blob 的内存应该用 caffe.Net.params['layer_name'][0].data
完成,更新 blob 的内存应该用 ...
完成,例如 caffe.Net.params['layer_name'][0].data[...]
以下代码说明了从 numpy 保存的文件 (.npy) 加载可学习参数:
def load_weights_and_biases(network):
k_list = list(network.params.keys())
suffix = ["weight", "bias"]
num_layers = len(network.layer_dict)
for idx, layer_name in enumerate(network.layer_dict):
print(f"\n-----------------------------")
print(f"layer index: {idx}/{num_layers}")
print(f"layer name: '{layer_name}''")
print(f"layer type: '{detection_nw.layers[idx].type}' ")
if layer_name in k_list:
params = network.params[layer_name]
print(f"{len(params)} learnable parameters in '{detection_nw.layers[idx].type}' type")
for i, p in enumerate(params):
#print(f"\tparams[{i}]: {p}")
#print(f"\tparams[{i}] CxHxW: {p.channels}x{p.height}x{p.width}")
print(f"\tp[{i}]: {p.data.shape} of {p.data.dtype}")
param_file_path = f"./npy_save/{layer_name}_{suffix[i]}.npy"
param_file = Path(param_file_path)
if param_file.exists():
print(f"\tload {param_file_path}")
arr = np.load(param_file_path, allow_pickle=True)
if p.data.shape == arr.shape:
print(f"\tset {layer_name}_{suffix[i]} with arr:shape {arr.shape}, type {arr.dtype}")
p.data[...] = arr
else:
print(f"p.data.shape: {p.data.shape} is not equal to arr.shape: {arr.shape}")
break
else:
print(f"{param_file_path} is not exits!!")
break
else:
print(f"no learnable parameters in '{layer_name}' of '{network.layers[idx].type}' type'")
Blob 类型在 pythoncaffe(又名 pycaffe)接口中定义为 caffe._caffe.Blob
。在 import caffe
之后使用 help(caffe._caffe.Blob)
并在此处定义的 数据描述符中描述的名称 帮助输出部分作为属性。
有关 Caffe 中 Blob 参考的更多详细信息
- Blobs, Layers, and Nets: anatomy of a Caffe model - caffe documentations
- caffe::Blob Class Template Reference - C++ source for Blob class
我对具有固定预定义矩阵的卷积感兴趣,而不是拥有可学习的过滤器;例如 sobel 过滤器:
所以,我将 learning = 0(所以它是固定的)设置为:
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param { lr_mult: 0 decay_mult: 0 }
convolution_param {
num_output: 10
kernel_size: 3 # filter is 3x3
stride: 2
weight_filler {
type: ??}
}
}
现在,我不知道如何将矩阵信息提供给conv层。有任何想法吗?我认为它应该转到 weight_filler,但是如何呢?
还有一个问题:num_output 必须与 bottom 的(此处数据通道 = 10)通道大小相同吗?我可以设置 num_output 另一个号码吗?如果是,会发生什么,这意味着什么?
如何将权重初始化为特定值?
您可以使用 net_surgery
在 python 中加载您的 untrained/un-initialized 网络,然后将您想要的特定权重分配给过滤器,保存网络,并与权重一起使用你想要这个特定的图层。
如何设置num_output
和其他conv_params
?
这是个好问题:你有一个形状为 b
x10
xh
xw
的输入 blob,你想应用一个 3
x3
过滤每个通道并得到一个新的过滤 b
x10
xh
xw
。如果你只设置num_output: 10
,过滤器的形状将是10
x10
x3
x3
,即10个形状为[=的过滤器14=]x3
x3
- 这 不是 想要的。您需要 3
x3
过滤器。
为此,您需要查看 group
conv_param。将 group: 10
与 num_output: 10
一起设置(假设输入 c=10)将为您提供您想要的,权重形状将为 10
x1
x3
x 3
.
在pythoncaffe接口中,caffe.Net
对象通过加载.prototxt
文件实例化,它定义了网络架构。您可以使用具有以下属性的 caffe.Net
对象来访问网络上的各种信息。
blob_loss_weights
:按层名称索引的网络 blob 损失权重的 OrderedDict(从下到上,即输入到输出)blobs
:按层名称索引的网络 blob 的 OrderedDict(从下到上,即输入到输出)bottom_names
:全网下名inputs
:输入到这个网络layer_dict
:按层名称索引的网络层的 OrderedDict(从下到上,即输入到输出)layers
:caffe._caffe.LayerVec
- 其元素是网络中caffe.Layer
个对象的列表,caffe.Layer
个类有blobs
层参数内存字段和type
层类型(例如卷积、数据等)outputs
:来自这个网络的输出params
:按名称索引的网络参数的OrderedDict(从下到上,即输入到输出);每个都是多个 blob 的列表(例如,权重和偏差)top_names
: 网络中的所有顶级人物
您可以使用 caffe.Net.params
访问层的可学习参数,并使用 caffe.Net.layer_dict
访问层信息。
caffe.Net.params
是有序字典,其中键是层名称,值是参数(例如权重和偏差)的斑点,在卷积层的情况下,首先blob 的元素是 weiht,blob 的第二个元素是 bias:
caffe.Net.params['layer_name'][0]
: 体重caffe.Net.params['layer_name'][1]
:偏差
请注意,访问 blob 的内存应该用 caffe.Net.params['layer_name'][0].data
完成,更新 blob 的内存应该用 ...
完成,例如 caffe.Net.params['layer_name'][0].data[...]
以下代码说明了从 numpy 保存的文件 (.npy) 加载可学习参数:
def load_weights_and_biases(network):
k_list = list(network.params.keys())
suffix = ["weight", "bias"]
num_layers = len(network.layer_dict)
for idx, layer_name in enumerate(network.layer_dict):
print(f"\n-----------------------------")
print(f"layer index: {idx}/{num_layers}")
print(f"layer name: '{layer_name}''")
print(f"layer type: '{detection_nw.layers[idx].type}' ")
if layer_name in k_list:
params = network.params[layer_name]
print(f"{len(params)} learnable parameters in '{detection_nw.layers[idx].type}' type")
for i, p in enumerate(params):
#print(f"\tparams[{i}]: {p}")
#print(f"\tparams[{i}] CxHxW: {p.channels}x{p.height}x{p.width}")
print(f"\tp[{i}]: {p.data.shape} of {p.data.dtype}")
param_file_path = f"./npy_save/{layer_name}_{suffix[i]}.npy"
param_file = Path(param_file_path)
if param_file.exists():
print(f"\tload {param_file_path}")
arr = np.load(param_file_path, allow_pickle=True)
if p.data.shape == arr.shape:
print(f"\tset {layer_name}_{suffix[i]} with arr:shape {arr.shape}, type {arr.dtype}")
p.data[...] = arr
else:
print(f"p.data.shape: {p.data.shape} is not equal to arr.shape: {arr.shape}")
break
else:
print(f"{param_file_path} is not exits!!")
break
else:
print(f"no learnable parameters in '{layer_name}' of '{network.layers[idx].type}' type'")
Blob 类型在 pythoncaffe(又名 pycaffe)接口中定义为 caffe._caffe.Blob
。在 import caffe
之后使用 help(caffe._caffe.Blob)
并在此处定义的 数据描述符中描述的名称 帮助输出部分作为属性。
有关 Caffe 中 Blob 参考的更多详细信息
- Blobs, Layers, and Nets: anatomy of a Caffe model - caffe documentations
- caffe::Blob Class Template Reference - C++ source for Blob class