【问题标题】:Input dimension mismatch binary crossentropy Lasagne and Theano输入维度不匹配二元交叉熵千层面和 Theano
【发布时间】:2016-02-12 06:58:37
【问题描述】:

我阅读了网上所有关于人们忘记将目标向量更改为矩阵的问题的帖子,并且由于更改后问题仍然存在,我决定在这里提出我的问题。下面提到了解决方法,但出现了新问题,感谢您的建议!

使用卷积网络设置和带有 sigmoid 激活函数的二元交叉熵,我得到了一个维度不匹配的问题,但在训练数据期间没有,只有在验证/测试数据评估期间。出于某种奇怪的原因,我的验证集向量中的他的维度被切换了,我不知道为什么。如上所述,训练效果很好。代码如下,非常感谢您的帮助(很抱歉劫持了线程,但我没有看到创建新线程的理由),其中大部分是从千层面教程示例中复制的。

解决方法和新问题:

  1. 删除 valAcc 定义中的“axis=1”会有所帮助,但验证准确度仍然为零,并且无论我有多少节点、层、过滤器等,测试分类总是返回相同的结果。即使改变训练集的大小(我有大约 350 个样本,每个类都有 48x64 灰度图像)也不会改变这一点。所以似乎有些不对劲

网络创建:

def build_cnn(imgSet, input_var=None):
# As a third model, we'll create a CNN of two convolution + pooling stages
# and a fully-connected hidden layer in front of the output layer.

# Input layer using shape information from training
network = lasagne.layers.InputLayer(shape=(None, \
    imgSet.shape[1], imgSet.shape[2], imgSet.shape[3]), input_var=input_var)
# This time we do not apply input dropout, as it tends to work less well
# for convolutional layers.

# Convolutional layer with 32 kernels of size 5x5. Strided and padded
# convolutions are supported as well; see the docstring.
network = lasagne.layers.Conv2DLayer(
        network, num_filters=32, filter_size=(5, 5),
        nonlinearity=lasagne.nonlinearities.rectify,
        W=lasagne.init.GlorotUniform())

# Max-pooling layer of factor 2 in both dimensions:
network = lasagne.layers.MaxPool2DLayer(network, pool_size=(2, 2))

# Another convolution with 16 5x5 kernels, and another 2x2 pooling:
network = lasagne.layers.Conv2DLayer(
        network, num_filters=16, filter_size=(5, 5),
        nonlinearity=lasagne.nonlinearities.rectify)

network = lasagne.layers.MaxPool2DLayer(network, pool_size=(2, 2))

# A fully-connected layer of 64 units with 25% dropout on its inputs:
network = lasagne.layers.DenseLayer(
        lasagne.layers.dropout(network, p=.25),
        num_units=64,
        nonlinearity=lasagne.nonlinearities.rectify)

# And, finally, the 2-unit output layer with 50% dropout on its inputs:
network = lasagne.layers.DenseLayer(
        lasagne.layers.dropout(network, p=.5),
        num_units=1,
        nonlinearity=lasagne.nonlinearities.sigmoid)

return network

所有集合的目标矩阵都是这样创建的(以训练目标向量为例)

 targetsTrain = np.vstack( (targetsTrain, [[targetClass], ]*numTr) );

...以及theano 变量

inputVar = T.tensor4('inputs')
targetVar = T.imatrix('targets')
network = build_cnn(trainset, inputVar)
predictions = lasagne.layers.get_output(network)
loss = lasagne.objectives.binary_crossentropy(predictions, targetVar)
loss = loss.mean()
params = lasagne.layers.get_all_params(network, trainable=True)
updates = lasagne.updates.nesterov_momentum(loss, params, learning_rate=0.01, momentum=0.9)
valPrediction = lasagne.layers.get_output(network, deterministic=True)
valLoss = lasagne.objectives.binary_crossentropy(valPrediction, targetVar)
valLoss = valLoss.mean()
valAcc = T.mean(T.eq(T.argmax(valPrediction, axis=1), targetVar), dtype=theano.config.floatX)
train_fn = function([inputVar, targetVar], loss, updates=updates,  allow_input_downcast=True)
val_fn = function([inputVar, targetVar], [valLoss, valAcc])

最后,这里有两个循环,训练和测试。第一个很好,第二个抛出错误,摘录如下

# -- Neural network training itself -- #
numIts = 100
for itNr in range(0, numIts):
train_err = 0
train_batches = 0
for batch in iterate_minibatches(trainset.astype('float32'), targetsTrain.astype('int8'), len(trainset)//4, shuffle=True):
    inputs, targets = batch
    print (inputs.shape)
    print(targets.shape)        
    train_err += train_fn(inputs, targets)
    train_batches += 1

# And a full pass over the validation data:
val_err = 0
val_acc = 0
val_batches = 0

for batch in iterate_minibatches(valset.astype('float32'), targetsVal.astype('int8'), len(valset)//3, shuffle=False):
    [inputs, targets] = batch
    [err, acc] = val_fn(inputs, targets)
    val_err += err
    val_acc += acc
    val_batches += 1

错误(摘录)

Exception "unhandled ValueError"
Input dimension mis-match. (input[0].shape[1] = 52, input[1].shape[1] = 1)
Apply node that caused the error: Elemwise{eq,no_inplace}(DimShuffle{x,0}.0, targets)
Toposort index: 36
Inputs types: [TensorType(int64, row), TensorType(int32, matrix)]
Inputs shapes: [(1, 52), (52, 1)]
Inputs strides: [(416, 8), (4, 4)]
Inputs values: ['not shown', 'not shown']

再次感谢您的帮助!

【问题讨论】:

    标签: theano dimension mismatch lasagne


    【解决方案1】:

    所以似乎错误在于验证准确性的评估。 当您在计算中删除“axis = 1”时,argmax 会继续执行所有操作,只返回一个数字。 然后,广播介入,这就是为什么您会看到整个集合的值相同的原因。

    但是根据您发布的错误,“T.eq”操作会引发错误,因为它必须将 52 x 1 与 1 x 52 向量(theano/numpy 的矩阵)进行比较。 因此,我建议您尝试将这一行替换为:

        valAcc = T.mean(T.eq(T.argmax(valPrediction, axis=1), targetVar.T))
    

    我希望这能修复错误,但我自己没有测试过。

    编辑: 错误在于调用的 argmax 操作。 通常,argmax 用于确定哪个输出单元被激活最多。 但是,在您的设置中,您只有一个输出神经元,这意味着所有输出神经元的 argmax 将始终返回 0(对于第一个 arg)。

    这就是为什么你的网络给你的印象总是 0 作为输出。

    通过替换:

        valAcc = T.mean(T.eq(T.argmax(valPrediction, axis=1), targetVar.T))
    

    与:

        binaryPrediction = valPrediction > .5
        valAcc = T.mean(T.eq(binaryPrediction, targetVar.T)
    

    你应该得到想要的结果。

    我只是不确定是否仍然需要转置。

    【讨论】:

    • 如前所述,当axis=1时出现尺寸不匹配。一旦我删除它,错误就会消失,但训练似乎不起作用。我还尝试将预测展平,这会导致另一个维度错误。
    • 好的,使用转置工作,但现在在每一步验证准确性从第一次迭代到最后一次迭代保持不变......
    • 你能发布网络输出的尺寸吗?您的输入似乎是形状为 batchsize x stacksize x row x col 的张量4?
    • 是的,输入是猜测的,目标大小是(batchsize,stacksize),在这两种情况下stacksize = 1。预测是Shape.0
    • 不,他们不是。 shape.0 只是 theano var 的输出,您可以尝试通过在函数声明中将 valAcc 临时替换为 valPrediction 来尝试输出形状。即: val_fn = function([inputVar, valPrediction], [valLoss, valAcc]) 这样,theano 会向您输出验证预测,然后您可以在批处理 for 循环中调用“acc.shape”。
    猜你喜欢
    • 2020-07-16
    • 2020-08-13
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    • 2019-07-13
    • 2017-01-17
    • 1970-01-01
    • 2018-11-03
    相关资源
    最近更新 更多