Keras:在培训示例中共享一层权重(不在各层之间)

时间:2019-06-25 21:45:14

标签: python tensorflow keras lstm-stateful

问题如下。我有一个词汇量为25K的分类预测任务。在其中之一(输入vocab 10K,输出暗淡即嵌入50)上,我想引入一个可训练的权重矩阵,用于输入嵌入(形状1,50)和权重(形状(50,128))(无偏差)之间的矩阵乘法),得出的矢量分数将与其他功能一起用于预测任务。

关键是,如果我简单地将其添加进去,我认为可训练的权重矩阵会因每个输入而异。我希望该权重矩阵在所有输入中都相同。

我应该澄清-这里的输入是指培训示例。因此,所有示例都将学习一些示例特定的嵌入,并乘以共享的权重矩阵。

每隔一个纪元后,我打算进行一次批处理更新以学习这些通用权重(或使用其他目标变量进行多个输出预测)

LSTM?那是我应该研究的东西吗?

2 个答案:

答案 0 :(得分:1)

除“嵌入”层外,层均适用于批次中的所有示例。

以一个非常简单的网络为例:

inp = Input(shape=(4,))
h1 = Dense(2, activation='relu', use_bias=False)(inp)
out = Dense(1)(h1)
model = Model(inp, out)

这是一个简单的网络,具有1个输入层,1个隐藏层和一个输出层。如果我们以隐藏层为例;该层具有形状为(4,2,)的权重矩阵。在每次迭代中,将形状为矩阵(batch_size,4)的输入数据乘以隐藏层权重(前馈阶段)。因此,h1激活取决于所有样本。损失也是基于每个batch_size计算的。输出层的形状为(batch_size,1)。鉴于在前进阶段,所有批次样品都会影响权重值,因此背景和渐变更新也是如此。

在处理文本时,通常将问题指定为根据单词序列预测特定标签。这被建模为(batch_size,sequence_length,word_index)的形状。让我们举一个非常基本的例子:

from tensorflow import keras
from tensorflow.keras.layers import *
from tensorflow.keras.models import Model

sequence_length = 80
emb_vec_size = 100
vocab_size = 10_000


def make_model():
  inp = Input(shape=(sequence_length, 1))
  emb = Embedding(vocab_size, emb_vec_size)(inp)
  emb = Reshape((sequence_length, emb_vec_size))(emb)
  h1 = Dense(64)(emb)
  recurrent = LSTM(32)(h1)
  output = Dense(1)(recurrent)
  model = Model(inp, output)
  model.compile('adam', 'mse')
  return model

model = make_model()
model.summary()

您可以将其复制并粘贴到colab中,然后查看摘要。

此示例正在执行的操作是:

  1. 将单词索引序列转换为单词嵌入向量序列。
  2. 将名为h1的密集层应用于所有批次(以及序列中的所有元素);该层减小了嵌入向量的尺寸。 (隔离)处理文本不是网络的典型元素。但这似乎符合您的问题。
  3. 每个示例使用循环层将序列简化为单个向量。
  4. 从“句子”向量预测单个标签。

答案 1 :(得分:1)

如果我正确解决了问题,则可以在另一个模型中重用图层甚至模型。

带有密集层的示例。假设您有10个输入

moment

如果输入具有不同的形状,则此代码将不起作用。首次调用D定义其属性。在此示例中,输出直接设置为网络。但是,您当然可以串联,堆叠或任何您想要的东西。

现在,如果您有一些可训练的模型,则可以使用它代替D:

import tensorflow as tf
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
# defining 10 inputs in a List with (X,) shape
inputs = [Input(shape = (X,),name='input_{}'.format(k)) for k in 
range(10)]
# defining a common Dense layer
D = Dense(64, name='one_layer_to_rule_them_all')
nets = [D(inp) for inp in inputs]
model = Model(inputs = inputs, outputs = nets)
model.compile(optimizer='adam', loss='categorical_crossentropy')

该模型的权重在所有输入中共享。