我有一个语义分割问题,如果一个特征向量可以有多个标签,那就太好了。所以我有一些属于类1、2和3的数据部分(还有一些只属于一个类,有些根本不属于类…)
我认为一个类似但简单得多的玩具问题是建立一个神经网络,该网络以二进制格式获取一个数字作为输入特征,并应决定它是否可被2、3、二者整除,或不可被二者整整除。
我尝试过的
我用nolearn构建了一个有两个输出神经元的网络(一个用于"可被2整除",另一个用于"可被3整除"
请注意,我知道,对于这个简单的例子,我可以简单地添加两个类"可被二者整除"one_answers"不可被2或3整除"。然而,我只是为一个更复杂的问题创建了这个例子,而我没有这种可能性。
输出层可能不是softmax层,因为我不想在输出的总和中得到1(但0、1或2)。问题是我不知道我的标签向量应该是什么样子。通常,我只给出label_vector = [class_for_first, class_for_second, ...]
,但这次我需要一个类的列表。我该如何调整?
(这不一定要用nolearn来完成。纯的Lasagne溶液也可以。)
#!/usr/bin/env python
"""Neural Network to decide for numbers in 0..15 if they are divisble by
2, 3, both or none.
"""
import lasagne
from lasagne import layers
from lasagne.updates import nesterov_momentum
from nolearn.lasagne import NeuralNet
import numpy
def nn_example():
feature_vectors, labels = [], []
for i in range(2):
for j in range(2):
for k in range(2):
for l in range(2):
feature_vectors.append([i, j, k, l])
sum_val = 2**0 * i + 2**1 * j + 2**2 * k + 2**3 * l
if sum_val % 2 == 0 and sum_val % 3 != 0:
# Only output node for '2' should be one
labels.append(0)
elif sum_val % 2 != 0 and sum_val % 3 == 0:
# Only output node for '3' should be one
labels.append(1)
elif sum_val % 2 != 0 and sum_val % 3 != 0:
# _ALL_ output should be zero
labels.append(0) # dummy value
else:
# It is divisible by 2 and 3
# _BOTH_ output nodes should be 1
labels.append(1) # dummy value
feature_vectors = numpy.array(feature_vectors, dtype=numpy.float32)
labels = numpy.array(labels, dtype=numpy.int32)
net1 = NeuralNet(layers=[('input', layers.InputLayer),
('hidden', layers.DenseLayer),
('hidden2', layers.DenseLayer),
('output', layers.DenseLayer),
],
# layer parameters:
input_shape=(None, 4),
hidden_num_units=3,
hidden2_num_units=2,
output_nonlinearity=lasagne.nonlinearities.sigmoid,
output_num_units=2,
# optimization method:
update=nesterov_momentum,
update_learning_rate=0.01,
update_momentum=0.9,
max_epochs=1000,
verbose=1,
)
# Train the network
net1.fit(feature_vectors, labels)
# Try the network
print("Predicted: %s" % str(net1.predict_proba([[0, 0, 1, 0]])))
if __name__ == '__main__':
nn_example()
标签应编码在矩阵(num_samples,num_classes)中,所有条目都为0或1。从sigmoid输出层获取激活,并计算交叉熵:
-T.sum(y * T.log(z) + (1 - y) * T.log(1 - z))