You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将三维数组序列输入到LSTM模型中?

问题解答:韩语文本形态素拆分后输入LSTM的实现方案

可行性说明

完全可行。韩语作为黏着语,将单词拆分为形态素(如나는拆为['나','는'])的预处理方式,能让模型捕捉更细粒度的语言特征,而LSTM天生适配序列数据,只要将三维数组调整为符合PyTorch LSTM的输入格式即可。

原代码问题与修改方案

基础错误修正

原代码中类定义为Tagger,但super调用时写的是WordTagger,这会导致运行报错,需修正为super(Tagger, self).__init__()。

输入维度适配与代码修改

PyTorch的nn.LSTM支持两种输入格式:

  • 默认格式:(seq_len, batch_size, input_size)
  • 开启batch_first=True时:(batch_size, seq_len, input_size)

针对你的三维输入数组(num_word_groups, num_morphemes_per_group, embedding_dim),提供两种处理思路的代码实现:

思路1:先编码词素组内部序列,再处理词素组序列

适合以单词为单位的任务(如词性标注、文本分类),先对每个词素组内的形态素序列编码,得到单词级表示后再输入上层LSTM:

import torch
import torch.nn as nn
import torch.nn.functional as F

class Tagger(nn.Module):
    def __init__(self,
                 embedding_dim=43,
                 n_layers=4,
                 dropout=0.2,
                 output_dim=11,
                 bidirectional=False):
        super(Tagger, self).__init__()  # 修正类名不一致问题
        # 编码词素组内部的形态素序列
        self.morph_lstm = nn.LSTM(embedding_dim, embedding_dim,
                                  num_layers=1, bidirectional=bidirectional, batch_first=True)
        # 编码词素组构成的单词序列
        self.word_lstm = nn.LSTM(
            embedding_dim * 2 if bidirectional else embedding_dim,
            embedding_dim * 2 if bidirectional else embedding_dim,
            num_layers=n_layers-1, bidirectional=bidirectional, batch_first=True
        )
        self.hidden_dim = (embedding_dim * 2) if bidirectional else embedding_dim
        self.linear = nn.Linear(self.hidden_dim, output_dim)
        self.dropout = nn.Dropout(dropout)

    def forward(self, embedded):
        # embedded输入维度: (batch_size, 词素组数量, 每组词素数, embedding_dim)
        batch_size, num_groups, num_morphemes, emb_dim = embedded.shape
        # 重塑为批量处理每个词素组的格式
        morph_embedded = embedded.view(-1, num_morphemes, emb_dim)
        # 获取词素组的最后一个时间步输出作为单词表示
        morph_out, _ = self.morph_lstm(morph_embedded)
        group_rep = morph_out[:, -1, :]
        # 重塑回词素组序列格式
        group_rep = group_rep.view(batch_size, num_groups, -1)
        # 处理词素组序列并输出结果
        lstmed, _ = self.word_lstm(self.dropout(group_rep))
        outputs = self.linear(self.dropout(lstmed))
        scores = F.log_softmax(outputs, dim=-1)
        return scores

思路2:将所有词素展开为一维序列输入

适合以形态素为单位的任务(如形态素标注),直接将所有词素按顺序展开为长序列输入LSTM:

import torch
import torch.nn as nn
import torch.nn.functional as F

class Tagger(nn.Module):
    def __init__(self,
                 embedding_dim=43,
                 n_layers=4,
                 dropout=0.2,
                 output_dim=11,
                 bidirectional=False):
        super(Tagger, self).__init__()  # 修正类名错误
        self.lstm = nn.LSTM(embedding_dim, embedding_dim,
                            num_layers=n_layers, bidirectional=bidirectional, batch_first=True)
        self.hidden_dim = (embedding_dim * 2) if bidirectional else embedding_dim
        self.linear = nn.Linear(self.hidden_dim, output_dim)
        self.dropout = nn.Dropout(dropout)

    def forward(self, embedded):
        # embedded输入维度: (batch_size, 词素组数量, 每组词素数, embedding_dim)
        batch_size, num_groups, num_morphemes, emb_dim = embedded.shape
        # 展开为一维形态素序列
        flat_embedded = embedded.view(batch_size, -1, emb_dim)
        # 处理序列并输出结果
        lstmed, _ = self.lstm(self.dropout(flat_embedded))
        outputs = self.linear(self.dropout(lstmed))
        scores = F.log_softmax(outputs, dim=-1)
        return scores

补充说明

  • 若为单样本输入(无batch维度),需先用embedded.unsqueeze(0)添加batch维度,将(词素组数量, 每组词素数, embedding_dim)转换为(1, 词素组数量, 每组词素数, embedding_dim)。
  • 针对变长词素组(如有的组2个词素、有的组4个词素),建议使用torch.nn.utils.rnn.pack_padded_sequence处理,避免padding引入噪声。

内容的提问来源于stack exchange,提问作者HanGoil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 02:07:09