【问题标题】:Tensorflow: Getting same prediction for all rows with LSTMTensorflow:使用 LSTM 对所有行进行相同的预测
【发布时间】:2020-09-29 23:13:18
【问题描述】:

我是 Tensorflow 的新手,一直在玩 TF 教程。一个这样的教程是this,它使用 LSTM 将温度的时间序列预测作为回归问题处理。相反,我想将其转换为分类问题 - 如果 12 小时后的温度高于当前温度,则输出 1,否则输出 0。但是,所有预测似乎都输出 0。这不是一个不平衡的数据集(约 50% 均分)。以下是我正在使用的代码:

import os
import math

import tensorflow as tf
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score

mpl.rcParams['figure.figsize'] = (8, 6)
mpl.rcParams['axes.grid'] = False


# In[2]:


zip_path = tf.keras.utils.get_file(
    origin='https://storage.googleapis.com/tensorflow/tf-keras-datasets/jena_climate_2009_2016.csv.zip',
    fname='jena_climate_2009_2016.csv.zip',
    extract=True)
csv_path, _ = os.path.splitext(zip_path)

df = pd.read_csv(csv_path)
df.head()


# In[3]:


TRAIN_SPLIT = 0.70
VAL_SPLIT = 0.20
tf.random.set_seed(13)


# In[4]:


def create_time_steps(length):
  return list(range(-length, 0))

# In[7]:


def baseline(history):
  return np.mean(history)


# In[8]:


features_considered = ['p (mbar)', 'T (degC)', 'rho (g/m**3)']
features = df[features_considered]
features.index = df['Date Time']
features.head()


# In[9]:


features.plot(subplots=True)


# In[10]:


dataset = features.values
len_train = math.floor(TRAIN_SPLIT * len(dataset))
len_val = math.floor(VAL_SPLIT * len(dataset))
data_mean = dataset[:len_train].mean(axis = 0)
data_std = dataset[:len_train].std(axis = 0)
dataset = (dataset - data_mean) / data_std


# In[11]:


def multivariate_data(dataset, target, start_index, end_index, history_size,
                      target_size, step):
  data = []
  labels = []
  vals = []

  start_index = start_index + history_size
  if end_index is None:
    end_index = len(dataset) - target_size

  for i in range(start_index, end_index):
    indices = range(i-history_size, i, step)
    data.append(dataset[indices])
    target_var = 1 if target[i + target_size] > target[i - 1] else 0
    labels.append(target_var)
    vals.append(target[i + target_size])

  return np.array(data), np.array(labels), np.array(vals)


# In[12]:


past_history = 720
future_target = 72
STEP = 6

x_train, y_train, v_train = multivariate_data(dataset, dataset[:, 1], 0, len_train, past_history, future_target, STEP)
x_val, y_val, v_val = multivariate_data(dataset, dataset[:, 1], len_train, len_train + len_val, past_history, future_target, STEP)
x_test, y_test, v_test = multivariate_data(dataset, dataset[:, 1], len_train + len_val, None, past_history, future_target, STEP)

print(len(x_train), len(x_val), len(x_test))


# In[13]:


print ('Single window of past history : {}'.format(x_train[0].shape))


# In[15]:


model = tf.keras.models.Sequential()
model.add(tf.keras.layers.LSTM(32, input_shape = x_train.shape[-2:]))
model.add(tf.keras.layers.Dense(1, activation = "sigmoid"))
model.compile(optimizer = 'adam', loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), metrics=['accuracy'])


# In[16]:


print(model.predict(x_test[:1]).shape)


# In[26]:


EVALUATION_INTERVAL = 200
EPOCHS = 10

single_step_history = model.fit(x_train, y_train, batch_size = BATCH_SIZE, epochs = EPOCHS,
                                steps_per_epoch = EVALUATION_INTERVAL,
                                validation_data = val_data,
                                validation_steps = 50)


# In[18]:


EVALUATION_INTERVAL = 200
EPOCHS = 1

single_step_history = model.fit(train_data, epochs=EPOCHS,
                                            steps_per_epoch=EVALUATION_INTERVAL,
                                            validation_data=val_data,
                                            validation_steps=50)


# Evaluate the model on the test data using `evaluate`
print('\n# Evaluate on test data')
results = model.evaluate(x_test, y_test, batch_size = 256)
print('Loss, Acc:', results)


# In[21]:


predictions = tf.argmax(model.predict(x_test), axis = 1)
print('predictions shape:', predictions.shape)


# In[22]:


df = pd.DataFrame(None, columns = ['actual', 'prediction'])
df['actual'] = y_test
df['prediction'] = predictions.numpy()
df.head()

print(df.loc[:, 'prediction'].sum())

我使用了 BinaryCrossEntropy 损失并尝试了“tanh”和“sigmoid”激活(在输出层中),但输出始终相同(所有行均为 0)。这里可能有什么问题?请帮忙。

【问题讨论】:

    标签: python tensorflow machine-learning classification lstm


    【解决方案1】:

    所以基本上,sigmoid 激活将返回一个介于 0.0 和 1.0 之间的值,这基本上表示样本属于 1 类的概率。

    要获得实际标签,而不是执行 argmax,您需要检查它是否 > 0.5,如果是,则该样本被分配 label=1,否则它被分配 label=0。

    您可以用以下内容替换您最初的预测分配:

    predictions = model.predict(x_test)
    predictions = (predictions < 0.5).astype(np.int)
    print('predictions shape:', predictions.shape)
    
    df = pd.DataFrame(None, columns = ['actual', 'prediction'])
    df['actual'] = y_test
    df['prediction'] = predictions
    df.head()
    
    print(df.loc[:, 'prediction'].sum())
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2017-09-14
      • 2021-06-13
      • 2018-09-24
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多