sen soil moisture lstm 总结

发布时间 2023-04-07 20:37:00作者: 辛宣

LSTM模型后增加Dense(全连接)层的目的是什么?

  • LSTM的输出是最后一个时刻的h,是个unit维的向量,必须接一个全连接层才能把LSTM的输出转换成你想要的输出,可以简单理解成维度变换。
  • LSTM输出的向量的维度是指定的units,但是最后在计算损失的时候是用的标签,标签也是向量,但是标签的向量维数和units不一致,这样就没有办法计算损失了,所以要加一个Dense将输出的向量转换成标签向量的维度,这样就可以计算损失了

pytorch中LSTM的输出的理解,以及batch_first=True or False的输出层的区别?

首先,pytorch中LSTM的输出一般用到的是输出层和隐藏层这两个,另一个细胞状态,我没咋用过,就不讲了。
一般两种用法,要么将输出层全连接然后得出结果,要么用隐藏层全连接,然后得出结果,有学长说用隐藏层效果会好一点。两种用法应该都可以。如果网络只有一层的时候,用输出层和隐藏层是没有任何区别的,当网络层数大于1时,才会有区别。
https://blog.csdn.net/qq_52785473/article/details/124368762

lstm里的dropout

含义
在训练过程中,对神经网络单元按照一定比例暂时将其丢弃。
原理
由于网络参数过多,训练数据少,或者训练次数过多,会产生过拟合的现象。
dropout产生的一个重大原因就是为了避免过拟合。 每一层的神经元按照不同的概率进行dropout,这样每次训练的网络都不一样,对每一个的batch就相当于训练了一个网络,dropout本质是一种模型融合的方式,当dropout设置为0.5时,模型总类最多为2^n, 另外在更新参数时,只对保留的神经元进行更新,也能加快训练速度。

torch.optim.Adam

优化器。优化器(optim)不同参数组,不同学习率设置的操作

class torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)[source]

  • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
  • lr (float, 可选) – 学习率(默认:1e-3)
  • betas (Tuple[float, float], 可选) – 用于计算梯度以及梯度平方的运行平均值的系数(默认:0.9,0.999)
  • eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
  • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)

AverageValueMeter

AverageValueMeter能够计算所有数的平均值和标准差,同意几个epoch中损失的平均值。

tqdm

Tqdm 是Python 进度条库,可以在 Python 长循环中添加一个进度提示信息。

optimizer.zero_grad()

optimizer.zero_grad() 是 PyTorch 中定义优化器的一个方法,它会将模型中所有可训练的参数的梯度清零。在训练神经网络时,通常需要在每次迭代之前调用这个函数。因为如果不清零梯度,那么优化器在更新权重时会累加之前的梯度。

train_loss.backward()

这是一个 PyTorch 中的函数,用于计算神经网络的反向传播梯度。它将计算出每个参数的梯度,并将其存储在参数的.grad属性中,以便在优化器中使用。

optimizer.step()

optimizer.step() 是 PyTorch 中用于更新模型参数的函数,它会根据当前的梯度和学习率来更新模型参数。通常在训练神经网络时,我们会在每个 batch 的训练结束后调用 optimizer.step() 来更新模型参数。
epoch_loss += train_loss.item()
这是一个关于机器学习的问题,epoch_loss 是指每个 epoch 训练后的损失值,train_loss.item() 是指当前训练批次的损失值。

loss_metrics.reset()

这是一个函数调用,用于重置损失度量器。

val_loss

网络的权重参数W在每一个batch size都会进行一次更新,界面显示的loss值是 iteration次batch size训练后loss值的加权求和值。val_loss是跑完一次Epoch后,跑完一次验证集计算的值。

iteration

将数据分为几个batch而不是一次性通过神经网络时,iteration是batch需要完成一个epoch的次数
比如,对于一个有2000个训练样本的数据集,将2000个样本分成大小为500的batch,那么完成一个epoch需要4个iteration

---------训练总结------------

train loss 不断下降,test loss不断下降,说明网络仍在学习;(最好的)

train loss 不断下降,test loss趋于不变,说明网络过拟合;(max pool或者正则化)

train loss 趋于不变,test loss不断下降,说明数据集100%有问题;(检查dataset)

train loss 趋于不变,test loss趋于不变,说明学习遇到瓶颈,需要减小学习率或批量数目;(减少学习率)

train loss 不断上升,test loss不断上升,说明网络结构设计不当,训练超参数设置不当,数据集经过清洗等问题。(最不好的情况)
keras中epoch,batch,loss,val_loss相关概念https://blog.csdn.net/audio_algorithm/article/details/89468096

optimizer.step()

optimizer.step()通常用在每个mini-batch之中,可以根据具体的需求来做。只有用了optimizer.step(),模型才会更新。

loss的值最大为1?

损失函数的最大值并不一定是 1。在训练神经网络时,需要根据具体的问题和损失函数来理解损失的大小和变化。通常,更重要的是观察损失函数的趋势,而不是损失的具体值。
MAE(平均绝对误差,Mean Absolute Error)和 ubRMSE(无偏均方根误差,Unbiased Root Mean Squared Error)都是常见的回归问题的评价指标。

MAE 衡量了预测值和真实值之间的平均绝对误差,其值没有上限,会随着预测值和真实值之间的差距的增大而增大。

ubRMSE 是 RMSE 的一种无偏估计,也没有一个固定的最大值。它通过计算预测值和真实值之间的平均偏差和平均标准差来计算。

r 的平方(r-squared, \(R^2\))是衡量线性回归模型拟合优度的指标,其取值范围是 [0,1]。当 \(R^2\) 取值为 1 时,说明模型完美拟合数据,而当 \(R^2\) 取值为 0 时,说明模型无法对数据进行拟合。

对于 MSE(均方误差,Mean Squared Error)和 RMSE(均方根误差,Root Mean Squared Error),其值没有上限,会随着预测值和真实值之间的差距的增大而增大。当模型完全无法预测正确时,MSE 和 RMSE 的值可能会趋近于无穷大。

val的loss值越来越大,是什么原因?

如果验证集的损失值持续增加,这表明模型过度拟合了训练数据,不能很好地推广到新数据。过拟合会导致模型学习适应训练数据中的噪声而不是潜在的模式,从而导致在新的、未见过的数据上表现较差。

验证集的损失值持续增加的原因有很多,下面是一些常见的原因:

  • 模型复杂度过高:如果模型的容量过高,就可能会过度拟合训练数据,而无法很好地推广到新数据。

  • 训练数据量不足:如果训练数据太少,模型就会很难从中学习到足够的模式,也会导致过拟合。

  • 学习率设置过高:如果学习率设置得太高,模型就可能无法很好地收敛,并导致过拟合。

  • 数据集分布不均:如果验证集的分布与训练集不同,或者其中包含的特殊情况较多,就可能导致验证集的损失值上升。

  • 数据预处理不当:如果数据预处理不当,也可能会导致模型过拟合。例如,如果没有进行归一化处理,一些特征的权重可能会过高,导致模型过拟合。

如果出现这种情况,可以考虑采取以下措施来解决过拟合问题:

  • 减少模型的复杂度:可以通过减少模型的参数数量、降低层数或使用正则化等方法来减少模型的复杂度。

  • 增加训练数据:可以通过增加训练数据来减少过拟合。如果无法增加训练数据量,可以考虑使用数据增强等技术来扩充训练集。

  • 调整学习率:可以通过调整学习率来控制模型的收敛速度,避免过拟合。

  • 调整数据集分布:可以尝试调整数据集的分布,使其更加接近于实际情况。

  • 进行数据预处理:可以通过归一化、标准化、特征选择等方法来优化数据预处理,减少模型过拟合的可能性。

train_loss.item()是啥意思

train_loss.item() 是一个 PyTorch 中的函数,它用于返回一个标量张量(scalar tensor)中的元素值。在深度学习中,模型的损失函数通常是一个标量,train_loss 是模型在一次训练迭代中计算出的损失函数值,而 train_loss.item() 返回的是这个标量张量中的元素值,也就是损失函数的数值。

迭代次数和epoch区别

迭代次数和 epoch 是深度学习中常用的两个概念,它们之间有一些区别。

  • 迭代次数:表示在每个 epoch 中训练模型的次数。通常,一个 epoch 包含多次迭代,每次迭代都会从训练数据集中随机抽取一批数据进行训练,这批数据的数量称为 batch size。因此,迭代次数可以计算为:数据集大小 / batch size。
  • Epoch:表示模型对整个训练数据集的训练次数。在每个 epoch 中,模型会使用训练数据集进行多次迭代训练,直到达到预定的 epoch 数量为止。

在实践中,通常会将 epoch 和迭代次数同时用于训练模型。迭代次数通常被用来调整学习率、权重衰减等超参数,并且可以用来衡量训练速度。而 epoch 则通常用来衡量模型的训练效果,例如监控训练集和验证集上的损失值等指标。

需要注意的是,在使用 epoch 进行训练时,通常会使用 early stopping 等技术来避免过拟合。Early stopping 可以通过监控验证集上的损失值,当损失值停止下降时停止训练,这样可以避免模型在训练集上过拟合,从而提高模型的泛化能力。

dropout

如果dropout太高,会导致网络不够深,难以学习到有效的特征,从而导致欠拟合。如果dropout太低,会导致网络过拟合,无法泛化到测试集数据。因此,你可以尝试不同的dropout值来找到最优的dropout值,一般建议先从0.1或0.2开始调整。

layer_dim和hidden_dim有啥区别

layer_dimhidden_dim都是LSTM中的超参数,但含义不同。

hidden_dim是指LSTM网络中隐藏状态的维度,也就是LSTM每个时间步输出的向量维度。这个参数通常用来控制LSTM的容量大小,即控制LSTM网络的复杂度。如果hidden_dim设置得较小,LSTM网络就比较简单,很可能无法很好地捕捉数据中的复杂关系,从而导致欠拟合;如果设置得过大,网络就容易过拟合,而且计算成本也会增加。

layer_dim是指LSTM网络中的层数。LSTM网络的每一层都有一个隐藏状态,前一层的隐藏状态作为后一层的输入,因此每层的输出也可以作为前一层的输入。增加层数可以增加LSTM的容量和复杂度,从而使网络更加深层次,更好地捕捉数据中的复杂关系。但是,增加层数也会增加网络的计算成本,并且较深的网络也容易过拟合。

过拟合

过拟合了咋办

过拟合是指模型在训练集上表现很好,但在测试集或新数据上表现较差的现象。这通常是因为模型在训练集上过度拟合,导致其对于噪声或随机性很强的数据过于敏感。

以下是一些缓解过拟合的方法:

  1. 更多数据:如果可行的话,可以尝试增加训练集的大小,从而让模型学习到更多的模式和变化。
  2. 正则化:正则化是一种常见的缓解过拟合的方法。常用的正则化方法有 L1 正则化、L2 正则化和 Dropout 等。这些方法都可以通过惩罚模型的权重大小或随机断开一些神经元来减少模型的复杂度。
  3. 提前停止:提前停止是一种早期停止训练的方法,可以避免模型在训练集上过拟合。一般来说,我们会在验证集上监控模型的性能,并在模型的性能停止提高时停止训练。
  4. 数据增强:数据增强是一种通过增加训练集中的样本数量和多样性来减少过拟合的方法。例如,可以通过旋转、翻转、剪切等方式来生成新的训练数据。
  5. 简化模型:简化模型是指减少模型的复杂度,以避免过拟合。例如,可以通过减少网络的层数、减少神经元的数量或使用更简单的模型架构等方式来降低模型的复杂度。

需要注意的是,缓解过拟合并不是一个完全避免过拟合的方法,而是尽可能减少过拟合的风险。在实践中,需要根据具体情况选择适合的方法来减少过拟合。

可以通过调节loss值

image

torch.optim.Adam()

torch.optim.Adam()是一个用于实现Adam优化算法的PyTorch内置优化器。在深度学习中,优化器是用来更新模型参数的算法,以便最小化损失函数。torch.optim.Adam()的输入参数包括:

  • params:需要更新的模型参数。

  • lr:学习率,控制参数更新的步长。

  • betas:Adam优化器中控制梯度平方和和梯度的比例的超参数,通常使用默认值(0.9, 0.999)。

  • eps:Adam优化器中用于避免除以0的小数值,通常使用默认值1e-8。

  • weight_decay:Adam优化器中的L2正则化系数,可选参数,默认为0。

    Adam是一种自适应的优化算法,能够有效地学习适应各种情况的学习率。它的核心思想是根据梯度的一阶矩估计和二阶矩估计自适应地调整每个参数的学习率,从而有效地平衡稳定性和收敛速度。

Adam()是每次的训练,都会更新嘛,会不会保存数据

是的,每次训练时,优化器会根据损失函数的梯度计算来更新神经网络的参数。所以每次训练后,神经网络的参数都会被修改。

优化器并不会自动保存数据,所以如果要保存数据,需要在训练过程中手动添加相关代码来保存需要的数据。

optimizer.step()是啥意思

optimizer.step() 是优化器的方法之一,用于根据计算出的梯度来更新神经网络中的参数。在进行反向传播计算得到每个参数的梯度之后,通过 optimizer.step() 方法来更新参数。具体来说,该方法会使用优化算法更新神经网络中的每个参数,使其向着能够最小化损失函数的方向进行调整。因此,在训练过程中,每次计算完损失函数的梯度后,我们需要通过调用 optimizer.step() 方法来更新神经网络中的参数。

一般的训练过程为:

  1. 在一个 epoch 的训练过程中,循环遍历训练数据集,取出一个 batch 的数据。

  2. 将 batch 的数据输入到模型中,计算模型输出和损失函数。

  3. 使用反向传播算法计算模型参数的梯度。

  4. 调用 optimizer.zero_grad() 方法清空梯度信息。

  5. 调用 optimizer.step() 方法更新模型参数。

  6. 重复步骤 1~5,直到训练结束。

清空了还怎么更新模型的参数

一般在每次更新模型参数之前都会调用 optimizer.zero_grad() 来清空之前计算的梯度信息。这个操作只是清空之前的梯度信息,不会对模型的参数进行修改。而 optimizer.step() 函数是用来更新模型参数的,它会根据当前计算出的梯度信息和设定的学习率对模型参数进行修改。

因此,先调用 optimizer.zero_grad() 再调用 optimizer.step() 是模型训练的常见操作。

def train_lstm(net, )里的net是啥意思

在函数参数列表中,net 是指所要训练的神经网络模型,通常是继承自 PyTorch 中 torch.nn.Module 类的一个子类对象。在 train_lstm 函数中,net 被传递进来后,会被用来进行模型的训练。

比如:

net = myLSTM(input_size=IN_FEATURE, hidden_dim=hidden_dim, out_features=OUT_FEATURE, layer_dim=1)

early stopping 后还要net = train_lstm()干嘛

早期停止之后,我们就得到了一个在训练集和验证集上都表现较好的模型。这个模型可以被用于后续的预测任务,或者保存下来用于未来的训练或调用。在这里,使用net来接收经过训练的LSTM模型,并返回这个经过训练的LSTM模型的参数。

当 early stopping 条件满足时,训练过程会提前停止,此时 net 模型已经是最佳模型(在验证集上表现最好的模型)了。后续可以使用这个最佳模型进行预测任务。

数据的形状变化

label_train = np.load('../../train_test_data_1D/' + str(seq_length) + str(lead_time) + str(point) + str(num) + 'label_train.npy')    features_validation = np.load('../../train_test_data_1D/' + str(seq_length) + str(lead_time) + str(point) + str(num) + 'features_val.npy')    
label_validation = np.load('../../train_test_data_1D/' + str(seq_length) + str(lead_time) + str(point) + str(num) + 'label_val.npy')    
label_train = label_train.reshape(368896,1)    
label_train = label_train[:, 0]

label_train它变成列又变成行是因为什么

这段代码中,label_train最初的shape为(368896,),也就是只有一个维度,即行向量。经过label_train = label_train.reshape(368896,1)操作,它被转换为(368896,1)的形状,其中第一个维度为行数,第二个维度为列数。这个操作可以将行向量转换为列向量。

接着进行了label_train = label_train[:, 0]操作,它会将二维数组label_train中的所有行的第0个元素提取出来组成一个行向量。因为此时label_train的第二个维度只有一个元素,所以提取出来的行向量也只有一个元素,即变回了一维数组。

label_train原本的形状是(368896, 1),即包含368896个长度为1的一维向量。而经过label_train = label_train[:, 0]操作之后,label_train变成了一个一维向量,即形状变成了(368896,)。这个操作本质上是将一个二维数组中的每一个元素提取出来,组成一个一维向量。这个过程并没有改变数组中元素的值,只是改变了数组在内存中的表示方式。

for step, (x, y) in tqdm(enumerate(train_loader))是啥意思

这是一个在训练数据集上进行迭代的循环,其中:

  • train_loader是一个PyTorch中的DataLoader对象,它包含了训练数据集中的数据;
  • enumerate(train_loader)train_loader转换成一个可迭代对象,它返回一个二元组 (step, (x, y)),其中step是迭代的步数,而(x, y)则是从train_loader中获取的一批训练数据,x是输入特征,y是对应的目标输出;
  • tqdm是一个Python中的进度条库,它将这个迭代过程的进度可视化,让用户了解当前训练的进展情况。