Recently I was learning the PyTorch framework, so I ran through the Github code following the Mottlepython code

Organize handwritten digital data

# Mnist Handwritten numbers
train_data = torchvision.datasets.MNIST(
    root='./mnist/'.Save or extract the location
    train=True.# this is training data
    transform=torchvision.transforms.ToTensor(),    # Convert pil. Image or numpy.ndarray to
                                                    # torch.FloatTensor (C x H x W), normalize the training interval to [0.0, 1.0]
    download=DOWNLOAD_MNIST,          # Don't download, download, don't need to download again
)

test_data = torchvision.datasets.MNIST(root='./mnist/', train=False)

# Batch training 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)

# To save time, we only tested the first 2000
test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[:2000] /255.   # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
test_y = test_data.test_labels[:2000]
Copy the code

Data is the object data pytorch < torch. Utils. Data. The dataloader. Dataloader object at 0 x000002292cf4c160 > data into training data and test data, test matrix and test labels

Building a CNN network

class CNN(nn.Module) :
    def __init__(self) :
        super(CNN, self).__init__()
        self.conv1 = nn.Sequential(  # input shape (1, 28, 28)
            nn.Conv2d(
                in_channels=1.# input height
                out_channels=16.# n_filters
                kernel_size=5.# filter size
                stride=1.# filter movement/step
                padding=2.# Padding =(kernel_size-1)/2 when the stride=1
            ),      # output shape (16, 28, 28)
            nn.ReLU(),    # activation
            nn.MaxPool2d(kernel_size=2),    Output Shape (16, 14, 14)
        )
        self.conv2 = nn.Sequential(  # input shape (16, 14, 14)
            nn.Conv2d(16.32.5.1.2),  # output shape (32, 14, 14)
            nn.ReLU(),  # activation
            nn.MaxPool2d(2),  # output shape (32, 7, 7)
        )
        self.out = nn.Linear(32 * 7 * 7.10)   # fully connected layer, output 10 classes

    def forward(self, x) :
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.view(x.size(0), -1)   # Flatten multidimensional convolution graph into (batch_size, 32 * 7 * 7)
        output = self.out(x)
        return output
""" CNN ( (conv1): Sequential ( (0): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)) (1): ReLU () (2): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) ) (conv2): Sequential ( (0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)) (1): ReLU () (2): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) ) (out): Linear (1568 -> 10) ) """
Copy the code

You can see the CNN network built like thisIt can be seen from this figure that the 28*28 channel is 1. After convolution with the convolution kernel, the 28*28\ channel is 16. After activation by ReLu activation function and data compression by MaxPool, the 14*14 channel is 16It can be seen from this figure that the 14*14 channel is 16 and the 14*14\ channel is 32 after the convolution of the convolution kernel. After the ReLu activation function is activated and the MaxPool is compressed, the 7*7 channel is 32Finally, expand a vector of 32*7*7 and set 10 vectors of classification

training

optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)   # optimize all cnn parameters
loss_func = nn.CrossEntropyLoss()   # the target label is not one-hotted

# training and testing
for epoch in range(EPOCH):
    for step, (b_x, b_y) in enumerate(train_loader):   Normalize X when iterate train_loader
        output = cnn(b_x)               # cnn output
        loss = loss_func(output, b_y)   # cross entropy loss
        optimizer.zero_grad()           # clear gradients for this training step
        loss.backward()                 # backpropagation, compute gradients
        optimizer.step()                # apply gradients
Copy the code

The parameter Loss.Backward () loss_func is one way to calculate the loss when it is updated backward once for each forward propagation

test

test_output = cnn(test_x[:10])
pred_y = torch.max(test_output, 1) [1].data.numpy().squeeze()
print(pred_y, 'prediction number')
print(test_y[:10].numpy(), 'real number')
Copy the code

Output result:

[7 2 1 0 4 1 4 9 5 9] prediction number
[7 2 1 0 4 1 4 9 5 9] real number
Copy the code

Save the model

torch.save(cnn.state_dict(), 'net_params.pkl')
Copy the code

This saves the parameters of the model training, not the network

Extraction model

cnn.load_state_dict(torch.load('net_params.pkl'))
Copy the code

This is extracting network parameters, so build the network before you use it

The complete code

Save the model

import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision      # Database module
import matplotlib.pyplot as plt

torch.manual_seed(1)    # reproducible

# Hyper Parameters
EPOCH = 1           # How many times to train the whole batch of data? To save time, we only train once
BATCH_SIZE = 50
LR = 0.001          Vector #
DOWNLOAD_MNIST = False  # False if you have already downloaded mnIST data


# Mnist Handwritten numbers
train_data = torchvision.datasets.MNIST(
    root='./mnist/'.Save or extract the location
    train=True.# this is training data
    transform=torchvision.transforms.ToTensor(),    # Convert pil. Image or numpy.ndarray to
                                                    # torch.FloatTensor (C x H x W), normalize the training interval to [0.0, 1.0]
    download=DOWNLOAD_MNIST,          # Don't download, download, don't need to download again
)

test_data = torchvision.datasets.MNIST(root='./mnist/', train=False)

# Batch training 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)

# To save time, we only tested the first 2000
test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[:2000] /255.   # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
test_y = test_data.test_labels[:2000]

class CNN(nn.Module) :
    def __init__(self) :
        super(CNN, self).__init__()
        self.conv1 = nn.Sequential(  # input shape (1, 28, 28)
            nn.Conv2d(
                in_channels=1.# input height
                out_channels=16.# n_filters
                kernel_size=5.# filter size
                stride=1.# filter movement/step
                padding=2.# Padding =(kernel_size-1)/2 when the stride=1
            ),      # output shape (16, 28, 28)
            nn.ReLU(),    # activation
            nn.MaxPool2d(kernel_size=2),    Output Shape (16, 14, 14)
        )
        self.conv2 = nn.Sequential(  # input shape (16, 14, 14)
            nn.Conv2d(16.32.5.1.2),  # output shape (32, 14, 14)
            nn.ReLU(),  # activation
            nn.MaxPool2d(2),  # output shape (32, 7, 7)
        )
        self.out = nn.Linear(32 * 7 * 7.10)   # fully connected layer, output 10 classes

    def forward(self, x) :
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.view(x.size(0), -1)   # Flatten multidimensional convolution graph into (batch_size, 32 * 7 * 7)
        output = self.out(x)
        return output

cnn = CNN()
print(cnn)  # net architecture
""" CNN ( (conv1): Sequential ( (0): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)) (1): ReLU () (2): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) ) (conv2): Sequential ( (0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2)) (1): ReLU () (2): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) ) (out): Linear (1568 -> 10) ) """

optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)   # optimize all cnn parameters
loss_func = nn.CrossEntropyLoss()   # the target label is not one-hotted

# training and testing
for epoch in range(EPOCH):
    for step, (b_x, b_y) in enumerate(train_loader):   Normalize X when iterate train_loader
        output = cnn(b_x)               # cnn output
        loss = loss_func(output, b_y)   # cross entropy loss
        optimizer.zero_grad()           # clear gradients for this training step
        loss.backward()                 # backpropagation, compute gradients
        optimizer.step()                # apply gradients

torch.save(cnn.state_dict(), 'net_params.pkl')

test_output = cnn(test_x[:10])
pred_y = torch.max(test_output, 1) [1].data.numpy().squeeze()
print(pred_y, 'prediction number')
print(test_y[:10].numpy(), 'real number')
Copy the code

Extract the code

import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision      # Database module
import matplotlib.pyplot as plt

torch.manual_seed(1)    # reproducible

# Hyper Parameters
EPOCH = 1           # How many times to train the whole batch of data? To save time, we only train once
BATCH_SIZE = 50
LR = 0.001          Vector #
DOWNLOAD_MNIST = False  # False if you have already downloaded mnIST data


# Mnist Handwritten numbers
train_data = torchvision.datasets.MNIST(
    root='./mnist/'.Save or extract the location
    train=True.# this is training data
    transform=torchvision.transforms.ToTensor(),    # Convert pil. Image or numpy.ndarray to
                                                    # torch.FloatTensor (C x H x W), normalize the training interval to [0.0, 1.0]
    download=DOWNLOAD_MNIST,          # Don't download, download, don't need to download again
)

test_data = torchvision.datasets.MNIST(root='./mnist/', train=False)

# Batch training 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)

# To save time, we only tested the first 2000
test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[:2000] /255.   # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
test_y = test_data.test_labels[:2000]

class CNN(nn.Module) :
    def __init__(self) :
        super(CNN, self).__init__()
        self.conv1 = nn.Sequential(  # input shape (1, 28, 28)
            nn.Conv2d(
                in_channels=1.# input height
                out_channels=16.# n_filters
                kernel_size=5.# filter size
                stride=1.# filter movement/step
                padding=2.# Padding =(kernel_size-1)/2 when the stride=1
            ),      # output shape (16, 28, 28)
            nn.ReLU(),    # activation
            nn.MaxPool2d(kernel_size=2),    Output Shape (16, 14, 14)
        )
        self.conv2 = nn.Sequential(  # input shape (16, 14, 14)
            nn.Conv2d(16.32.5.1.2),  # output shape (32, 14, 14)
            nn.ReLU(),  # activation
            nn.MaxPool2d(2),  # output shape (32, 7, 7)
        )
        self.out = nn.Linear(32 * 7 * 7.10)   # fully connected layer, output 10 classes

    def forward(self, x) :
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.view(x.size(0), -1)   # Flatten multidimensional convolution graph into (batch_size, 32 * 7 * 7)
        output = self.out(x)
        return output

cnn = CNN()

cnn.load_state_dict(torch.load('net_params.pkl'))
test_output = cnn(test_x[:10])
pred_y = torch.max(test_output, 1) [1].data.numpy().squeeze()
print(pred_y, 'prediction number')
print(test_y[:10].numpy(), 'real number')
Copy the code

conclusion

The above understanding is personal understanding, may be missing or mistakes, please comment

Don’t bother python