NLP实战高手课学习笔记(13):Pytorch中的Dataset和网络定义

230 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情

说明

本系列博客将记录自己学习的课程:NLP实战高手课,链接为:time.geekbang.org/course/intr… 本篇为25-26节的课程笔记,主要介绍Pytorch中Dataset和Dataloader的定义以及如何在Pytorch中定义实现自己的神经网络模型。

Dataset与Dataloader

Dataset的定义

Pytorch中的数据集加载是通过继承和重写torch.utils.data中的Dataset类来实现,自定义的Dataset类必须要重写原类的以下三个方法:

  • _init_: 初始化函数;
  • _len_: 数据集的总长度;
  • _getitem_: 数据样例的索引函数。

下面我们来看一个示例:

class MySimpleDataset(Dataset):
    def __init__(self):
        super(MySimpleDataset, self).__init__()
        self.data = torch.randn([1024, 10, 10])
    def __len__(self):
        return 1024
    def __getitem__(self, idx):
        return self.data[idx, :, :] 

上述代码定义了一个叫做MySimpleDataset的数据集类,其数据来源是有torch.randn生成的1024个随机数据样例,每个样例的维度为10*10。

接着我们通过

my_dataset = MySimpleDataset()

就可以实现数据集类的初始化。

Dataloader的使用

在定义好数据集后,我们不太可能一下子把所有数据全部丢给模型,而是需要有一个数据集加载器,帮助我们每次从数据集中加载一个batch_size大小的数据样例送给模型。在Pytorch中,这部分功能由Dataloader类实现。

my_data_loader = DataLoader(my_simple_dataset, batch_size=64, shuffle=True)
for data in my_data_loader:
    ……

通过上面的方式,我们就可以以batch_size作为单位,逐个将数据送到模型中。

Pytorch中的模型定义

在了解完Pytorch中的数据集后,我们来看一下一个神经网络模型在Pytorch中如何被定义。

一般而言,对于一个Pytorch中的自定义网络模型,我们需要继承与重写torch.nn.Module类,并且需要重写这两个函数:

  • _init_: 初始化函数;
  • forward: 模型的训练的前项计算函数。

下面展示一个多层神经网络(MLP)的示例:

class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.first_layer = nn.Linear(1000,50)
        self.second_layer = nn.Linear(50, 1)
    def forward(self, x):
        x = torch.flatten(x, start_dim=1, end_dim=2)
        x = nn.functional.relu(self.first_layer(x))
        x = self.second_layer(x)
        return x

可以看到我们定义了一个两层的神经网络,输入维度为1000,隐藏层的维度为50,输出维度为1。这里选取了Relu函数作为激活函数。

Pytorch中的神经网络示例

在了解完Pytorch中的模型定义后,我们来看几个Pytorch中封装好的神经网络模块。

Embedding层

Embedding层用于将一个index转换为其对应的Embedding取出。示例代码如下:

class Embedding(nn.Module):
    def __init__(self):
        super(Embedding, self).__init__()
        self.embedding = nn.Embedding(4, 100)
    def forward(self, x):
        return self.embedding(x)

embedding = Embedding()

embedding_input = torch.tensor([[0,1, 0],[2,3, 3]])
embedding_output = embedding(embedding_input)

print(embedding_output.shape)

得到输出为

torch.Size([2, 3, 100])

这里,2,3是原索引的维度,100则是Embedding的维度。

LSTM层

LSTM层有很多参数需要提前定义,比如隐层的维度大小、层数、是否使用双向网络,dropout的概率等,示例代码如下:

class LSTM(nn.Module):
    def __init__(self):
        super(LSTM, self).__init__()
        self.lstm = nn.LSTM(10, 
                           15, 
                           num_layers=2, 
                           bidirectional=True, 
                           dropout=0.1)
    def forward(self, x):
        output, (hidden, cell) = self.lstm(x)
        return output, hidden, cell

这里定义了一个双向LSTM,其输入维度为10,隐藏层维度为15,层数为2,dropout的取值为0.1。

CNN 层

CNN层也需要指定好卷积核的大小和数目。示例代码如下:

class Conv(nn.Module):
    def __init__(self):
        super(Conv, self).__init__()
        self.conv1d = nn.Conv1d(100, 50, 2)
    def forward(self, x):
        return self.conv1d(x)

这里使用了卷积核的数目为50,大小为2*100。

总结

本文介绍了Pytorch中的数据集操作和神经网络的定义方式,同时介绍了几个常用的网络模块的实现,希望对您有所帮助。