Pytorch多分类问题实战
Posted 凸头统治世界
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pytorch多分类问题实战相关的知识,希望对你有一定的参考价值。
多分类问题实战
定义一个简单的神经网络模型,并使用SGD优化算法进行训练和测试MNIST数据集
import torch
import torch.nn.functional as F
import torch.optim as optim
"""
torchvision 可以帮助简化计算机视觉任务的实现,包括图像分类、目标检测、语义分割等。它提供了一些预训练的模型(如 ResNet、VGG、AlexNet 等)和用于训练和测试这些模型的数据集。此外,torchvision 还提供了数据转换操作,如图像预处理、数据增强和归一化等,用于准备数据以供模型使用。
在代码中,torchvision.datasets 模块用于加载 MNIST 数据集,并且 torchvision.transforms 模块用于定义数据转换操作,如将图像转换为张量、归一化等。这些模块都是 torchvision 库的一部分,可以帮助处理计算机视觉任务中的数据集和数据转换操作。
"""
from torchvision import datasets, transforms
# 每个训练批次的样本数量
batch_size = 200
# 学习率
learning_rate = 0.01
#批次的数量
epochs = 10
# 创建一个名为train_loader的数据加载器对象
train_loader = torch.utils.data.DataLoader(
# 加载MNIST数据集。该类会检查指定路径\'../data\'是否存在MNIST数据集,如果不存在,则会下载数据集到该路径。
# 当train=True时,datasets.MNIST会加载MNIST数据集的训练集部分,并返回一个包含训练图像和对应标签的数据集对象。这样我们可以使用这个数据集对象来训练模型。
# 当train=False时,datasets.MNIST会加载MNIST数据集的测试集部分,并返回一个包含测试图像和对应标签的数据集对象。这样我们可以使用这个数据集对象来评估模型的性能。
datasets.MNIST(\'../data\',train=True,download=True,
# 使用transforms.Compose函数将多个预处理操作组合在一起。
transform=transforms.Compose([
# MNIST数据集中的图像最初是PIL图像对象,通过该操作将其转换为张量形式,便于后续的计算和训练。
transforms.ToTensor(),
# 对数据进行标准化处理。这里使用了均值和标准差进行标准化,均值为0.1307,标准差为0.3081。这样做 的目的是将数据的分布调整为均值为0,标准差为1的标准正态分布,有助于提高模型的训练效果。
transforms.Normalize((0.1307,),(0.3081,))
])
),
# 在每个训练批次之前对数据进行洗牌,以增加训练的随机性。这样做可以避免模型仅仅学习到样本的固定顺序,提高模型的泛化能力。
batch_size=batch_size,shuffle=True
)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST(\'../data\',train=False,download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,),(0.3081,))
]
)),
batch_size=batch_size,shuffle=True
)
w1, b1 = torch.randn(200, 784,requires_grad=True),\\
torch.zeros(200, requires_grad=True)
w2, b2 = torch.randn(200, 200,requires_grad=True),\\
torch.zeros(200, requires_grad=True)
w3, b3 = torch.randn(10, 200,requires_grad=True),\\
torch.zeros(10, requires_grad=True)
"""
是PyTorch中的一个函数,用于对张量进行Kaiming正态分布初始化。在给定的张量上应用Kaiming初始化方法,可以初始化具有较好初始权重的神经网络模型,以便更有效地进行训练。
具体地说,torch.nn.init.kaiming_normal_()函数采用以下方式初始化张量:
它从一个均值为0,标准差为gain / sqrt(fan_in)的正态分布中,随机地抽取值来填充输入张量。其中,fan_in是输入张量的扇入(输入单元的数量),gain是一个可选的缩放因子,通常取sqrt(2)。
Kaiming初始化方法(也称为"He初始化"或"He正态分布初始化)是为了解决深度神经网络中梯度消失或梯度爆炸问题而提出的。通过使用合适的初始权重,可以更好地保持梯度在网络层之间传播,从而提高网络的训练效果。
"""
torch.nn.init.kaiming_normal_(w1)
torch.nn.init.kaiming_normal_(w2)
torch.nn.init.kaiming_normal_(w3)
def forward(x):
x = x@w1.t() + b1
x = F.relu(x)
x = x@w2.t() + b2
x = F.relu(x)
x = x @ w3.t() + b3
x = F.relu(x)
return x
# 创建一个使用随机梯度下降算法的优化器对象
optimizer = optim.SGD([w1,b1,w2,b2,w3,b3],lr=learning_rate)
criteon = torch.nn.CrossEntropyLoss()
for epoch in range(epochs):
# 使用enumerate函数对train_loader进行迭代,同时获取索引和对应的数据。
# batch_idx:这是一个索引变量,用于表示当前批次的索引号。
# (data, target):一个元组,data表示图像数据,target表示标签。
for batch_idx,(data,target) in enumerate(train_loader):
# data是一个图像数据的张量,其形状为(batch_size, 1, 28, 28),表示每个批次中有batch_size个图像,每个图像大小为28x28像素。
# -1:它表示在给定维度上自动计算对应的大小。在这里,将其用于第一个维度,即批次维度,以便根据剩余的维度自动计算批次大小。28*28:这是新的形状,表示将每个图像展平为一个大小为784的向量。通过将28x28像素的图像展开为一维向量,可以将图像数据作为特征输入到模型中。
data = data.view(-1,28*28) # view()函数对张量进行形状变换
logits = forward(data)
# CrossEntropyLoss已包含Softmax
loss = criteon(logits,target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (batch_idx % 100) == 0:
print(\'Train Epoch: [/ (:.0f%)]\\tLoss: :.6f\'.format(
epoch,
batch_idx * len(data),
len(train_loader.dataset),
100. * batch_idx / len(train_loader),
loss.item()
))
test_loss = 0
correct = 0
for data,target in test_loader:
data = data.view(-1,28 * 28)
logits = forward(data)
test_loss += criteon(logits,target).item()
pred = logits.data.max(1)[1]
correct += pred.eq(target.data).sum()
test_loss /= len(test_loader.dataset)
print(\'\\nTest set: Average loss: :.4f, Accuracy: / (:.0f%)\\n\'.format(
test_loss,
correct,
len(test_loader.dataset),
100. * correct / len(test_loader.dataset)
))
输出结果
Train Epoch:0 [0/60000 (0%)] Loss: 3.088388
Train Epoch:0 [20000/60000 (33%)] Loss: 0.587288
Train Epoch:0 [40000/60000 (67%)] Loss: 0.374099
Test set: Average loss: 0.0017, Accuracy: 8983/10000 (90%)
Train Epoch:1 [0/60000 (0%)] Loss: 0.276809
Train Epoch:1 [20000/60000 (33%)] Loss: 0.418936
Train Epoch:1 [40000/60000 (67%)] Loss: 0.340238
Test set: Average loss: 0.0013, Accuracy: 9190/10000 (92%)
Train Epoch:2 [0/60000 (0%)] Loss: 0.284477
Train Epoch:2 [20000/60000 (33%)] Loss: 0.260783
Train Epoch:2 [40000/60000 (67%)] Loss: 0.228615
Test set: Average loss: 0.0012, Accuracy: 9312/10000 (93%)
Train Epoch:3 [0/60000 (0%)] Loss: 0.233259
Train Epoch:3 [20000/60000 (33%)] Loss: 0.155293
Train Epoch:3 [40000/60000 (67%)] Loss: 0.229180
Test set: Average loss: 0.0010, Accuracy: 9388/10000 (94%)
Train Epoch:4 [0/60000 (0%)] Loss: 0.144686
Train Epoch:4 [20000/60000 (33%)] Loss: 0.216506
Train Epoch:4 [40000/60000 (67%)] Loss: 0.146811
Test set: Average loss: 0.0010, Accuracy: 9430/10000 (94%)
Train Epoch:5 [0/60000 (0%)] Loss: 0.197008
Train Epoch:5 [20000/60000 (33%)] Loss: 0.276877
Train Epoch:5 [40000/60000 (67%)] Loss: 0.247613
Test set: Average loss: 0.0009, Accuracy: 9462/10000 (95%)
Train Epoch:6 [0/60000 (0%)] Loss: 0.162596
Train Epoch:6 [20000/60000 (33%)] Loss: 0.138650
Train Epoch:6 [40000/60000 (67%)] Loss: 0.180352
Test set: Average loss: 0.0008, Accuracy: 9503/10000 (95%)
Train Epoch:7 [0/60000 (0%)] Loss: 0.141457
Train Epoch:7 [20000/60000 (33%)] Loss: 0.113807
Train Epoch:7 [40000/60000 (67%)] Loss: 0.112289
Test set: Average loss: 0.0008, Accuracy: 9517/10000 (95%)
Train Epoch:8 [0/60000 (0%)] Loss: 0.171669
Train Epoch:8 [20000/60000 (33%)] Loss: 0.182690
Train Epoch:8 [40000/60000 (67%)] Loss: 0.207414
Test set: Average loss: 0.0008, Accuracy: 9554/10000 (96%)
Train Epoch:9 [0/60000 (0%)] Loss: 0.175700
Train Epoch:9 [20000/60000 (33%)] Loss: 0.130695
Train Epoch:9 [40000/60000 (67%)] Loss: 0.074462
Test set: Average loss: 0.0007, Accuracy: 9551/10000 (96%)
Pytorch100例 | 用深度学习处理分类问题实战教程
PyTorch和TensorFlow库是用于深度学习的两个最常用的 Python 库。PyTorch 是 Facebook 开发的,而 TensorFlow 是 Google 的项目。在本文中,你将看到如何使用 PyTorch 库来解决分类问题。
分类问题属于机器学习问题的范畴,其中给定一组特征,任务是预测离散值。预测肿瘤是否癌变,或者学生是否可能通过考试,是分类问题的一些常见示例。
在本文中,我们将根据银行客户的某些特征,预测客户是否有可能在 6 个月后离开银行。客户离开的现象也称为客户流失。因此,我们的任务是根据各种客户特征来预测客户流失。
在你继续之前,假定你对 Python 编程语言具有中级水平,并且你已经安装了 PyTorch 库。此外,了解了基本机器学习概念的知识可能会对理解本文有所帮助。如果你尚未安装 PyTorch,则可以使用以下 pip 命令进行安装:
$ pip install pytorch
数据集
我们将在本文中使用的数据集可通过此Kaggle 链接免费获得,也可以添加我微信获取。让我们将所需的库和数据集导入我们的 Python 应用程序:
import torch
import torch.nn as nn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
我们可以使用第三方库的read_csv()
方法pandas
导入包含我们数据集的 CSV 文件。
dataset = pd.read_csv(r'E:Datasets\\customer_data.csv')
让我们打印数据集的形状:
dataset.shape
输出:
(10000, 14)
输出显示数据集有 10,000 条记录和 14 列。
我们可以使用.head()
方法打印数据集的前五行。
dataset.head()
输出:
你可以在我们的数据集中看到 14 列。我们的任务是基于前 13 列预测第 14 列的值,即Exited
。需要注意的是,前 13 列的值是在Exited
获取该列的值之前 6 个月记录的,因为任务是预测自记录客户信息起 6 个月后的客户流失。
探索性数据分析
让我们对我们的数据集执行一些探索性数据分析。我们将首先预测 6 个月后实际离开银行的客户的比例,并使用饼图进行可视化。
让我们首先增加图表的默认绘图大小:
fig_size = plt.rcParams["figure.figsize"]
fig_size[0] = 10
fig_size[1] = 8
plt.rcParams["figure.figsize"] = fig_size
以下脚本绘制Exited
列的饼图。
dataset.Exited.value_counts().plot(kind='pie', autopct='%1.0f%%', colors=['skyblue', 'orange'], explode=(0.05, 0.05))
输出:
输出显示,在我们的数据集中,20% 的客户离开了银行。这里1代表客户离开银行的情况,0代表客户没有离开银行的情况。
让我们绘制数据集中所有地理位置的客户数量:
sns.countplot(x='Geography', data=dataset)
输出:
输出显示,几乎一半的客户属于法国,而属于西班牙和德国的客户比例各为 25%。
现在让我们绘制每个独特地理位置的客户数量以及客户流失信息。我们可以使用seaborn
库中的countplot()
函数来做到这一点。
sns.countplot(x='Exited', hue='Geography', data=dataset)
输出:
输出显示,尽管法国客户的总数是西班牙和德国客户的两倍,但法国和德国客户离开银行的客户比例相同。同样,德国和西班牙客户的总体数量相同,但德国客户离开银行的数量是西班牙客户的两倍,这表明德国客户更有可能在 6 个月后离开银行。
数据预处理
在我们训练我们的 PyTorch 模型之前,我们需要预处理我们的数据。如果查看数据集,你会看到它有两种类型的列:数值列和分类列。数字列包含数字信息。CreditScore
、Balance
、Age
等。类似地,Geography
和Gender
是分类列,因为它们包含分类信息,例如客户的位置和性别。有一些列可以被视为数字列和分类列。例如,该HasCrCard
列的值可以是 1 或 0。但是,那HasCrCard
列包含有关客户是否拥有信用卡的信息。建议将既可被视为分类又可被视为数值的列视为分类。
让我们再次打印数据集中的所有列,并找出哪些列可以被视为数字列,哪些列应该被视为分类列。数据框的columns属性打印所有列名:
dataset.columns
输出:
Index(['RowNumber', 'CustomerId', 'Surname', 'CreditScore', 'Geography',
'Gender', 'Age', 'Tenure', 'Balance', 'NumOfProducts', 'HasCrCard',
'IsActiveMember', 'EstimatedSalary', 'Exited'],
dtype='object')
在我们数据集中的列中,我们不会使用RowNumber
、CustomerId
和Surname
列,因为这些列的值是完全随机的并且与我们需要预测的目标无关。例如,客户的姓氏对客户是否会离开银行没有影响。在其余列中,Geography
、Gender
、HasCrCard
和IsActiveMember
列可以视为分类列。让我们创建这些列的列表:
categorical_columns = ['Geography', 'Gender', 'HasCrCard', 'IsActiveMember']
除Exited
列外的所有剩余列都可以视为数字列。
numerical_columns = ['CreditScore', 'Age', 'Tenure', 'Balance', 'NumOfProducts', 'EstimatedSalary']
最后,输出(Exited
列)存储在outputs
变量中。
outputs = ['Exited']
我们已经创建了分类、数字和输出的列表。但是,目前分类列的类型不是分类的。你可以使用以下脚本检查数据集中所有列的类型:
dataset.dtypes
输出:
RowNumber int64
CustomerId int64
Surname object
CreditScore int64
Geography object
Gender object
Age int64
Tenure int64
Balance float64
NumOfProducts int64
HasCrCard int64
IsActiveMember int64
EstimatedSalary float64
Exited int64
dtype: object
你可以看到Geography
和 Gender
列的类型为object
,HasCrCard 和IsActive 列的类型为int64
,我们需要将分类列的类型转换为category
,我们可以使用函数来做到这一点,如下所示:
for category in categorical_columns:
dataset[category] = dataset[category].astype('category')
现在,如果您再次绘制数据集中列的类型,您应该会看到以下结果:
dataset.dtypes
输出
RowNumber int64
CustomerId int64
Surname object
CreditScore int64
Geography category
Gender category
Age int64
Tenure int64
Balance float64
NumOfProducts int64
HasCrCard category
IsActiveMember category
EstimatedSalary float64
Exited int64
dtype: object
现在让我们看看Geography
列中的所有类别:
dataset['Geography'].cat.categories
输出:
Index(['France', 'Germany', 'Spain'], dtype='object')
当你将列的数据类型更改为类别时,列中的每个类别都会分配一个唯一代码。例如,让我们绘制该Geography
列的前五行并打印前五行的代码值:
dataset['Geography'].head()
输出:
0 France
1 Spain
2 France
3 France
4 Spain
Name: Geography, dtype: category
Categories (3, object): [France, Germany, Spain]
以下脚本绘制Geography
列前五行中值的编号:
dataset['Geography'].head().cat.codes
输出:
0 0
1 2
2 0
3 0
4 2
dtype: int8
输出显示法国已编码为 0,西班牙已编码为 2。
由于我们将使用 PyTorch 进行模型训练,因此我们需要将分类列和数值列转换为张量。让我们首先将分类列转换为张量。在 PyTorch 中,可以通过 numpy 数组创建张量。我们首先将四个分类列中的数据转换为 numpy 数组,然后水平堆叠所有列,如以下脚本所示:
geo = dataset['Geography'].cat.codes.values
gen = dataset['Gender'].cat.codes.values
hcc = dataset['HasCrCard'].cat.codes.values
iam = dataset['IsActiveMember'].cat.codes.values
categorical_data = np.stack([geo, gen, hcc, iam], 1)
categorical_data[:10]
上面的脚本打印分类列中水平堆叠的前十条记录。输出如下:
输出:
array([[0, 0, 1, 1],
[2, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 0, 0],
[2, 0, 1, 1],
[2, 1, 1, 0],
[0, 1, 1, 1],
[1, 0, 1, 0],
[0, 1, 0, 1],
[0, 1, 1, 1]], dtype=int8)
现在要从前面提到的 numpy 数组创建一个张量,你可以简单地将数组传递给模块的torch
类的tensor
模块。对于分类列,数据类型应为torch.int64
.
categorical_data = torch.tensor(categorical_data, dtype=torch.int64)
categorical_data[:10]
输出:
tensor([[0, 0, 1, 1],
[2, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 0, 0],
[2, 0, 1, 1],
[2, 1, 1, 0],
[0, 1, 1, 1],
[1, 0, 1, 0],
[0, 1, 0, 1],
[0, 1, 1, 1]])
在输出中,你可以看到分类数据的 numpy 数组现已转换为tensor
对象。以同样的方式,我们可以将数值列转换为张量:
numerical_data = np.stack([dataset[col].values for col in numerical_columns], 1)
numerical_data = torch.tensor(numerical_data, dtype=torch.float)
numerical_data[:5]
输出:
tensor([[6.1900e+02, 4.2000e+01, 2.0000e+00, 0.0000e+00, 1.0000e+00, 1.0135e+05],
[6.0800e+02, 4.1000e+01, 1.0000e+00, 8.3808e+04, 1.0000e+00, 1.1254e+05],
[5.0200e+02, 4.2000e+01, 8.0000e+00, 1.5966e+05, 3.0000e+00, 1.1393e+05],
[6.9900e+02, 3.9000e+01, 1.0000e+00, 0.0000e+00, 2.0000e+00, 9.3827e+04],
[8.5000e+02, 4.3000e+01, 2.0000e+00, 1.2551e+05, 1.0000e+00, 7.9084e+04]])
在输出中,你可以看到前五行包含我们数据集中六个数字列的值。
最后一步是将输出的 numpy 数组转换为tensor
对象。
outputs = torch.tensor(dataset[outputs].values).flatten()
outputs[:5]
输出:
tensor([1, 0, 1, 0, 0])
现在让我们绘制分类数据、数值数据和相应输出的形状:
print(categorical_data.shape)
print(numerical_data.shape)
print(outputs.shape)
输出:
torch.Size([10000, 4])
torch.Size([10000, 6])
torch.Size([10000])
在我们训练模型之前有一个非常重要的步骤。我们将分类列转换为数字列(类别数字化),其中唯一值由整数表示。例如,在Geography
列中,我们看到法国用 0 表示,德国用 1 表示。我们可以使用这些值来训练我们的模型。但是,更好的方法是以 N 维向量的形式表示分类列中的值,而不是整数。向量能够捕获更多信息,并能以更合适的方式找到不同分类值之间的关系。因此,我们将以 N 维向量的形式表示分类列中的值。这个过程称为嵌入。
我们需要为所有分类列定义嵌入大小(向量维度)。关于维数没有硬性规定。定义列的嵌入大小的一个好的经验法则是将列中唯一值的数量除以 2(但不超过 50)。例如,对于该Geography
列,唯一值的数量为 3。该Geography
列的相应嵌入大小将为 3/2 = 1.5 = 2
(四舍五入)。
以下脚本创建一个元组,其中包含唯一值的数量和所有分类列的维度大小:
categorical_column_sizes = [len(dataset[column].cat.categories) for column in categorical_columns]
categorical_embedding_sizes = [(col_size, min(50, (col_size+1)//2)) for col_size in categorical_column_sizes]
print(categorical_embedding_sizes)
输出:
[(3, 2), (2, 1), (2, 1), (2, 1)]
对于有监督的深度学习模型,例如我们在本文中开发的模型,需要使用训练数据进行训练,并在测试数据集上评估模型性能。因此,我们需要将我们的数据集划分为训练集和测试集,如下面的脚本所示:
total_records = 10000
test_records = int(total_records * .2)
categorical_train_data = categorical_data[:total_records-test_records]
categorical_test_data = categorical_data[total_records-test_records:total_records]
numerical_train_data = numerical_data[:total_records-test_records]
numerical_test_data = numerical_data[total_records-test_records:total_records]
train_outputs = outputs[:total_records-test_records]
test_outputs = outputs[total_records-test_records:total_records]
我们的数据集中有 10,000 条记录,其中 80% 的记录,即 8000 条记录,将用于训练模型,而其余 20% 的记录将用于评估我们模型的性能。请注意,在上面的脚本中,分类和数值数据以及输出已分为训练集和测试集。
为了验证我们是否正确地将数据划分为训练集和测试集,让我们打印训练和测试记录的长度:
print(len(categorical_train_data))
print(len(numerical_train_data))
print(len(train_outputs))
print(len(categorical_test_data))
print(len(numerical_test_data))
print(len(test_outputs))
输出:
8000
8000
8000
2000
2000
2000
创建预测模型
我们已将数据分为训练集和测试集,现在是时候定义我们的训练模型了。为此,我们可以定义一个名为Model
的类,它将用于训练模型。
class Model(nn.Module):
def __init__(self, embedding_size, num_numerical_cols, output_size, layers, p=0.4):
super().__init__()
self.all_embeddings = nn.ModuleList([nn.Embedding(ni, nf) for ni, nf in embedding_size])
self.embedding_dropout = nn.Dropout(p)
self.batch_norm_num = nn.BatchNorm1d(num_numerical_cols)
all_layers = []
num_categorical_cols = sum((nf for ni, nf in embedding_size))
input_size = num_categorical_cols + num_numerical_cols
for i in layers:
all_layers.append(nn.Linear(input_size, i))
all_layers.append(nn.ReLU(inplace=True))
all_layers.append(nn.BatchNorm1d(i))
all_layers.append(nn.Dropout(p))
input_size = i
all_layers.append(nn.Linear(layers[-1], output_size))
self.layers = nn.Sequential(*all_layers)
def forward(self, x_categorical, x_numerical):
embeddings = []
for i,e in enumerate(self.all_embeddings):
embeddings.append(e(x_categorical[:,i]))
x = torch.cat(embeddings, 1)
x = self.embedding_dropout(x)
x_numerical = self.batch_norm_num(x_numerical)
x = torch.cat([x, x_numerical], 1)
x = self.layers(x)
return x
如果你以前从未使用过 PyTorch,上面的代码可能看起来会有些难度,我尽力为你分解。
在第一行中,我们声明了一个Model
继承自Module
的类。在类的构造函数(__init__()
方法)中传递以下参数:
embedding_size
:包含分类列的嵌入大小(embedding size)num_numerical_cols
:存储数字列的总数output_size
:输出层的大小或可能输出的数量。layers
:包含所有层的神经元数量的列表。p
:Dropout值,默认值为0.5
在构造函数内部,初始化了一些变量。首先,该all_embeddings
变量包含所有分类列的ModuleList
对象列表。embedding_dropout
存储所有层的丢失值。最后,batch_norm_num存储所有数字列的BatchNorm1d
对象列表。
接下来,为了找到输入层的大小,将分类列数和数字列数相加并存储在input_size
变量中。之后,for循环迭代并将相应的层添加到all_layers
列表中。添加的层是:
Linear
:用于计算输入和权重矩阵之间的点积ReLu
:用作激活函数BatchNorm1d
: 用于对数值列应用批量归一化Dropout
:用于避免过拟合
for
循环后,输出层将附加到层列表。由于我们希望神经网络中的所有层按顺序执行,因此将层列表传递给nn.Sequential
类。
接下来,在该forward
方法中,分类列和数字列都作为输入传递。分类列的嵌入发生在以下几行中。
embeddings = []
for i, e in enumerate(self.all_embeddings):
embeddings.append(e(x_categorical[:,i]))
x = torch.cat(embeddings, 1)
x = self.embedding_dropout(x)
数字列的批量归一化应用以下脚本:
x_numerical = self.batch_norm_num(x_numerical)
最后,嵌入的分类列x
和数字列x_numerical
连接在一起并传递给 sequential layers
。
训练模型
要训练模型,首先我们必须创建一个Model
(我们在上一节中定义的类的对象)。
model = Model(categorical_embedding_sizes, numerical_data.shape[1], 2, [200,100,50], p=0.4)
你可以看到我们传递了分类列的嵌入大小、数字列的数量、输出大小(在我们的例子中为 2)和隐藏层中的神经元。你可以看到我们有三个隐藏层,分别有 200、100 和 50 个神经元。如果需要,你可以选择任何其他尺寸。
让我们打印我们的模型,看看它的外观:
print(model)
输出:
Model(
(all_embeddings): ModuleList(
(0): Embedding(3, 2)
(1): Embedding(2, 1)
(2): Embedding(2, 1)
(3): Embedding(2, 1)
)
(embedding_dropout): Dropout(p=0.4)
(batch_norm_num): BatchNorm1d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(layers): Sequential(
(0): Linear(in_features=11, out_features=200, bias=True)
(1): ReLU(inplace)
(2): Batch以上是关于Pytorch多分类问题实战的主要内容,如果未能解决你的问题,请参考以下文章
PyTorch 深度学习实战 | 基于 ResNet 的花卉图片分类