Нейронная сеть для более чем одного класса не работает
Я пытаюсь использовать нейронную сеть для проблемы классификации. У меня есть 6 возможных классов, и один и тот же вход может быть в нескольких классах.
Проблема в том, что когда я пытаюсь обучить по одному NN для каждого класса, я устанавливаю output_num_units = 1 и в поезде пропускаю первый столбец y, y[:,0]. Я получаю следующий вывод и ошибку:
## Layer information
# name size
--- ------ ------
0 input 32
1 dense0 32
2 output 1
IndexError: index 1 is out of bounds for axis 1 with size 1
Apply node that caused the error: CrossentropyCategorical1Hot(Elemwise{Composite{scalar_sigmoid((i0 + i1))}}[(0, 0)].0, y_batch)
Inputs types: [TensorType(float32, matrix), TensorType(int32, vector)]
Inputs shapes: [(128, 1), (128,)]
Inputs strides: [(4, 4), (4,)]
Inputs values: ['not shown', 'not shown']
Если я попытаюсь использовать output_num_units=num_class
(6) и полный y (все шесть полей), сначала я получаю сообщение об ошибке KStratifiedFold, потому что кажется, что у y не будет нескольких строк. Если я установлю eval_size=None
, чем я получаю следующую ошибку:
TypeError: ('Bad input argument to theano function with name "/usr/local/lib/python2.7/site-packages/nolearn-0.6a0.dev0-py2.7.egg/nolearn/lasagne/base.py:311"
at index 1(0-based)', 'Wrong number of dimensions: expected 1, got 2 with shape (128, 6).')
Единственная работающая конфигурация - это установка более одного выходного устройства и передача только одного столбца y. Чем он обучает NN, но, похоже, он не прав, поскольку он дает мне 2 выходных слоя, и у меня есть только один Y для сравнения.
Что я делаю неправильно? Почему я не могу использовать только один выход? Должен ли я преобразовать мои классы y из вектора из 6 столбцов в вектор только из одного столбца с номером?
Я использую следующий код (выдержка):
# load data
data,labels = prepare_data_train('../input/train/subj1_series1_data.csv')
# X_train (119496, 32) <type 'numpy.ndarray'>
X_train = data_preprocess_train(data)
#print X_train.shape, type(X_train)
# y (119496, 6) <type 'numpy.ndarray'>
y = labels.values.astype(np.int32)
print y.shape, type(y)
# net config
num_features = X_train.shape[1]
num_classes = labels.shape[1]
# train neural net
layers0 = [('input', InputLayer),
('dense0', DenseLayer),
('output', DenseLayer)]
net1 = NeuralNet(
layers=layers0,
# layer parameters:
input_shape=(None, num_features), # 32 input
dense0_num_units = 32, # number of units in hidden layer
output_nonlinearity=sigmoid, # sigmoid function as it has only one class
output_num_units=2 , # if I try 1, it does not work
# optimization method:
update=nesterov_momentum,
update_learning_rate=0.01,
update_momentum=0.9,
max_epochs=50, # we want to train this many epochs
verbose=1,
eval_size=0.2
)
net1.fit(X_train, y[:,0])
1 ответ
Затем я хотел использовать CNN в Lasagne, но не работал так же, так как предсказания всегда были 0... рекомендую взглянуть на пример MNIST. Я считаю, что этот вариант гораздо лучше использовать и расширять, так как старые фрагменты кода не работали полностью из-за изменений API с течением времени. Я исправил пример MNIST, мой целевой вектор имеет метки 0 или 1 и создаю выходной слой для NN следующим образом:
# Finally, we'll add the fully-connected output layer, of 2 softmax units:
l_out = lasagne.layers.DenseLayer(
l_hid2_drop, num_units=2,
nonlinearity=lasagne.nonlinearities.softmax)
И для CNN:
layer = lasagne.layers.DenseLayer(
lasagne.layers.dropout(layer, p=.5),
num_units=2,
nonlinearity=lasagne.nonlinearities.softmax)