python – LSTM – 对部分序列进行预测

这问题是继续到previous question我问过.

我已经训练了一个LSTM模型来预测100个样本的批次的二进制类(1或0),每个样本有3个特征,即:数据的形状是(m,100,3),其中m是批次的数量.

数据:

[
    [[1,2,3],[1,3]... 100 sampels],[[1,... avaialble batches in the training data
]

目标:

[
   [1]
   [0]
   ...
]

型号代码

def build_model(num_samples,num_features,is_training):
    model = Sequential()
    opt = optimizers.Adam(lr=0.0005,beta_1=0.9,beta_2=0.999,epsilon=1e-08,decay=0.0001)

    batch_size = None if is_training else 1
    stateful = False if is_training else True
    first_lstm = LSTM(32,batch_input_shape=(batch_size,num_samples,num_features),return_sequences=True,activation='tanh',stateful=stateful)

    model.add(first_lstm)
    model.add(LeakyReLU())
    model.add(Dropout(0.2))
    model.add(LSTM(16,stateful=stateful))
    model.add(Dropout(0.2))
    model.add(LeakyReLU())
    model.add(LSTM(8,return_sequences=False,stateful=stateful))
    model.add(LeakyReLU())
    model.add(Dense(1,activation='sigmoid'))

    if is_training:
        model.compile(loss='binary_crossentropy',optimizer=opt,metrics=['accuracy',keras_metrics.precision(),keras_metrics.recall(),f1])
    return model

对于训练阶段,模型不是有状态的.在预测我正在使用有状态模型时,迭代数据并输出每个样本的概率:

for index,row in data.iterrows():
    if index % 100 == 0:
        predicting_model.reset_states()
    vals = np.array([[row[['a','b','c']].values]])
    prob = predicting_model.predict_on_batch(vals)

当查看批处理结束时的概率时,它正是我用整个批处理预测时得到的值(不是一个一个).但是,我预计当新样本到达时,概率将始终在正确的方向上继续.实际发生的是,概率输出可能会在任意样本上出现错误的类别(见下文).

预测时100个样品批次的两个样品(标签= 1):

enter image description here

和Label = 0:

enter image description here

有没有办法实现我想要的(避免极端尖峰,同时预测概率),或者这是一个给定的事实?

任何解释,建议将不胜感激.

更新
感谢@today建议,我尝试使用最后一个LSTM层上的return_sequence = True为每个输入时间步骤训练网络隐藏状态输出.

所以现在标签看起来像这样(形状(100,100)):

[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
...]

模型摘要

Layer (type)                 Output Shape              Param #   
=================================================================
lstm_1 (LSTM)                (None,32)           4608      
_________________________________________________________________
leaky_re_lu_1 (LeakyReLU)    (None,32)           0         
_________________________________________________________________
dropout_1 (Dropout)          (None,32)           0         
_________________________________________________________________
lstm_2 (LSTM)                (None,16)           3136      
_________________________________________________________________
dropout_2 (Dropout)          (None,16)           0         
_________________________________________________________________
leaky_re_lu_2 (LeakyReLU)    (None,16)           0         
_________________________________________________________________
lstm_3 (LSTM)                (None,8)            800       
_________________________________________________________________
leaky_re_lu_3 (LeakyReLU)    (None,8)            0         
_________________________________________________________________
dense_1 (Dense)              (None,1)            9         
=================================================================
Total params: 8,553
Trainable params: 8,553
Non-trainable params: 0
_________________________________________________________________

但是,我得到一个例外:

ValueError: Error when checking target: expected dense_1 to have 3 dimensions,but got array with shape (75,100)

我需要修理什么?

最佳答案
注意:这只是一个想法,可能是错误的.如果您愿意,请尝试一下,我将不胜感激任何反馈.

Is there a way to achieve what I want (avoid extreme spikes while
predicting probability),or is that a given fact?

您可以执行此实验:将最后一个LSTM图层的return_sequences参数设置为True,并复制每个样本的标签,与每个样本的长度一样多.例如,如果样本的长度为100且其标签为0,则为此样本创建一个由100个零组成的新标签(您可以使用像np.repeat这样的numpy函数轻松完成此操作).然后重新训练您的新模型,然后在新样本上进行测试.我不确定这一点,但这次我会期待更多单调增加/减少的概率图.

更新:您提到的错误是由标签应该是3D数组(在模型摘要中查看最后一层的输出形状)引起的.使用np.expand_dims将另一个大小为1的轴添加到末尾.假设y_train的形状为(num_samples,),重复标签的正确方法如下所示:

rep_y_train = np.repeat(y_train,num_reps).reshape(-1,num_reps,1)

关于IMDB数据集的实验:

实际上,我使用带有一个LSTM层的简单模型尝试了上面在IMDB数据集上建议的实验.有一次,我每个样本只使用一个标签(如@Shlomi的原始方法),另一次我复制标签,每个时间步长一个标签(如上所述).如果您想自己尝试,请输入以下代码

from keras.layers import *
from keras.models import Sequential,Model
from keras.datasets import imdb
from keras.preprocessing.sequence import pad_sequences
import numpy as np

vocab_size = 10000
max_len = 200
(x_train,y_train),(x_test,y_test) = imdb.load_data(num_words=vocab_size)
X_train = pad_sequences(x_train,maxlen=max_len)

def create_model(return_seq=False,stateful=False):
    batch_size = 1 if stateful else None
    model = Sequential()
    model.add(Embedding(vocab_size,128,None)))
    model.add(CuDNNLSTM(64,return_sequences=return_seq,stateful=stateful))
    model.add(Dense(1,activation='sigmoid'))

    model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['acc'])
    return model

# train model with one label per sample
train_model = create_model()
train_model.fit(X_train,y_train,epochs=10,batch_size=128,validation_split=0.3)

# replicate the labels
y_train_rep = np.repeat(y_train,max_len).reshape(-1,max_len,1)

# train model with one label per timestep
rep_train_model = create_model(True)
rep_train_model.fit(X_train,y_train_rep,validation_split=0.3)

然后我们可以创建训练模型的有状态副本,并在一些测试数据上运行它们来比较它们的结果:

# replica of `train_model` with the same weights
test_model = create_model(False,True)
test_model.set_weights(train_model.get_weights())
test_model.reset_states()

# replica of `rep_train_model` with the same weights
rep_test_model = create_model(True,True)
rep_test_model.set_weights(rep_train_model.get_weights())
rep_test_model.reset_states()

def stateful_predict(model,samples):
    preds = []
    for s in samples:
        model.reset_states()
        ps = []
        for ts in s:
            p = model.predict(np.array([[ts]]))
            ps.append(p[0,0])
        preds.append(list(ps))
    return preds

X_test = pad_sequences(x_test,maxlen=max_len)

实际上,X_test的第一个样本具有0标签(即属于负类),而X_test的第二个样本具有1个标签(即属于正类).因此,让我们首先看看这两个样本的test_model的状态预测(即每个样本使用一个标签训练的那个)看起来如下:

import matplotlib.pyplot as plt

preds = stateful_predict(test_model,X_test[0:2])

plt.plot(preds[0])
plt.plot(preds[1])
plt.legend(['Class 0','Class 1'])

结果:

<code>test_model</code> stateful predictions

最后的正确标签(即概率)(即时间步长200),但其间非常尖锐且波动.现在让我们将它与rep_test_model的有状态预测进行比较(即每个时间步使用一个标签训练的那个):

preds = stateful_predict(rep_test_model,'Class 1'])

结果:

<code>rep_test_model</code> stateful predictions

再次,正确的标签预测结束,但这次正如预期的那样更加平滑和单调的趋势.

请注意,这只是演示的一个示例,因此我在这里使用了一个非常简单的模型,只有一个LSTM层,而我根本没有尝试调整它.我想通过更好地调整模型(例如调整层数,每层中的单元数,使用的激活函数,优化器类型和参数等),您可能会得到更好的结果.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我最近重新拾起了计算机视觉,借助Python的opencv还有face_recognition库写了个简单的图像识别demo,额外定制了一些内容,原本想打包成exe然后发给朋友,不过在这当中遇到了许多小问题,都解决了,记录一下踩过的坑。 1、Pyinstaller打包过程当中出现warning,跟d
说到Pooling,相信学习过CNN的朋友们都不会感到陌生。Pooling在中文当中的意思是“池化”,在神经网络当中非常常见,通常用的比较多的一种是Max Pooling,具体操作如下图: 结合图像理解,相信你也会大概明白其中的本意。不过Pooling并不是只可以选取2x2的窗口大小,即便是3x3,
记得大一学Python的时候,有一个题目是判断一个数是否是复数。当时觉得比较复杂不好写,就琢磨了一个偷懒的好办法,用异常处理的手段便可以大大程度帮助你简短代码(偷懒)。以下是判断整数和复数的两段小代码: 相信看到这里,你也有所顿悟,能拓展出更多有意思的方法~
文章目录 3 直方图Histogramplot1. 基本直方图的绘制 Basic histogram2. 数据分布与密度信息显示 Control rug and density on seaborn histogram3. 带箱形图的直方图 Histogram with a boxplot on t
文章目录 5 小提琴图Violinplot1. 基础小提琴图绘制 Basic violinplot2. 小提琴图样式自定义 Custom seaborn violinplot3. 小提琴图颜色自定义 Control color of seaborn violinplot4. 分组小提琴图 Group
文章目录 4 核密度图Densityplot1. 基础核密度图绘制 Basic density plot2. 核密度图的区间控制 Control bandwidth of density plot3. 多个变量的核密度图绘制 Density plot of several variables4. 边
首先 import tensorflow as tf tf.argmax(tenso,n)函数会返回tensor中参数指定的维度中的最大值的索引或者向量。当tensor为矩阵返回向量,tensor为向量返回索引号。其中n表示具体参数的维度。 以实际例子为说明: import tensorflow a
seaborn学习笔记章节 seaborn是一个基于matplotlib的Python数据可视化库。seaborn是matplotlib的高级封装,可以绘制有吸引力且信息丰富的统计图形。相对于matplotlib,seaborn语法更简洁,两者关系类似于numpy和pandas之间的关系,seabo
Python ConfigParser教程显示了如何使用ConfigParser在Python中使用配置文件。 文章目录 1 介绍1.1 Python ConfigParser读取文件1.2 Python ConfigParser中的节1.3 Python ConfigParser从字符串中读取数据
1. 处理Excel 电子表格笔记(第12章)(代码下载) 本文主要介绍openpyxl 的2.5.12版处理excel电子表格,原书是2.1.4 版,OpenPyXL 团队会经常发布新版本。不过不用担心,新版本应该在相当长的时间内向后兼容。如果你有新版本,想看看它提供了什么新功能,可以查看Open
1. 发送电子邮件和短信笔记(第16章)(代码下载) 1.1 发送电子邮件 简单邮件传输协议(SMTP)是用于发送电子邮件的协议。SMTP 规定电子邮件应该如何格式化、加密、在邮件服务器之间传递,以及在你点击发送后,计算机要处理的所有其他细节。。但是,你并不需要知道这些技术细节,因为Python 的
文章目录 12 绘图实例(4) Drawing example(4)1. Scatterplot with varying point sizes and hues(relplot)2. Scatterplot with categorical variables(swarmplot)3. Scat
文章目录 10 绘图实例(2) Drawing example(2)1. Grouped violinplots with split violins(violinplot)2. Annotated heatmaps(heatmap)3. Hexbin plot with marginal dist
文章目录 9 绘图实例(1) Drawing example(1)1. Anscombe’s quartet(lmplot)2. Color palette choices(barplot)3. Different cubehelix palettes(kdeplot)4. Distribution
Python装饰器教程展示了如何在Python中使用装饰器基本功能。 文章目录 1 使用教程1.1 Python装饰器简单示例1.2 带@符号的Python装饰器1.3 用参数修饰函数1.4 Python装饰器修改数据1.5 Python多层装饰器1.6 Python装饰器计时示例 2 参考 1 使
1. 用GUI 自动化控制键盘和鼠标第18章 (代码下载) pyautogui模块可以向Windows、OS X 和Linux 发送虚拟按键和鼠标点击。根据使用的操作系统,在安装pyautogui之前,可能需要安装一些其他模块。 Windows: 不需要安装其他模块。OS X: sudo pip3
文章目录 生成文件目录结构多图合并找出文件夹中相似图像 生成文件目录结构 生成文件夹或文件的目录结构,并保存结果。可选是否滤除目录,特定文件以及可以设定最大查找文件结构深度。效果如下: root:[z:/] |--a.py |--image | |--cat1.jpg | |--cat2.jpg |
文章目录 VENN DIAGRAM(维恩图)1. 具有2个分组的基本的维恩图 Venn diagram with 2 groups2. 具有3个组的基本维恩图 Venn diagram with 3 groups3. 自定义维恩图 Custom Venn diagram4. 精致的维恩图 Elabo
mxnet60分钟入门Gluon教程代码下载,适合做过深度学习的人使用。入门教程地址: https://beta.mxnet.io/guide/getting-started/crash-course/index.html mxnet安装方法:pip install mxnet 1 在mxnet中使
文章目录 1 安装2 快速入门2.1 基本用法2.2 输出图像格式2.3 图像style设置2.4 属性2.5 子图和聚类 3 实例4 如何进一步使用python graphviz Graphviz是一款能够自动排版的流程图绘图软件。python graphviz则是graphviz的python实