Python 在Keras中具有RNN/LSTM的残疾人辩论者

Python 在Keras中具有RNN/LSTM的残疾人辩论者,python,machine-learning,keras,Python,Machine Learning,Keras,我正投身于机器学习,并希望将Keras用于一个时间紧迫的大学项目。我意识到学习个人概念和构建块是最好的,但重要的是要尽快做到这一点 我正在和一个对机器学习有一定经验和兴趣的人一起工作,但我们似乎无法取得更进一步的进展。以下代码改编自中提到的 在上下文中,我从多个物理传感器(其中每个传感器都是一列)获取数据,这些传感器的每个样本由一行表示。我希望使用机器学习来确定传感器在任何给定时间跟踪谁。我试图将大约80%的行分配给培训,20%分配给测试,并创建自己的“y”数据集(前521549行来自一个参与者

我正投身于机器学习,并希望将Keras用于一个时间紧迫的大学项目。我意识到学习个人概念和构建块是最好的,但重要的是要尽快做到这一点

我正在和一个对机器学习有一定经验和兴趣的人一起工作,但我们似乎无法取得更进一步的进展。以下代码改编自中提到的

在上下文中,我从多个物理传感器(其中每个传感器都是一列)获取数据,这些传感器的每个样本由一行表示。我希望使用机器学习来确定传感器在任何给定时间跟踪谁。我试图将大约80%的行分配给培训,20%分配给测试,并创建自己的“y”数据集(前521549行来自一个参与者,其余来自另一个参与者)。我的数据(训练和测试)总共有1019802行和16列(全部填充),但如果需要,可以减少列数

我很想知道以下几点:

  • 在我试图实现的上下文中,这个错误意味着什么?如何更改代码以避免它
  • 下面的代码是否适合我要实现的目标
  • 在我理解机器学习(一般或具体)的目的时,这段代码是否代表了任何特定的基本缺陷
  • 下面是我试图运行的Python代码,以利用机器学习:

    x_all = pd.read_csv("(redacted)...csv",
                    delim_whitespace=True, header=None, low_memory=False).values
    y_all = np.append(np.full((521549,1), 0), np.full((498253,1),1))
    limit = 815842
    x_train = x_all[:limit]
    y_train = y_all[:limit]
    x_test = x_all[limit:]
    y_test = y_all[limit:]
    
    max_features = 16
    maxlen = 80
    batch_size = 32
    
    model = Sequential()
    model.add(Embedding(500, 32, input_length=max_features))
    model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2))
    model.add(Dense(1, activation='sigmoid'))
    
    model.compile(loss='binary_crossentropy',
                  optimizer='adam',
                  metrics=['accuracy'])
    
    model.fit(x_train, y_train,
              batch_size=batch_size,
              epochs=15,
              validation_data=(x_test, y_test))
    score, acc = model.evaluate(x_test, y_test,
                                batch_size=batch_size)
    
    这是代码中引用的CSV的摘录:

    6698.486328125  4.28260869565217    4.6304347826087 10.6195652173913    2.4392579293836 2.56134051466188    9.05326152004788    0.0 1.0812  924.898261191267    -1.55725190839695   -0.244274809160305  0.320610687022901   -0.122938530734633  0.490254872563718   0.382308845577211   
    6706.298828125  4.28260869565217    4.58695652173913    10.5978260869565    2.4655894673848 2.50867743865949    9.04368641532017    0.0 1.0812  924.898261191267    -1.64885496183206   -0.366412213740458  0.381679389312977   -0.122938530734633  0.490254872563718   0.382308845577211   
    6714.111328125  4.26086956521739    4.64130434782609    10.5978260869565    2.45601436265709    2.57809694793537    9.03411131059246    0.0 1.0812  924.898261191267    -0.931297709923664  -0.320610687022901  0.320610687022901   -0.125937031484258  0.493253373313343   0.371814092953523   
    
    运行此操作时发生以下错误:

    tensorflow.python.framework.errors_impl.InvalidArgumentError: indices[0,0] = 972190 is not in [0, 500)
             [[Node: embedding_1/embedding_lookup = GatherV2[Taxis=DT_INT32, Tindices=DT_INT32, Tparams=DT_FLOAT, _class=["loc:@training/Adam/Assign_2"], _device="/job:localhost/replica:0/task:0/device:CPU:0"](embedding_1/embeddings/read, embedding_1/Cast, training/Adam/gradients/embedding_1/embedding_lookup_grad/concat/axis)]]
    

    作为参考,我使用的是2017款27英寸iMac Retina 5K,配有4.2 GHz i7、32 GB RAM和Radeon Pro 580 8 GB。

    还有一些关于机器学习掌握的教程,供您学习

    我会很快解释一下你可能想做什么

    现在,看起来您正在使用与模型中的X和y输入完全相同的数据。y输入是标签,在您的情况下是“传感器跟踪的对象”。因此,在有两个可能的人的二元情况下,第一个人设置为0,第二个人设置为1

    最后一层上的sigmoid激活将输出一个介于0和1之间的数字。如果数字小于0.5,则预测传感器正在跟踪人员0;如果数字大于0.5,则预测人员1。这将在准确度分数中表示

    您可能不想使用嵌入层,您可能不想使用,但我会先删除它。不过,在将数据输入网络以改进培训之前,请先对数据进行规范化。如果您需要快速解决方案,Scikit Learn提供了很好的工具。

    处理时间序列数据时,您通常希望输入时间点窗口,而不是单个时间点。如果将时间序列发送到Keras model.fit(),则它将使用单个点作为输入

    为了有一个时间窗口作为输入,您需要将数据集中的每个示例重新组织为一个完整的窗口,或者如果需要占用大量内存,您可以使用生成器。这在我链接的机器学习掌握页面中有描述。 Keras有一个你可以使用的发电机,叫做

    其中数据是要素的时间序列,目标是标签的时间序列。 如果使用timeseries生成器,则在安装时必须使用fit_生成器

    model.fit_generator(timeseries_generator)
    
    与使用evaluate_生成器()进行求值相同

    如果您的数据设置正确,那么您的模型应该可以工作

    model = Sequential()
    model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2))
    model.add(Dense(1, activation='sigmoid'))
    
    您也可以尝试更简单的密集模型

    model = Sequential()
    model.add(Flatten())
    model.add(Dense(64, dropout=0.2, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    
    我看到的另一个问题是,似乎您将拆分一个只包含一种标签类型的测试集,这不仅是不好的做法,而且还会将您的训练集与另一种标签进行加权,这可能会损害您的结果

    希望这能让你开始。确保数据设置正确

    model = Sequential()
    model.add(Flatten())
    model.add(Dense(64, dropout=0.2, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))