我正在对数据进行自动编码器训练,其中每个观察值都是p=[p_1, p_2,...,p_n]
,其中0<p_i<1
代表所有i
。此外,每个输入p
可以划分为每个部分的总和等于1的部分。这是因为元素表示分类分布的参数,而p
包含多个分类分布的参数。
例如,我的数据来自一个概率数据库,看起来可能像这样:
为了对我的输出强制执行此约束,我在Keras的功能模型API中使用了多个softmax激活。实际上,我正在做的事情类似于多标签分类。可能如下所示:
实现如下:
encoding_dim = 3
numb_cat = len(structure)
inputs = Input(shape=(train_corr.shape[1],))
encoded = Dense(6, activation='linear')(inputs)
encoded = Dense(encoding_dim, activation='linear')(encoded)
decoded = Dense(6, activation='linear')(encoded)
decodes = [Dense(e, activation='softmax')(decoded) for e in structure]
losses = [jsd for j in range(numb_cat)] # JSD loss function
autoencoder = Model(inputs, decodes)
sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
autoencoder.compile(optimizer=sgd, loss=losses, loss_weights=[1 for k in range(numb_cat)])
train_attr_corr = [train_corr[:, i:j] for i, j in zip(np.cumsum(structure_0[:-1]), np.cumsum(structure_0[1:]))]
test_attr_corr = [test_corr[:, i:j] for i, j in zip(np.cumsum(structure_0[:-1]), np.cumsum(structure_0[1:]))]
history = autoencoder.fit(train_corr, train_attr_corr, epochs=100, batch_size=2,
shuffle=True,
verbose=1, validation_data=(test_corr, test_attr_corr))
其中structure
是一个列表,其中包含每个属性具有的类别数量,从而控制输出层中的哪些节点被分组并转到相同的softmax层。在上面的示例中,structure = [2,2]
。此外,损失jsd
是KL散度的对称形式。
问题:
使用linear
激活功能时,效果非常好。但是,当我尝试使用非线性激活函数(relu
或sigmoid
)时,结果会更糟。可能是什么原因?