8.pytorch lightning之训练时的技术

训练可用的技术

梯度累积 Accumulate Gradients

accumulate_grad_batches=K,设置后会每K个batches累积梯度,然后反向传播一次,相当于增加了batch size但内存没有增加。

# DEFAULT (ie: no accumulated grads)
trainer = Trainer(accumulate_grad_batches=1)

# Accumulate gradients for 7 batches
trainer = Trainer(accumulate_grad_batches=7)

梯度裁剪 Gradient Clipping

将梯度值限制在指定范围内,防止梯度爆炸。

# DEFAULT (ie: don't clip) 不u
trainer = Trainer(gradient_clip_val=0)

# clip gradients' global norm to <=0.5 using gradient_clip_algorithm='norm' by default
# 将norm后>0.5的梯度裁剪
trainer = Trainer(gradient_clip_val=0.5)

# 将梯度值>0.5的裁剪
# clip gradients' maximum magnitude to <=0.5
trainer = Trainer(gradient_clip_val=0.5, gradient_clip_algorithm="value")

学习率搜索

PL中内置学习率搜索工具,其使用论文Cyclical Learning Rates for Training Neural Networks的方法将学习率逐渐增大,然后运行少量batches,最后绘制loss vs lr曲线,并给出建议的学习率。

为了搜索学习率,LightningModule模型中必须声明一个learning_rate属性,创建Tuner对象,调用lr_fine方法。

from lightning.pytorch.tuner import Tuner


class LitModel(LightningModule):
    def __init__(self, learning_rate):
        super().__init__()
        # 声明学习率字段
        self.learning_rate = learning_rate
        self.model = Model(...)

    # 配置优化器,但是搜索学习率时只能指定一个优化器。
    def configure_optimizers(self):
        return Adam(self.parameters(), lr=(self.lr or self.learning_rate))


model = LitModel()
trainer = Trainer(...)

# Create a Tuner
tuner = Tuner(trainer)

# finds learning rate automatically
# sets hparams.lr or hparams.learning_rate to that learning rate
tuner.lr_find(model)

# to set to your own hparams.my_value 如果模型中学习率的字段不为learning_rate,则需要声明字段名。
# tuner.lr_find(model, attr_name="my_value")


# 打印搜索结果
print(lr_finder.results)

# 画出曲线图
fig = lr_finder.plot(suggest=True)
fig.show()

# 获取建议值Pick point based on plot, or get suggestion
new_lr = lr_finder.suggestion()

# update hparams of the model
model.hparams.lr = new_lr

# Fit model
trainer.fit(model)

绘制的曲线如下,红点为建议值,建议不是最低点,而是在最陡峭的下坡中间。

以下是使用Jupyter实现pytorch-forecasting预测的代码,用于对一个包含5维特征的1600x5的数据集进行预测。 ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt import torch from torch.utils.data import Dataset, DataLoader from sklearn.preprocessing import StandardScaler from pytorch_forecasting import TimeSeriesDataSet, TemporalFusionTransformer from pytorch_forecasting.metrics import MAE, MAPE, MSE, RMSE, SMAPE from pytorch_forecasting.data import GroupNormalizer # 读取数据集 data = pd.read_csv("data.csv") # 数据标准化 scaler = StandardScaler() scaled_data = scaler.fit_transform(data) # 绘制数据趋势图 plt.figure(figsize=(10, 6)) plt.plot(data) plt.xlabel("Time") plt.ylabel("Value") plt.title("Data Trend") plt.legend(data.columns) plt.show() # 创建间序列数据集 max_encoder_length = 100 max_prediction_length = 10 training_cutoff = int(len(data) * 0.8) context_length = max_encoder_length data["time_idx"] = range(len(data)) data["group"] = 0 # 可以根据需要进行分组 # 定义间序列数据集 dataset = TimeSeriesDataSet( data=data, time_idx="time_idx", target=data.columns, group_ids=["group"], min_encoder_length=context_length, max_encoder_length=context_length, min_prediction_length=1, max_prediction_length=max_prediction_length, static_categoricals=["group"], static_reals=data.columns.drop("time_idx").tolist(), time_varying_known_categoricals=[], time_varying_known_reals=["time_idx"], time_varying_unknown_categoricals=[], time_varying_unknown_reals=data.columns.drop(["time_idx"]).tolist(), ) # 数据划分 train_data = dataset.to_pandas(dataset.training_data) val_data = dataset.to_pandas(dataset.validation_data) # 创建数据加载器 batch_size = 32 train_dataloader = DataLoader(train_data, batch_size=batch_size, shuffle=True) val_dataloader = DataLoader(val_data, batch_size=batch_size) # 初始化模型 model = TemporalFusionTransformer.from_dataset(dataset, hidden_size=32, dropout=0.1) # 早停 early_stop_callback = EarlyStopping(monitor="val_loss", min_delta=1e-4, patience=10) # 正则化 trainer = pl.Trainer( max_epochs=100, gpus=0, weights_summary="top", gradient_clip_val=0.1, limit_train_batches=30, callbacks=[early_stop_callback], ) # 训练模型 trainer.fit(model, train_dataloader=train_dataloader, val_dataloaders=val_dataloader) # 绘制训练损失和验证损失 plt.figure(figsize=(10, 6)) plt.plot(model.history["train_loss"], label="Train Loss") plt.plot(model.history["val_loss"], label="Validation Loss") plt.xlabel("Epoch") plt.ylabel("Loss") plt.title("Training and Validation Loss") plt.legend() plt.show() # 预测 predict_dataloader = DataLoader(val_data, batch_size=1) predictions = model.predict(predict_dataloader) # 反标准化预测结果 predictions = scaler.inverse_transform(predictions.squeeze()) # 计算指标 actuals = val_data["target"].values mae = MAE()(torch.tensor(predictions), torch.tensor(actuals)) mape = MAPE()(torch.tensor(predictions), torch.tensor(actuals)) mse = MSE()(torch.tensor(predictions), torch.tensor(actuals)) rmse = RMSE()(torch.tensor(predictions), torch.tensor(actuals)) smape = SMAPE()(torch.tensor(predictions), torch.tensor(actuals)) # 绘制各列数据的预测图和总体数据的预测图 plt.figure(figsize=(10, 6)) for i in range(len(data.columns)): plt.subplot(len(data.columns), 1, i+1) plt.plot(range(len(predictions)), predictions[:, i], label="Predicted") plt.plot(range(len(actuals)), actuals[:, i], label="Actual") plt.xlabel("Time") plt.ylabel("Value") plt.title(data.columns[i]) plt.legend() plt.tight_layout() plt.show() # 打印指标 print("MAE:", mae) print("MAPE:", mape) print("MSE:", mse) print("RMSE:", rmse) print("SMAPE:", smape) ``` 以上代码使用了pytorch-forecasting库进行间序列预测,包括了数据标准化、绘制数据趋势图、早停、正则化、交叉验证,计算训练损失和验证损失并绘图,以及绘制各列数据的预测图和总体数据的预测图,并计算了MAE/MAPE/MSE/RMSE/SMAPE指标。请注意,代码中的"data.csv"是指包含特征数据的CSV文件路径,你需要根据实际情况进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值