【问题标题】:Handling Binary Input / Output处理二进制输入/输出
【发布时间】:2017-11-29 04:47:30
【问题描述】:

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

示例

我有一个这样的单热编码向量序列:

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

因此,关于此,出现了一些想法或问题:

  • 将它用作像LSTM 这样的神经网络的输入是否合理?还是我应该无论如何改变它?

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

  • 我意识到并且有点奇怪的是,我当前的网络倾向于将它的所有(内部)输出设置为几乎精确的 -1、0 或 1...我如何(应该?)防止神经网络来做到这一点?

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

输入看起来像这样(单热编码,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:]))

但是经过几个epochs的训练,就没有什么进步了。

开头例子的输出是这样的,不太一样...

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,
         ..............

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

【问题讨论】:

  • 向量有多长?您能向我们展示您的网络架构吗?
  • 在我的实际用例中,我最终会得到长度约为 150 个值的向量。以及长度为 100 的序列。
  • 你想要一个生成模型?
  • @danche:我有兴趣将整个序列表示为一个单一的、有意义的向量。所以这个模型的输入和输出应该是完全一样的(自动编码器)。从编码器传递到解码器的嵌入(向量)是我的兴趣点。

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


【解决方案1】:
  1. 二进制输入没问题
  2. tanh(0) = 0,但 tanh(1) = 0.76。我建议第一层使用 RELU 激活函数来获得 0 或 1 激活和所有隐藏层。最后一层 RELU 或 sigmoid。不要四舍五入输出值,而是使用 SOFTMAX。
  3. 您提供的信息有限,这很难说清楚。

【讨论】:

  • 感谢您的回答。我现在提供了更多信息。在我当前的架构和编码(参见我的编辑)中,使用 ReLu 而不是 tanh 不会导致收敛。 Softmax 代替 sigmoid 几乎没有区别。
【解决方案2】:
  1. 我认为您的输入没问题,因为它就像一次性嵌入。据我所知,该结构是 seq2seq 模型的混合体,但您只需要最终编码的嵌入,它应该代表整个句子。

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

  3. 您的W 是随机生成的吗?或者你添加一些规则?您可以更改参数分布或其他一些设置以查看发生了什么。

【讨论】:

  • 感谢您的回答。我尝试使用softmax 而不是sigmoid,两者之间没有真正的区别。我添加了更多信息(和编码)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2011-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-09
相关资源
最近更新 更多