0

我正在使用 lasagne 和 theano 预测来自 VGG 的回归任务的 20 个数字。对于我编写的示例脚本,图像数量为 100。我认为我在做一些愚蠢的事情,但被卡住了。

在网上看,用nolearn的人,可以通过指定来修复regression=True,但我只是用千层面

所以:

('X.shape', (100, 3, 224, 224))
('y.shape', (100, 20))

这是确切的错误消息

Traceback (most recent call last):
  File "script_1.py", line 167, in <module>
    loss = train_batch()
  File "script_1.py", line 90, in train_batch
    return train_fn(X_tr[ix], y_tr[ix])
  File "/usr/local/lib/python2.7/dist-packages/Theano-0.8.0rc1-py2.7.egg/theano/compile/function_module.py", line 786, in __call__
    allow_downcast=s.allow_downcast)
  File "/usr/local/lib/python2.7/dist-packages/Theano-0.8.0rc1-py2.7.egg/theano/tensor/type.py", line 177, in filter
    data.shape))
TypeError: ('Bad input argument to theano function with name "script_1.py:159"  at index 1(0-based)', 'Wrong number of dimensions: expected 1, got 2 with shape (16, 20).')

这是模型

def build_model():
    net = {}
    net['input'] = InputLayer((None, 3, 224, 224))
    net['conv1'] = ConvLayer(net['input'], num_filters=96, filter_size=7, stride=2, flip_filters=False)
     ...............
    net['drop7'] = DropoutLayer(net['fc7'], p=0.5)
    net['fc8'] = DenseLayer(net['drop7'], num_units=20, nonlinearity=None)
    return net

发电机:

def batches(iterable, N):
    chunk = []
    for item in iterable:
        chunk.append(item)
        if len(chunk) == N:
            yield chunk
            chunk = []
    if chunk:
        yield chunk
def train_batch():
    ix = range(len(y_tr))
    np.random.shuffle(ix)
    ix = ix[:BATCH_SIZE]
    return train_fn(X_tr[ix], y_tr[ix])

相关训练片段

X_sym = T.tensor4()
y_sym = T.ivector()
output_layer = net['fc8']
prediction = lasagne.layers.get_output(output_layer, X_sym)
loss = lasagne.objectives.squared_error(prediction, y_sym)
loss = loss.mean()
acc = T.mean(T.eq(T.argmax(prediction, axis=1), y_sym), dtype=theano.config.floatX)
params = lasagne.layers.get_all_params(output_layer, trainable=True)
updates = lasagne.updates.nesterov_momentum(loss, params, learning_rate=0.0001, momentum=0.9)

train_fn = theano.function([X_sym, y_sym], loss, updates=updates)
val_fn = theano.function([X_sym, y_sym], [loss, acc])
pred_fn = theano.function([X_sym], prediction)

for epoch in range(5):
    for batch in range(25):
       loss = train_batch()
.....
4

1 回答 1

1

您的预测输出具有形状 (batchsize, 20) 但您的 y_sym 变量是 ivector 类型,因此它可能是长度为 batchsize 的向量。我不确定这是否是导致错误的原因,但我认为您无法计算这两个量的平方误差项。一个是矩阵,另一个是向量,它们的形状似乎没有对齐?

你的回归目标是什么?如果您为每个数据点预测 20 个数字,您的 y_sym 可能应该是一个矩阵,那么您可以计算平方误差项。

另一种可能性是改变你的最后一层,使非线性成为 sigmoid。通过这种方式,您可以将卷积神经网络解释为产生多标签概率。然后,您可以为回归综合生成多标签概率目标变量。一个例子是,假设一个数据点 x 有多个标签 0、1、10。您可以创建一个长度为 20 的向量,其中 0、1、10 就像一些小的 a 的 1-a,而其他条目是小的正数.

您还可以将目标函数切换为二元交叉熵。在这种情况下,我们不执行回归。然而,我们的网络仍然输出一个类得分矩阵,而不是一个向量。这通常是在检测图像中是否存在 K 个不同对象(例如猫、狗、人、汽车、自行车等)时使用的损失函数,例如多标签分类。如果你想试试这条路线,我们将最后一层更改如下:

net['fc8'] = DenseLayer(net['drop7'], num_units=20, nonlinearity=sigmoid)

现在我将我的网络解释为输出概率;每个概率将代表关于我们的网络是否相信该对象类在图像中的置信度分数。

我们现在将有以下损失函数:

X_sym = T.tensor4()
y_sym = T.imatrix() 
output_layer = net['fc8']
probabilities = lasagne.layers.get_output(output_layer, X_sym)
loss = lasagne.objectives.binary_crossentropy(probabilities, y_sym)
loss = loss.mean()
... the rest of the update stuff...
train_fn = theano.function([X_sym, y_sym], loss, updates=updates)

这里的关键区别在于我们的目标变量 y_sym 现在是一个矩阵。这必须是一个 {0,1} 值 (batchsize,K) 大小的矩阵,其中 0 表示图像中不存在对象,1 表示图像中存在对象。

为了计算多标签预测的准确性,通常使用 F1 分数。是有关如何使用 scikit-learn 计算 F1 分数的参考。在这种情况下,我们的验证函数会有所不同,它可能看起来像这样:

 from sklearn.metrics import f1_score
 probabilities_fn = theano.function([X_sym], probabilities)
 confidence_threshold = .5 
 predictions = np.where(probabilities_fn(X_sym) > confidence_threshold, 1, 0)  
 f1_score(y_true, predictions, average='micro')

上面的代码片段返回来自我们网络的概率/置信度分数,以及超过我们的 confidence_threshold 参数的任何概率,这里我选择 .5,我们将其解释为存在类标签。

于 2016-03-28T13:27:04.637 回答