- Home
- >
- Software Development
- >
- Train a Deep Learning Model in PyTorch and Export It to ONNX – InApps Technology 2022
Train a Deep Learning Model in PyTorch and Export It to ONNX – InApps Technology is an article under the topic Software Development Many of you are most interested in today !! Today, let’s InApps.net learn Train a Deep Learning Model in PyTorch and Export It to ONNX – InApps Technology in today’s post !
Read more about Train a Deep Learning Model in PyTorch and Export It to ONNX – InApps Technology at Wikipedia
You can find content about Train a Deep Learning Model in PyTorch and Export It to ONNX – InApps Technology from the Wikipedia website
In this tutorial, we will train a Convolutional Neural Network in PyTorch and convert it into an ONNX model. Once we have the model in ONNX format, we can import that into other frameworks such as TensorFlow for either inference and reusing the model through transfer learning.
Setting up the Environment
The only prerequisite for this tutorial is Python 3.x. Make sure it is installed on your machine.
Create a Python virtual environment that will be used for this and the next tutorial.
python3 -m virtualenv pyt2tf
source pyt2tf/bin/activate
Create a file, requirements.txt, with the below content that has the modules needed for the tutorial.
torch torchvision opencv–python tensorflow==1.15 onnx onnxruntime onnx_tf |
Note that we are using TensorFlow 1.x for this tutorial. You may see errors if you install any version of TensorFlow above 1.15.
Install the modules from the above file with pip.
pip install -r requirements.txt
Finally, create a directory to save the model.
mkdir output
Train a CNN with MNIST Dataset
Let’s start by importing the right modules needed for the program.
import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, transforms |
We will then define the neural network with appropriate layers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 20, 5, 1) self.conv2 = nn.Conv2d(20, 50, 5, 1) self.fc1 = nn.Linear(4*4*50, 500) self.fc2 = nn.Linear(500, 10) def forward(self, x): x = F.relu(self.conv1(x)) x = F.max_pool2d(x, 2, 2) x = F.relu(self.conv2(x)) x = F.max_pool2d(x, 2, 2) x = x.view(–1, 4*4*50) x = F.relu(self.fc1(x)) x = self.fc2(x) return F.log_softmax(x, dim=1) |
Create a method to train the PyTorch model.
def train(model, device, train_loader, optimizer, epoch): model.train() for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device), target.to(device) optimizer.zero_grad() output = model(data) loss = F.nll_loss(output, target) 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())) |
The below method will test and evaluate the model:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | def test(model, device, test_loader): model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: data, target = data.to(device), target.to(device) output = model(data) test_loss += F.nll_loss(output, target, reduction=‘sum’).item() # sum up batch loss pred = output.argmax(dim=1, keepdim=True) # get the index of the max log-probability correct += pred.eq(target.view_as(pred)).sum().item() 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))) |
With the network architecture, train, and test methods in place, let’s create the main method to create an instance of the neural network and train it with the MNIST dataset.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | def main(): device = “cpu” train_loader = torch.utils.data.DataLoader( datasets.MNIST(‘../data’, train=True, download=True, transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ])), batch_size=64, shuffle=True) test_loader = torch.utils.data.DataLoader( datasets.MNIST(‘../data’, train=False, transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ])), batch_size=1000, shuffle=True) model = Net().to(device) optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) for epoch in range(0, 10): train(model, device, train_loader, optimizer, epoch) test(model, device, test_loader) torch.save(model.state_dict(),“output/model.pt”)
if __name__ == ‘__main__’: main() |
Within the main method, we download the MNIST dataset, preprocess it, and train the model with 10 epochs.
If you are training the model on a beefy box with a powerful GPU, you can change the device variable and tweak the number of epochs to get better accuracy. But, for the MNIST dataset, you will hit ~98% accuracy with just 10 epochs running on the CPU.Below is the complete code to train the model in PyTorch.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, transforms class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 20, 5, 1) self.conv2 = nn.Conv2d(20, 50, 5, 1) self.fc1 = nn.Linear(4*4*50, 500) self.fc2 = nn.Linear(500, 10) def forward(self, x): x = F.relu(self.conv1(x)) x = F.max_pool2d(x, 2, 2) x = F.relu(self.conv2(x)) x = F.max_pool2d(x, 2, 2) x = x.view(–1, 4*4*50) x = F.relu(self.fc1(x)) x = self.fc2(x) return F.log_softmax(x, dim=1) def train(model, device, train_loader, optimizer, epoch): model.train() for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device), target.to(device) optimizer.zero_grad() output = model(data) loss = F.nll_loss(output, target) 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()))
def test(model, device, test_loader): model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: data, target = data.to(device), target.to(device) output = model(data) test_loss += F.nll_loss(output, target, reduction=‘sum’).item() # sum up batch loss pred = output.argmax(dim=1, keepdim=True) # get the index of the max log-probability correct += pred.eq(target.view_as(pred)).sum().item() 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))) def main(): device = “cpu” train_loader = torch.utils.data.DataLoader( datasets.MNIST(‘../data’, train=True, download=True, transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ])), batch_size=64, shuffle=True) test_loader = torch.utils.data.DataLoader( datasets.MNIST(‘../data’, train=False, transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ])), batch_size=1000, shuffle=True) model = Net().to(device) optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) for epoch in range(0, 10): train(model, device, train_loader, optimizer, epoch) test(model, device, test_loader) torch.save(model.state_dict(),“output/model.pt”)
if __name__ == ‘__main__’: main() |
Once the training is done, you will find the file, model.pt, in the output directory. This is the artifact we need to convert the model into ONNX format.
Exporting PyTorch Model to ONNX Format
PyTorch supports ONNX natively which means we can convert the model without using an additional module.
Let’s load the trained model from the previous step, create an input that matches the shape of the input tensor, and export the model to ONNX.
The neural network class is included in the code to ensure that the model architecture is accessible along with the input tensor shape.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | from torch.autograd import Variable import torch import torch.nn.functional as F import torch.nn as nn class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 20, 5, 1) self.conv2 = nn.Conv2d(20, 50, 5, 1) self.fc1 = nn.Linear(4*4*50, 500) self.fc2 = nn.Linear(500, 10) def forward(self, x): x = F.relu(self.conv1(x)) x = F.max_pool2d(x, 2, 2) x = F.relu(self.conv2(x)) x = F.max_pool2d(x, 2, 2) x = x.view(–1, 4*4*50) x = F.relu(self.fc1(x)) x = self.fc2(x) return F.log_softmax(x, dim=1) trained_model = Net() trained_model.load_state_dict(torch.load(‘output/model.pt’)) dummy_input = Variable(torch.randn(1, 1, 28, 28)) torch.onnx.export(trained_model, dummy_input, “output/model.onnx”) |
Running the above code results in the creation of model.onnx file which contains the ONNX version of the deep learning model originally trained in PyTorch.
You can open this in the Netron tool to explore the layers and the architecture of the neural network.
In the next part of this tutorial, we will import the ONNX model into TensorFlow and use it for inference. Stay tuned.
Janakiram MSV’s Webinar series, “Machine Intelligence and Modern Infrastructure (MI2)” offers informative and insightful sessions covering cutting-edge technologies. Sign up for the upcoming MI2 webinar at http://mi2.live.
Feature image: “Taking in the Wheat Sheaves,” New Old Stock.
At this time, InApps Technology does not allow comments directly on this website. We invite all readers who wish to discuss a story to visit us on Twitter or Facebook. We also welcome your news tips and feedback via email: [email protected].
Source: InApps.net
Let’s create the next big thing together!
Coming together is a beginning. Keeping together is progress. Working together is success.