处理二进制输入/输出

时间:2017-06-26 10:54:56

标签: machine-learning neural-network deep-learning keras

如果我的神经网络的输入和输出是(或应该是)二进制值,我应该考虑哪些事项?

示例

我有一系列单热编码矢量,如下所示:

[0 1 0 0], [1 0 0 0], ... 

所以,关于这一点,会出现一些想法或问题:

  • 使用它是否合理,就像它作为LSTM之类的神经网络的输入一样?或者我应该改变它吗?

  • 另一方面,LSTM返回介于-1和1之间的连续值(tanh),我应该使用另一个激活函数吗?最后我也想要离散输出,就像我的输入向量一样。我应该对值进行舍入吗?

  • 我意识到并且有点奇怪的是,我现在的网络倾向于将它的所有(内部)输出设置为几乎精确的-1,0或1 ...我怎么能(我应该?)阻止神经网络做到这一点?

编辑:我的网络架构看起来像这样,期待一系列单热编码序列,将其转换为矢量(也往往只有几乎为零或一个值)和解码器应该返回与输入相同的(自动编码器)。编码器和解码器有一些堆叠的LSTM。

enter image description here

输入看起来像这样(一个热编码,120个时间步长,115个矢量长度)。

array([[[1, 0, 0, ..., 0, 0, 0],
        [0, 1, 0, ..., 0, 0, 0],
        [0, 0, 1, ..., 0, 0, 0],
        ..., 
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]]])

我有11.000个例子。

这是我目前的编码:

 inp = Input((120,115))

 out = LSTM(units = 200, return_sequences=True, activation='tanh')(inp)
 out = LSTM(units = 180, return_sequences=True)(out)
 out = LSTM(units = 140, return_sequences=True, activation='tanh')(out)
 out = LSTM(units = 120, return_sequences=False, activation='tanh')(out)
 encoder = Model(inp,out)   

 out_dec = RepeatVector(120)(out) # I also tried to use Reshapeinstead, not really a difference

 out1 = LSTM(200,return_sequences=True, activation='tanh')(out_dec)   
 out1 = LSTM(175,return_sequences=True, activation='tanh')(out1)   
 out1 = LSTM(150,return_sequences=True, activation='tanh')(out1)   
 out1 = LSTM(115,return_sequences=True, activation='sigmoid')(out1) # I also tried softmax instead of sigmoid, not really a difference

 decoder = Model(inp,out1)

autoencoder = Model(encoder.inputs, decoder(encoder.inputs))

autoencoder.compile(loss='binary_crossentropy',
              optimizer='RMSprop',
              metrics=['accuracy'])

autoencoder.fit(padded_sequences[:9000], padded_sequences[:9000],
          batch_size=150,
          epochs=5,
          validation_data=(padded_sequences[9001:], padded_sequences[9001:]))

但经过几个训练时期后,再也没有任何进步了。

开头示例的输出看起来像这样,不是很相同......

array([[[ 0.14739206,  0.49056929,  0.06915747, ...,  0.        ,
          0.        ,  0.        ],
        [ 0.03878205,  0.7227878 ,  0.03550367, ...,  0.        ,
          0.        ,  0.        ],
        [ 0.02073009,  0.74334699,  0.03663541, ...,  0.        ,
          0.        ,  0.        ],
        ..., 
        [ 0.        ,  0.08416401,  0.        , ...,  0.        ,
          0.        ,  0.        ],
        [ 0.        ,  0.08630376,  0.        , ...,  0.        ,
          0.        ,  0.        ],
        [ 0.        ,  0.08602102,  0.        , ...,  0.        ,
          0.        ,  0.        ]]], dtype=float32)

嵌入向量(由encoder.predict生成)看起来像这样(不知何故,因为所有值都接近-1,0或1)。

array([[ -1.00000000e+00,  -0.00000000e+00,  -1.00000000e+00,
          1.00000000e+00,   1.00000000e+00,   9.99999523e-01,
          1.00000000e+00,   9.99999881e-01,   1.00000000e+00,
          9.99989152e-01,   9.99999821e-01,   9.99998808e-01,
          1.00000000e+00,  -0.00000000e+00,  -4.86032724e-01,
          9.99996543e-01,   1.00000000e+00,   0.00000000e+00,
          1.00000000e+00,   0.00000000e+00,   0.00000000e+00,
          1.00000000e+00,  -0.00000000e+00,   0.00000000e+00,
          0.00000000e+00,  -0.00000000e+00,   9.99999464e-01,
         -9.99999881e-01,  -0.00000000e+00,   4.75281268e-01,
          3.01986277e-01,   6.65608108e-01,  -9.99999881e-01,
          0.00000000e+00,  -0.00000000e+00,  -0.00000000e+00,
          0.00000000e+00,  -0.00000000e+00,  -3.65448680e-15,
         -9.99888301e-01,  -0.00000000e+00,  -1.00000000e+00,
         -1.00000000e+00,  -9.90761220e-01,  -9.96851087e-01,
         -0.00000000e+00,   0.00000000e+00,  -1.47916377e-02,
         -9.99999523e-01,  -2.90349454e-01,  -9.99999702e-01,
         -7.63339102e-02,  -1.00000000e+00,  -4.16638345e-01,
         -9.99999940e-01,  -1.00000000e+00,  -9.99996841e-01,
         ..............

我的猜测是与我的二进制输入/输出有关。

2 个答案:

答案 0 :(得分:0)

  1. 二进制输入很好
  2. tanh(0)= 0,但tanh(1)= 0.76。我建议第一层的RELU激活函数获得0或1激活和所有隐藏层。最后一层RELU或sigmoid。不要对输出值进行舍入,而是使用SOFTMAX。
  3. 您提供的信息有限,很难说清楚。

答案 1 :(得分:0)

  1. 我认为您的输入正常,因为它就像一个热插入。据我所知,该结构是seq2seq模型的混合体,但您只需要最终的编码嵌入,您应该代表整个句子。

  2. 对于(0,1)范围,您只需要对具有多分类目标的最后一层使用softmax激活。 crossentropyhinge-loss损失函数是不错的选择。

  3. 您的W是否随机生成?或者你添加一些规定?您可以更改参数分配或其他设置以查看发生的情况。