深度学习入门 1(自用)
·
环境搭建记录
# 已经配置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拼接

更多推荐




所有评论(0)