gpt4 book ai didi

neural-network - Caffe Python层中的向后传递未被调用/工作?

转载 作者:行者123 更新时间:2023-12-04 06:45:52 26 4
gpt4 key购买 nike

我没有成功尝试使用 Caffe 在 Python 中实现一个简单的损失层。作为引用,我发现了几个用 Python 实现的层,包括 here , herehere .

从 Caffe 文档/示例提供的 EuclideanLossLayer 开始,我无法让它工作并开始调试。即使使用这个简单的 TestLayer:

def setup(self, bottom, top):
"""
Checks the correct number of bottom inputs.

:param bottom: bottom inputs
:type bottom: [numpy.ndarray]
:param top: top outputs
:type top: [numpy.ndarray]
"""

print 'setup'

def reshape(self, bottom, top):
"""
Make sure all involved blobs have the right dimension.

:param bottom: bottom inputs
:type bottom: caffe._caffe.RawBlobVec
:param top: top outputs
:type top: caffe._caffe.RawBlobVec
"""

print 'reshape'
top[0].reshape(bottom[0].data.shape[0], bottom[0].data.shape[1], bottom[0].data.shape[2], bottom[0].data.shape[3])

def forward(self, bottom, top):
"""
Forward propagation.

:param bottom: bottom inputs
:type bottom: caffe._caffe.RawBlobVec
:param top: top outputs
:type top: caffe._caffe.RawBlobVec
"""

print 'forward'
top[0].data[...] = bottom[0].data

def backward(self, top, propagate_down, bottom):
"""
Backward pass.

:param bottom: bottom inputs
:type bottom: caffe._caffe.RawBlobVec
:param propagate_down:
:type propagate_down:
:param top: top outputs
:type top: caffe._caffe.RawBlobVec
"""

print 'backward'
bottom[0].diff[...] = top[0].diff[...]

我无法让 Python 层正常工作。学习任务相当简单,因为我只是试图预测一个实数值是正数还是负数。对应的数据生成如下并写入LMDB:

N = 10000
N_train = int(0.8*N)

images = []
labels = []

for n in range(N):
image = (numpy.random.rand(1, 1, 1)*2 - 1).astype(numpy.float)
label = int(numpy.sign(image))

images.append(image)
labels.append(label)

将数据写入 LMDB 应该是正确的,因为使用 Caffe 提供的 MNIST 数据集进行的测试显示没有问题。网络定义如下:

 net.data, net.labels = caffe.layers.Data(batch_size = batch_size, backend = caffe.params.Data.LMDB, 
source = lmdb_path, ntop = 2)
net.fc1 = caffe.layers.Python(net.data, python_param = dict(module = 'tools.layers', layer = 'TestLayer'))
net.score = caffe.layers.TanH(net.fc1)
net.loss = caffe.layers.EuclideanLoss(net.score, net.labels)

使用手动完成求解:

for iteration in range(iterations):
solver.step(step)

对应的prototxt文件如下:

solver.prototxt:

weight_decay: 0.0005
test_net: "tests/test.prototxt"
snapshot_prefix: "tests/snapshot_"
max_iter: 1000
stepsize: 1000
base_lr: 0.01
snapshot: 0
gamma: 0.01
solver_mode: CPU
train_net: "tests/train.prototxt"
test_iter: 0
test_initialization: false
lr_policy: "step"
momentum: 0.9
display: 100
test_interval: 100000

train.prototxt:

layer {
name: "data"
type: "Data"
top: "data"
top: "labels"
data_param {
source: "tests/train_lmdb"
batch_size: 64
backend: LMDB
}
}
layer {
name: "fc1"
type: "Python"
bottom: "data"
top: "fc1"
python_param {
module: "tools.layers"
layer: "TestLayer"
}
}
layer {
name: "score"
type: "TanH"
bottom: "fc1"
top: "score"
}
layer {
name: "loss"
type: "EuclideanLoss"
bottom: "score"
bottom: "labels"
top: "loss"
}

test.prototxt:

layer {
name: "data"
type: "Data"
top: "data"
top: "labels"
data_param {
source: "tests/test_lmdb"
batch_size: 64
backend: LMDB
}
}
layer {
name: "fc1"
type: "Python"
bottom: "data"
top: "fc1"
python_param {
module: "tools.layers"
layer: "TestLayer"
}
}
layer {
name: "score"
type: "TanH"
bottom: "fc1"
top: "score"
}
layer {
name: "loss"
type: "EuclideanLoss"
bottom: "score"
bottom: "labels"
top: "loss"
}

我尝试追踪它,在 TestLayerbackwardfoward 方法中添加调试消息,只有 forward 方法(请注意,不执行任何测试,调用只能与求解相关)。同样,我在 python_layer.hpp 中添加了调试消息:

virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
LOG(INFO) << "cpp forward";
self_.attr("forward")(bottom, top);
}
virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
LOG(INFO) << "cpp backward";
self_.attr("backward")(top, propagate_down, bottom);
}

同样,只执行前向传球。当我删除 TestLayer 中的 backward 方法时,求解仍然有效。删除 forward 方法时,由于未实现 forward 会引发错误。我希望 backward 也是如此,因此似乎根本不会执行向后传递。切换回常规层并添加调试消息,一切正常。

我感觉我遗漏了一些简单或基本的东西,但我已经好几天没能解决问题了。因此,感谢任何帮助或提示。

谢谢!

最佳答案

这是预期的行为,因为您的 python 层“下方”没有任何实际需要梯度来计算权重更新的层。 Caffe 注意到了这一点并跳过了这些层的反向计算,因为这会浪费时间。

如果在网络初始化时需要在日志中进行反向计算,则 Caffe 会打印所有层。在您的情况下,您应该看到如下内容:

fc1 does not need backward computation.

如果您在“Python”层下方放置“InnerProduct”或“Convolution”层(例如,Data->InnerProduct->Python->Loss),则反向计算变得必要,而您的反向计算方法被调用。

关于neural-network - Caffe Python层中的向后传递未被调用/工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40540106/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com