1. install
请看https://wsxk.github.io/AI_env/
2. dir/help
dir用于查看一个库中有哪些组件,help用于查看组件的具体用法
import torch
if __name__ == '__main__':
print(dir(torch))
print((dir(torch.cuda)))
print(help((torch.cuda.is_available)))
当然,官方文档是最好的老师https://pytorch.org/docs/stable/nn.html
3. pytorch教程
3.1 torch.utils.tensorboard
tensorboard主要是画图用的
from torch.utils.tensorboard import SummaryWriter
from PIL import Image
import numpy as np
writer = SummaryWriter("logs")
image_path = "DataSet/hymenoptera_data/train/ants/0013035.jpg"
image_pil = Image.open(image_path)
image_array = np.array(image_pil)
writer.add_image("picture",image_array,1,dataformats="HWC") # tag y轴 x轴 通道(height width channel)
# for i in range(100):
# writer.add_scalar("y=2x",2*i,i) # y=2x曲线 y轴 x轴
writer.close()
运行完后在terminal执行tensorboard --logdir=logs --port=6007
即可在浏览器中查看,--logdir
是你存放的结果的目录,即SummaryWriter填入的目录
3.2 torchvision.transforms
transforms主要是对图片进行处理,即把图片转换成tensor(张量)
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
if __name__ == "__main__":
img_path = "DataSet/hymenoptera_data/train/ants/0013035.jpg"
img = Image.open(img_path)
writer = SummaryWriter("logs")
# tensor
tensor_trans = transforms.ToTensor()
img_tensor = tensor_trans(img)
writer.add_image("test", img_tensor, 0)
# normalize (input-mean)/standard
tensor_normal = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_normal = tensor_normal.forward(img_tensor)
writer.add_image("test", img_normal, 1)
# Resize 改变图片大小
tensor_resize = transforms.Resize((512, 512))
img_resize = tensor_resize(img)
img_resize = tensor_trans(img_resize)
writer.add_image("test", img_resize, 2)
# Compose 组合,流水线步骤
tensor_compose = transforms.Compose([tensor_resize, tensor_trans, tensor_normal])
img_compose = tensor_compose(img)
writer.add_image("test", img_compose, 3)
# RandomCrop: 随机裁剪
tensor_crop = transforms.RandomCrop((100, 100))
tensor_compose2 = transforms.Compose([tensor_trans, tensor_crop])
for i in range(10):
img_crop = tensor_compose2(img)
writer.add_image("Crop", img_crop, i)
writer.close()
3.3 torchvision.datasets
datasets主要是用于加载数据集,并且其自集成了一些数据集,下载时,你需要转换成美国服务器(目前试过cn服务器与jp服务器,没成功下载)
from torchvision.datasets import CIFAR10
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter(log_dir="logs")
dataset_transform = transforms.Compose([transforms.ToTensor()])
train_set = CIFAR10(root="./torchvision_dataset", train=True, transform=dataset_transform, download=True)
test_set = CIFAR10(root="./torchvision_dataset", train=False, transform=dataset_transform, download=True)
# print(train_set)
# print(train_set[0])
# train, target = train_set[0]
# print(train)
# print(train_set.classes[target])
# train.show()
for i in range(10):
img, target = train_set[i]
writer.add_image("train_set", img, i)
3.4 torch.utils.data.DataLoader
DataLoader主要是用于加载数据集,其可以自动分批次,shuffle等
from torchvision.datasets import CIFAR10
from torchvision import transforms
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
transformers = transforms.Compose([transforms.ToTensor()])
test_dataset = CIFAR10("torchvision_dataset", train=False, transform=transformers, download=False)
# 数据集,每次取64个数据,取完数据后重新清洗数据集中的数据,只有一个线程,不舍弃最后几张数据
test_dataloader = DataLoader(dataset=test_dataset, batch_size=64, shuffle=True, num_workers=0, drop_last=False)
writer = SummaryWriter(log_dir="logs")
# img, target = test_dataset[0]
# print(img.shape)
# print(target)
step = 0
for epoch in range(2):
step = 0
for i in test_dataloader:
imgs, targets = i
writer.add_images("test {}".format(epoch), imgs, step)
step += 1
writer.close()
3.5 torch.nn
nn主要是用于搭建神经网络,它相当于一个基本骨架,下面给一个简单的例子
from torch import nn
import torch
# 这是一个简单的神经网络
class Wsxk(nn.Module):
def __init__(self):
super().__init__()
# 前向传播,即输入一个数据,输出一个数据
def forward(self, input):
output = input+1
return output
wsxk = Wsxk()
x = torch.tensor(1.0)
output = wsxk(x)
print(output)
3.5.1 torch.nn.functional
torch.nn.functional是torch.nn中其他模块的底层
import torch
import torch.nn.functional as F
# 输入 5*5 的二维矩阵
input = torch.tensor([[1, 2, 0, 3, 1],
[0, 1, 2, 3, 1],
[1, 2, 1, 0, 0],
[5, 2, 3, 1, 1],
[2, 1, 0, 1, 1]])
# 卷积核,即贴到矩阵中进行数据提取的
kernel = torch.tensor([[1, 2, 1],
[0, 1, 0],
[2, 1, 0]])
# 变形,因为卷积时,需要有 batch_size , channel , height , width 四个维度
input = torch.reshape(input, [1, 1, 5, 5])
kernel = torch.reshape(kernel, [1, 1, 3, 3])
print(input)
print(kernel)
# bias是开始时的偏移,stride是步数,padding是填充的数,即5*5 -》 (5+padding)*(5+padding)
output = F.conv2d(input, kernel, bias=None, stride=1, padding=0)
print(output)
output = F.conv2d(input, kernel, bias=None, stride=1, padding=1)
print(output)
3.5.2 卷积层的使用
直接上代码,卷积层其实是取一个矩阵,从目标矩阵中提取数据的过程,本质上是提取重要特征
import torch
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import torchvision
transformer = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
dataset = torchvision.datasets.CIFAR10(root="torchvision_dataset", train=False, transform=transformer, download=False)
data_loader = DataLoader(dataset=dataset, batch_size=64, shuffle=False, num_workers=0, drop_last=False)
writer = SummaryWriter(log_dir="logs")
class Wsxk(torch.nn.Module):
def __init__(self):
super().__init__()
self.conv1 = torch.nn.Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)
def forward(self, input):
output = self.conv1(input)
return output
test = Wsxk()
step = 0
for data in data_loader:
imgs, targets = data
print(imgs.shape)
print(targets.shape)
output_imgs = test(imgs)
print(output_imgs.shape)
writer.add_images("input", imgs, step)
# 因为输出是6个通道, tensorboard只能画出3通道的,所以需要对输出进行变形,比如 64个batch * 6通道 = 128个batch * 3通道
output_imgs = torch.reshape(output_imgs, [-1, 3, 30, 30])
writer.add_images("output", output_imgs, step)
step += 1
3.5.3 池化层的使用
直接上代码,池化层的作用是减少数据量,以最大池化为例,它只会取矩阵中最大的值
import torch
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import torchvision
# input = torch.tensor([[1, 2, 0, 3, 1],
# [0, 1, 2, 3, 1],
# [1, 2, 1, 0, 0],
# [5, 2, 3, 1, 1],
# [2, 1, 0, 1, 1]], dtype=torch.float32)
# input = torch.reshape(input, [1, 1, 5, 5])
# print(input.shape)
transformer = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
dataset = torchvision.datasets.CIFAR10(root="torchvision_dataset", train=False, transform=transformer, download=False)
dataloader = DataLoader(dataset=dataset, batch_size=64, shuffle=True, num_workers=0, drop_last=False)
writer = SummaryWriter(log_dir="logs")
class Wsxk(torch.nn.Module):
def __init__(self):
super().__init__()
# ceil_mode=True 时,输出大小为 ceil(input_size/stride),即向上取整
self.max_pool = torch.nn.MaxPool2d(kernel_size=3, ceil_mode= True)
def forward(self, input):
output = self.max_pool(input)
return output
wsxk = Wsxk()
step = 0
for data in dataloader:
imgs, targets = data
output_imgs = wsxk(imgs)
writer.add_images("input", imgs, step)
writer.add_images("output", output_imgs, step)
step += 1
writer.close()
3.5.4 非线性激活的使用
非线性激活的作用是,让神经网络加入非线性成分,拟合非线性的数据,比如sigmoid函数,tanh函数,relu函数等,其能增加模型的泛化能力
3.5.4.1 Relu
relu其实是取max(0,x),即取0和x中的最大值
import torch
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import torchvision
transformer = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
dataset = torchvision.datasets.CIFAR10(root="torchvision_dataset", train=False, transform=transformer, download=False)
dataloader = DataLoader(dataset=dataset, batch_size=64, shuffle=False, num_workers=0, drop_last=False)
writer = SummaryWriter(log_dir="logs")
class Wsxk(torch.nn.Module):
def __init__(self):
super().__init__()
self.relu1 = torch.nn.ReLU(inplace=False)
def forward(self, x):
y = self.relu1(x)
return y
wsxk = Wsxk()
step = 0
for data in dataloader:
imgs, targets = data
writer.add_images("origin", imgs, step)
output = wsxk(imgs)
writer.add_images("relu", output, step)
step += 1
3.5.4.2 sigmoid
import torch
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import torchvision
transformer = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
dataset = torchvision.datasets.CIFAR10(root="torchvision_dataset", train=False, transform=transformer, download=False)
dataloader = DataLoader(dataset=dataset, batch_size=64, shuffle=False, num_workers=0, drop_last=False)
writer = SummaryWriter(log_dir="logs")
class Wsxk(torch.nn.Module):
def __init__(self):
super().__init__()
self.relu1 = torch.nn.ReLU(inplace=False)
self.sigmoid = torch.nn.Sigmoid()
def forward(self, x):
y = self.sigmoid(x)
return y
wsxk = Wsxk()
step = 0
for data in dataloader:
imgs, targets = data
writer.add_images("origin_1", imgs, step)
output = wsxk(imgs)
writer.add_images("sigmoid_1", output, step)
step += 1
3.5.5 线性层的使用
线性层的作用是,将输入的数据进行线性变换,即 y = wx + b
import torchvision
import torch
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
dataset = torchvision.datasets.CIFAR10(root="torchvision_dataset", train=False, transform=transform, download=False)
dataloader = DataLoader(dataset, batch_size=64, shuffle=False, num_workers=0, drop_last=True)
writer = SummaryWriter(log_dir="logs")
class Wsxk(torch.nn.Module):
def __init__(self):
super().__init__()
self.linear1 = torch.nn.Linear(196608, 10)
def forward(self, x):
y = self.linear1(x)
return y
wsxk = Wsxk()
for data in dataloader:
imgs, targets = data
# output = torch.reshape(imgs, [1, 1, 1, -1])
output = torch.flatten(imgs)
print(output.shape)
output = wsxk(output)
print(output.shape)
3.5.6 torch.nn.Sequential
torch.nn.Sequential就是把所有的层都放在一个列表中,然后按顺序执行,这样就不用一个一个写了
import torch
from torch.utils.tensorboard import SummaryWriter
class Wsxk(torch.nn.Module):
def __init__(self):
super().__init__()
self.conv1 = torch.nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2, dilation=1)
self.maxpool1 = torch.nn.MaxPool2d(kernel_size=2)
self.conv2 = torch.nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2, dilation=1)
self.maxpool2 = torch.nn.MaxPool2d(kernel_size=2)
self.conv3 = torch.nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2, dilation=1)
self.maxpool3 = torch.nn.MaxPool2d(kernel_size=2)
self.flattern = torch.nn.Flatten()
self.linear1 = torch.nn.Linear(in_features=1024, out_features=64)
self.linear2 = torch.nn.Linear(in_features=64, out_features=10)
self.model1 = torch.nn.Sequential(torch.nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2, dilation=1),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2, dilation=1),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Conv2d(in_channels=32, out_channels=64, kernel_size=5, stride=1, padding=2, dilation=1),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Flatten(),
torch.nn.Linear(in_features=1024, out_features=64),
torch.nn.Linear(in_features=64, out_features=10))
def forward(self, x):
# x = self.conv1(x)
# x = self.maxpool1(x)
# x = self.conv2(x)
# x = self.maxpool2(x)
# x = self.conv3(x)
# x = self.maxpool3(x)
# x = self.flattern(x)
# x = self.linear1(x)
# x = self.linear2(x)
x = self.model1(x)
return x
writer = SummaryWriter(log_dir="logs")
wsxk = Wsxk()
print(wsxk)
input = torch.ones([64, 3, 32, 32])
output = wsxk(input)
print(output.shape)
writer.add_graph(wsxk, input)
writer.close()
4. 总结
到这里,pytorch的基本用法就已经结束了,fly bitch!