es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Forma eficiente de enviar un tensor de datos a través de una función sin un bucle.

Tengo una red neuronal (mi función):

import torch
import torch.nn as nn
import torch.optim as optim

softplus = torch.nn.Softplus()

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.fc1 = nn.Linear(4, 10)
        self.fc2 = nn.Linear(10, 10)
        self.fc3 = nn.Linear(10, 1)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = softplus(self.fc3(x))
        return x

net = Model()

También tengo datos en forma de un tensor grande (ten en cuenta que aquí hay un ejemplo pequeño) que se genera sobre la marcha (es decir, en cada época obtengo un nuevo tensor):

for epoch in range(10):
    data = torch.rand(5,3)

Estos datos deben enviarse a la red. La dificultad es que mi función debe tomar 4 valores como entrada, donde 3 de ellos son cada uno de los tensores en el tensor de datos (5×3 para 5 triples en este ejemplo), y la cuarta entrada es la suma de las salidas anteriores de la función. El primer triple se combina con un valor inicial de 0:

init_value = torch.tensor([0])
torch.cat((data[0],init_value))

Por lo tanto, para mi primera entrada, concateno el init_value y lo envío a la función. Si esta función produce una salida de valor 1.2, necesito enviar el siguiente triple a la red como [x, y, z, 0+1.2], donde x, y, z es el segundo triple del tensor de datos. Según aquí, parece que torch.cat funciona con la operación backward que se necesita y por eso lo estoy usando.

¿Hay alguna manera eficiente de hacer esto? Actualmente, lo que estoy haciendo es usar un bucle for, enviando cada tensor del tensor de datos a la red y concatenando la suma de los valores hasta el momento. Pero dado que este es un tensor muy grande, no es muy óptimo.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una posible solución a este problema es utilizar las clases DataLoader y IterableDataset de PyTorch para generar el tensor de datos sobre la marcha y enviarlo a la red neuronal.

    En primer lugar, podemos definir una clase personalizada IterableDataset que genere el tensor de datos sobre la marcha utilizando la declaración yield. Para realizar un seguimiento de la suma acumulada de las salidas de la función, podemos definir una variable prev_output que inicialmente se establece en cero.

    class MyDataset(torch.utils.data.IterableDataset):
        def __iter__(self):
            prev_output = torch.zeros(1)
            for i in range(10):
                data = torch.rand(5,3)
                for j in range(5):
                    if j == 0:
                        x = torch.cat((data[j], prev_output))
                    else:
                        x = torch.cat((data[j], prev_output.item()))
                    yield x, prev_output
                    prev_output += net(x)
    

    A continuación, podemos utilizar un DataLoader para iterar sobre los datos en lotes y enviarlos a la red neuronal para su entrenamiento.

    dataset = MyDataset()
    dataloader = torch.utils.data.DataLoader(dataset, batch_size=1)
    
    for x, prev_output in dataloader:
        # realizar paso hacia adelante y hacia atrás
    

    Este enfoque debería ser más eficiente que utilizar un bucle ‘for’ para iterar sobre el tensor de datos, ya que solo genera datos sobre la marcha según sea necesario y evita asignaciones de memoria innecesarias.

Comments are closed.