当前位置:   article > 正文

自然语言处理入门——新闻主题分类任务_ag_news新闻分类

ag_news新闻分类

自然语言处理入门

新闻主题分类任务

  • 以一段新闻中的文本描述内容作为输入,使用模型判断最有可能属于哪一种类型新闻。假定每种类型是互斥的,即文本描述有且只有一种类别。
# 通过torchtext获取数据
import torch
import torchtext
# 导入torchtext.datasets中的文本分类任务
import torchtext.datasets
import os

path = './data'
if not os.path.isdir(path):
     os.mkdir(path)
     
     
# 将文本分类数据集'AG_NEWS'保存在指定目录
train_dataset, test_dataset = torchtext.datasets.DATASETS['AG_NEWS'](root=path)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • train.csv表示训练数据,共12万条数据,共由三列组成:标签、新闻标题、新闻简述,标签用1、2、3、4表示,依次对应classes中的['World', 'Sports', 'Business', 'Sci/Tech']

  • 整个案例的实现可以分为五个步骤

    1. 构建带有Embedding层的文本分类模型:
    2. 对数据进行batch处理
    3. 构建训练与验证函数
    4. 进行模型训练和验证
    5. 查看Embedding层嵌入的词向量

构建带有Embedding层的文本分类模型

# 导入必备的torch模型构建工具
import torch.nn as nn # nn指的是neutral network
import torch.nn.functional as F

# 指定批次训练BATCH_SIZE大小
BATCH_SIZE = 16

# 进行可用设备检测
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

class TextSentiment(nn.Module):
    '''文本分类模型'''
    def __init__(self, vocab_size, embed_dim, num_class):
        '''
        Description : 类的初始化函数
        
        Parameters
        ----------
        vocab_size : 
            整个语料包含的不同词汇整数.
        embed_dim : 
            指定词嵌入的维度.
        num_class : 
            文本分类的类别总数.

        Returns
        -------
        None.
        '''
        super().__init__()
        # 实例化embedding层、sparse=True代表每次对该层求解梯度时,只更新部分权重
        self.embedding = nn.Embedding(vocab_size, embed_dim, sparse=True)
        # 实例化线性层,参数分别是embed_dim和num_class
        self.fc = nn.Linear(embed_dim, num_class)
        # 为各层初始化权重
        self.init_weights()

    def init_weights(self):
        '''
        Description : 初始化权重函数

        Returns
        -------
        None.

        '''
        # 指定初始权重的取值范围
        initrange = 0.5
        # 各层的权重参数都是初始化为均匀分布
        self.embedding.weight.data.uniform_(-initrange, initrange)
        self.fc.weight.data.uniform_(-initrange, initrange)
        # 偏置初始化为0
        self.fc.bias.data.zero_()
        
    def forward(self, text):
        '''
        Description : nn主要逻辑函数

        Parameters
        ----------
        text : 
            文本数值映射后的结果.

        Returns
        -------
        与类别数尺寸相同的张量,用以判断文本类别.

        '''
        # 执行词嵌入
        embedded = self.embedding(text)
        # 将(m,32)转化成(BATCH_SIZE, 32)
        c = embedded.size(0) // BATCH_SIZE
        # 使新的embedded中的向量个数可以整除BATCH_SIZE
        embedded = embedded[:BATCH_SIZE*c]
        # 利用平均池化的方法求embedded中指定行数的列的平均数
        embedded = embedded.transpose(1, 0).unsqueeze(0)
        # 调用平均池化的方法,并且核的大小为c
        embedded = F.avg_pool1d(embedded, kernel_size=c)
        # 减去新增的维度,转置回去输送给fc层
        return self.fc(embedded[0].transpose(1,0))
                     


# 获取整个语料中词汇总数
VOCAB_SIZE = len(train_dataset.get_vocab())

# 指定词嵌入维度
EMBED_DIM = 32

# 获取整个文本分类总数
NUM_CLASS = len(train_dataset.get_labels())

# 实例化模型对象
model = TextSentiment(VOCAB_SIZE, EMBED_DIM, NUM_CLASS).to(device)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

对数据进行batch处理

def generate_batch(batch):
    '''
    Description : 生成batch数据函数

    Parameters
    ----------
    batch : TYPE
        由样本张量和对应标签的元组组成的batch_size大小的列表.

    Returns
    -------
    样本张量和标签各自的列表形式(张量).

    '''
    # 从batch中获取标签张量
    label = torch.tensor([entry[1] for entry in batch])
    # 从batch中获得样本张量
    text = [entry[0] for entry in batch]
    text = torch.cat(text)
    # 返回结果
    return text, label
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

构建模型训练和验证函数

# 导入torch中数据加载器方法
from torch.utils.data import DataLoader

def train(train_data):
    '''
    Description : 模型训练函数

    Parameters
    ----------
    train_data : TYPE
        要训练的数据集.

    Returns
    -------
    本轮训练的平均损失率和平均准确率.

    '''
    # 初始化训练损失率和准确率为0
    train_loss = 0
    train_acc = 0
    
    # 使用数据加载器生成BATCH_SIZE大小的数据进行批次训练
    # data是N个generate_batch函数处理后的BATCH_SIZE大小的数据生成器
    data = DataLoader(train_data, batch_size=BATCH_SIZE, shuffle=True,
                      collate_fn=generate_batch)
    
    # 对data进行循环遍历,使用每个batch的数据进行参数更新
    for i, (text, cls) in enumerate(data):
        # 设置优化器初始梯度0
        optimizer.zero_grad()
        # 模型输入一个批次数据,获得输出
        output = model(text)
        # 根据真实标签与模型输出计算损失
        loss = criterion(output, cls)
        # 将该批次损失加到总损失中
        train_loss += loss.item()
        # 误差反向传播
        loss.backward()
        # 参数更新
        optimizer.step()
        # 将该批次准确率加入总准确率中
        train_acc += (output.argmax(1) == cls).sum().item()

    # 调整优化器学习率
    scheduler.step()
    # 返回本轮训练平均损失和平均准确率
    return train_loss / len(train_data) , train_acc / len(train_data)


def valid(valid_data):
    '''
    Description : 模型验证函数

    Parameters
    ----------
    valid_data : 
        训练集.

    Returns
    -------
    返回本轮训练平均损失和平均准确率.

    '''
    # 初始化训练损失率和准确率为0
    loss = 0
    acc = 0
    
    # 和训练相同,使用DataLoader获得训练数据生成器
    data = DataLoader(valid_data, batch_size=BATCH_SIZE, collate_fn=generate_batch)
    # 按批次取出验证
    for text, cls in data:
        # 不再求解梯度
        with torch.no_grad():
            # 使用模型获得输出
            output = model(text)
            # 计算损失
            loss = criterion(output, cls)
            # 将损失和准确率加总
            loss += loss.item()
            acc += (output.argmax(1) == cls).sum().item()
            
    # 返回本轮验证的平均损失和平均准确率
    return loss / len(valid_data), acc / len(valid_data)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83

进行模型训练和验证

# 导入时间工具包
import time
# 导入数据随机划分工具
from torch.utils.data.dataset import random_split

# 指定训练轮数
N_EPOCHS = 10

# 定义初始的验证损失
min_valid_loss = float('inf')

# 选择损失函数,这里选择预定义的交叉熵损失函数
criterion = torch.nn.CrossEntropyLoss().to(device)
# 选择随机梯度下降优化器
optimizer = torch.optim.SGD(model.parameters(), lr=4.0)
# 选择优化器步长调节方法StepLR,用来衰减学习率
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1, gamma=0.9)

# 从train_dataset取出0.95作为训练集,先取其长度
train_len = int(len(train_dataset) * 0.95)

# 然后使用random_split进行乱序划分,得到对应的训练集和验证集
sub_train_, sub_valid_ = \
    random_split(train_dataset, [train_len, len(train_dataset) - train_len])
    
# 开始每一轮训练
for epoch in range(N_EPOCHS):
    # 记录概论训练的开始时间
    start_time = time.time()
    # 调用train和valid函数得到训练和验证的平均损失,平均准确率
    train_loss, train_acc = train(sub_train_)
    valid_loss, valid_acc = valid(sub_valid_)
    
    # 计算训练和验证总耗时
    secs = int(time.time()) - start_time
    # 换算成分秒
    mins = secs/60
    secs = secs%60
    # 打印训练和验证耗时,平均损失、平均损失率
    print('Epoch: %d' % (epoch + 1), ' | time in %d minutes, %d seconds' %(mins, secs))
    print(f'\tLoss: {train_loss:.4f}(train)\t|\5Acc: {train_acc * 100:.1f}%(train)')
    print(f'\tLoss: {valid_loss:.4f}(valid)\t|\5Acc: {valid_acc * 100:.1f}%(valid)')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

整体代码和运行结果

# 导入相关的torch工具包
import torch
# 导入torchtext.datasets中的文本分类任务
from torchtext.datasets import text_classification
import os

# 定义数据下载路径, 当前路径的data文件夹
load_data_path = "./data"
# 如果不存在该路径, 则创建这个路径
if not os.path.isdir(load_data_path):
    os.mkdir(load_data_path)

# 选取torchtext中的文本分类数据集'AG_NEWS'即新闻主题分类数据, 保存在指定目录下
# 并将数值映射后的训练和验证数据加载到内存中
train_dataset, test_dataset = text_classification.DATASETS['AG_NEWS'](root=load_data_path, vocab=None)
 
# 导入必备的torch模型构建工具
import torch.nn as nn # nn指的是neutral network
import torch.nn.functional as F

# 指定批次训练BATCH_SIZE大小
BATCH_SIZE = 16

# 进行可用设备检测
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

class TextSentiment(nn.Module):
    '''文本分类模型'''
    def __init__(self, vocab_size, embed_dim, num_class):
        '''
        Description : 类的初始化函数
        
        Parameters
        ----------
        vocab_size : 
            整个语料包含的不同词汇整数.
        embed_dim : 
            指定词嵌入的维度.
        num_class : 
            文本分类的类别总数.

        Returns
        -------
        None.
        '''
        super().__init__()
        # 实例化embedding层、sparse=True代表每次对该层求解梯度时,只更新部分权重
        self.embedding = nn.Embedding(vocab_size, embed_dim, sparse=True)
        # 实例化线性层,参数分别是embed_dim和num_class
        self.fc = nn.Linear(embed_dim, num_class)
        # 为各层初始化权重
        self.init_weights()

    def init_weights(self):
        '''
        Description : 初始化权重函数

        Returns
        -------
        None.

        '''
        # 指定初始权重的取值范围
        initrange = 0.5
        # 各层的权重参数都是初始化为均匀分布
        self.embedding.weight.data.uniform_(-initrange, initrange)
        self.fc.weight.data.uniform_(-initrange, initrange)
        # 偏置初始化为0
        self.fc.bias.data.zero_()
        
    def forward(self, text):
        '''
        Description : nn主要逻辑函数

        Parameters
        ----------
        text : 
            文本数值映射后的结果.

        Returns
        -------
        与类别数尺寸相同的张量,用以判断文本类别.

        '''
        # 执行词嵌入
        embedded = self.embedding(text)
        # 将(m,32)转化成(BATCH_SIZE, 32)
        c = embedded.size(0) // BATCH_SIZE
        # 使新的embedded中的向量个数可以整除BATCH_SIZE
        embedded = embedded[:BATCH_SIZE*c]
        # 利用平均池化的方法求embedded中指定行数的列的平均数
        embedded = embedded.transpose(1, 0).unsqueeze(0)
        # 调用平均池化的方法,并且核的大小为c
        embedded = F.avg_pool1d(embedded, kernel_size=c)
        # 减去新增的维度,转置回去输送给fc层
        return self.fc(embedded[0].transpose(1,0))
                     


# 获取整个语料中词汇总数
VOCAB_SIZE = len(train_dataset.get_vocab())

# 指定词嵌入维度
EMBED_DIM = 32

# 获取整个文本分类总数
NUM_CLASS = len(train_dataset.get_labels())

# 实例化模型对象
model = TextSentiment(VOCAB_SIZE, EMBED_DIM, NUM_CLASS).to(device)


# 对数据进行batch处理
def generate_batch(batch):
    '''
    Description : 生成batch数据函数

    Parameters
    ----------
    batch : TYPE
        由样本张量和对应标签的元组组成的batch_size大小的列表.

    Returns
    -------
    样本张量和标签各自的列表形式(张量).

    '''
    # 从batch中获取标签张量
    label = torch.tensor([entry[0] for entry in batch])
    # 从batch中获得样本张量
    text = [entry[1] for entry in batch]
    text = torch.cat(text)
    # 返回结果
    return text, label




# 导入torch中数据加载器方法
from torch.utils.data import DataLoader

def train(train_data):
    '''
    Description : 模型训练函数

    Parameters
    ----------
    train_data : TYPE
        要训练的数据集.

    Returns
    -------
    本轮训练的平均损失率和平均准确率.

    '''
    # 初始化训练损失率和准确率为0
    train_loss = 0
    train_acc = 0
    
    # 使用数据加载器生成BATCH_SIZE大小的数据进行批次训练
    # data是N个generate_batch函数处理后的BATCH_SIZE大小的数据生成器
    data = DataLoader(train_data, batch_size=BATCH_SIZE, shuffle=True,
                      collate_fn=generate_batch)
    
    # 对data进行循环遍历,使用每个batch的数据进行参数更新
    for i, (text, cls) in enumerate(data):
        # 设置优化器初始梯度0
        optimizer.zero_grad()
        # 模型输入一个批次数据,获得输出
        output = model(text)
        # 根据真实标签与模型输出计算损失
        loss = criterion(output, cls)
        # 将该批次损失加到总损失中
        train_loss += loss.item()
        # 误差反向传播
        loss.backward()
        # 参数更新
        optimizer.step()
        # 将该批次准确率加入总准确率中
        train_acc += (output.argmax(1) == cls).sum().item()

    # 调整优化器学习率
    scheduler.step()
    # 返回本轮训练平均损失和平均准确率
    return train_loss / len(train_data) , train_acc / len(train_data)


def valid(valid_data):
    '''
    Description : 模型验证函数

    Parameters
    ----------
    valid_data : 
        训练集.

    Returns
    -------
    返回本轮训练平均损失和平均准确率.

    '''
    # 初始化训练损失率和准确率为0
    loss = 0
    acc = 0
    
    # 和训练相同,使用DataLoader获得训练数据生成器
    data = DataLoader(valid_data, batch_size=BATCH_SIZE, collate_fn=generate_batch)
    # 按批次取出验证
    for text, cls in data:
        # 不再求解梯度
        with torch.no_grad():
            # 使用模型获得输出
            output = model(text)
            # 计算损失
            loss = criterion(output, cls)
            # 将损失和准确率加总
            loss += loss.item()
            acc += (output.argmax(1) == cls).sum().item()
            
    # 返回本轮验证的平均损失和平均准确率
    return loss / len(valid_data), acc / len(valid_data)



# 导入时间工具包
import time
# 导入数据随机划分工具
from torch.utils.data.dataset import random_split

# 指定训练轮数
N_EPOCHS = 10

# 定义初始的验证损失
min_valid_loss = float('inf')

# 选择损失函数,这里选择预定义的交叉熵损失函数
criterion = torch.nn.CrossEntropyLoss().to(device)
# 选择随机梯度下降优化器
optimizer = torch.optim.SGD(model.parameters(), lr=4.0)
# 选择优化器步长调节方法StepLR,用来衰减学习率
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1, gamma=0.9)

# 从train_dataset取出0.95作为训练集,先取其长度
train_len = int(len(train_dataset) * 0.95)

# 然后使用random_split进行乱序划分,得到对应的训练集和验证集
sub_train_, sub_valid_ = \
    random_split(train_dataset, [train_len, len(train_dataset) - train_len])
    
# 开始每一轮训练
for epoch in range(N_EPOCHS):
    # 记录概论训练的开始时间
    start_time = time.time()
    # 调用train和valid函数得到训练和验证的平均损失,平均准确率
    train_loss, train_acc = train(sub_train_)
    valid_loss, valid_acc = valid(sub_valid_)
    
    # 计算训练和验证总耗时
    secs = int(time.time()) - start_time
    # 换算成分秒
    mins = secs/60
    secs = secs%60
    # 打印训练和验证耗时,平均损失、平均损失率
    print('Epoch: %d' % (epoch + 1), ' | time in %d minutes, %d seconds' %(mins, secs))
    print(f'\tLoss: {train_loss:.4f}(train)\t|\5Acc: {train_acc * 100:.1f}%(train)')
    print(f'\tLoss: {valid_loss:.4f}(valid)\t|\5Acc: {valid_acc * 100:.1f}%(valid)')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 运行结果如下:
120000lines [00:13, 9115.61lines/s] 
120000lines [00:20, 5871.92lines/s]
7600lines [00:01, 5522.88lines/s]
Epoch: 1  | time in 0 minutes, 43 seconds
	Loss: 0.0591(train)	|Acc: 64.1%(train)
	Loss: 0.0004(valid)	|Acc: 69.6%(valid)
Epoch: 2  | time in 0 minutes, 43 seconds
	Loss: 0.0510(train)	|Acc: 71.2%(train)
	Loss: 0.0003(valid)	|Acc: 70.1%(valid)
Epoch: 3  | time in 0 minutes, 51 seconds
	Loss: 0.0479(train)	|Acc: 73.3%(train)
	Loss: 0.0004(valid)	|Acc: 71.0%(valid)
Epoch: 4  | time in 0 minutes, 45 seconds
	Loss: 0.0466(train)	|Acc: 74.0%(train)
	Loss: 0.0004(valid)	|Acc: 69.9%(valid)
Epoch: 5  | time in 0 minutes, 44 seconds
	Loss: 0.0453(train)	|Acc: 74.9%(train)
	Loss: 0.0004(valid)	|Acc: 70.7%(valid)
Epoch: 6  | time in 0 minutes, 41 seconds
	Loss: 0.0449(train)	|Acc: 75.2%(train)
	Loss: 0.0004(valid)	|Acc: 71.2%(valid)
Epoch: 7  | time in 0 minutes, 43 seconds
	Loss: 0.0444(train)	|Acc: 75.3%(train)
	Loss: 0.0004(valid)	|Acc: 70.6%(valid)
Epoch: 8  | time in 0 minutes, 49 seconds
	Loss: 0.0437(train)	|Acc: 76.0%(train)
	Loss: 0.0004(valid)	|Acc: 71.3%(valid)
Epoch: 9  | time in 0 minutes, 44 seconds
	Loss: 0.0430(train)	|Acc: 76.4%(train)
	Loss: 0.0004(valid)	|Acc: 71.2%(valid)
Epoch: 10  | time in 0 minutes, 42 seconds
	Loss: 0.0425(train)	|Acc: 76.7%(train)
	Loss: 0.0004(valid)	|Acc: 71.6%(valid)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

查看embedding层嵌入的词向量

# 打印从模型的状态字典中获得的Embedding矩阵
print(model.state_dict()['embedding.weight'])

tensor([[ 0.4049, -0.1971,  0.3739,  ...,  0.1506,  0.3608,  0.3898],
        [ 0.2040, -0.4809,  0.3838,  ..., -0.0592, -0.4796,  0.1442],
        [ 0.0912,  0.2452,  0.0459,  ...,  0.1351,  0.0379, -0.0419],
        ...,
        [-0.3961, -0.3199, -0.2815,  ...,  0.4672, -0.3334,  0.4858],
        [ 0.3872, -0.2327, -0.0710,  ...,  0.3487,  0.4416, -0.2740],
        [ 0.1301,  0.2633, -0.3815,  ..., -0.1415,  0.1318, -0.4704]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

发现问题及解决方案

  • torchtext版本太新,很多内容发生了改动,使用pip install torchtext==0.4下载0.4.x版本即可。

  • 下载数据集时,由于是外网,会一直出现服务器拒绝连接,打开AG_NEWS类,看到其返回值调用了_setup_datasets(*("AG_NEWS",) + args), **kwargs)方法,找到该方法,发现在第一行dataset_tar = download_from_url(URLS[dataset_name], root=root正是由于download_from_url导致我们的请求一直被deny。这个方法的返回值是path,所以我们直接写入dataset_tar = './data/ag_news_csv.tgz'将本地文件地址返回即可。

  • 再次运行时,出现了OverflowError: Python int too large to convert to C long的问题,查到该问题出现在unicode_csv_reader()方法内的csv.field_size_limit(sys.maxsize),将这一段代码注释掉即可。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/344586
推荐阅读
相关标签
  

闽ICP备14008679号