2016-02-12 1 views
4

Я прочитал все сообщения в сети, в которых упоминается проблема, когда люди забыли изменить целевой вектор на матрицу, и поскольку проблема остается после этого изменения, я решил задать свой вопрос здесь. Обходные решения упоминаются ниже, но появляются новые проблемы, и я благодарен за предложения!Несоответствие размерности входных данных бинарная кроссентропия Лазань и Теано

Использование конфигурации сети свертки и бинарной кроссентропии с функцией активации сигмоида, я получаю проблему несоответствия размеров, но не во время учебных данных, только во время проверки данных проверки/тестирования. По какой-то странной причине, из моих векторов вектора проверки меняет свое измерение, и я понятия не имею, почему. Обучение, как упоминалось выше, отлично работает. Ниже приведен код, спасибо за помощь (и извините за захват потока, но я не видел причин для создания нового), большая часть которого была скопирована из примера урока лазаньи.

Обходные и новые проблемы:

  1. Удаление «ось = 1» в определение valAcc помогает, но точность проверки остается равной нулю, и тест классификации всегда возвращает тот же результат, независимо от того, сколько узлов, слои, фильтры и т.д. У меня есть. Даже изменение размера обучающего набора (у меня есть около 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 

Erorr (выдержки)

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'] 

Еще раз спасибо за помощь!

ответ

3

поэтому, кажется, что ошибка заключается в оценке точности проверки. Когда вы удаляете «ось = 1» в своем вычислении, argmax переходит на все, возвращая только число. Затем, вещание шагов, и именно поэтому вы увидите то же значение для всего набора.

Но из-за ошибки, которую вы опубликовали, функция «T.eq» выдает ошибку, поскольку она должна сравнивать 52 x 1 с вектором 1 x 52 (матрица для anano/numpy). Итак, я предлагаю вам попробовать заменить строку с:

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

Я надеюсь, что это должно исправить ошибку, но я не проверял сам.

EDIT: Ошибка заключается в вызываемом argmax op. Обычно 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) 

вы должны получить желаемый результат.

Я просто не уверен, если транспонирование по-прежнему необходимо или нет.

+0

Как упоминалось выше, несоответствие размеров возникает, когда ось = 1. Как только я удаляю его, ошибка исчезает, но тренировка не работает. Я также попытался сгладить предсказания, что приводит к другой ошибке измерения. – gilgamash

+0

Хорошо, используя транспонирование, но теперь на каждом шаге точность проверки остается неизменной от первой до последней итерации ... – gilgamash

+0

Можете ли вы опубликовать размеры выхода сети? Ваш вход кажется тензором4 с формой _batchsize_ x _stacksize_ x _row_ x _col_ или нет? – romeasy

Смежные вопросы