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