Criando um gerador da lista de sequências para RNN

votos
6

Eu preciso criar um gerador para os meus dados para passar para a minha função de treinamento RNN. I tem uma lista das amostras dos pacientes, em que cada amostra é uma série temporal de comprimento n i (que varia, irritante) em três dimensões, e que deseja criar lotes de dados, onde cada uma das amostras num lote pertence apenas a um único paciente mas cada lote pode conter múltiplas amostras. Fazendo dessa forma, deve maximizar o número de amostras que podem treinar usando sem consequências como meu RNN não é stateful . No começo eu tinha a seguinte função

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)

No entanto, este recorta cada uma das amostras dos pacientes, a fim de se ajustar ao tamanho do lote. Então eu quero algo que cria todos os lotes possíveis, incluindo a subdimensionado no final. No entanto a minha falta de familiaridade com geradores me deixou bastante confuso. Até agora eu tenho trabalhado para fora que vai ter que usar aritmetic modulo, mas exatamente como eu não tenho certeza, então eu só tenho a este ponto:

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):
        ...

EDIT Aqui está um pequeno exemplo para mostrar como eu iria resolver o problema sem o uso de geradores

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

Que produz:

[[[[  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]]]]

Que, como você pode ver tem dois lotes de tamanho de três, os quais contêm dois 'pacientes' diferentes neles, mas a série de tempo para cada 'paciente' não se sobrepõem.

Publicado 23/03/2016 em 10:07
fonte usuário
Em outras línguas...                            


1 respostas

votos
-1

Não está exatamente claro o que você está procurando. Uma pequena amostra de entrada e de saída desejada ajudaria. No entanto, eu vou tomar uma facada em que eu acho que você está perguntando:

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]
Respondeu 02/04/2016 em 05:33
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more