pytorch基础知识学习(1)

概要

本文主要是记录 pytorch 的基础学习,参考文章为:一文理解PyTorch:附代码实例

1、主程序:hewu_train.py


"""
export CUDA_VISIBLE_DEVICES='7'
cd "$(find ~/ -type f -name "hewu_train.py" -exec dirname {} \; -quit)"
/ssddata/home/hewu/anaconda3/envs/torch==1.9.0+cu102/bin/python hewu_train.py

"""

import torch
import torch.optim as optim
import torch.nn as nn

import hewu_input_data
import hewu_models



# 加载输入数据,并指定设备
device = "cuda" if torch.cuda.is_available() else "cpu"
print("device is : ",device)

train_loader = hewu_input_data.train_loader
val_loader = hewu_input_data.val_loader


# 创建模型
torch.manual_seed(42)
if False:
    model = hewu_models.LayerLinearRegression().to(device)
else:
    # 用顺序模型代替嵌套模型
    model = nn.Sequential(nn.Linear(1, 1)).to(device)
print(model.state_dict())


lr = 1e-1
n_epochs = 1000

loss_fn = nn.MSELoss(reduction='mean')
optimizer = optim.SGD(model.parameters(), lr=lr)


# Creates the train_step function for our model, loss function and optimizer
losses = []
val_losses = []
train_step = hewu_models.make_train_step(model, loss_fn, optimizer)

for epoch in range(n_epochs):
    for x_batch, y_batch in train_loader:
        # 整个数据以及小批量数据集都在CPU中,因此我们需要把将要使用的小批量数据集送到GPU中
        x_batch = x_batch.to(device)
        y_batch = y_batch.to(device)

        loss = train_step(x_batch, y_batch) # 使用小批量来计算损失,更新参数
        losses.append(loss)

    if epoch % (n_epochs/5) == 0:    # 只验证5次
        with torch.no_grad():
            for x_val, y_val in val_loader:
                x_val = x_val.to(device)
                y_val = y_val.to(device)

                model.eval()

                yhat = model(x_val)
                val_loss = loss_fn(y_val, yhat)
                val_losses.append(val_loss.item())


# Checks model's parameters
print(model.state_dict())
print(losses[0:n_epochs:(n_epochs//5)])
print(val_losses)

2、模型:hewu_models.py

import torch.nn as nn


class LayerLinearRegression(nn.Module):
    def __init__(self):
        super().__init__()  # 调用父类构造函数,初始化父类属性,确保子类能继承并使用父类属性
        self.linear = nn.Linear(1, 1)

    def forward(self, x):
        return self.linear(x)


def make_train_step(model, loss_fn, optimizer):
    # Builds function that performs a step in the train loop
    def train_step(x, y):   # 嵌套函数可以使用外层函数的局部变量和参数,使用嵌套函数是为了模块化
        # Sets model to TRAIN mode
        model.train()  # 唯一作用是将模型设置为训练模式,因为模型如果有 dropout 机制的话,训练和评估是不同的
        # Makes predictions
        yhat = model(x)
        """
        model(x)等价于model.forward(x),这是因为在父类 nn.Module 中使用了 __call__ 函数
        详情请参考:https://zhuanlan.zhihu.com/p/357021687
                  https://zhuanlan.zhihu.com/p/356059224
        """
        # Computes loss
        loss = loss_fn(y, yhat)
        # Computes gradients
        loss.backward()
        # Updates parameters and zeroes gradients
        optimizer.step()
        optimizer.zero_grad()
        # Returns the loss
        return loss.item()  # item()是PyTorch的一个方法,用于从张量中提取单一值,并将其转换为Python浮点数。

    # Returns the function that will be called inside the train loop
    """
    这种技术非常有用:
    在一个函数内部定义了另一个函数,实现函数嵌套,并且将这个内部函数作为结果返回给外部。这意味着外部函数实际上生成了一个新的函数,
    并且这个新函数可以在外部函数之外的地方调用和使用。
    此代码中,make_train_step() 是一个外部函数,它接受一个参数 (model, loss_fn, optimizer)。
    在内部,它定义了一个内部函数 train_step(x, y),并将 train_step 作为结果返回给外部。
    这就意味着在调用 make_train_step() 后,我们实际上获得了一个新的函数 train_step,该函数可以在程序的其他地方调用,就像任何其他函数一样。
    """
    return train_step

3、数据集:hewu_input_data.py


import numpy as np
import torch
from torch.utils.data import Dataset, TensorDataset
from torch.utils.data.dataset import random_split
from torch.utils.data import DataLoader
import sys

class CustomDataset(Dataset):
    def __init__(self, x_tensor, y_tensor):
        self.x = x_tensor
        self.y = y_tensor

    def __getitem__(self, index):
        return (self.x[index], self.y[index])

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



# 数据生成
# Data Generation
np.random.seed(42)
x = np.random.rand(100, 1)
y = 1 + 2 * x

# 为什么放 CPU ,不把全部训练数据加载到 GPU 中去,是为了把 GPU 的内存空出来
x_tensor = torch.from_numpy(x).float()
y_tensor = torch.from_numpy(y).float()

if True:   # 自定义数据集
    dataset = CustomDataset(x_tensor, y_tensor)
else:      # 张量比较少
    dataset = TensorDataset(x_tensor, y_tensor)

train_dataset, val_dataset = random_split(dataset, [80, 20])


train_loader = DataLoader(dataset=train_dataset, batch_size=16)
val_loader = DataLoader(dataset=val_dataset, batch_size=20)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值