【深度学习笔记】-代码解读2-模型

本文是一篇关于深度学习基础的教程,详细介绍了如何从头开始构建一个简单的神经网络模型。内容包括导入必要的库、加载数据集如FashionMNIST、定义数据加载器、创建模型、选择优化器、定义训练和测试函数、训练模型并保存参数、加载模型以及进行预测。整个过程涵盖了数据预处理、模型搭建、前向传播、反向传播、损失函数和优化器的使用,适合深度学习初学者入门学习。
摘要由CSDN通过智能技术生成

转载(12条消息) 「深度学习一遍过」必修2:解读简化版模型代码_荣仔的博客-CSDN博客

话不多说,记笔记:

 1.整体代码

  • 导入库
  • 加载数据集 datasets
  • 定义数据加载器 dataloader
  • 创建模型 class:def _init_(self)  #初始化自身属性+模型相关函数
  • 选择优化函数 optimizer
  • 定义训练函数:数据加载器dataloader、模型model、损失函数loss_fn、优化器optimizer
  • 定义测试函数:数据加载器dataloader、模型model、损失函数loss_fn
  • 开始训练
  • 保存模型参数
  • 加载模型:model.load_state_dict(torch.load("model.pth"))
  • 获取预测效果

2.代码具体笔记

2.1 导入库

  • import A
  • from B import A
  • from B.a import A

e.g. 

from torch import nn : 神经网络模块相关包
from torch.utils.data import DataLoader : 实现一个数据加载器 

2.2 加载数据集 datasets

  • training_data = datasets.XXX( ) 加载datasets中的XXX数据集
  • root = 'data' :保存到 data 文件夹中
  • train = True :设定为训练集  or train = False :设定为测试集 
  • download = True :为 True 时若本地没有该数据集就从官网进行下载-源码会指定官方下载路径
  • transform = ToTensor() :此代码作用是对数据进行转换,直接把数据变为输入,相当于是进行了数据预处理;其他数据预处理常用的还有:resize()、尺度变换、随即翻转等。

e.g.

training_data = datasets.FashionMNIST(
    root='data',
    train=True,
    download=True,
    transform=ToTensor(),
)
test_data = datasets.FashionMNIST(
    root='data',
    train=False,
    download=True,
    transform=ToTensor(),
)

2.3 定义数据加载器 dataloader

  • training_dataloader = DataLoader(training_data, batch_size=batch_size)
    test_dataloader = DataLoader(test_data, batch_size=batch_size)
  • 加载数据 +设置单次传入的数据数量

e.g.

# 设置一次传入的数据数量
batch_size = 64
# 用于给训练集、测试集分别创建一个数据集加载器 
training_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)
 
for X, y in test_dataloader:
    print("shape of X [N, C, H, W]: ", X.shape)
    # X.shape 表示多个维度的图片
    # N:代表传入64张图片 
    # C:代表通道数(灰度图通道数为1) 
    # H:图片的长  
    # W:图片的宽
    print("Shape of y: ", y.shape, y.dtype)
    # y:标签。
    break


# 结果:
shape of X [N,C,H,W]: torch.Size([64,1,28,28])
shape of y : torch.Size([64]) torch.int64

2.4 创建模型 class:def _init_(self)  #初始化自身属性+模型相关函数

  • 如果显卡可用,则用显卡进行训练。 
device = "cuda" if torch.cuda.is_available() else 'cpu'
print("Using {} device".format(device))
  • 模型创建 
# 创建模型
class NeuralNetwork(nn.Module):
    
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        # 平铺,将数据平铺成一维
        # https://blog.csdn.net/GhostintheCode/article/details/102530451
        self.flatten = nn.Flatten()  
        # 定义linear_relu_stack-由多层神经网络构成
        # Sequential 意为其下定义的多层操作一个接一个按顺序进行,把它们前后全部拼接在一起
        self.linear_relu_stack = nn.Sequential(
            #全连接层:28 * 28表示输入维度数量; 512表示目前维度数/下一层输出数量
            nn.Linear(28 * 28, 512),
            #nn.ReLU()表示 ReLU 非线性激活函数
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
            nn.ReLU()
        )
    
    #def forward(self, x)-forward 定义前向传播函数,x为输入数据
    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits


#model = NeuralNetwork().to(device) :调用刚定义的模型,如果 cuda 可用将模型转到 GPU。 
model = NeuralNetwork().to(device)
print(model)

2.5 选择优化函数 optimizer

  • 损失函数+优化器 
# 定义损失函数,计算实际输出与真实相差多少
# 此处使用的是交叉熵损失,为图像分类常用的损失函数
loss_fn = nn.CrossEntropyLoss()  

# 定义优化器,用来训练时候优化模型参数
# SGD表示随机梯度下降,用于控制实际输出y与真实y之间的相差有多大
# lr=1e-3 代表初始学习率
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)

2.6 定义训练函数:

  • 数据加载器dataloader、模型model、损失函数loss_fn、优化器optimizer
  • loss值越低越好,预测值与真实值越来越靠近,说明模型设计成功
# 此处定义训练函数,把数据加载器、模型、损失、优化器等传到网络中
def train(dataloader, model, loss_fn, optimizer):
    #  用于查看 dataloader 有多少张图片-size = len(dataloader.dataset)
    size = len(dataloader.dataset)
    # 从数据集中读取batch
    # batch:一次读取张数,即批次数
    # X:图片数据
    # y: 图片真实标签
    for batch, (X, y) in enumerate(dataloader):
        # 将数据存到显卡
        X, y = X.to(device), y.to(device)
        # 用于得到预测的结果pred
        pred = model(X)
        # 用于计算预测的误差
        loss = loss_fn(pred, y)
        # 优化器工作前先将梯度置0,进行归0操作
        optimizer.zero_grad()
        # 用相差多少这种损失值对模型进行参数更新(反向传播,更新模型参数)
        loss.backward()
        # 更新优化其中的参数
        optimizer.step()
 
        # 每当训练100次,输出当前信息
        if batch % 100 == 0:
            loss, current = loss.item(), batch * len(X)
            print(f"loss:{loss:>7f} [{current:>5d}/{size:>5d}]")

2.7 定义测试函数:

  •  数据加载器dataloader、模型model、损失函数loss_fn
def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    # 将模型转换为验证模式
    model.eval()
    # 初始化test_loss、corrent 用来统计每次的误差
    test_loss, corrent = 0, 0
    # 测试时模型参数不用更新,所以 no_grad,整个模型参数正向推就ok,不反向更新参数
    with torch.no_grad():
        # 加载数据加载器,得到里面的 X(图片数据)和 y(真实标签)
        for X, y in dataloader:
            # 将数据转换为 GPU
            X, y = X.to(device), y.to(device)
            # 将图片传图到模型中就得到预测的 pred
            pred = model(X)
            # 计算预测值pred和真实值y的差距
            test_loss += loss_fn(pred, y).item()
            # 统计预测正确的个数
            corrent += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= num_batches
    corrent /= size
    print(f"Test Error: \n Accuracy: {(100 * corrent):>0.1f}%, Avg loss:{test_loss:>8f}\n")

2.8 开始训练

epoch = 50
for t in range(epoch):
    print(f"Epoch {t + 1}\n----------------------")
    train(training_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model, loss_fn)
print("Done!")

2.9 保存模型参数

torch.save(model.state_dict(), "model.pth")
print("Save PyTorch Model State to model.pth")

2.10 加载模型:model.load_state_dict(torch.load("model.pth"))

  • 加载时,需要保证前后呼应,即 :
  • 先 torch.load 读取模型 pth, 再用 load_state_dict 读取到里面所有参数。
# 得到先前所定义的模型框架
model = NeuralNetwork()
# 框架本身加载模型中的参数
model.load_state_dict(torch.load("model.pth"))

2.11 获取预测效果

  • 定于整个标签类
# classes 用于定义整个标签类。
#本身标签中有什么,模型并不知道,只是简化标签为 0、1、2、. . . 
#之后再将 0、1、2、. . .  对应标签的名字。
classes = [
    "T-shirt/top",
    "Trouser",
    "Pollover",
    "Dress",
    "coat",
    "Sandal",
    "Shirt",
    "Sneaker",
    "Bag",
    "Ankle boot",
]
# 进入验证阶段,不会梯度更新,只会向前推
model.eval()
x, y = test_data[0][0], test_data[0][1]
with torch.no_grad():
    pred = model(x)
    # 得到预测类别中最高的那一类,再把最高的这一类对应 classes 中的哪一个标签。
    predicted, actual = classes[pred[0].argmax(0)], classes[y]
    # 最终输出预测值与真实值
    print(f'Predicted: "{predicted}", Actual: "actual"')
版权声明:本文为CSDN博主「荣仔!最靓的仔!」的原创文章,遵循 CC 4.0 BY-SA 版权协议。
         转载请在醒目位置附上原文出处链接及本声明。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值