Make writing a habit together! This is the third day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

preface

Pytorch is essentially an enhancement of Numpy, which allows matrices to run on gpus. Pytorch is the first version of PyTorch to run on gpus. Pytorch is the first version of PyTorch to run on gpus. If you have learned linear regression, you will know that we use the loss function to calculate and correct our unknown parameters. If you do it by hand, you need to take the derivative. In Pytorch, you do not take the derivative directly, but by recording the change value. That is, change the value of the current parameter to reverse the modification. So this thing is called a gradient, and it can propagate either forward or backward. After that, pyTorch provides some apis for us, such as self-made data set, common neural network, CNN convolution kernel, etc.

The environment

Note here that my environment is Windows10, N card, pytorch is GPU version, CUDA driver is 10.1 (10.2 is the same)

As you can see, my graphics card is GTX1650. If you don’t have a graphics card, don’t panic. We can use Google LABS. Free, 30 hours a week of use time, you can write the code locally, then change to GPU version, put on the experimental platform to run first, can pass, and then in the full training.

Tensor first

Tensor with numpy

We use the word Tensor a lot in Pytorch and TensorFlow, and that’s actually its basic data structure, and it’s actually the same structure as numpy, it’s actually that structure, but it’s called Tensor now, The difference is that in our deep learning framework this Tensor can do GPU acceleration! You can get a feel for it

So tensor does a lot of things that numpy does except CURD, and numpy does a lot of things that list does, so tensor does the same thing

So Python is a rogue, writing algorithms in Python.

If I wanted to use tuples in Flink, I had to call the API Tuple wrapped in Scale, which Python did with a little bracket.

And of course coming back to the point, we said tensor can also run on the GPU, so let’s take an example.

Now our code is already in our GPU. So what else is the difference? Yes. The gradient

This gradient is what we have in our higher numbers. Pytorch can automatically differentiate, mainly in the neural network needs back propagation. (Well, if you don’t understand neural networks, this is really hard to understand, and I mentioned it in a previous blog post, which should be more clear, also in this column.)

Tensor using

The basic use

This section is not much, nor complicated, and much of it is similar to Numpy. See this article for details

Tensor

I’m going to focus on different details here.

Numpy and tensor conversion

Numpy and tensor translate to each other.

But notice two things: first, only things that are on the CPU can be converted to each other and second, things that use from_numpy directly refer to the same address

If you want to create a new one

b = torch.tensor(a)

Functions with an “_” tail

In PyTorch you’ll see a lot of functions of this type add_() with an “_” at the end

What this function means is that it overwrites the value. For example,

The gradient

Gradient using

That’s one of the things that’s really important about tensor. It’s just a gradient, so let me give you an example.


import torch

a = torch.tensor([[1.1.4.4], [4.4.4.4]],requires_grad=True,dtype=torch.float) Initialize tensor A

b = a**2 # is equivalent to x squared

c = b.sum(a)# sum

print(c)

c.backward() # reverse transfer (equivalent to taking a derivative)
print(a.grad) # result, refers to the gradient from a to C
Copy the code

I can actually explain that. Watch this

So let’s think of a as a function

A (x) = {[X1, X2, 4 * (X3), 4 * (X4)], [...]. }Copy the code

Now we multiply it by the squared and it becomes theta

A ^ 2 (x) = {[X1 ^ 2 X2 ^ 2, 4 * (X3 ^ 2)... }Copy the code

And then we’re going to sum and we’re going to sum again

Sum(A^2) = {[X1^2+X2^2+4*(X3^2) ...] )Copy the code

You take the partial derivative of this function, and then you restore it back to the matrix

And here we start to notice the detail, that is, we are the backpropagation of a –> C, the gradient of A –> C, a is our root node, only A has our gradient. You can actually think of it this way, that B is actually a reference to A, and it’s the change in A that creates the gradient. Or you can look at the gradient of B.

And the reason why we’re doing that is because we’re going to use it later, but also because we’re copying the tensor

Cancel the gradient

Sometimes we don’t want that gradient, because this Tensor might just be a normal variable. You can then use detach() directly to cancel the gradient. A lot of other blogs also say that this is a duplicate function, but I think this is inaccurate, because it just removes the gradient and the memory orientation is the same. However, in particular, for example, b = a.datach (), where B is the address reference of A, there is no gradient when b is used, but there is a gradient when a is used, so it is not replication in a strict sense.

There won’t be when you declare detach(), besides

import torch
import numpy as np

a = torch.tensor([[1.1.4.4], [4.4.4.4]],requires_grad=True,dtype=torch.float)
a.requires_grad_(False) Tensor (data,requires_grad=True)
a.detach()
b = a**2
f = a.detach()
a.detach()
c = b.sum(a)Copy the code

You can just say no, or. Or

Copy the tensor

And the reason I’m going to say gradient first is because it’s one thing to use, and one thing to be careful about when you copy, remember deep copy, assuming we’re going to use gradient.

First we want to clone or make a deep copy of something. Notice, I thought we said that only the leaves get the gradient at the end. We want to copy using clone () or copy_().

So sometimes in order to get the gradient, make the two variables completely independent, so we have to

>>> a = torch.tensor(1.0, requires_grad=True)
>>> b = a.clone().detach()
Copy the code

Data loading and conversion

So we’ve already seen some of the basic concepts of the tensor from Pytorch, and some of the details of how we do gradient and tensor copying, that tensor is very much like Numpy, and in some cases we can even use the tensor to do things. So now let’s talk about some basic uses of PyTorch.

After all, we used PyTorch to build our neural networks for deep learning. As mentioned in the brief introduction of machine learning, deep learning is actually a branch of machine learning, which is a special kind of machine learning. So the previous skLearn and Aruze machine learning steps are roughly divided into five parts, so PyTorch is similar, but the algorithm part is replaced by a more abstract neural network.

So we can roughly divide PyTorch into these parts

So what we’re going to do here is load the data and transform it.

Type conversion

At the beginning we said that the tensor will translate numpy data, but sometimes you need to do text, you need to do pictures, you need to do sounds. So we need a translator (of course you can translate it into Numpy and then translate it into tensor but that’s what you have to do.)

So this is the tool kit

tensorvision

For example, we convert images.

We’ve learned that there’s a lot more to the kit, Totensor() you can translate directly.

This is where we can easily do the transformation.

For example: Compose

Sometimes we need to do multiple transformations, for example we need to change the size of an image and then transform it. So in order to avoid repeating code at this point, we can still do this.


from torchvision import transforms

tensor_to = transforms.ToTensor()
compose = transforms.Compose([tensor_to,])
image = Image.open("train/1/0BGHNV6P.jpg")

img = compose(image)
print(img)


Copy the code

So there are other ways, I won’t say, you pycharm all the way out, and comments. Type conversion is actually very simple, and the corresponding situation is more, I really can not explain.

The data processing

As we all know, machine learning is all about data, data sets. For some of the more well-known network models, or data sets, pyTorch provides automatic download tools.

Native data set

This means that PyTorch automatically downloads the data set through the crawler and wraps it for us. This one also uses TenssorVision for example to download the CIFAR10 dataset

train_set = torchvision.datasets.CIFAR10(root="./dataset",train=True,download=True)
tese_set = torchvision.datasets.CIFAR10(root="./dataset",train=False,download=True)

Copy the code

We’ll just do it, but remember, we’re not going to have a tensor set here, so we’re going to have to do a conversion

from torchvision import transforms

trans = transforms.Compose([transforms.ToTensor()])
dataset = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=trans,download=True)
Copy the code

The data load

And then we load the data using the tools below utils

from torch.utils.data import DataLoader
from torchvision import transforms

trans = transforms.Compose([transforms.ToTensor()])
dataset = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=trans,download=True)

dataloader = DataLoader(dataset,batch_size=64)
Copy the code

Here are some of the DataLoader parameters.

Custom data acquisition

This one is a little more primitive, which is that sometimes we need to load the data set ourselves, for example.This is the data set that we downloaded from the web, and now we’re going to import this into our PyTorch. This folder is the label name, and it’s in this data set. 1 is the picture for $1 and 100 is the picture for $100.

I’m just going to give you the code

from torch.utils.data import Dataset,DataLoader
from torchvision import transforms
import os
from PIL import Image

Retrieve data from Dataset
class MyDataset(Dataset) :

    def __init__(self,RootDir,LabelDir) :
        self.RootDir = RootDir

        self.LabelDir = LabelDir
        self.transform = transforms.ToTensor()
        self.ImagePathDir = os.path.join(self.RootDir,self.LabelDir)
        self.ImageNameItems = os.listdir(self.ImagePathDir)

    def __getitem__(self, item) :
        # item is getting some data element, lazy mode, I'll give it to you if you want to use it
        ItemName = self.ImageNameItems[item]
        ImagePathItem = os.path.join(self.RootDir,self.LabelDir,ItemName)
        ItemGet = self.transform(Image.open(ImagePathItem).resize((500.500)))
        ItemLabel = self.LabelDir
        return ItemGet,ItemLabel

    def __len__(self) :
        return len(self.ImageNameItems)




if __name__ =="__main__":
    RootDir = "train"
    OneYuanLabel = "1"
    HandoneYuanLabel = "100"
    OneYuanData = MyDataset(RootDir,OneYuanLabel)
    HandoneData = MyDataset(RootDir,HandoneYuanLabel)

    DataGet  = OneYuanData+HandoneData


    train_data = DataLoader(dataset=DataGet,batch_size=18,shuffle=True,num_workers=0,drop_last=True)

    for data in train_data:
        imgs,tags = data
        print(imgs.shape)



Copy the code

The point is that we do that inherited Dataset and then implement the __getitem()__ magic method. So it’s really easy to look at the code, get the image name of our path, and then when we call the magic method, we read the image and we translate it directly into tensor, and that’s actually the same thing we did before, but we just translate it, and that’s why we use DataLoader, You can use this to get the data out instead of waiting until you train the model, which is slow.

TensorBoard Visualization toolkit

The target

This is mainly divided into two parts, one is how to intuitively show the effect of our prediction, or error, the other is how to build the network, and understand the neural network again.

The neural network

We gave an example earlier of deriving the workflow of a neural network from linear regression. We’re going to use the loss function to propagate back, so we’re going to use the loss function to do gradient descent, and we’re going to assume that y is equal to x2 plus 2 and we’re going to put in x and y but we’re going to guess 2 and 2 so y is equal to ax plus b of a and b. And then for nonlinear fitting, we have an activation function, so what is the activation function? It’s a nonlinear transformation of our linear fit. (learning neural networks, machine learning, intelligent optimization algorithm, you will find that most of the mathematical modeling can use these things to do, such as the 2021 mathematical modeling of A question I don’t understand, actually not difficult to C questions but too lazy to analysis, B directly, first to A fitting, and then I directly use Fourier fitting, neural network prediction relations (this approach can have, But fitting is absolute, because the data is too little, so want to have a lot of error, the sensitivity analysis to filling holes (however goose I forgot the process), the final optimization direct optimization algorithm, and then there is a problem to also want to evaluate analysis, the final step according to your analysis with experiments, it is to analyze the insufficiency, also is your model is not enough, Those numbers are still needed to correct. Although the practice is very violent, but much better than language modeling, and the analysis in place is able to win the national award).

In fact, the neural network can be divided into three parts in the operation process. The first part is initialization, which is what I said: first guess a few parameters randomly; the second part is to optimize our unknown parameters by reverse transfer (namely gradient descent) through the loss function; the last step is various optimizations

OK, let’s look at a basic neural network model

And that network model we had last time

Here’s what the whole process actually looks likeBut notice that in real neural networks we have “linear” in quotes, like images and so on. If we were just talking about fitting, we could say this, because the input parameters, the dimensions are linear and discrete like this.

Build the linear regression model by hand

Now, it’s time to build a simple linear model using PyTorch, and let’s briefly talk about our APILinearThis is our linear layer, compared to the picture above

OK, now let’s go straight to the code

from torch import nn
from torch.optim import SGD
import torch

class LineBack(nn.Module) :
    def __init__(self) :
        super().__init__()
        # y=ax+b
        self.line = nn.Linear(1.1)

    def forward(self,x) :
        x = self.line(x)
        return x



myline = LineBack()

# Set the learning speed
optim = SGD(myline.parameters(),lr=0.01)

lossfunction = nn.MSELoss()

# Data generation
x = [i for i in range(10)]
y = [(i*2 + 2) for i in range(10)]


# Data conversion
x = torch.tensor(x,dtype=torch.float)
x = x.reshape(-1.1) # becomes 10 rows in a column
y = torch.tensor(y,dtype=torch.float)
y = y.reshape(-1.1)

for epoch in range(1.1001):

    optim.zero_grad()# Clear gradients to prevent impact

    outputs = myline(x)

    loss = lossfunction(outputs,y)

    loss.backward()

    optim.step()

    if(epoch % 50= =0) :print("Training: the total error of {} times is {}".format(epoch,loss.item()))


Copy the code

Then, let’s see what happens

Overall, it’s pretty simple.

Our y is equal to 2 times x plus 2

Nonlinear model building

So we built the linear model, so now let’s look at the nonlinear model.

Here we have to use the activation function because it’s nonlinear. I’m using rule here and rule is a nonlinear variation, and the function looks something like this

Our neural network is essentially a fitting process, so what Fourier fitting we use, for example, is the same thing, but we use a different model. But of course there are a lot of details to pay attention to.

from torch import nn
from torch.optim import SGD
import torch
import torch.nn.functional as F

class LineBack(nn.Module) :
    def __init__(self) :
        super().__init__()
        self.line1 = nn.Linear(1.10)
        self.line2 = nn.Linear(10.1)

    def forward(self,x) :
        x = F.relu(self.line1(x)) # this is the same as nn.relu (), except that this function can be used in forward
        x = self.line2(x)
        return x



myline = LineBack()

optim = SGD(myline.parameters(),lr=0.01)

lossfunction = nn.MSELoss()

# Data generation

x = torch.linspace(-1.1.100) # Generate 100 numbers from -1 to 1
y =  x.pow(2) + 0.2*torch.rand(x.size())
# Data conversion

x = x.reshape(-1.1) # becomes 10 rows in a column
y = y.reshape(-1.1)

for epoch in range(1.1001):

    optim.zero_grad()# Clear gradients to prevent impact

    outputs = myline(x)

    loss = lossfunction(outputs,y)

    loss.backward()

    optim.step()

    if(epoch % 50= =0) :print("Training: the total error of {} times is {}".format(epoch,loss.item()))


Copy the code

TensorBoard intuitive display

We didn’t look very good on the console, so we had to do vago diagrams, we could have just used Matplotlib but in our TensorFlow or PyTorch we have tensorBoard which is a very powerful thing to draw diagrams.

But before you can use it, you need to download it

pip install tensorboard

Or use Conda, depending on your environment, I am directly in the pyTorch environment native environment, I dual system, and previously had the VirtualEnv to create the development environment.

from torch import nn
from torch.optim import SGD
import torch
import torch.nn.functional as F
from torch.utils.tensorboard import SummaryWriter
class LineBack(nn.Module) :
    def __init__(self) :
        super().__init__()
        self.line1 = nn.Linear(1.10)
        self.line2 = nn.Linear(10.1)

    def forward(self,x) :
        x = F.relu(self.line1(x)) # this is the same as nn.relu (), except that this function can be used in forward
        x = self.line2(x)
        return x


wirter = SummaryWriter("logs") # Graph tool,logs save path

myline = LineBack()

optim = SGD(myline.parameters(),lr=0.01)

lossfunction = nn.MSELoss()

# Data generation

x = torch.linspace(-1.1.100) # Generate 100 numbers from -1 to 1
y =  x.pow(2) + 0.2*torch.rand(x.size())
# Data conversion

x = x.reshape(-1.1) # becomes 10 rows in a column
y = y.reshape(-1.1)

for epoch in range(1.1001):

    optim.zero_grad()# Clear gradients to prevent impact

    outputs = myline(x)

    loss = lossfunction(outputs,y)

    loss.backward()

    optim.step()

    if(epoch % 50= =0):
        percent =(1- loss.item())*100
        wirter.add_scalar("Proximity",percent,epoch)
        print("Training: the total error of {} times is {}".format(epoch,loss.item()))


Copy the code

Code as above, then type in our consoleAnd I’m gonna open up my browserLater we will talk about how to use Pytorch to build CNN neural networks, which are already common neural networks. Then we set up a simple 5-layer neural network CIFAR10, the most classical neural network, which also has a relatively small data set. There’s no way neural networks are just feeding data.

CIRAF10 Network setup

Since our CIRAF10 is a CNN model, we need to briefly say what CNN neural network is here.

Remember one thing, one of the things I said before, neural networks are essentially doing fitting. Let’s think of this process as a mathematical modeling process.

CNN + Neural network

CNN is the process of modeling, (CNN convolution, convolution later we explain the concept) for a picture, we human beings can be easily identified, but for the computer, this can make it not to come out, so we have to think of some way to get a computer to recognize the image and computer, the most good at the favorite is matrix, So we try to match an image to some information, for example in our model, which is a classification model, we try to match an image to a tag.

Anything that we humans can visualize and understand like text, pictures, audio can be represented in a matrix on a computer, and the problem becomes linear algebra, discrete mathematics, calculus, high numbers.

So in this process, for this model, CIARF10, we can understand it this way.

Our neural network is an abstract black box, and after training, we get the parameters of each node of the neural network, the threshold value, so that we can make simple predictions.

And then there’s a bunch of optimization problems for neural networks.

So in this process, we need to solve two problems, one is the neural network model, and the other is the processing of this picture. So here we use CNN convolution.

Ok, let’s take a look at our CIARF10 model

convolution

The concept of convolution

In fact, we need to make a simple distinction here, that is, convolution is mathematically defined, and there is a difference between the convolution we actually use, which is of course 㕛, otherwise our neural network would not be called a convolutional neural network. But convolution is a little bit easier to understand, but anyway, they’re really just a way of dealing with data, so don’t get too tangled up.

Convolution linguistic meaning

Yes, before we understand convolution, we have to look at the language, although sometimes things are very abstract. But in terms of convolution, it means something similar in terms of what we actually do.

Convolution: alias: convolution. It just means taking two or more things and turning them into one thing and putting them out, and combining them together, and rolling them up, and the product you can think of here as a kind of operation, which is the product, and we combine these two things by multiplying them. The name convolution comes from mathematics, and it’s actually a mathematical operation. So let’s just define here, convolution is a special kind of operation.

Mathematics performance

We said this is a special operation so the question is, how special is it, you can call it convolution. I can look at the formula for convolution first.

And then let’s look at the picture of the operation of convolution

And just by looking at this picture and the state of the operation, I think you can see why this operation is called a roll, right

So why does it do this, and what are the scenarios?

case

Let me give you a little example

So let’s say that we have an explosion experiment, and we have a device to observe the shock wave from our explosion. First of all, we know that our explosion waves are constantly being generated (we measure them in nanoseconds). And the waves from the explosion also decay over time.

So we now assume that one of the relationships between them is as follows

(Our image-drawing code is assumed as follows).

import matplotlib.pyplot as plt
import matplotlib.pylab as mpl


mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False

fig,axes = plt.subplots(nrows=2, ncols=1, figsize=(8.6), dpi=100)

time = [i for i in range(10)]
boomStree = [(i**5) + 10 for i in time ]
boomLess = [(i-20) * *2 for i in time]

axes[0].set_xticks(time)
axes[0].set_yticks([0.100.50])
axes[1].set_xticks(time)
axes[1].set_yticks([0.100.50])

axes[0].plot(time,boomStree,color='r',linestyle="-.",label="Explosion pressure")

axes[1].plot(time,boomLess,color='b',linestyle="-.",label="Explosion attenuation")

axes[0].legend()
axes[1].legend()
plt.show()

Copy the code

Now I want to know what the number of explosions my device is detecting at any given moment. Let’s say I want to know what I detected at time four.

State influence

The first thing we need to know is that we have an explosion wave, which we have for a period of time, that is, the explosion wave at the first moment, the impact at the fourth moment is still there, but it decreases, and it decreases like this.

In the same way, the effects of the explosion at time 0 are still there

So again let’s analyze our first moment

Since we are looking at the pressure at time four, for the blast wave at time one, it goes through three moments of decay to time four!

Let’s assume that the picture is discrete!

So in order to figure out what happens at time four, we do this

operation

Now our actual graph is continuous, so we’re actually integrating and multiplying. But here’s the problem

So if you look at the formula, why is g of x minus t, then this is actually going to be our operation.

And then you integrate

So this is really our mathematical definition of convolution.

Convolution in the field of image processing

So, finally, convolution in the field of image processing, and as we know from the previous mathematical examples, convolution is essentially the conversion of different inputs into one output, which is the hybridization of our key information.

So the same is true for image processing, the reason why we use convolution in image processing, or why we have convolution operations, what is the similarity between their convolution operations and our mathematical convolution operations?

The similarities

First of all, the similarity is that the integral in mathematics is actually the same thing as summing up, okay? And we’re still using the product. So in our image processing, we also have continuous multiplication and accumulation. So this operation is very similar to convolution in mathematics, which is why we call it convolution here, which is also a special operation.

Image convolution

So how does it convolve in our picture?

And this is actually not too hard, but first we need to know the composition of the picture

So for a computer, things are a little bit many, so we have to compress the matrix, but because the matrix has a special meaning, we can’t just compress it, we have to have a rule.

Convolution kernel/convolution layer

In order to compress the matrix well, without losing the features of the matrix, or highlighting one of the features of the matrix, we designed a special matrix. The eigenmatrix is used like this.

Let’s multiply and add. This is going to be the same thing as our new matrix, and our matrix is going to be smaller once.

This operation is called convolution. So let’s go back to our original model

This layer is called the convolution layer. But when WE say we’re going to simplify the matrix, we’re just going to reduce one circle, which is not enough

So we also have the pooling layer

Pooling layer

The effect is compression (compression that preserves maximum features)

But that’s not enough, matrices are too abstract for computers so we have one last layer

The connection layer

We’re going to take the matrix and turn it into a one-dimensional array and run it through the neural network

The network structures,

Now that we’ve laid the groundwork, we’re ready to play.

Convolution API

Now we come to the first part, which is convolution, and we have a convolution kernel, which is responsible for processing the data, and this convolution kernel is actually the parameter that needs to be optimized, and we can think of all of these convolution operations as parameters that need to be optimized. So let’s talk about the apis that we have here.

Conv2d convolution function

This is our convolution kernel.

There are a few parameters to note here. Check out our official website first.

These are the parameters

These parameters are very important when we build the CNN neural network. Let’s focus on a few parameters

padding

This parameter, we said that in front of the convolution after our image will become smaller, so sometimes, we can fill the original image, make it bigger, so the image size of the output after the convolution don’t send certain change, that is to say our padding to fill in the original image, padding_mode refers to, what are you going to fill in, For example, fill 0

Calculates the size of the output

A formula is provided to calculate the size of the output image.

We can calculate it. I’ll give you an example when we’re building the network.

MaxPool2d pooling

this

That’s the thing

Flatten a draw

It’s just amortizing our data.

The network structures,

Let’s go straight to the code now

import torchvision
from torch import nn
import torch
from torch.utils.data import DataLoader
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential, CrossEntropyLoss
from torchvision import transforms

trans = transforms.Compose([transforms.ToTensor()])
dataset = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=trans,download=True)

dataloader = DataLoader(dataset,batch_size=64)
class MyModule(nn.Module) :

    def __init__(self) :
        super().__init__()

        self.model = Sequential(
            Conv2d(3.32, kernel_size=(5.5), padding=2),
            MaxPool2d(2),
            Conv2d(32.32, (5.5), padding=2),
            MaxPool2d(2),
            Conv2d(32.64, (5.5), padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024.64),
            Linear(64.10))def forward(self,x) :
        x = self.model(x)

        return x


if __name__ == '__main__':
    mymodule = MyModule()
    loss = torch.nn.CrossEntropyLoss()
    optim = torch.optim.SGD(mymodule.parameters(),lr=0.01)

    for data in dataloader:
        imgs,targets = data
        outputs = mymodule(imgs)
        result_loss = loss(outputs,targets)
        optim.zero_grad()
        result_loss.backward()
        optim.step()
Copy the code

This is the CIFAR10 model code that we are going to build. Because the data is too large, SO I also took the training set first.

Compute the convolution kernel size

Now let’s pay attention

So we’re going to use the previous formula to calculate the parameters

Enter (32 + 2PADDing-1 (5-1) -1) /1) +1= 32-4 + 2padding

So the padding is equal to 2 and the rest of the parameters we’ll just use the default values, you don’t have to use them as long as you can guarantee your output.

So what we end up with is this model.

class MyModule(nn.Module) :

    def __init__(self) :
        super().__init__()

        self.model = Sequential(
            Conv2d(3.32, kernel_size=(5.5), padding=2),
            MaxPool2d(2),
            Conv2d(32.32, (5.5), padding=2),
            MaxPool2d(2),
            Conv2d(32.64, (5.5), padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024.64),
            Linear(64.10))def forward(self,x) :
        x = self.model(x)

        return x
Copy the code

Network training and model loading

Finally, we have arrived at the next few key steps

Model training complete steps

Our training set usually has two parts, one for you to train and one for verification. Of course, your own data sets are similar. In short, there are two parts to it, and the part of the verification should not enter the training network.

The complete code is as follows: commented


import torchvision
from torch import nn
import torch
from torch.utils.data import DataLoader
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential, CrossEntropyLoss
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter

trans = transforms.Compose([transforms.ToTensor()])
Get the training set
dataset = torchvision.datasets.CIFAR10(root="./dataset",train=True,transform=trans,download=True)
dataset2 = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=trans,download=True)
train_dataloader = DataLoader(dataset,batch_size=64)
test_dataloader = DataLoader(dataset2,batch_size=64)

test_len = len(dataset2)

class MyModule(nn.Module) :

    def __init__(self) :
        super().__init__()

        self.model = Sequential(
            Conv2d(3.32, kernel_size=(5.5), padding=2),
            MaxPool2d(2),
            Conv2d(32.32, (5.5), padding=2),
            MaxPool2d(2),
            Conv2d(32.64, (5.5), padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024.64),
            Linear(64.10))def forward(self,x) :
        x = self.model(x)

        return x


if __name__ == '__main__':
    writer = SummaryWriter()
    mymodule = MyModule()
    loss = torch.nn.CrossEntropyLoss()
    learnstep = 0.01
    optim = torch.optim.SGD(mymodule.parameters(),lr=learnstep)
    epoch = 1000

    train_step = 0 # Number of sessions per round
    mymodule.train()# The model is in training state
    for i in range(epoch):
        print("Round {} training".format(i+1))
        train_step = 0
        for data in train_dataloader:
            imgs,targets = data
            outputs = mymodule(imgs)
            result_loss = loss(outputs,targets)
            optim.zero_grad()
            result_loss.backward()
            optim.step()

            train_step+=1
            if(train_step%100= =0) :print("Loss for the {} training of the {} round :{}".format((i+1),train_step,result_loss.item()))

        # effect on the test set
        mymodule.eval(a)Verify status
        test_total_loss = 0
        right_number = 0
        with torch.no_grad(): # The verification part is not training so don't put in gradients
            for test_data  in test_dataloader:
                imgs,label = test_data
                outputs_ = mymodule(imgs)

                test_result_loss=loss(outputs_,label)

                right_number += (outputs_.argmax(1)==label).sum(a)# writer.add_Scalar (" Accuracy on the test set ",(right_Number /test_len),(I +1))
            print("The accuracy of the training round {} on the test set is {}".format((i+1),(right_number/test_len)))

        if((i+1) %500= =0) :# Save the model
            torch.save(mymodule.state_dict(),"mymodule_{}.pth".format((i+1)))
Copy the code

Model saving and loading

Saving the model is simple, and there are two main methods.

One is to save the model and the trained data directly.

torch.save(yourmodlue,path)
modlue = torch.load(path)
Copy the code

The second way is to save the data, you just load the data into your model

torch.save(yourmodlue.state_dict(),path)
modlue.load_state_dict(torch.load(path))
Copy the code

GPU training

First of all, what can be placed on the GPU — models, data, loss functions — as long as you have a little bit of it, and cudA () at the end of it. You need to decide if you can run on the GPU, i.e. your local environment.

torch.cuda.is_available()

So the code changed to this



import torchvision
from torch import nn
import torch
from torch.utils.data import DataLoader
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential, CrossEntropyLoss
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter

trans = transforms.Compose([transforms.ToTensor()])
Get the training set
dataset = torchvision.datasets.CIFAR10(root="./dataset",train=True,transform=trans,download=True)
dataset2 = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=trans,download=True)
train_dataloader = DataLoader(dataset,batch_size=64)
test_dataloader = DataLoader(dataset2,batch_size=64)

test_len = len(dataset2)
if(torch.cuda.is_available()):
    device = torch.device("cuda")
    print("Using GPU training: {}".format(torch.cuda.get_device_name()))
else:
    device = torch.device("cpu")
    print("Training with CPU")
class MyModule(nn.Module) :

    def __init__(self) :
        super().__init__()

        self.model = Sequential(
            Conv2d(3.32, kernel_size=(5.5), padding=2),
            MaxPool2d(2),
            Conv2d(32.32, (5.5), padding=2),
            MaxPool2d(2),
            Conv2d(32.64, (5.5), padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024.64),
            Linear(64.10))def forward(self,x) :
        x = self.model(x)

        return x


if __name__ == '__main__':
    writer = SummaryWriter()
    mymodule = MyModule()
    mymodule = mymodule.to(device) # Model transfer GPU
    loss = torch.nn.CrossEntropyLoss()
    learnstep = 0.01
    optim = torch.optim.SGD(mymodule.parameters(),lr=learnstep)
    epoch = 1000

    train_step = 0 # Number of sessions per round
    mymodule.train()# The model is in training state
    for i in range(epoch):
        print("Round {} training".format(i+1))
        train_step = 0
        for data in train_dataloader:
            imgs,targets = data

            imgs = imgs.to(device) Put the IMG tensor in the GPU
            targets =targets.to(device)

            outputs = mymodule(imgs)
            result_loss = loss(outputs,targets)
            optim.zero_grad()
            result_loss.backward()
            optim.step()

            train_step+=1
            if(train_step%100= =0) :print("Loss for the {} training of the {} round :{}".format((i+1),train_step,result_loss.item()))

        # effect on the test set
        mymodule.eval(a)Verify status
        test_total_loss = 0
        right_number = 0
        with torch.no_grad(): # The verification part is not training so don't put in gradients
            for test_data  in test_dataloader:
                imgs,label = test_data

                imgs = imgs.to(device)
                label = label.to(device)

                outputs_ = mymodule(imgs)

                test_result_loss=loss(outputs_,label)

                right_number += (outputs_.argmax(1)==label).sum(a)# writer.add_Scalar (" Accuracy on the test set ",(right_Number /test_len),(I +1))
            print("The accuracy of the training round {} on the test set is {}".format((i+1),(right_number/test_len)))

        if((i+1) %500= =0) :# Save the model
            torch.save(mymodule.state_dict(),"mymodule_{}.pth".format((i+1)))
Copy the code

And then we’re going to do a simple test, which is run

At that speed, no. We need to train for years.

Use the Free remote platform

I don’t think my computer can handle that.

Let’s use Google’s platform directly. It’s free as long as you have a Google account.

And it is foreign, some data sets download fast

Then sleep it off.

Model USES

This is actually the same thing we use when we check, we need to call our model and put your image in.

This is the subscript animal that we’re dealing with.


from PIL import Image
import torchvision
import torch
from MyModule import MyModule
path_img = "dog.jpg"

image = Image.open(path_img)

compose = torchvision.transforms.Compose([
    torchvision.transforms.Resize((32.32)),
    torchvision.transforms.ToTensor()
])



# See what kind of saved model you are
module_path = "mymodule_500.pth"
image = compose(image)
module = MyModule()
module.load_state_dict(torch.load("mymodule_500.pth"))



image = torch.reshape(image,(1.3.32.32))

module.eval(a)with torch.no_grad():
    out = module(image)

    print(out.argmax(1))
Copy the code

Then we can see the output

Then I also downloaded a picture here

But it’s worth noting that the model I trained 500 times here only got around 62% accuracy

Then I can switch data sets later and tweak the neural network slightly for different purposes.

In addition, we also have many neural network models, such as VGG, which has too many layers and is officially packaged in TorchVision.

The deployment of

The last step is to deploy our model, which I will do directly inside Django.

The environment

I’m using Django3.2 with a test project I use a lot (it’s already there) and then I’m writing it in HTML, CSS and js.

The project structure

I created this directly from the original test project. That’s what it looks like. All of our code is in this APP. And, of course, there’s a background imageNothing else, basically.

The front end

Now go to our front end code and this is just two pages

Image upload

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Image recognition Demo</title>
</head>

<style>
    .center {

        margin: 0 auto;
        width: 80%;
        border: 5px solid #18a0ec;
        transition: all 0.9 s;
        border-radius: 10px;
        background-image:url("/static/media/torchbackground.jpg");background-repeat: no-repeat;
        background-size: cover;
        -webkit-background-size: cover;
        -o-background-size: cover;
        background-position: center 0;


    }
    .centerin{
        width: 500px;
        height: 500px;
        margin: 0 auto;
        padding: 10%;

        border-radius: 10px;
    }

        button {
        margin-left: 80%;
        width: 20%;
        height: 35px;
        border-width: 0px;
        border-radius: 3px;
        background: #1E90FF;
        cursor: pointer;
        outline: none;
        font-family: Microsoft YaHei;
        color: white;
        font-size: 17px;
    }
    #info{
        width: 500px;
        /* This is centered */
        margin: 0 auto;
        background: #9becff;
        border-radius: 10px;
    }
    #info:hover {
      box-shadow: 0px 15px 30px rgba(0.0.0.0.4);
      margin-top: 5px;
}

    .tips{

      text-align:center;
      color:#fff;
      text-shadow: #1e88e1 5px 5px 5px;
}
</style>

<body>
<div class="center">
    <div class="centerin">

        <div id="info">
              <p class="tips" style="margin: 0 auto;">This Demo is a 10 classification model based on CIARF10 model and official data set. It can recognize {aircraft, bicycle, bird, cat, dog, deer, frog, pony, boat, truck} @huterox</p>
        </div>
        <br>
        <br>
        <form action="{% url 'torch:hello' %}" enctype="multipart/form-data" method="POST">
            <div style="background-color:#9becff; width: 100%; height: 300px;">
                <img src="" id="showimg">
            </div>
            <br>

            <input id="file" onchange="changepic(this)" type="file" name="pic"
                   style="height: 70px; display:inline-block; width: 50%;">
            <button style="height: 40px; position: relative; margin-left: 29%;">determine</button>
        </form>

    </div>

</div>
</body>
<script>
    function changepic() {
        var reads = new FileReader();
        f = document.getElementById('file').files[0];
        reads.readAsDataURL(f);
        reads.onload = function (e) {
            var showing = document.getElementById('showimg');
            var userpic = document.getElementById('userpic');
            showing.src = this.result;
            showing.style.height = "300px";
            showing.style.width = "100%";
        };
    }
</script>

</html>
Copy the code

The results showed

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Answear</title>
</head>
<style>

.show {
  margin: 100px auto;
  width: 80%;

  border: 5px solid #18a0ec;
  transition: all 0.9 s;
  border-radius: 10px;


}

.show:hover {
  box-shadow: 0px 15px 30px rgba(0.0.0.0.4);
  margin-top: 90px;
}
.tips{

  text-align:center;
  font: 50px helvetica,arial,sans-serif;
  color:#fff;
  text-shadow: #1e88e1 5px 5px 5px;
}




</style>
<body>
 <div >
    <div class="show">
      <p class="tips">
        {{ answear }}
      </p>
    </div>
  </div>
</body>
</html>
Copy the code

The back-end

This also has no what to say, you configure the environment, can do

Deployment model

So here we define our model, and we call our model.

# coding=utf-8

from torch import nn

from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential


class MyModule(nn.Module) :

    def __init__(self) :
        super().__init__()

        self.model = Sequential(
            Conv2d(3.32, kernel_size=(5.5), padding=2),
            MaxPool2d(2),
            Conv2d(32.32, (5.5), padding=2),
            MaxPool2d(2),
            Conv2d(32.64, (5.5), padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024.64),
            Linear(64.10))def forward(self,x) :
        x = self.model(x)

        return x


Copy the code

Model called

# coding=utf-8
from PIL import Image
import torchvision
import torch
from PytorchDemo.ModuleTorch.MyModle import MyModule

def recognize_img(Image) :

    compose = torchvision.transforms.Compose([
        torchvision.transforms.Resize((32.32)),
        torchvision.transforms.ToTensor()
    ])


    module_path = "PytorchDemo/ModuleTorch/modulestate/mymodule_500.pth"
    image = compose(Image)
    module = MyModule()
    module.load_state_dict(torch.load(module_path))

    image = torch.reshape(image, (1.3.32.32))

    module.eval(a)with torch.no_grad():
        out = module(image)

        return out.argmax(1).item()

Copy the code

routing

The main road by

Shunt by

Business code

There’s an explanation for that

#coding = utf-8
from django.http import HttpResponse
from django.shortcuts import render
import asyncio

# Create your views here.
from django.views.decorators.clickjacking import xframe_options_sameorigin
from django.views.decorators.csrf import csrf_exempt
from PIL import Image
from PytorchDemo.ModuleTorch.CIARF10 import recognize_img

async def UseCIARF10(request,image) :
    # {plane, bike, bird, cat, dog, deer, frog, pony, boat, truck}
    # Yes, I changed this view from the old demo, and later I remembered that this is a computancy-intensive task, asynchronous synchronization is no different ~
    Things = {0:"Plane".1:"Bicycle".2:"The bird".3:"Cat".4:"The deer".5:"The dog".6:"Frog".7:"Pony".8:"Ship".9:"Truck"
              }

    out = recognize_img(image)

    out = Things.get(out,"No Answear")
    print(out)
    Data = {
        "answear": "Answear maybe:{}".format(out)
    }
    return Data



@csrf_exempt
@xframe_options_sameorigin
def Hello(request) :
    if(request.method=="GET") :return render(request,"Show.html")

    elif(request.method=="POST"):
        image = request.FILES.get('pic')
        if(image):
            image = Image.open(image)


            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop) Set the event loop

            try:
                res = loop.run_until_complete(UseCIARF10(request,image))
            finally:
                loop.close()

            return render(request, "Answear.html",context=res)

        else:
            return render(request, "Show.html")


    return HttpResponse("NO Power")
Copy the code

It is worth mentioning that django3. x supports async, but it is generally synchronous for a view. Sync View optimizes the system, and the current view can be switched when IO operations occur, providing computing power for other users. After the operation, a return returns data.

conclusion

At this point, you should be able to go to GitHub and have fun hooking up