BERT+textcnn代码及报错解决

报错时检查维度

过程中报过2个主要错误

第一个expected input [1,32,768] to have 1 channel, but got 32 channels instead.

第二个calculated padded input size per channel: (1*768)...kernel size can't be greater than actaual input size.

但是实际上是textcnn输入维度的错误

这里模型的第4行,输出是有两个,两个的维度不同。对于textCNN来说,输入的维度是3维,如前者。对于LSTM来说,输入是后者

# encoder_out:[batch_size,seq_len,hidden_size],text_cls:[batch_size,hidden_size]

def forward(self, x): # x:{[batch_size,seq_len],[batch_size,],[batch_size,seq_len]}
        context = x[0] # context:[batch_size,seq_len],输入的句子
        mask = x[2] # mask:[bacth_size,seq_len],对padding部分进行mask
        encoder_out, text_cls = self.bert(context, attention_mask=mask, output_all_encoded_layers=False) # encoder_out:[batch_size,seq_len,hidden_size],text_cls:[batch_size,hidden_size]
        out = encoder_out.unsqueeze(1) # out:[batch_size,1,seq_len,hidden_size]
        out = torch.cat([self.conv_and_pool(out, conv) for conv in self.convs], 1) # out:[batch_size,num_filters * len(filter_sizes)]
        out = self.dropout(out)
        out = self.fc_cnn(out) # out:[batch_size,num_class]
        return out

这部分代码

作者:影子
链接:https://www.zhihu.com/question/477075127/answer/2731541347
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

可运行代码

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


class TextCNNBert(nn.Module):
    def __init__(self, vocab_size, embedding_size, num_classes):
        super(TextCNNBert, self).__init__()
        self.filter_sizes = [2, 3, 4]
        num_filter = 2
        self.num_filters_total = num_filter * len(self.filter_sizes)

        # 卷积核打包
        self.filter_list = nn.ModuleList(
            [nn.Conv2d(1, num_filter, (size, 768)) for size in self.filter_sizes])
        self.dropout = nn.Dropout(0.5)
        self.fc = nn.Linear(num_filter * len(self.filter_sizes), num_classes)  #

    def forward(self, x):
        x = x.float()
        x = x.unsqueeze(1)  # ( 输入,输出 )

        pooled_outputs = []
        # 卷积运算
        for i, conv in enumerate(self.filter_list):
            conv_feature = F.relu(conv(x))  # 得到卷积后的特征
            # 定义池化层
            maxp = nn.MaxPool2d((x.shape[2] - self.filter_sizes[i] + 1, 1))  # 其中x.shape[1]代表句子的长度,
            # self.filter_sizes[i]代表卷积核的宽度,1代表词语嵌入的维度
            pooled = maxp(conv_feature).permute(0, 3, 2, 1)  # 在进行最大池化之后,得到的张量是四维的,
            # 包括了样本数、通道数、池化后的高度和宽度。而在这里,作者想要将高度和宽度的维度交换,
            # 即从(样本数、通道数、高度、宽度)变为(样本数、宽度、高度、通道数)的形式。
            # 这是为了后续的拼接操作,将不同窗口大小的池化结果按通道方向拼接,方便进行全连接层的处理。
            pooled_outputs.append(pooled)
        # 池化层的拼接
        feature = torch.cat(pooled_outputs, len(self.filter_sizes))  # 在第3个维度上拼接起来,即在不同卷积核尺寸的特征图之间进行拼接。
        # 改变尺寸
        feature = torch.reshape(feature, [-1, self.num_filters_total])
        # dropout
        feature = self.dropout(feature)
        outs = self.fc(feature)

        return outs

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
基于深度学习的文本分类系统常用的包括BERT、RNN、TextCNN、FastCNN等模型。下面将为您提供完整代码和数据。 首先,我们需要导入相关的库:tensorflow、keras、numpy等。 ```python import tensorflow as tf from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences from tensorflow.keras.layers import Dense, Embedding, LSTM, Conv1D, GlobalMaxPooling1D, Concatenate from tensorflow.keras.models import Sequential import numpy as np ``` 接下来,我们准备训练数据和测试数据。假设已经准备好了train_texts和train_labels作为训练集的文本和标签,test_texts和test_labels作为测试集的文本和标签。 ```python train_texts = [...] # 训练集文本 train_labels = [...] # 训练集标签 test_texts = [...] # 测试集文本 test_labels = [...] # 测试集标签 ``` 然后,我们需要对文本进行预处理,将其转换为数值表示。这里我们使用Tokenizer将文本转换为单词索引序列。 ```python tokenizer = Tokenizer() tokenizer.fit_on_texts(train_texts) train_sequences = tokenizer.texts_to_sequences(train_texts) test_sequences = tokenizer.texts_to_sequences(test_texts) vocab_size = len(tokenizer.word_index) + 1 # 词汇表大小 ``` 接着,我们需要将序列填充为相同的长度,这里我们采用max_len作为填充长度。 ```python max_len = 100 # 填充长度 train_data = pad_sequences(train_sequences, maxlen=max_len) test_data = pad_sequences(test_sequences, maxlen=max_len) ``` 现在,我们可以构建基于RNN的文本分类模型了。 ```python model = Sequential() model.add(Embedding(vocab_size, 100, input_length=max_len)) model.add(LSTM(128)) model.add(Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(train_data, train_labels, validation_data=(test_data, test_labels), epochs=10, batch_size=64) ``` 如果您想使用TextCNN或FastCNN模型进行文本分类,可以参考以下代码: ```python filters = 100 kernel_size = 3 model = Sequential() model.add(Embedding(vocab_size, 100, input_length=max_len)) model.add(Conv1D(filters, kernel_size, activation='relu', padding='valid')) model.add(GlobalMaxPooling1D()) model.add(Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(train_data, train_labels, validation_data=(test_data, test_labels), epochs=10, batch_size=64) ``` 最后,对于BERT模型,您可以使用Hugging Face提供的transformers库。您可以根据自己的需求选择相应的BERT模型,例如bert-base-uncased、bert-large-uncased等。 ```python from transformers import BertTokenizer, TFBertModel tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') train_encodings = tokenizer(train_texts, truncation=True, padding=True) test_encodings = tokenizer(test_texts, truncation=True, padding=True) train_dataset = tf.data.Dataset.from_tensor_slices(( dict(train_encodings), train_labels )) test_dataset = tf.data.Dataset.from_tensor_slices(( dict(test_encodings), test_labels )) model = TFBertModel.from_pretrained('bert-base-uncased') input_ids = tf.keras.layers.Input(shape=(None,), dtype=tf.int32) attention_mask = tf.keras.layers.Input(shape=(None,), dtype=tf.int32) outputs = model(input_ids, attention_mask=attention_mask) output = outputs[0][:, 0, :] output = Dense(1, activation='sigmoid')(output) model = tf.keras.models.Model(inputs=[input_ids, attention_mask], outputs=output) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) model.fit(train_dataset.shuffle(1000).batch(16), epochs=10, batch_size=16) ``` 以上是基于深度学习的文本分类系统的完整代码和数据示例,您可以根据需要进行修改和调整。注意,BERT模型的训练可能需要较长的时间和更大的计算资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值