环境搭建记录

# 已经配置conda24 python3.10
创建新的深度学习环境
conda create -n d2l-zh python=3.10 pip -y
conda activate d2l-zh   # 注意后面都是在这环境执行的
python --version
which python
gcc --version
nvidia-smi
free -h
df -h
安装jupyter、d2l和pytorch
python -m pip install jupyter
python -m pip install d2l -i https://pypi.tuna.tsinghua.edu.cn/simple
检查显卡驱动版本并安装torch
nvidia-smi
python -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
# ubuntu20.04
sudo nvidia-modprobe -u -c=0
nvidia-smi

Jupyter

shift 回车 = 运行

conda activate d2l-zh
jupyter notebook

鱼书基础知识

训练集 → 被切成很多个 batch
训练 1 个 batch → 叫 1 次 iteration
iteration 总次数 → 叫 iters_num
完整看完一遍训练集 → 叫 1 个 epoch

Affine层
激活函数

sigmoid

ReLU

输出层

softmax

...懒得写了看书吧

小土堆教程

一、基础教程

1. pytorch加载数据

from torch.utils.data import Dataset
from PIL import Image
import os  # Python 标准库,用于操作系统相关功能
# 自定义数据集类需要重写 getitem、len 和 add 方法
class MyData(Dataset):   # 继承Dataset类,语法: class 子类名(父类名)
# 自定义数据集类示例
# 这里的数据标签格式是文件夹名字为标签,文件夹里面放待识别的图,图的名字差不多随便命名的
    def __init__(self, root_dir, label_dir):
        """初始化方法"""
        self.root_dir = root_dir
        self.label_dir = label_dir
        # 为了让linux和windows都可以用(linux是/,而windows是//)
        self.path = os.path.join(self.root_dir, self.label_dir)
        self.img_path = os.listdir(self.path)   # 列出某个文件夹下面有哪些文件和文件夹,并且是列表格式的    
        
    def __getitem__(self, idx):  # 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 = "dataset/train"
ants_label_dir = "ants"
ants_dataset = MyData(root_dir, ants_label_dir)

img, label = ants_dataset[0]   # 这个类里的方法比较特殊,是双下划线的
len(ants_dataset)

# 用同样的方法可以创建bees_dataset,还可以合并两个
train_dataset = ants_dataset + bees_dataset

2. TensorBoard

使用时要在终端输入:

tensorboard --logdir=logs
from torch.utils.tensorboard import SummaryWriter # SummaryWriter是一个类
import numpy as np
from PIL import Image

# SummaryWriter是直接向log_dir文件夹写事件文件的类,这个事件文件可以被tensoroboard解析
writer = SummaryWriter("logs") # 需要输入的核心参数就是文件夹名称,这里就是“log”
# 常用的两个方法:writer.add_image()和writer.add_scalar()
image_path = ""
img_PIL = Image.open(image_path)
img_array = np.array(img_PIL)

# 1.writer.add_image()
# def add_image(
#     self, tag, img_tensor,
#     global_step=None, walltime=None, dataformats="CHW"
# ):
# tag (string): Data identifier
# img_tensor (torch.Tensor, numpy.array, or string/blobname): Image data
# global_step (int): Global step value to record
# walltime (float): Optional override default walltime (time.time())
#     seconds after epoch of event
# dataformats (string): Image data format specification of the form
#     CHW, HWC, HW, WH, etc.
writer.add_image("test", img_array, 1, dataformats="HWC")   #高 宽 通道数
# 这里可以通过1,2,3滑动那个滑杆看到不同阶段的图片,1表示第一阶段



# 2.writer.add_scalar()
# def add_scalar(
#     self,
#     tag, 就是图标的标题
#     scalar_value, 需要保存的数值(y)
#     global_step=None, 训练的次数(x)
#     walltime=None,
#     new_style=False,
#     double_precision=False,
# ):
for i in range(100):
    writer.add_scalar("y=x", i, i)
writer.close()



writer.close()

3. Transforms

ToTensor:
from torchvision import transforms
from PIL import Image
import cv2
from torch.utils.tensorboard import SummaryWriter
# 最常用的有ToTesor, Compose, Normalize, To PILImage
# tensor 数据类型

# class ToTensor:
#     """Convert a ``PIL Image`` or ``numpy.ndarray`` to tensor. This transform does not support torchscript.

#     Converts a PIL Image or numpy.ndarray (H x W x C) in the range
#     [0, 255] to a torch.FloatTensor of shape (C x H x W) in the range [0.0, 1.0]
#     if the PIL Image belongs to one of the modes (L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1)
#     or if the numpy.ndarray has dtype = np.uint8

#     In the other cases, tensors are returned without scaling.

#     .. note::
#         Because the input image is scaled to [0.0, 1.0], this transformation should not be used when
#         transforming target image masks. See the `references`_ for implementing the transforms for image masks.

#     .. _references: https://github.com/pytorch/vision/tree/main/references/segmentation
#     """

#     def __init__(self) -> None:
#         _log_api_usage_once(self)

#     def __call__(self, pic):
#         """
#         Args:
#             pic (PIL Image or numpy.ndarray): Image to be converted to tensor.

#         Returns:
#             Tensor: Converted image.
#         """
#         return F.to_tensor(pic)

#     def __repr__(self) -> str:
#         return f"{self.__class__.__name__}()"

img_path = "/home/ljy/Projects/DDPM/hymenoptera_data/train/ants/0013035.jpg"
img = Image.open(img_path)   # 这就是PIL数据类型 <class 'PIL.JpegImagePlugin.JpegImageFile'>
cv_img = cv2.imread(img_path)   # <class 'numpy.ndarray'>


writer = SummaryWriter("logs")


tensor_trans = transforms.ToTensor()   # 可以实现对Image和Opencv读取的图片进行格式转换 
tensor_img = tensor_trans(img)   # <class 'torch.Tensor'>

writer.add_image("Tensor_img", tensor_img)   # torch.tensor本来就是[3, H, W]格式了,所以没有写
writer.close()

包含totensor在内的常用transfrom功能:
# 补充一点__call__/class知识
# class Person:
#     def __call__(self, name):
#         print("__call__" + name)
        
#     def call(self, name):
#         print("call" + name)
        
# Li = Person()   # 因为没有__init__所以不能接受参数,不可以写Li = Person("LiSi")
# Li("LiSi")   # 用__call__调用可以直接括号内调用,而不用.方法
# Li.call("Lisi")

# class Person_with_init:
#     def __init__(self, name):
#         print("Init" + name)
#     def __call__(self, name):
#         print("__call__" + name)
        
# Wa = Person_with_init("XiaoWang")
# Wa("XiaoWang")

# # 输出结果
# # __call__LiSi
# # callLisi
# # InitXiaoWang
# # __call__XiaoWang

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

writer = SummaryWriter("logs")

img_path = "/home/ljy/Projects/DDPM/hymenoptera_data/train/ants/0013035.jpg"
img_PIL = Image.open(img_path)

# to tensor
to_tensor = transforms.ToTensor()
img_tensor = to_tensor(img_PIL)
writer.add_image("norm_test", img_tensor, 1)

# normalize
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
writer.add_image("norm_test", img_norm, 2)

# resize
print(img_PIL.size)
trans_resize = transforms.Resize((512, 512))
img_resize = trans_resize(img_PIL)   # 也可以用img_tensor,但是输出的img_resize还是PIL格式的
print(img_resize.size)

img_resize_tensor = to_tensor(img_resize)   # add_image需要是np.array或者tensor格式的
writer.add_image("norm_test", img_resize_tensor, 3)


# compose - resize 即利用compose的resieze的实现方法
trans_resize_2 = transforms.Resize(256)   # 整体按比例缩放,使短边为256
trans_compose = transforms.Compose([trans_resize_2, to_tensor])   # 需要给一个列表,里面都是transform格式,而且要注意前后格式是否匹配
# 常见顺序
# transforms.Compose([
#     transforms.Resize(...),    # 可以处理 PIL
#     transforms.ToTensor(),     # PIL -> Tensor
#     transforms.Normalize(...)  # 只能处理 Tensor
# ])
img_compose_resize = trans_compose(img_PIL)         
writer.add_image("norm_test", img_compose_resize, 4)
# print(img_PIL.size)   (768, 512)
# print(img_compose_resize.shape)   torch.Size([3, 256, 384])

writer.close()

4. DataLoader

# 取出64个,打乱,最后不整的丢掉
test_data = DataLoader(dataset=test_set, batch_size=64, shuffle=True, num_workers=0, drop_last=True)

二、神经网络搭建

1. nn.Model

from torch import nn
import torch

class MYNN(nn.Module):
    def __init__(self):
        super().__init__()
        
    def forward(self, input):
        output = input + 1
        return output

jjj = MYNN()
x = torch.tensor(1.0)
output = jjj(x)
print(output)

2. conv2d.function

import torch
import torch.nn.functional as F

input = torch.tensor([  [1, 2, 3, 4, 5],
                        [6, 7, 8, 9, 10],
                        [11, 12, 13, 14, 15],
                        [16, 17, 18, 19, 20],
                        [21, 22, 23, 24, 25]])

kernal = torch.tensor([[1, 2, 1],
                       [0, 1, 0],
                       [2, 1, 0]])

print(input.shape)

# conv2d 要求格式是 [batch_size, channel, height, width]
input = torch.reshape(input, (1, 1, 5, 5))
kernal = torch.reshape(kernal, (1, 1, 3, 3))

print(input.shape)
print(kernal.shape)

output = F.conv2d(input, kernal, stride=2)   #padding表示在外围扩充
print(output)
# 输出结果
torch.Size([5, 5])
torch.Size([1, 1, 5, 5])
torch.Size([1, 1, 3, 3])
tensor([[[[ 49,  57,  65],
          [ 89,  97, 105],
          [129, 137, 145]]]])

3. conv2d

        卷积核数量是与out_channel有关的

import torch
import torchvision
from torch.utils.data import DataLoader
from torch import nn
from torch.nn import Conv2d
from torch.utils.tensorboard import SummaryWriter

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

dataloader = DataLoader(dataset, batch_size=64)

# class Conv2d(
#     in_channels: int,
#     out_channels: int,
#     kernel_size: _size_2_t,
#     stride: _size_2_t = 1,
#     padding: _size_2_t | str = 0,
#     dilation: _size_2_t = 1,
#     groups: int = 1,
#     bias: bool = True,
#     padding_mode: str = 'zeros',
#     device: Any | None = None,
#     dtype: Any | None = None
# )
class MyC2(nn.Module):
    def __init__(self):
        super(MyC2, self).__init__()
        self.conv1 = Conv2d(3, 6, 3, stride=1, padding=0)
        
    def forward(self, x):
        x = self.conv1(x)
        return x

c1 = MyC2()

writer = SummaryWriter("logs")
step = 0

for data in dataloader:
    imgs, targets = data   # imgs:[64, 3, 32, 32] 3个channel是rgb
    output = c1(imgs)   # output:[64, 6, 30, 30] 没有padding所以像素值变小了
    # print(output.shape)   # tensor的shape :[batch_size, channel, height, width]
    output = torch.reshape(output, (-1, 3, 30, 30))   # 6个channel会不知道怎么显示,-1表示适应后面的变化
    writer.add_images("inputs", imgs, step)   # 注意是imgs [NCHW]
    writer.add_images("onputs", output, step)
    step += 1
    
writer.close()

4. maxpool

        卷积是卷积核求和,池化是池化核选最大。

池化:每个 channel 独立使用同一种池化规则;卷积:每个输出卷积核生成一个输出 channel

import torch
import torchvision
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

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

dataloader = DataLoader(dataset, batch_size=64)

# 一种方式
# 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)

# kernal = torch.tensor([[1, 2, 1],
#                        [0, 1, 0],
#                        [2, 1, 0]])

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

class Maxp2(nn.Module):
    def __init__(self):
        super().__init__()
        self.mp = MaxPool2d(kernel_size=3, ceil_mode=True)
        
    def forward(self, x):
        return self.mp(x)
    
maxpool = Maxp2()

writer = SummaryWriter("logs")
step = 0

for data in dataloader:
    imgs, targets = data
    output = maxpool(imgs)
    writer.add_images("before_mp", imgs, step)   # 用了batch_size一定要记得s
    writer.add_images("after_mp", output, step)
    step += 1
writer.close()

5. 激活

        relu和sigmoid

import torch
from torch import nn
from torch.nn import ReLU
from torch.nn import Sigmoid
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

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

writer = SummaryWriter("logs")

# 矩阵输入
# input = torch.tensor([[1, -0.5],
#                       [-1, 3]])

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

# inplace表示是否替代input
class sigd(nn.Module):
    def __init__(self):
        super().__init__()
        # self.relul1 = ReLU()
        self.sigmoid = Sigmoid()
    
    def forward(self, x):
        return self.sigmoid(x)

# relu_my = relu()
s = sigd()
step = 0
for data in dataloader:
    imgs, targets = data
    writer.add_images("before", imgs, step)
    out_imgs = s(imgs)
    writer.add_images("after", out_imgs, step)
    step +=1
    

# output = relu_my(imgs)
# print(output)

6. 线性层

from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import torch
from torch import nn
from torch.nn import Linear
import torchvision

class my_linear(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = Linear(196608, 10)   # 转变列数
        
    def forward(self, input):
        return self.linear(input)
        

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

writer = SummaryWriter("logs")
step = 0

my = my_linear()

# 要有含义的才可以在add_image里面用
# C=1:灰度图
# C=3:RGB 图
# C=4:RGBA 图

for data in dataloader:
    imgs, targets = data
    print(imgs.shape)
    
    output = torch.reshape(imgs, (1, 1, 1, -1))
    # output = torch.flatten(imgs)
    
    # writer.add_images("before", imgs, step)
    # writer.add_images("after", output, step)
    # step += 1
    out_imgs = my(output)
    print(out_imgs.shape)
    
    

7. 网络搭建实战

import torch
from torch import nn
from torch.utils.tensorboard import SummaryWriter

class classify_10(nn.Module):
    def __init__(self):
        super().__init__()
        # self.conv1 = nn.Conv2d(3, 32, 5, padding=2)
        # self.maxpool1 = nn.MaxPool2d(2)
        # self.conv2 = nn.Conv2d(32, 32, 5, padding=2)
        # self.maxpool2 = nn.MaxPool2d(2)
        # self.conv3 = nn.Conv2d(32, 64, 5, padding=2)
        # self.maxpool3 = nn.MaxPool2d(2)
        # self.flattern = nn.Flatten()
        # self.linear1 = nn.Linear(1024, 64)
        # self.linear2 = nn.Linear(64, 10)
        
        self.model1 = nn.Sequential(
            nn.Conv2d(3, 32, 5, padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 32, 5, padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5, padding=2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(1024, 64),
            nn.Linear(64, 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
    
my_model = classify_10()
input = torch.ones((64, 3, 32, 32))
# print(input.shape)
output = my_model(input)
# print(output.shape)
writer = SummaryWriter("logs")
writer.add_graph(my_model, input)
writer.close()

8. 损失函数

        loss求解方法:
import torch
from torch import nn


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))

# class L1Loss(
#     size_average: Any | None = None,
#     reduce: Any | None = None,
#     reduction: str = 'mean'
# )
# 可以是平均也可以是求和,默认是求和模式


# L1 loss
loss = nn.L1Loss()
# loss = nn.L1Loss(reduction="sum")
result = loss(inputs, targets)

# MSE 均方误差
loss_mse = nn.MSELoss()
result_mse = loss_mse(inputs, targets)

# 交叉熵 分类问题用的比较多,这个数据格式要注意
x = torch.tensor([0.1, 0.2, 0.3])   # torch.Size([3])
x = torch.reshape(x, (1, 3))   # torch.Size([1, 3])
# print(x.shape)
y = torch.tensor([1])
loss_cross = nn.CrossEntropyLoss()
result_corss = loss_cross(x, y) 

print(result)
print(result_mse)
print(result_corss)
        比较完整的流程:
import torch
import torchvision
from torch.utils.data import DataLoader
from torch import nn
from torch.nn import Conv2d
from torch.utils.tensorboard import SummaryWriter

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

class classify_10(nn.Module):
    def __init__(self):
        super().__init__()
        
        self.model1 = nn.Sequential(
            nn.Conv2d(3, 32, 5, padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 32, 5, padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5, padding=2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(1024, 64),
            nn.Linear(64, 10)
        )
          
                              
    def forward(self, x):
        x = self.model1(x)
        return x
    
my_model = classify_10()
loss_c = nn.CrossEntropyLoss()

for data in dataloader:
    imgs, targets = data
    outputs = my_model(imgs)
    result_loss = loss_c(outputs, targets)
    # print(result_loss)
    result_loss.backward()   # 求梯度
    
    # print(outputs)
    # print(targets)
    
    

# writer = SummaryWriter("logs")
# writer.add_graph(my_model, input)
# writer.close()

9. 优化器

        主要的步骤在里面用序号标出来了

import torch
import torchvision
from torch.utils.data import DataLoader
from torch import nn
from torch.nn import Conv2d
from torch.utils.tensorboard import SummaryWriter

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

class classify_10(nn.Module):
    def __init__(self):
        super().__init__()
        
        self.model1 = nn.Sequential(
            nn.Conv2d(3, 32, 5, padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 32, 5, padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5, padding=2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(1024, 64),
            nn.Linear(64, 10)
        )
          
                              
    def forward(self, x):
        x = self.model1(x)
        return x
    
my_model = classify_10()
loss_c = nn.CrossEntropyLoss()
optim = torch.optim.SGD(my_model.parameters(), lr=0.01)   # 1.首先设置优化器

for epoch in range(20):
    running_loss = 0.0
    for data in dataloader:
        imgs, targets = data
        outputs = my_model(imgs)
        result_loss = loss_c(outputs, targets)
        # print(result_loss)
        
        optim.zero_grad()   # 2.梯度清除
        result_loss.backward()   # 3.反向传播求梯度
        optim.step()   # 4.模型参数进行调节
        running_loss += result_loss
    print(running_loss)
    
        # print(outputs)
        # print(targets)
 

三、其他补充知识

1. 对现成模型进行微调

import torchvision
from torch import nn
from torchvision.models import vgg16, VGG16_Weights

# 这个是已经训练好的一个网络,后续要调整他应用到cifar10数据集
vgg16_true = torchvision.models.vgg16(weights=VGG16_Weights.DEFAULT )   

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

# 模型微调
# VGG16后面输出是1000,现在加一个线性层调整成10
# vgg16_true.add_module("add_linear", nn.Linear(1000, 10))

# 替换最后一层的写法(最后一层是classifier[6])
vgg16_true.classifier[6] = nn.Linear(4096, 10)

print(vgg16_true)

2. 模型保存与读取

        保存:
import torch
import torchvision

vgg16 = torchvision.models.vgg16(weights=None)   # 不写就是none

# 保存方式 1:包含模型结构和参数
torch.save(vgg16, "./models/vgg16_method1.pth")   # pth是pytorch后缀名

# 保存方式 2:仅保存模型参数(官方更推荐的,占用空间更小)
torch.save(vgg16.state_dict(), "./models/vgg16_method2.pth")
        读取:
import torch
import torchvision

# 加载保存的 1
model1 = torch.load("/home/ljy/Projects/DDPM/models/vgg16_method1.pth")
# print(model1)

# 加载保存的 2
# 里面是字典形式的参数
# model2_param_dict = torch.load("/home/ljy/Projects/DDPM/models/vgg16_method2.pth")
model2 = torchvision.models.vgg16()
model2.load_state_dict(torch.load("/home/ljy/Projects/DDPM/models/vgg16_method2.pth"))
# print(model2)

3. 完整训练流程

import torchvision
from torch.utils.data import DataLoader
from torch import nn
from model1 import *

train_data = torchvision.datasets.CIFAR10("./data", train=True, transform=torchvision.transforms.ToTensor(), download=True)
test_data = torchvision.datasets.CIFAR10("./data", 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)

c10 = cifar10()

loss_function = nn.CrossEntropyLoss()

lr = 1e-2
optimizer = torch.optim.SGD(c10.parameters(), lr = lr)

total_train_step = 0
total_test_step = 0

epoch = 10

for i in range(epoch):
    for data in train_dataloader:
        imgs, targets = data
        outputs = c10(imgs)
        
        loss = loss_function(outputs, targets) # outputs是各类概率,targets是类别标签
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        total_train_step += 1
        # print("训练次数为{},损失为{}".format(total_train_step, loss))
    
    # 测试
    total_test_loss = 0
    with torch.no_grad():
        for data in test_dataloader:
            test_imgs, test_targets = data
            test_outputs = c10(test_imgs)
            test_loss = loss_function(test_outputs, test_targets)
            total_test_loss += test_loss.item()
    print("整体测试集loss:{}".format(total_test_loss))
    
    torch.save(c10.state_dict(), "c10_{}.pth".format(i+1))
import torch
from torch import nn

class cifar10(nn.Module):
    def __init__(self):
        super(cifar10, 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(64*4*4, 64),
            nn.Linear(64, 10)
        )
        
    def forward(self, x):
        x = self.model(x)
        return x
    
if __name__ == "__main__":
    c10 = cifar10()
    input = torch.ones((64, 3, 32, 32))
    output = c10(input)
    print(output.shape)

4. GPU加速

网络模型,损失函数,数据可以调用cuda()

device = torch.device("cuda")
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
xxx.to(device)

刘二部分网课内容

一、神经网络

二、卷积

说明:filter是n*h*w,即卷积核通道和输入通道数量一样;一共m个卷积核,和输出通道数一样;输入图像的size通常为[batch_size, channel, h, w]

补充:Residual Network可以解决梯度消失网络退化问题,使网络可以堆得更深。

三、RNN网络

主要处理又序列连接的数据(eg:天气和自然语言)

绿色的东西参数都是一样的

补充细碎知识

1.concat拼接

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐