PyTorch比NumPy能省多少时间?(附代码)

上节,我已经展示了如何通过反向传播为前馈神经网络实现这些计算,让我们看看与 NumPy 相比,PyTorch 为我们节省了多少时间。

加载 MNIST 数据集

其中一件看起来比它应该更复杂或更难理解的事情是使用 PyTorch 加载数据集。首先定义数据的转换,指定它应该是一个张量,并且应该对其进行规范化。然后,将 in 与数据集结合使用来加载数据集。这就是您所需要的。稍后将了解如何从这些加载程序中解压缩值。

DataLoader``import

import torch
from torchvision import datasets, transforms
​
transform = transforms.Compose([
                transforms.ToTensor(),
                transforms.Normalize((0.1307,), (0.3081,))
            ])
​
train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('data', train=True, download=True, transform=transform))
​
test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('data', train=False, transform=transform))

训练

我定义了一个名为类似于之前用 NumPy 编写的类的类。这个类有一些相同的方法,但你可以清楚地看到,我不需要考虑初始化网络参数,也不需要考虑PyTorch中的向后传递,因为这些函数和计算精度的函数都消失了。

Net``DeepNeuralNetwork

import time
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
​
class Net(nn.Module):
    def __init__(self, epochs=10):
        super(Net, self).__init__()
        self.linear1 = nn.Linear(784, 128)
        self.linear2 = nn.Linear(128, 64)
        self.linear3 = nn.Linear(64, 10)
​
        self.epochs = epochs
​
    def forward_pass(self, x):
        x = self.linear1(x)
        x = torch.sigmoid(x)
        x = self.linear2(x)
        x = torch.sigmoid(x)
        x = self.linear3(x)
        x = torch.softmax(x, dim=0)
        return x
​
    def one_hot_encode(self, y):
        encoded = torch.zeros([10], dtype=torch.float64)
        encoded[y[0]] = 1.
        return encoded
​
    def train(self, train_loader, optimizer, criterion):
        start_time = time.time()
        loss = None
​
        for iteration in range(self.epochs):
            for x,y in train_loader:
                y = self.one_hot_encode(y)
                optimizer.zero_grad()
                output = self.forward_pass(torch.flatten(x))
                loss = criterion(output, y)
                loss.backward()
                optimizer.step()
​
            print('Epoch: {0}, Time Spent: {1:.2f}s, Loss: {2}'.format(
                iteration+1, time.time() - start_time, loss
            ))

在阅读本类时,请注意 PyTorch 已经为我们实现了所有相关的激活函数,以及不同类型的层。你甚至不必考虑它。您可以只定义一些图层,例如全连接图层。nn.Linear()

我之前已经导入了优化器,现在我指定了要使用的优化器,以及损失的标准。我将优化器和标准都传递到训练函数中,PyTorch 开始运行示例,就像在 NumPy 中一样。我甚至可以包括一个衡量准确性的指标,但为了衡量损失而忽略了这一点。

model = Net()
​
optimizer = optim.SGD(model.parameters(), lr=0.001)
criterion = nn.BCEWithLogitsLoss()
​
model.train(train_loader, optimizer, criterion)

使用 Keras 的 TensorFlow 2.0

对于神经网络的 TensorFlow/Keras 版本,我选择使用一种简单的方法,最大限度地减少代码行数。这意味着我没有定义任何类,而是使用 Keras 的高级 API 来制作一个仅用几行代码的神经网络。如果你刚刚开始学习神经网络,你会发现使用 Keras 时进入门槛最低。因此,我推荐它。

我首先导入以后需要的所有函数。

import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.losses import BinaryCrossentropy

我只需这几行代码即可加载数据集并对其进行预处理。请注意,我只对训练数据进行预处理,因为我不打算将验证数据用于此方法。稍后,我将解释如何使用验证数据。

(x_train, y_train), (x_val, y_val) = mnist.load_data()
​
x_train = x_train.astype('float32') / 255
y_train = to_categorical(y_train)

下一步是定义模型。在 Keras 中,在知道要将哪些图层应用于数据后,这非常简单。在本例中,我将使用完全连接的层,如 NumPy 示例所示。在 Keras 中,这是由函数完成的。Dense()

定义模型的层后,我将编译模型并定义优化器、损失函数和度量。最后,我可以告诉 Keras 拟合 10 个 epoch 的训练数据,就像在其他示例中一样。

model = tf.keras.Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(128, activation='sigmoid'),
    Dense(64, activation='sigmoid'),
    Dense(10)
])
​
model.compile(optimizer='SGD',
              loss=BinaryCrossentropy(),
              metrics=['accuracy'])
​
model.fit(x_train, y_train, epochs=10)

如果要使用验证数据,可以使用 fit 函数的参数传入:

validation_data

model.fit(x_train, y_train, epochs=10, validation_data=(x_val, y_val))

你可能感兴趣的:(pytorch,numpy,人工智能,深度学习)