Pytorch 入門 (1) (Li Honyi 先生の宿題 1 2021 年春)

この記事のコードとデータセットは、Li Honyi 氏の HW1 からのものです。

データセットアドレス

リファレンスコードアドレス

この記事では、Li 氏の最初の宿題と、Pytorch を始めるために提供されたリファレンス コードを使用します。この記事は入門記事であり、特定のネットワーク設計については説明しません。

データを使用してモデルをトレーニングする場合、実際にはデータの読み取りとモデルのトレーニングという 2 つのステップに分かれます。次に、この手順に従って pytorch を開始します。

モデルの読み取り

1. データセットとデータローダーを使用してデータを読み取る

これはリファレンス コードで見た方法であり、推奨される方法です。(以下の読み取りは、いくつかの特別なデータ処理を削除して簡略化されています)

from torch.utils.data import Dataset, DataLoader
import numpy as np
class COVID19Dataset(Dataset):
    ''' Dataset for loading and preprocessing the COVID19 dataset '''
    def __init__(self,
                 path):
        #根据路径读取所需数据(使用pandas)
        df = pd.read_csv(path)
        #需要将数据转化为pytorch所需的格式
        data = torch.tensor(df.values, dtype=torch.float)
        #第一列为ID,无用数据,去除
        data = data[:,1:]
        #这里可以取所有列,也可以经过一些筛选,只使用有用的列
        feats = list(range(93))
        self.target = data[:, -1]
        self.data = data[:, feats]    


    def __getitem__(self, index):
        # 必须要实现的魔术方法,用于训练模型时返回数据
        return self.data[index], self.target[index]


    def __len__(self):
        # 返回数据长度,后面有使用到这个方法
        return len(self.data)

#再使用dataloader来实现打乱数据,批次读取等效果
batch_size = 100
train_ds = DataLoader(ds, batch_size=batch_size, shuffle=True)
dev_ds = DataLoader(ds, batch_size=batch_size, shuffle=True)

2. より直接的な方法

参考記事
も使えず、スクランブルや一括読み込みの効果を自分で直接実感できる

import pandas as pd
import torch
from torch import nn
path = './ml2021spring-hw1/covid.train.csv'
df = pd.read_csv(path)
dataset_tensor = torch.tensor(df.values, dtype=torch.float)
# 切分训练集 (60%),验证集 (20%) 和测试集 (20%)
random_indices = torch.randperm(dataset_tensor.shape[0])
traning_indices = random_indices[:int(len(random_indices)*0.6)]
validating_indices = random_indices[int(len(random_indices)*0.6):int(len(random_indices)*0.8):]
testing_indices = random_indices[int(len(random_indices)*0.8):]
traning_set_x = dataset_tensor[traning_indices][1:,feats]
traning_set_y = dataset_tensor[traning_indices][1:,-1:]
validating_set_x = dataset_tensor[validating_indices][1:,feats]
validating_set_y = dataset_tensor[validating_indices][1:,-1:]
testing_set_x = dataset_tensor[testing_indices][1:,feats]
testing_set_y = dataset_tensor[testing_indices][1:,-1:]

トレーニングモデル

トレーニング モデルはさらに複雑になるため、具体的な原則については説明せず、手順の概要のみを説明します。

  1. モデルをトレーニングする場合、同じデータセットを複数回トレーニング (E-poch) し、1 つのトレーニングを複数のバッチ (バッチ) に分割します。
  2. モデルをトレーニングするときに注意すべきモードがいくつかあります。トレーニングモード(train)は、モデルをトレーニングするために使用され、このモードを使用すると、勾配更新パラメータなどが計算されます。簡単に言うと、このモードはトレーニング中に使用されます。現時点では、残りのモードは非トレーニング モードであると考えており、通常、使用時に勾配を計算したりパラメータを更新したりする必要はありません。
  3. 適切な損失関数と対応するオプティマイザーを選択し、オプティマイザーを使用して、トレーニングの各バッチ中に損失関数に従ってパラメーターを更新します。
for poch in range(e_poch):
    model.train()#训练模式
    for x, y in train_ds:
        optimizer.zero_grad()#0梯度
        pred = model(x)
        mse_loss = model.cal_loss(pred, y.squeeze(-1))
        mse_loss.backward()  
        optimizer.step()

    model.eval()
    total_loss = 0
    for x, y in dev_ds:
        with torch.no_grad():
            pred = model(x)
            mse_loss = model.cal_loss(pred, y.squeeze(-1))
            total_loss += mse_loss
    total_loss = total_loss / len(dev_ds)

    if total_loss < mini_loss:
        mini_loss = total_loss
		print("poch %d find better model,MSE loss is %.4f\n" % (poch, mini_loss))

完全なコードの独自の簡易バージョン

# PyTorch
from torch.utils.data import Dataset, DataLoader

import pandas as pd

import torch
import torch.nn as nn

#这里的模型copy参考代码的,不在本文进行模型建立相关的介绍
class NeuralNet(nn.Module):
    ''' A simple fully-connected deep neural network '''

    def __init__(self, input_dim):
        super(NeuralNet, self).__init__()

        # Define your neural network here
        # TODO: How to modify this model to achieve better performance?
        self.net = nn.Sequential(
            nn.Linear(input_dim, 32),
            nn.BatchNorm1d(32),  # 使用BN,加速模型训练
            nn.Dropout(p=0.2),  # 使用Dropout,减小过拟合,注意不能在BN之前
            nn.LeakyReLU(),  # 更换激活函数
            nn.Linear(32, 1)
        )

        # Mean squared error loss
        self.criterion = nn.MSELoss(reduction='mean')
        # self.criterion = nn.SmoothL1Loss(size_average=True)

    def forward(self, x):
        ''' Given input of size (batch_size x input_dim), compute output of the network '''
        return self.net(x).squeeze(1)

    def cal_loss(self, pred, target):
        ''' Calculate loss '''
        regularization_loss = 0
        for param in self.parameters():
            # TODO: you may implement L1/L2 regularization here
            # 使用L2正则项
            # regularization_loss += torch.sum(abs(param))
            regularization_loss += torch.sum(param ** 2)
        return self.criterion(pred, target) + 0.00075 * regularization_loss


class COVID19Dataset(Dataset):
    def __init__(self, path):
        df = pd.read_csv(path)
        self.data = torch.tensor(df.values, dtype=torch.float)
        self.target = self.data[:, -1:]
        self.data = self.data[:, 1:-1]

    def __getitem__(self, index):
        return self.data[index], self.target[index]

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


train_path = './ml2021spring-hw1/covid.train.csv'

ds = COVID19Dataset(train_path)
batch_size = 100
train_ds = DataLoader(ds, batch_size=batch_size, shuffle=True)
dev_ds = DataLoader(ds, batch_size=batch_size, shuffle=True)

e_poch = 10000

mini_loss = 1000
early_stop = 500

model = NeuralNet(93)
optimizer = torch.optim.Adam(model.parameters())

for poch in range(e_poch):
    model.train()
    for x, y in train_ds:
        optimizer.zero_grad()
        pred = model(x)
        mse_loss = model.cal_loss(pred, y.squeeze(-1))
        mse_loss.backward()  # TODO
        optimizer.step()

    model.eval()
    total_loss = 0
    for x, y in dev_ds:
        with torch.no_grad():
            pred = model(x)
            mse_loss = model.cal_loss(pred, y.squeeze(-1))
            total_loss += mse_loss
    total_loss = total_loss / len(dev_ds)

    if total_loss < mini_loss:
        stop = 0
        mini_loss = total_loss
        c
    else:
        stop += 1

    if stop > early_stop:
        break

おすすめ

転載: blog.csdn.net/rglkt/article/details/120814864