自然语言处理实验报告-实验4

多层感知机(MLP)简介

多层感知机是一种基础的神经网络架构,包括输入层、一个或多个隐藏层以及输出层。每个层都由神经元(单元)组成,执行加权输入的总和,然后通常使用ReLU(修正线性单元)等激活函数进行激活。

我们将使用PyTorch实现一个基本的MLP。以下是定义MLP类的Python代码示例:

import torch.nn as nn

import torch.nn.functional as F

import torch

class MultilayerPerceptron(nn.Module):

    def __init__(self, input_dim, hidden_dim, output_dim):

        super(MultilayerPerceptron, self).__init__()

        self.fc1 = nn.Linear(input_dim, hidden_dim)

        self.fc2 = nn.Linear(hidden_dim, output_dim)

    def forward(self, x_in, apply_softmax=False):

        intermediate = F.relu(self.fc1(x_in))

        output = self.fc2(intermediate)

        if apply_softmax:

            output = F.softmax(output, dim=1)

        return output

代码解释

导入和设置: 我们导入必要的库(torch.nn用于神经网络组件,torch.nn.functional用于激活函数,torch用于张量操作)。

MultilayerPerceptron类:

__init__方法: 初始化MLP,输入参数包括input_dim、hidden_dim和output_dim。它定义了两个全连接层(nn.Linear),其中fc1连接输入层和隐藏层,fc2连接隐藏层和输出层。

forward方法: 定义网络的前向传播。它对第一层(fc1)的输出应用ReLU激活,并通过第二层(fc2)计算最终输出。可选地,如果apply_softmax=True,则应用softmax激活(F.softmax)。

使用示例:

batch_size = 2

input_dim = 3

hidden_dim = 100

output_dim = 4

# 初始化模型

mlp = MultilayerPerceptron(input_dim, hidden_dim, output_dim)

# 生成随机输入张量

x_input = torch.rand(batch_size, input_dim)

# 不使用softmax的前向传播

y_output = mlp(x_input, apply_softmax=False)

print("不使用softmax的输出:")

print(y_output)

# 使用softmax的前向传播

y_output_softmax = mlp(x_input, apply_softmax=True)

print("\n使用softmax的输出:")

print(y_output_softmax)

我们使用PyTorch构建多层感知机(MLP)的基础知识。我们讨论了MLP的架构,使用nn.Module在PyTorch中的实现,并展示了如何使用示例输入数据进行前向传播。PyTorch提供了一个灵活高效的框架,适用于构建和训练各种深度学习模型,非常适合机器学习任务。

使用PyTorch构建姓氏分类器

使用PyTorch构建一个姓氏分类器。这个分类器将根据输入的姓氏预测其所属的国籍。我们将逐步介绍如何准备数据、构建模型以及进行训练和评估。

数据准备与向量化

首先,我们需要准备和向量化数据。我们将使用一个自定义的SurnameDataset类来加载数据并进行向量化。以下是关键代码片段:

class SurnameDataset(Dataset):

    def __init__(self, surname_df, vectorizer):

        self.surname_df = surname_df

        self.vectorizer = vectorizer

    def __len__(self):

        return len(self.surname_df)

    def __getitem__(self, index):

        row = self.surname_df.iloc[index]

        surname_vector = self.vectorizer.vectorize(row.surname)

        nationality_index = self.vectorizer.nationality_vocab.lookup_token(row.nationality)

        return {'x_surname': surname_vector, 'y_nationality': nationality_index}

class SurnameVectorizer(object):

    def __init__(self, surname_vocab, nationality_vocab):

        self.surname_vocab = surname_vocab

        self.nationality_vocab = nationality_vocab

    def vectorize(self, surname):

        one_hot = np.zeros(len(self.surname_vocab), dtype=np.float32)

        for token in surname:

            one_hot[self.surname_vocab.lookup_token(token)] = 1

        return one_hot

    @classmethod

    def from_dataframe(cls, surname_df):

        surname_vocab = Vocabulary(unk_token="@")

        nationality_vocab = Vocabulary(add_unk=False)

        for index, row in surname_df.iterrows():

            for letter in row.surname:

                surname_vocab.add_token(letter)

            nationality_vocab.add_token(row.nationality)

        return cls(surname_vocab, nationality_vocab)

模型构建

我们将使用一个简单的两层全连接神经网络(Multilayer Perceptron,MLP)作为我们的分类器。以下是我们的模型代码:

import torch.nn as nn

import torch.nn.functional as F

class SurnameClassifier(nn.Module):

    def __init__(self, input_dim, hidden_dim, output_dim):

        super(SurnameClassifier, self).__init__()

        self.fc1 = nn.Linear(input_dim, hidden_dim)

        self.fc2 = nn.Linear(hidden_dim, output_dim)

    def forward(self, x_in, apply_softmax=False):

        intermediate_vector = F.relu(self.fc1(x_in))

        prediction_vector = self.fc2(intermediate_vector)

        if apply_softmax:

            prediction_vector = F.softmax(prediction_vector, dim=1)

        return prediction_vector

模型训练与评估

接下来,我们将展示如何训练和评估模型。我们使用PyTorch的优化器(例如Adam)和交叉熵损失函数来优化和计算损失。以下是训练步骤的核心代码:

import torch.optim as optim

# 初始化数据集和向量化器

dataset = SurnameDataset.load_dataset_and_make_vectorizer(args.surname_csv)

vectorizer = dataset.get_vectorizer()

# 初始化分类器模型

classifier = SurnameClassifier(input_dim=len(vectorizer.surname_vocab),

                               hidden_dim=args.hidden_dim,

                               output_dim=len(vectorizer.nationality_vocab))

classifier = classifier.to(args.device)

# 定义损失函数和优化器

loss_func = nn.CrossEntropyLoss()

optimizer = optim.Adam(classifier.parameters(), lr=args.learning_rate)

# 训练循环

for epoch in range(args.num_epochs):

    classifier.train()

    running_loss = 0.0

    for batch_dict in dataset.generate_batches(batch_size=args.batch_size):

        optimizer.zero_grad()

        y_pred = classifier(batch_dict['x_surname'])

        loss = loss_func(y_pred, batch_dict['y_nationality'])

        loss.backward()

        optimizer.step()

        # 计算和记录损失

        loss_batch = loss.to("cpu").item()

        running_loss += (loss_batch - running_loss) / (batch_index + 1)

    # 打印每个epoch的损失

    print(f'Epoch: {epoch+1}, Training Loss: {running_loss:.4f}')

# 保存模型状态

torch.save(classifier.state_dict(), args.model_state_file)

上面介绍了如何使用PyTorch构建和训练一个简单的姓氏分类器。我们从数据预处理和向量化开始,到模型的构建、训练和保存,逐步展示了整个过程。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值