2

我有一个语义分割问题,如果我可以为一个特征向量设置多个标签,那就太好了。因此,我的数据的某些部分属于 1、2 和 3 类(以及其他仅属于一个类,有些根本不属于任何类......)。

我认为一个类似但更简单的玩具问题是构建一个神经网络,它以二进制格式获取一个数字作为输入特征,并且应该决定它是否可以被 2、3、两者整除,或者两者都不能整除。

我试过的

我使用nolearn构建了一个具有两个输出神经元的网络(一个用于“可被 2 整除”,另一个用于“可被 3 整除”。

请注意,对于这个简单的示例,我知道我可以简单地添加两个类“可被两者整除”和“不能被 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()
4

1 回答 1

0

您的标签应编码在矩阵(num_samples,num_classes)中,所有条目为 0 或 1。从 sigmoid 输出层获取激活并计算交叉熵:

-T.sum(y * T.log(z) + (1 - y) * T.log(1 - z))

于 2015-06-26T20:05:36.160 回答