从RNN的序列列表创建生成器

时间:2016-03-23 12:07:43

标签: python batch-processing keras

我需要为我的数据创建一个生成器,以传递到我的RNN训练函数中。我有一份患者样本列表,其中每个样本都是一个长度为 n i 的时间序列(在三维空间中变化,烦人),我想创建一批数据中批次中的每个样本仅属于单个患者,但每个批次可能包含多个患者样本。这样做可以最大化我可以训练的样本数量而不会产生任何后果,因为我的RNN不是stateful。起初我有以下功能

def dataIterator(rawDataList, config):
    batchSize, nSteps = config.batchSize, config.nSteps
    for rawData in rawDataList:
        dataLen, dataWidth = rawData.shape
        batchLen = dataLen // batchSize
        data = np.zeros([batchSize, batchLen, dataWidth], dtype=np.float32)
        for i in xrange(batchSize):
            data[i] = rawData[batchLen*i:batchLen*(i+1), :]

        epochSize = (batchLen - 1) // nSteps

        if epochSize == 0:
            raise ValueError('epoch_size == 0')

        for i in xrange(epochSize):
            x = data[:, i*nSteps:(i+1)*nSteps, :]
            y = data[:, i*nSteps+1:(i+1)*nSteps+1, :]
            yield (x, y)

然而,这会修剪每个患者样本以适应批量大小。所以我想要创造所有可能批次的东西,包括最后的小号。然而,我对发电机的不熟悉让我非常困惑。到目前为止,我已经解决了它将不得不使用modulo aritmetic,但确切地说我不确定,所以我只是到了这一步:

def dataIterator(data, batchSize=batchSize, nSteps=nSteps, nDimensions=3):
    nTimePoints = sum([len(x) for x in data])
    totalBatchLen = 1+(nTimePoints-1)//batchSize
    newData = np.zeros([batchSize, totalBatchLen, nDimensions])
    for i in xrange(batchSize):
        ...

修改 这是一个简短的例子,展示如何在不使用生成器的情况下解决问题

import numpy as np
np.random.seed(42)
nPatients = 3
tsLength = 5
nDimensions = 3
rnnTSLength = 3
batchSize = 3
inputData = np.random.random((nPatients, tsLength, nDimensions))
inputData[1, :, :] *= 10
inputData[2, :, :] *= 100
outputData = []
for i in xrange(tsLength-rnnTSLength):
    outputData.append(inputData[0, i:i+rnnTSLength, :])
for i in xrange(tsLength-rnnTSLength):
    outputData.append(inputData[1, i:i+rnnTSLength, :])
for i in xrange(tsLength-rnnTSLength):
    outputData.append(inputData[2, i:i+rnnTSLength, :])
temp1 = np.array(outputData[:3])
temp2 = np.array(outputData[3:])
npOutput = np.array((temp1, temp2))
print npOutput

产生:

[[[[  3.74540119e-01   9.50714306e-01   7.31993942e-01]
[  5.98658484e-01   1.56018640e-01   1.55994520e-01]
[  5.80836122e-02   8.66176146e-01   6.01115012e-01]]

[[  5.98658484e-01   1.56018640e-01   1.55994520e-01]
[  5.80836122e-02   8.66176146e-01   6.01115012e-01]
[  7.08072578e-01   2.05844943e-02   9.69909852e-01]]

[[  1.83404510e+00   3.04242243e+00   5.24756432e+00]
[  4.31945019e+00   2.91229140e+00   6.11852895e+00]
[  1.39493861e+00   2.92144649e+00   3.66361843e+00]]]


[[[  4.31945019e+00   2.91229140e+00   6.11852895e+00]
[  1.39493861e+00   2.92144649e+00   3.66361843e+00]
[  4.56069984e+00   7.85175961e+00   1.99673782e+00]]

[[  6.07544852e+01   1.70524124e+01   6.50515930e+00]
[  9.48885537e+01   9.65632033e+01   8.08397348e+01]
[  3.04613769e+01   9.76721140e+00   6.84233027e+01]]

[[  9.48885537e+01   9.65632033e+01   8.08397348e+01]
[  3.04613769e+01   9.76721140e+00   6.84233027e+01]
[  4.40152494e+01   1.22038235e+01   4.95176910e+01]]]]

你可以看到其中有两批3号,其中两个都包含两个不同的“病人”,但每个“病人”的时间序列不重叠。

1 个答案:

答案 0 :(得分:-1)

目前还不清楚你在寻找什么。一小部分输入和所需输出将有所帮助。不过,我会抨击我认为你在问的问题:

def dataIterator(data, batchSize=batchSize):
    for patient_data in data:
        for n in range(0, len(patient_data), batchSize):
            yield patient_data[n:n+batchSize]