https://pytorch.org/docs/stable/nn.html

基本骨架

[Module](https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module) Base class for all neural network modules.
  1. import torch
  2. from torch import nn
  3. # 简单的实现y=x+1模型
  4. class Module(nn.Module):
  5. def __init__(self):
  6. super().__init__()
  7. def forward(self, input):
  8. output = input + 1
  9. return output
  10. module = Module()
  11. x = torch.tensor(1.0)
  12. output = module(x)
  13. print(output)

卷积层

卷积操作

卷积操作的目的是提取数据特征。
Conv2d

image.png

image.png

  1. import torch
  2. import torch.nn.functional as F
  3. input = torch.tensor([[1, 2, 0, 3, 1],
  4. [0, 1, 2, 3, 1],
  5. [1, 2, 1, 0, 0],
  6. [5, 2, 3, 1, 1],
  7. [2, 1, 0, 1, 1]])
  8. kernel = torch.tensor([[1, 2, 1],
  9. [0, 1, 0],
  10. [2, 1, 0]])
  11. input = torch.reshape(input, (1, 1, 5, 5))
  12. kernel = torch.reshape(kernel, (1, 1, 3, 3))
  13. print(input.shape)
  14. print(kernel.shape)
  15. output1 = F.conv2d(input, kernel, stride=1)
  16. print(output1)
  17. output2 = F.conv2d(input, kernel, stride=1)
  18. print(output2)

image.png
image.png

  1. output3 = F.conv2d(input, kernel, stride=1, padding=1)
  2. print(output3)

image.png

Conv2d的使用

image.png
*out_channel=2:生成两个卷积核,分别对输入进行卷积操作,然后生成两个输出。

  1. import torch
  2. import torchvision
  3. from torch import nn
  4. from torch.nn import Conv2d
  5. from torch.utils.data import DataLoader
  6. from torch.utils.tensorboard import SummaryWriter
  7. dataset = torchvision.datasets.CIFAR10("../dataset", train=False, transform=torchvision.transforms.ToTensor(),
  8. download=True)
  9. dataloader = DataLoader(dataset, batch_size=64)
  10. class Module(nn.Module):
  11. def __init__(self):
  12. super(Module, self).__init__()
  13. self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)
  14. def forward(self, x):
  15. x = self.conv1(x)
  16. return x
  17. module = Module()
  18. print(module)
  19. writer = SummaryWriter("log")
  20. step = 0
  21. for data in dataloader:
  22. imgs, targets = data
  23. output = module(imgs)
  24. print(imgs.shape)
  25. print(output.shape)
  26. # torch.Size([64, 3, 32, 32])
  27. writer.add_images("input", imgs, step)
  28. # torch.Size([64, 6, 30, 30]) -> [xxx, 3, 30, 30]
  29. output = torch.reshape(output, (-1, 3, 30, 30))
  30. writer.add_images("output", output, step)
  31. step = step + 1
  32. writer.close()

池化层

https://pytorch.org/docs/stable/nn.html#pooling-layers
最大池化目的是保留数据的特征,但使数据量减小,减少运算量。
image.png
image.png

  1. import torch
  2. from torch import nn
  3. from torch.nn import MaxPool2d
  4. input = torch.tensor([[1, 2, 0, 3, 1],
  5. [0, 1, 2, 3, 1],
  6. [1, 2, 1, 0, 0],
  7. [5, 2, 3, 1, 1],
  8. [2, 1, 0, 1, 1]], dtype=torch.float32)
  9. input = torch.reshape(input, (-1, 1, 5, 5))
  10. print(input.shape)
  11. class Module(nn.Module):
  12. def __init__(self):
  13. super(Module, self).__init__()
  14. self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=True)
  15. def forward(self, input):
  16. output = self.maxpool1(input)
  17. return output
  18. module = Module()
  19. output = module(input)
  20. print(output)

image.png

  1. import torch
  2. import torchvision.datasets
  3. from torch import nn
  4. from torch.nn import MaxPool2d
  5. from torch.utils.data import DataLoader
  6. from torch.utils.tensorboard import SummaryWriter
  7. class Module(nn.Module):
  8. def __init__(self):
  9. super(Module, self).__init__()
  10. self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=True)
  11. def forward(self, input):
  12. output = self.maxpool1(input)
  13. return output
  14. module = Module()
  15. dataset = torchvision.datasets.CIFAR10("dataset", train=False, download=True,
  16. transform=torchvision.transforms.ToTensor())
  17. dataloader = DataLoader(dataset, batch_size=64)
  18. writer = SummaryWriter("log")
  19. step = 0
  20. for data in dataloader:
  21. imgs, targets = data
  22. writer.add_images("maxpool_input", imgs, step)
  23. output = module(imgs)
  24. writer.add_images("maxpool_output", output, step)
  25. step = step + 1
  26. writer.close()

image.png

非线性激活

https://pytorch.org/docs/stable/nn.html#non-linear-activations-weighted-sum-nonlinearity

ReLU

image.png
image.png

  1. import torch
  2. from torch import nn
  3. from torch.nn import ReLU
  4. input = torch.tensor([[1, -0.5],
  5. [-1, 3]])
  6. input = torch.reshape(input, (-1, 1, 2, 2))
  7. print(input)
  8. class Module(nn.Module):
  9. def __init__(self):
  10. super(Module, self).__init__()
  11. self.relu1 = ReLU()
  12. def forward(self, input):
  13. output = self.relu1(input)
  14. return output
  15. module = Module()
  16. output = module(input)
  17. print(output)

Sigmoid

  1. import torch
  2. import torchvision
  3. from torch import nn
  4. from torch.nn import ReLU, Sigmoid
  5. from torch.utils.data import DataLoader
  6. from torch.utils.tensorboard import SummaryWriter
  7. class Module(nn.Module):
  8. def __init__(self):
  9. super(Module, self).__init__()
  10. self.relu1 = ReLU()
  11. self.sigmoid1 = Sigmoid()
  12. def forward(self, input):
  13. output = self.sigmoid1(input)
  14. return output
  15. module = Module()
  16. dataset = torchvision.datasets.CIFAR10("dataset", train=False, transform=torchvision.transforms.ToTensor())
  17. dataloader = DataLoader(dataset, batch_size=64)
  18. writer = SummaryWriter("log")
  19. step = 0
  20. for data in dataloader:
  21. imgs, targets = data
  22. writer.add_images("sigmoid_input", img_tensor=imgs, global_step=step)
  23. output = module(imgs)
  24. writer.add_images("sigmoid_output", img_tensor=output, global_step=step)
  25. step = step + 1
  26. writer.close()

image.png

线性层

  • in_features – size of each input sample
  • out_features – size of each output sample
  • bias – If set to False, the layer will not learn an additive bias. Default: True

image.png

  1. import torch
  2. import torchvision
  3. from torch import nn
  4. from torch.nn import Linear
  5. from torch.utils.data import DataLoader
  6. dataset = torchvision.datasets.CIFAR10("dataset", train=False, transform=torchvision.transforms.ToTensor(),
  7. download=True)
  8. dataloader = DataLoader(dataset, batch_size=64, drop_last=True)
  9. class Module(nn.Module):
  10. def __init__(self):
  11. super(Module, self).__init__()
  12. self.linear1 = Linear(196608, 10)
  13. def forward(self, input):
  14. output = self.linear1(input)
  15. return output
  16. module = Module()
  17. for data in dataloader:
  18. imgs, targets = data
  19. print(imgs.shape)
  20. # output = torch.reshape(imgs, (1, 1, 1, -1))
  21. output = torch.flatten(imgs)
  22. print(output.shape)
  23. output = module(output)
  24. print(output.shape)

image.png

Sequential使用例子

image.png

  1. import torch
  2. from torch import nn
  3. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
  4. from torch.utils.tensorboard import SummaryWriter
  5. class Module(nn.Module):
  6. def __init__(self):
  7. super(Module, self).__init__()
  8. self.conv1 = Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2)
  9. self.maxpool1 = MaxPool2d(kernel_size=2)
  10. self.conv2 = Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2)
  11. self.maxpool2 = MaxPool2d(kernel_size=2)
  12. self.conv3 = Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2)
  13. self.maxpool3 = MaxPool2d(kernel_size=2)
  14. self.flatten = Flatten()
  15. self.linear1 = Linear(in_features=1024, out_features=64)
  16. self.linear2 = Linear(in_features=64, out_features=10)
  17. self.module1 = Sequential(
  18. Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
  19. MaxPool2d(kernel_size=2),
  20. Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
  21. MaxPool2d(kernel_size=2),
  22. Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2),
  23. MaxPool2d(kernel_size=2),
  24. Flatten(),
  25. Linear(in_features=1024, out_features=64),
  26. Linear(in_features=64, out_features=10)
  27. )
  28. def forward(self, x):
  29. # x = self.conv1(x)
  30. # x = self.maxpool1(x)
  31. # x = self.conv2(x)
  32. # x = self.maxpool2(x)
  33. # x = self.conv3(x)
  34. # x = self.maxpool3(x)
  35. # x = self.flatten(x)
  36. # x = self.linear1(x)
  37. # x = self.linear2(x)
  38. x = self.module1(x) # 替代上述代码
  39. return x
  40. module = Module()
  41. print(module)
  42. input = torch.ones((64, 3, 32, 32))
  43. output = module(input)
  44. print(output.shape) # 验证网络参数的正确性

image.png

  1. # 可视化模型
  2. writer = SummaryWriter("log")
  3. writer.add_graph(module, input)
  4. writer.close()

image.png

损失函数

image.png

L1loss

image.png
image.png

  1. import torch
  2. from torch.nn import L1Loss
  3. inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
  4. targets = torch.tensor([1, 2, 5], dtype=torch.float32)
  5. inputs = torch.reshape(inputs, (1, 1, 1, 3))
  6. targets = torch.reshape(targets, (1, 1, 1, 3))
  7. loss = L1Loss() # 默认mean
  8. # loss = L1Loss(reduction='sum')
  9. result = loss(inputs, targets)
  10. print(result)

MSELoss

均方差
image.png
image.png

  1. loss_mse = MSELoss()
  2. result_mse = loss_mse(inputs, targets)
  3. print(result_mse)

CrossEntropyLoss

交叉墒(适合分类问题)
image.png
image.png

  1. x = torch.tensor([0.1, 0.2, 0.3])
  2. y = torch.tensor(([1]))
  3. x = torch.reshape(x, (1, 3))
  4. loss_cross = nn.CrossEntropyLoss()
  5. result_cross = loss_cross(x, y)
  6. print(result_cross)

优化Sequential使用例子,加入损失函数

  1. import torchvision.datasets
  2. from torch import nn
  3. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
  4. from torch.utils.data import DataLoader
  5. dataset = torchvision.datasets.CIFAR10("dataset", train=False, transform=torchvision.transforms.ToTensor(),
  6. download=True)
  7. dataloader = DataLoader(dataset, batch_size=1)
  8. class Module(nn.Module):
  9. def __init__(self):
  10. super(Module, self).__init__()
  11. self.module1 = Sequential(
  12. Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
  13. MaxPool2d(kernel_size=2),
  14. Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
  15. MaxPool2d(kernel_size=2),
  16. Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2),
  17. MaxPool2d(kernel_size=2),
  18. Flatten(),
  19. Linear(in_features=1024, out_features=64),
  20. Linear(in_features=64, out_features=10)
  21. )
  22. def forward(self, x):
  23. x = self.module1(x)
  24. return x
  25. module = Module()
  26. loss = nn.CrossEntropyLoss()
  27. for data in dataloader:
  28. imgs, targets = data
  29. outputs = module(imgs)
  30. # print(outputs)
  31. # print(targets)
  32. result_loss = loss(outputs, targets)
  33. result_loss.backward()
  34. print(result_loss)

优化器

https://pytorch.org/docs/stable/optim.html

  1. import torch.optim
  2. import torchvision
  3. from torch import nn
  4. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
  5. from torch.utils.data import DataLoader
  6. dataset = torchvision.datasets.CIFAR10("dataset", train=False, transform=torchvision.transforms.ToTensor(),
  7. download=True)
  8. dataloader = DataLoader(dataset, batch_size=1)
  9. class Module(nn.Module):
  10. def __init__(self):
  11. super(Module, self).__init__()
  12. self.module1 = Sequential(
  13. Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
  14. MaxPool2d(kernel_size=2),
  15. Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
  16. MaxPool2d(kernel_size=2),
  17. Conv2d(in_channels=32, out_channels=64, kernel_size=5, padding=2),
  18. MaxPool2d(kernel_size=2),
  19. Flatten(),
  20. Linear(in_features=1024, out_features=64),
  21. Linear(in_features=64, out_features=10)
  22. )
  23. def forward(self, x):
  24. x = self.module1(x)
  25. return x
  26. module = Module()
  27. loss = nn.CrossEntropyLoss()
  28. optim = torch.optim.SGD(module.parameters(), lr=0.01)
  29. for epoch in range(20):
  30. running_loss = 0.0
  31. for data in dataloader:
  32. imgs, targets = data
  33. outputs = module(imgs)
  34. result_loss = loss(outputs, targets)
  35. optim.zero_grad()
  36. result_loss.backward()
  37. optim.step()
  38. running_loss = running_loss + result_loss
  39. print(running_loss)

image.png