概要
学习项目:https://github.com/649453932/Chinese-Text-Classification-Pytorch
学习模型:textcnn
整体架构流程
torch代码实现
class Model(nn.Module):
def __init__(self, config):
super(Model, self).__init__()
if config.embedding_pretrained is not None:
# 参数freeze的作用,是指明训练时是否更新词向量矩阵的权重值,True为不更新,默认为True
self.embedding = nn.Embedding.from_pretrained(config.embedding_pretrained, freeze=False)
else:
self.embedding = nn.Embedding(config.n_vocab, config.embed, padding_idx=config.n_vocab - 1)
self.convs = nn.ModuleList(
[nn.Conv2d(1, config.num_filters, (k, config.embed)) for k in config.filter_sizes] )
self.dropout = nn.Dropout(config.dropout)
self.fc = nn.Linear( config.num_filters * len(config.filter_sizes), config.num_classes )
def conv_and_pool(self, x, conv):
# squeeze 用于移除张量中维度
# 参数3表示要移除第3个维度(从0开始计数)
x = F.relu(conv(x)).squeeze(3)
# nn.MaxPool1d是torch.nn模块中的一个类,通常在定义神经网络模型时使用。它需要被实例化并添加到网络中
# F.max_pool1d是torch.nn.functional模块中的一个函数,可以直接在代码中使用,无需创建类的实例
# max_pool1d 输入形状是 (batch_size, channels, length) , 此时 x的形状为 128*256*31 ,即将在31上最大池化
# squeeze(2) 移除第2维 ,从0计数
# 最终x维度为 batchsize*256,256为设置的每个卷积核输出的通道数
x = F.max_pool1d(x, x.size(2)).squeeze(2)
return x
def forward(self, x):
# 这里x传入的数据格式为 ( batchsize*32(表示的长度) , 每条文本的原始长度seq_len ) 32是填充后的 ; 从搜狗的词向量中获取相应的词向量
# 尺寸为 batchsize*32*300
out = self.embedding(x)
# 使用unsqueeze后,张量的总维度将增加1。这意味着如果原张量是二维的(如通道×高度),通过在某个位置插入一个新维度,可以得到一个三维张量(如通道×1×高度)。
# 这对于某些需要特定维度格式的操作特别有用,比如某些卷积操作要求输入为三维或四维张量
# 尺寸为 batchsize*1*32*300
out = out.unsqueeze(1)
# conv2d的输入尺寸为 batchsize*in_channels*height*width
# 所以上面需要增加一个维度
# 多个卷积核的结果cat一起,尺寸为batchsize*(256*3) , 3是卷积核的数量
out = torch.cat([self.conv_and_pool(out, conv) for conv in self.convs], 1)
out = self.dropout(out)
out = self.fc(out)
return out
关键方法的使用
nn.Embedding的详细用法
torch.nn.Embedding(num_embeddings
, embedding_dim
, padding_idx=None
, max_norm=None
, norm_type=2.0
, scale_grad_by_freq=False
, sparse=False
, _weight=None
, _freeze=False
, device=None
, dtype=None)
常用参数:
① num_embeddings : 词典中词的数量
② embedding_dim (int): 词典中每个词的嵌入维度
③ padding_idx (int, optional): 指定的索引位置(词表长度范围内),某个词的词向量将被置为0
nn.Embedding.from_pretrained方法获得预训练的权重,其中freeze的作用,是指明训练时是否更新词向量矩阵的权重值,True为不更新,默认为True
nn.Embedding.from_pretrained(config.embedding_pretrained, freeze=False)
unsqueeze\squeeze用法
unsqueeze:在张量的指定位置增加\减少一个新的维度,从而改变张量的形状
参数:
① dim : 范围是 [-input.dim() - 1, input.dim() + 1 ) , 负数等价于 dim = dim + input.dim() + 1
# 维度为2 ,shape为(2,4)
x = torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8] ].dim()
# torch.Size([2, 4, 1])
x.unsqueeze(dim=-1).shape
# torch.Size([2, 4, 1])
x.unsqueeze(dim=2).shape
squeeze: 去除张量中的尺寸为 1 的维度 , 输入维度从0开始计数
参数:
① dim :dim 为None,则会去除所有尺寸为 1 的维度。r若提供 dim 参数,则去除指定位置的尺寸为 1 的维度
# 创建一个形状为 (1, 2, 1, 3) 的张量
x = torch.randn(1, 2, 1, 3)
# torch.Size([2, 3])
x.squeeze().shape
# torch.Size([2, 1, 3])
x.squeeze(0).shape
# torch.Size([1, 2, 1, 3]) , 1位置上的维度不为1 , 所以没有任何改变
x.squeeze(1).shape