python - 张量流 keras 中的采样 softmax
问题描述
我想在 tf keras 中进行采样 softmax 损失。我通过继承 keras 模型来定义我自己的模型。在 init 中,我指定了我需要的层,包括最后一个 Dense 投影层。但是这个 Dense 层不应该在训练中被调用,因为我想做采样 softmax 并且只使用它的权重和偏差。然后我像这样定义损失函数:
class SampledSoftmax:
def init( self,
num_sampled,
num_classes,
projection,
bias,
hidden_size):
self.weights = tf.transpose(projection)
self.bias = bias
self.num_classes = num_classes
self.num_sampled = num_sampled
self.hidden_size = hidden_size
def call(self, y_true, input):
""" reshaping of y_true and input to make them fit each other """
input = tf.reshape(input, (-1,self.hidden_size))
y_true = tf.reshape(y_true, (-1,1))
return tf.nn.sampled_softmax_loss(
weights=self.weights,
biases=self.bias,
labels=y_true,
inputs=input,
num_sampled=self.num_sampled,
num_classes=self.num_classes,
partition_strategy='div')
它接受必要的参数进行初始化,类调用将是所需的采样 softmax 损失函数。问题是要增加模型编译的损失,我需要最后一个 Dense 的权重等。但是 1)在训练中 Dense 不包含在模型中,并且 2)即使它包含,Dense 层也只会与输入连接,从而在调用我的自定义模型时获取其输入尺寸等。简而言之,在编译模型之前,权重等将不可用。任何人都可以提供一些帮助来指出我正确的方向吗?
现在是导致它失败的代码。我首先将模型子类化如下:
class LanguageModel(tf.keras.Model):
def __init__(self,
vocal_size=15003,
embedding_size=512
input_len=64)
self.embedding = Embedding(vocal_size, embedding_size,
input_length=input_len)
self.lstm = LSTM(hidden_size, return_sequences=True)
self.dense = Dense(vocal_size, activation='softmax')
def call(self, inputs, training=False):
emb_out = self.embedding(inputs)
lstm_out = self.lstm(embrace_out)
res = self.dense(lstm_out)
if (training)
''' shouldn't use the last dense as we want to do sampling'''
return lstm_out
return res
然后是训练模型的部分如下
sampled_loss = SampledSoftmax(num_sampled, vocal_size,
model.dense.kernel, model.dense.bias,
hidden_size)
model.compile(optimizer=tf.train.RMSPropOptimizer(lr),
loss=sampled_loss)
它会失败,但是我玩弄它,因为 model.dense.kernel 不可访问,因为在编译模型时,密集层尚未在调用方法中初始化。错误信息如下:
Traceback (most recent call last):
File "/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/home/wuxinyu/workspace/nlu/lm/main.py", line 72, in <module>
train_main()
File "/home/wuxinyu/workspace/nlu/lm/main.py", line 64, in train_main
train_model.build_lm_model()
File "/home/wuxinyu/workspace/nlu/lm/main.py", line 26, in build_lm_model
self.model.dense.kernel,
AttributeError: 'Dense' object has no attribute 'kernel'
顺便说一句,上面定义的损失将适用于如下的小型测试用例。
x = Input(shape=(10,), name='input_x')
emb_out = Embedding(10000,200,input_length=10)(x)
lstm_out = LSTM(200, return_sequences=True)(emb_out)
dense = Dense(10000, activation='sigmoid')
output = dense(lstm_out)
sl = SampledSoftmax(10, 10000, dense.kernel, dense.bias)
model = Model(inputs=x, outputs=lstm_out)
model.compile(optimizer='adam', loss=sl)
model.summary()
model.fit(dataset, epochs=20, steps_per_epoch=5)
解决方案
推荐阅读
- python - 您如何将用户的输入与提供的字典中的值进行比较?
- flutter - 使用 GetX 状态管理颤振导航到上一个屏幕,其中包含来自 api 的更新数据
- sql - 如何在 Oracle SQL 中转换季度
- angular - 如何在角度 7 的 concatMap/switchMap 中使用检查条件
- c# - 在 Visual Studio Code 中调试时对象的条件表达式
- python - 如何从python中的行元素中获取最大值?
- r - 如何在 R 项目中使用 fviz_cluster 更改符号和颜色
- angular - 我们如何使用角垫表按姓氏排序或按字母顺序排列?
- c++ - 在迷宫中的 2 点之间找到一条最小转弯的路径
- nginx - Nginx 保留代理导航回主机