我正在使用nn.TransformerEncoder()
执行序列分类任务,它的流水线与nn.LSTM()
类似。
我已经尝试了几种时态特征融合方法:
1.选择最终输出作为整个序列的表示。
1.使用仿射变换来融合这些特征。
1.逐帧对序列进行分类,然后选取最大值作为整个序列的类别。
但是,这三种方法的准确率都很低,对4类分类的准确率只有25%,而使用带最后一个隐态的nn.LSTM,可以很容易地达到**83%**的准确率,我尝试了大量的nn.TransformerEncoder()
的超参数,但准确率没有任何提高。
我现在不知道如何调整这个模型。你能给予我一些实际的建议吗?谢谢。
对于LSTM
:forward()
是:
def forward(self, x_in, x_lengths, apply_softmax=False):
# Embed
x_in = self.embeddings(x_in)
# Feed into RNN
out, h_n = self.LSTM(x_in) #shape of out: T*N*D
# Gather the last relevant hidden state
out = out[-1,:,:] # N*D
# FC layers
z = self.dropout(out)
z = self.fc1(z)
z = self.dropout(z)
y_pred = self.fc2(z)
if apply_softmax:
y_pred = F.softmax(y_pred, dim=1)
return y_pred
对于transformer
:
def forward(self, x_in, x_lengths, apply_softmax=False):
# Embed
x_in = self.embeddings(x_in)
# Feed into RNN
out = self.transformer(x_in)#shape of out T*N*D
# Gather the last relevant hidden state
out = out[-1,:,:] # N*D
# FC layers
z = self.dropout(out)
z = self.fc1(z)
z = self.dropout(z)
y_pred = self.fc2(z)
if apply_softmax:
y_pred = F.softmax(y_pred, dim=1)
return y_pred
2条答案
按热度按时间nnt7mjpx1#
你提到的准确性表明有些地方不对。既然你在比较LSTM和TransformerEncoder,我想指出一些关键的区别。
1.位置嵌入:这一点非常重要,因为Transformer没有递归概念,所以它不会捕获序列信息。因此,请确保在输入嵌入沿着添加位置信息。
1.模型架构:
d_model
,n_head
,num_encoder_layers
是很重要的。使用Vaswani等人2017年使用的默认大小。(d_model=512
,n_head=8
,num_encoder_layers=6
)1.优化:在许多场景中,已经发现Transformer需要以较小的学习速率、较大的批量大小、WarmUpScheduling来训练。
最后但并非最不重要的一点是,对于健全性检查,只需确保模型的参数正在更新。您还可以检查训练准确性,以确保准确性随着训练的进行而不断增加。
虽然很难说你的代码中到底有什么错误,但我希望以上几点会有所帮助!
c0vxltue2#
我不确定
Selecting the final outputs as the representation of the whole sequence.
是否适用于变压器,因为这些模型的工作方式与递归网络不同,最后一个时间点并不代表序列的完整嵌入,所以只使用最后一个时间点,我认为您丢弃了很多信息。