【问题标题】:LSTM model has constant accuracy and doesn't variateLSTM 模型具有恒定的准确性并且不会变化
【发布时间】:2020-02-21 18:16:55
【问题描述】:

如你所见,我被我的 lstm 模型困住了。我试图预测每月生产的吨数。当我运行模型来训练精度几乎是恒定的时,它的变化很小,例如:

 0.34406
 0.34407
 0.34408

我尝试了激活、初始化程序和参数的不同组合,但 acc 没有增加。 我不知道这里的问题是我的数据,我的模型还是这个值是模型可以达到的最大 acc。

这里是代码(如果你注意到一些库未使用,那是因为我在第一个版本中做了一些更改)

import numpy as np
import pandas as pd
from pandas.tseries.offsets import DateOffset
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler
from sklearn import preprocessing

import keras
%tensorflow_version 2.x
import tensorflow as tf
from tensorflow import keras

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.layers import LSTM
from tensorflow.keras.layers import Dropout
from keras.optimizers import Adam
import warnings
warnings.filterwarnings("ignore")

%matplotlib inline
from plotly.offline import iplot
import matplotlib.pyplot as plt
import chart_studio.plotly as py
import plotly.offline as pyoff
import plotly.graph_objs as go


df_ventas = pd.read_csv('/content/drive/My Drive/proyectoPanimex/DEOPE.csv', parse_dates=['Data Emissão'], index_col=0, squeeze=True)
#df_ventas = df_ventas.resample('M').sum().reset_index()
df_ventas = df_ventas.drop(columns= ['weekday', 'month'], axis=1)
df_ventas = df_ventas.reset_index()

df_ventas = df_ventas.rename(columns= {'Data Emissão':'Fecha','Un':'Cantidad'})
df_ventas['dia'] = [x.day for x in df_ventas.Fecha]
df_ventas['mes']=[x.month for x in df_ventas.Fecha]
df_ventas['anio']=[x.year for x in df_ventas.Fecha]
df_ventas = df_ventas[:-48]
df_ventas = df_ventas.drop(columns='Fecha')

df_diff = df_ventas.copy()
df_diff['cantidad_anterior'] = df_diff['Cantidad'].shift(1)
df_diff = df_diff.dropna()
df_diff['diferencia'] = (df_diff['Cantidad'] - df_diff['cantidad_anterior'])
df_supervised = df_diff.drop(['cantidad_anterior'],axis=1)

#adding lags
for inc in range(1,31):
    nombre_columna = 'retraso_' + str(inc)
    df_supervised[nombre_columna] = df_supervised['diferencia'].shift(inc)

df_supervised = df_supervised.dropna()
df_supervisedNumpy = df_supervised.to_numpy()

train = df_supervisedNumpy

scaler = MinMaxScaler(feature_range=(0, 1))
X_train = scaler.fit(train)

train = train.reshape(train.shape[0], train.shape[1])
train_scaled = scaler.transform(train)

X_train, y_train = train_scaled[:, 1:], train_scaled[:, 0:1]
X_train = X_train.reshape(X_train.shape[0], 1, X_train.shape[1])

#LSTM MODEL
model = Sequential()

act = 'tanh'
actF = 'relu'

model.add(LSTM(200, activation = act, input_dim=34, return_sequences=True ))
model.add(Dropout(0.15))

#model.add(Flatten())

model.add(LSTM(200, activation= act))
model.add(Dropout(0.2))

#model.add(Flatten())

model.add(Dense(200, activation= act))
model.add(Dropout(0.3))

model.add(Dense(1, activation= actF))

optimizer = keras.optimizers.Adam(lr=0.00001)

model.compile(optimizer=optimizer, loss=keras.losses.binary_crossentropy, metrics=['accuracy'])

history = model.fit(X_train, y_train, batch_size = 100, 
                epochs = 50, verbose = 1)

hist = pd.DataFrame(history.history)
hist['Epoch'] = history.epoch
hist

历史情节:

    loss        acc         Epoch
0   0.847146    0.344070    0
1   0.769400    0.344070    1
2   0.703548    0.344070    2
3   0.698137    0.344070    3
4   0.653952    0.344070    4

您可以看到唯一改变其损失的值,但是 Acc 发生了什么?我从机器学习开始,我没有更多的知识可以看到我的错误。谢谢!

【问题讨论】:

  • Relu 对于输出来说从来都不是一个好主意,对于 1 个单元来说也不是一个好主意。
  • 谢谢,我永远不会忘记!
  • @DanielMöller 不正确,如果您想预测正值(用于回归),这很有用。
  • @MatiasValdenegro,它会冻结,你会有很多输出卡在零,更糟糕的是,这些不会影响权重的增加,因为它们的反向传播被杀死了。
  • 在网络中间时,零点最终会导致后续层发生变化,并且由于高度变化可能经常变化,因此输出中的情况并非如此。零不会带来任何好处,变化/随机性也不会有用,因为它们是输出,您需要输出精度。

标签: python tensorflow keras lstm


【解决方案1】:

您的输出激活应该是linear 用于连续预测或softmax 用于分类。还要将你的学习率乘以 100。你的损失应该是mean_absolute_error。您还可以轻松地将您的 lstm 神经元除以 10。tanh 应替换为 relu 或类似的。

对于您的准确性问题,使用准确性是没有意义的,因为您没有尝试进行分类。对于指标,您可以使用mae。您正在尝试了解预测与实际目标之间的连续距离。准确性是针对类别,而不是连续数据。

【讨论】:

  • “sigmoid”,而不是“softmax”,它是 1 个单位。 ---- 如果预期 0+ 行为,“softplus”是“relu”的一个很好的替代品。
  • Nicolas,我尝试了你对我说的话,它没有真正的变化,但从 0.3441 到 0.3448 的增加很小。在您发表评论之前,它停留在 0.3441
  • 我真的尝试了几乎所有的组合,但没有增加0.34。问题是标准化吗?
  • @NicolasGervais mmm 我明白了,但是我怎么知道我的模型是否已经学会了?,当我用它来预测“model.predict”时,预测值非常糟糕。
  • @NicolasGervais 这是结果损失:0.0638 - mean_absolute_error: 0.0638
【解决方案2】:
  • Dense(1, activation='softmax')总是冻结,不会学到任何东西
  • Dense(1, activation='relu')很可能冻结并且什么也学不到
  • Dense(1, activation='sigmoid') 是分类(二元)问题的理想选择,对于值介于 0 和 1 之间的回归也有一定的好处。
  • Dense(1, activation='tanh') 对于值在 -1 和 1 之间的回归有点好
  • Dense(1, activation='softplus') 对于值在 0 和 +infinite 之间的回归有点好
  • Dense(1, actiavation='linear') 通常适用于没有限制的回归(但强烈建议之前对数据进行归一化)

对于回归,您不能使用准确度,但指标 'mae''mse' 不提供“相对”差异,它们提供“绝对”均值差异,一个是线性的,另一个是平方的。

【讨论】:

  • 我去试试,稍等。
  • 线性激活,它带来了真正的改变,非常感谢!你能推荐一本书或文章来了解更多吗?
猜你喜欢
  • 1970-01-01
  • 2017-07-16
  • 1970-01-01
  • 2020-11-06
  • 2016-07-18
  • 1970-01-01
  • 2018-09-07
  • 2019-10-06
  • 2018-11-22
相关资源
最近更新 更多