文章目录

  • 1 python ;两大法宝函数
  • 2 加载数据
  • 3 TensorBoard 的使用
  • 4 transforms的使用
  • 5 torchvision中的数据集使用
  • 6 dataloader的使用
  • 7 卷积操作
  • 8 卷积层
  • 9 最大池化
  • 10 非线性激活
  • 11 线性层
  • 12 Sequential的使用
  • 13 损失函数
  • 14 优化器
  • 15 现有网络模型的使用及修改
  • 16 网络模型的保存及读取
  • 17 完整的模型训练套路
  • 18 利用gpu训练
  • 19 完整的模型验证套路


1 python ;两大法宝函数

dir(): 打开,看见

helo(): 说明书

使用python控制台运行

import torch
tourch.cuda.is_available()
dir(torch)
dir(torch.cuda)
dir(torch.cuda.is_available)
help(torch.cuda.is_available())

命令行输入:jupyter notebook打开jupyter

2 加载数据

import os.path

from torch.utils.data import Dataset
from PIL import Image


class MyData(Dataset):
    def __init__(self, root_dir, label_dir):
        self.root_dir = root_dir
        self.label_dir = label_dir
        self.path = os.path.join(self.root_dir, self.label_dir)   //路径拼接
        //图像路径数组
        self.img_path = os.listdir(self.path)

    def __getitem__(self, idx):
        img_name = self.img_path[idx]
        img_item_path = os.path.join(self.root_dir, self.label_dir, img_name)
        img = Image.open(img_item_path)
        label = self.label_dir
        return img, label

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


root_dir = 'hymenoptera_data/train'
ants_label_dir = 'ants'
bees_label_dir = 'bees'

bees_dataset= MyData(root_dir,bees_label_dir)
ants_dataset = MyData(root_dir, ants_label_dir)
train_dataset=ants_dataset+bees_dataset

3 TensorBoard 的使用

from torch.utils.tensorboard import SummaryWriter

writer=SummaryWriter("logs")

for i in range(100):
    writer.add_scalar("y=x", i, i)

writer.close()

使用查看图像

tensorboard  --logdir=logs  # --port=6007 更换端口号

显示图像

from torch.utils.tensorboard import SummaryWriter
import  numpy as np
from PIL import  Image

writer=SummaryWriter("logs")
image_path= "hymenoptera_data/train/bees/85112639_6e860b0469.jpg"
# 打开图像,转换类型
img_PIL=Image.open(image_path)
img_array=np.array(img_PIL)

print(type(img_array))
# 图像大小
print(img_array.shape)
# 默认格式是CHW ,转换格式   1 可以显示多少图片
writer.add_image("test",img_array,1,dataformats="HWC")

writer.close()

4 transforms的使用

from PIL import Image
from torch.utils.tensorboard import SummaryWriter

from torchvision import transforms

img_path="hymenoptera_data/train/ants/175998972.jpg"
img=Image.open(img_path)

writer=SummaryWriter("logs")

print(img)
# 1. 如何使用transforms
# 创建对象,加载图片
tensor_trans= transforms.ToTensor()
tensor_img=tensor_trans(img)

# tensorboard 加载
writer.add_image("Tensor_img",tensor_img)

print(tensor_img)
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

writer = SummaryWriter('logs')
img = Image.open("hymenoptera_data/train/ants/kurokusa.jpg")

print(img)

# ToTensor  图像加载
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("ToTensor", img_tensor)

# Normalize  归一化
print((img_tensor[0][0][0]))
trans_norm = transforms.Normalize([0.5, 5, 0.5], [9, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
print((img_tensor[0][0][0]))
writer.add_image("Normalize", img_norm, 2)

# Resize
print(img.size)
transforms_resize = transforms.Resize((512, 512))
resize_img = transforms_resize(img)
resize_img = trans_totensor(resize_img)
writer.add_image("Resize", resize_img, 0)
print(resize_img)

# Compose
trans_resize2 = transforms.Resize(512)
transforms_compose = transforms.Compose([trans_resize2, trans_totensor])
resize_img2 = transforms_compose(img)
writer.add_image("Resize", resize_img2, 1)

# RandomCrop
trans_random = transforms.RandomCrop(500, 1000)
trans_compose2 = transforms.Compose([trans_random, trans_totensor])
for i in range(10):
    img_crop = trans_compose2(img)
    writer.add_image("RandomCrop", img_crop, i)

writer.close()

5 torchvision中的数据集使用

import torchvision
from tensorboardX import SummaryWriter

# 数据集转化成ToTensor
dataset_transform=torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])

# S = torchvision.datasets.SBDataset("./dataset", "train", "boundaries", True)

# 添加transform=dataset_transform
train_set = torchvision.datasets.CIFAR10(root="./dataset",train=True,transform=dataset_transform,download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=dataset_transform,download=True)

# print(test_set[0])
# print(test_set.classes)
#
# img, target=test_set[0]
# print(img)
# print(target)
# print(test_set.classes[target])
# img.show()
# print(test_set[0])

writer=SummaryWriter("p10")
# 图片加载
for i in range(10):
    img,target=test_set[i]
    writer.add_image("test_set",img,i)

writer.close()

6 dataloader的使用

import torchvision
from tensorboardX import SummaryWriter
from torch.utils.data import DataLoader

test_data=torchvision.datasets.CIFAR10("dataset",False,torchvision.transforms.ToTensor())

test_loader=DataLoader(dataset=test_data,batch_size=4,shuffle=False,num_workers=0,drop_last=True)

# 测试数据集的图片
img,target=test_data[0]
print(img.shape)
print(target)

writer=SummaryWriter("dataloader")
for epoch in range(2):
    step=0
    for data in test_loader:
        imgs, target=data
        writer.add_images("Epoch:{}".format(epoch),imgs,step)
        step=step+1

writer.close()

7 卷积操作

import torch
import torch.nn.functional as F

input =torch.tensor([[1,2,0,3,1],
                     [0,1,2,3,2],
                     [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]])
                     
# 卷积就是使用3X3 矩阵剩 5X5 矩阵  3X3 不断在5X5的上面移动最后得出3x3的矩阵
# 1x1 2x2 1x0 0x0 1x1 2x0 2x5 1x2 3x1 = 21  3X3左移再剩

input =torch.reshape(input,(1,1,5,5))  # batchsize  channel  
kernel=torch.reshape(kernel,(1,1,3,3))

print(input.shape)
print(kernel.shape)

output=F.conv2d(input,kernel,stride=1,padding=1)
# stride 步长     padding=1 上下左右都填充的一行 
print(output)

8 卷积层

dilation 就是空洞卷积 ,隔一个元素再乘

dataset = torchvision.datasets.CIFAR10("../data", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=64)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)
# 多少个卷积核就有多少个输入通道
    def forward(self, x):
        x = self.conv1(x)
        return x

tudui = Tudui()

writer = SummaryWriter("../logs")

step = 0
for data in dataloader:
    imgs, targets = data
    output = tudui(imgs)
    print(imgs.shape)
    print(output.shape)
    # torch.Size([64, 3, 32, 32])
    writer.add_images("input", imgs, step)
    # 6 通道的卷积核不能展示图片 需要用rehsape 转换
    # torch.Size([64, 6, 30, 30])  -> [xxx, 3, 30, 30]

    output = torch.reshape(output, (-1, 3, 30, 30))  #-1代替size
    writer.add_images("output", output, step)

    step = step + 1

9 最大池化

最大池化操作, 3X3 的池化核就是在3x3里选择最大的元素

目的是保留输入特征,数据量减少

dataset = torchvision.datasets.CIFAR10("../data", train=False, download=True,
                                       transform=torchvision.transforms.ToTensor())

dataloader = DataLoader(dataset, batch_size=64)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=False)  // 不足池化数,是否保留池化

    def forward(self, input):
        output = self.maxpool1(input)
        return output

tudui = Tudui()

writer = SummaryWriter("../logs_maxpool")
step = 0

for data in dataloader:
    imgs, targets = data
    writer.add_images("input", imgs, step)
    output = tudui(imgs)
    writer.add_images("output", output, step)
    step = step + 1

writer.close()

10 非线性激活

input = torch.tensor([[1, -11],
                      [-3, 99]])

input = torch.reshape(input, (-1, 1, 2, 2))
print(input)
print(input.shape)

relu = ReLU()
print(relu(input))

dataset = torchvision.datasets.CIFAR10("dataset", False, torchvision.transforms.ToTensor()
                                       , download=True)
dataloader = DataLoader(dataset, batch_size=64)


class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.relu1 = ReLU()
        self.sigmoid1=Sigmoid()


    def forward(self, input):
        output = self.sigmoid1(input)
        return output


tudui = Tudui()

writer = SummaryWriter("logs_relu")
step = 0

for data in dataloader:
    imgs, targets = data
    writer.add_images("input", imgs, global_step=step)
    output = tudui(imgs)
    writer.add_images("output", output, step)
    step += 1

writer.close()

11 线性层

dataset = torchvision.datasets.CIFAR10("../data", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)

dataloader = DataLoader(dataset, batch_size=64)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.linear1 = Linear(196608, 10)

    def forward(self, input):
        output = self.linear1(input)
        return output

tudui = Tudui()

for data in dataloader:
    imgs, targets = data
    print(imgs.shape)
    output = torch.flatten(imgs)
    print(output.shape)
    output = tudui(output)
    print(output.shape)

12 Sequential的使用

检查torch是否有gpu torch怎么检查_深度学习

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1=Sequential(
            Conv2d(3,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,64,5,padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024,64),
            Linear(64,10)
        )

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

tudui = Tudui()
print(tudui)
input=torch.ones((64,3,32,32))
output=tudui(input)
print(output)

writer=SummaryWriter("log_seq")
# 网络结构图可视化
writer.add_graph(tudui,input)
writer.close()

13 损失函数

L1Loss 是 (1-1 + 2-2 + 5-3 )/ 3=0.667

MSE= (0+0+2^2)=1.333

CrossEntropyLoss

检查torch是否有gpu torch怎么检查_python_02

inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
targets = torch.tensor([1, 2, 5], dtype=torch.float32)

inputs = torch.reshape(inputs, (1, 1, 1, 3))
targets = torch.reshape(targets, (1, 1, 1, 3))
#差的和
loss = L1Loss(reduction='sum')
result = loss(inputs, targets)
#方差的和/个数
loss_mse = nn.MSELoss()
result_mse = loss_mse(inputs, targets)

print(result)
print(result_mse)


x = torch.tensor([0.1, 0.2, 0.3])
y = torch.tensor([1])
x = torch.reshape(x, (1, 3))
loss_cross = nn.CrossEntropyLoss()
result_cross = loss_cross(x, y)
print(result_cross)
dataset=torchvision.datasets.CIFAR10("dataset",False,torchvision.transforms.ToTensor(),
                                     download=True)
dataloader=DataLoader(dataset,batch_size=1)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1=Sequential(
            Conv2d(3,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,64,5,padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024,64),
            Linear(64,10)
        )

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

loss=nn.CrossEntropyLoss()
tudui = Tudui()
for data in dataloader:
    imgs,targets=data
    output=tudui(imgs)
    print(output)
    print(targets)
    result_loss=loss(output,targets)
    result_loss.backward()
    print(result_loss)

14 优化器

dataset=torchvision.datasets.CIFAR10("dataset",False,torchvision.transforms.ToTensor(),
                                     download=True)
dataloader=DataLoader(dataset,batch_size=1)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1=Sequential(
            Conv2d(3,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,32,5,padding=2),
            MaxPool2d(2),
            Conv2d(32,64,5,padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024,64),
            Linear(64,10)
        )

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

loss=nn.CrossEntropyLoss()
tudui=Tudui()
optim=torch.optim.SGD(tudui.parameters(),lr=0.01)

for epoch in range(20):
    running_loss=0.0
    for data in dataloader:
        imgs,targets=data
        outputs=tudui(imgs)
        result_loss=loss(outputs,targets)

        optim.zero_grad()
        result_loss.backward()
        optim.step()
        # print(result)
        running_loss=running_loss+result_loss
    print(running_loss)

15 现有网络模型的使用及修改

vgg16_false = torchvision.models.vgg16(pretrained=False)
vgg16_true = torchvision.models.vgg16(pretrained=True)

print(vgg16_true)

train_data = torchvision.datasets.CIFAR10('../data', train=True, transform=torchvision.transforms.ToTensor(),
                                          download=True)
# 增加线性层
vgg16_true.classifier.add_module('add_linear', nn.Linear(1000, 10))
print(vgg16_true)

print(vgg16_false)
vgg16_false.classifier[6] = nn.Linear(4096, 10)
print(vgg16_false)

16 网络模型的保存及读取

保存

vgg16 = torchvision.models.vgg16(pretrained=False)
# 保存方式1,模型结构+模型参数
torch.save(vgg16, "vgg16_method1.pth")

# 保存方式2,模型参数(官方推荐)
torch.save(vgg16.state_dict(), "vgg16_method2.pth")

# 陷阱
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3)

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

tudui = Tudui()
torch.save(tudui, "tudui_method1.pth")

读取

#model1
model=torch.load("vgg16_method1.pth")
# print(model)

# model2
# model=torch.load("vgg16_method2.pth")
# print(model)
vgg16=torchvision.models.vgg16(pretrained=False).load_state_dict(torch.load("vgg16_method2.pth"))
# print(vgg16)

# 陷阱 还是需要写出class Tudui 类,但是不需要创建了,用来确保确实是这个类
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.conv1=nn.Conv2d(3,64,kernel_size=3)

    def forward(self):
        x=self.conv1(x)
        return x

model_tudui=torch.load("tudui_method1.pth")
# print(model_tudui)

# 方法2只能load出字典,vgg16方法用不了
model_tudui2=torch.load("tudui_method2.pth")
print(model_tudui2)

17 完整的模型训练套路

import torch.nn
import torchvision
from tensorboardX import SummaryWriter
from torch import nn
from torch.utils.data import DataLoader
# from  model import *
import  time

device=torch.device("cuda")
train_data= torchvision.datasets.CIFAR10(root="dataset",train=True,transform= torchvision.transforms.ToTensor(), download=True)
test_data=torchvision.datasets.CIFAR10(root="dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

train_data_size=len(train_data)
test_data_size=len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))

#加载数据集
train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)


class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model=nn.Sequential(
            nn.Conv2d(3,32,5,1,2),
            nn.MaxPool2d(2),
            nn.Conv2d(32,32,5,1,2),
            nn.MaxPool2d(2),
            nn.Conv2d(32,64,5,1,2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(1024,64),
            nn.Linear(64,10)
        )

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


# 创建网络模型
tudui=Tudui()

# # 这种判断方法全部都要加
# if torch.cuda.is_available():
#     tudui = tudui.cuda()
tudui=tudui.to(device)
# 损失函数
loss_fn=nn.CrossEntropyLoss()
loss_fn = loss_fn.to(device)

# 优化器
# learing_rate=0.01
learing_rate=1e-2
optimizer=torch.optim.SGD(tudui.parameters(),lr=learing_rate)

# 设置训练网络的一些参数
# 训练的次数
total_train_step=0
# 测试的次数
total_test_step=0
# 训练的轮数
epoch=10

# 添加tensorboard
writer=SummaryWriter("logs_train")

start_time=time.time()
for i in  range(epoch):
    print("第{}轮训练开始".format(i+1))

    # 训练步骤开始
    tudui.train()
    for data in train_dataloader:
        imgs,targets=data
        imgs = imgs.to(device)
        targets=targets.to(device)
        outputs=tudui(imgs)
        loss=loss_fn(outputs,targets)

        # 优化器优化模型
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        total_train_step=total_train_step+1
        if total_train_step % 100==0:
            end_time=time.time()
            print(end_time-start_time)
            print("训练次数:{},loss: {}".format(total_train_step,loss.item()))
            writer.add_scalar("train_loss",loss.item(),total_train_step)

    # 测试开始
    tudui.eval()
    total_test_loss=0
    #整体正确个数
    total_accuracy=0
    with torch.no_grad():
        for data in test_dataloader:
            imgs,targets=data
            imgs = imgs.to(device)
            targets = targets.to(device)
            outputs=tudui(imgs)
            loss=loss_fn(outputs,targets)
            total_test_loss=total_test_loss+loss
            accuracy=(outputs.argmax(1)==targets).sum()
            total_accuracy=total_accuracy+accuracy

    print("整体测试集上的loss:{}".format(total_test_loss))
    print("整体测试集的正确率:{}".format(total_accuracy/test_data_size))
    writer.add_scalar("test_loss",total_test_loss,total_test_step)
    writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)
    total_test_step=total_test_step+1

    torch.save(tudui,"tudui_{}.pth".format(i))
    print("模型已保存")

writer.close()

18 利用gpu训练

# 创建网络模型
tudui=Tudui()
# 这种判断方法全部都要加
if torch.cuda.is_available():
    tudui = tudui.cuda()

# 损失函数
loss_fn=nn.CrossEntropyLoss()
loss_fn = loss_fn.cuda()

    # 训练步骤开始
    tudui.train()
    for data in train_dataloader:
        imgs,targets=data
        imgs = imgs.cuda()
        targets=targets.cuda()

利用gpu方式二:

device=torch.device("cuda")

# 创建网络模型
tudui=Tudui()

tudui=tudui.to(device)
loss_fn = loss_fn.to(device)

19 完整的模型验证套路

img_path="img_1.png"
img=Image.open(img_path)
print(img)
img = img.convert('RGB')

transform=torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),
                                          torchvision.transforms.ToTensor()])
img=transform(img)
print(img.shape)



class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model=nn.Sequential(
            nn.Conv2d(3,32,5,1,2),
            nn.MaxPool2d(2),
            nn.Conv2d(32,32,5,1,2),
            nn.MaxPool2d(2),
            nn.Conv2d(32,64,5,1,2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(1024,64),
            nn.Linear(64,10)
        )

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


# model = torch.load("tudui_2.pth",map_location=torch.device('cpu'))
model = torch.load("tudui_1.pth")
print(model)
image=torch.reshape(img,(1,3,32,32))
model.eval()
with torch.no_grad():
    output=model(image)
print(output)

print(output.argmax(1))