PyTorch - базовые c математические операции с массивами numpy разной формы - PullRequest
0 голосов
/ 13 июля 2020

1: У меня есть два массива numpy с разными формами, я намерен получить среднеквадратичную ошибку из результирующей операции. Массивы numpy имеют разные формы, в рамках обучения у меня есть набор проверки, отдельный от массива прогнозов numpy, но набор прогнозов был построен из массива numpy.

2 : Я пытался использовать torch.Tensor.repeat () как способ расширить набор прогнозов, но мне не хватает правильных математических расчетов для эффективного повторения.

3: метод обучения:

def train(net, x_train, x_opt, BATCH_SIZE, EPOCHS, input_dim):
    outputs = 0
    mse = 0
    optimizer = optim.SGD(net.parameters(), lr=0.001)
    loss_function = nn.MSELoss()
    loss = 0
    for epoch in range(EPOCHS):
        for i in tqdm(range(0, len(x_train), BATCH_SIZE)):
           
            batch_y = x_opt[i:i + BATCH_SIZE]
            
            net.zero_grad()
            
            outputs = net(batch_y)
            
            loss = loss_function(outputs, batch_y)
            loss.backward()
            optimizer.step()  # Does the update

        print(f"Epoch: {epoch}. Loss: {loss}")
        
    outputs = torch.Tensor.repeat(outputs, *****....***?, 1)
    return np.mean(np.power(x_opt - outputs.data.numpy(), 2), axis=1)

4: ошибка: ValueError: операнды не могут транслироваться вместе с фигурами (92334,10) (46,10)

1 Ответ

0 голосов
/ 14 июля 2020

Вы можете сделать широковещательную передачу между ними, если вы добавите большую фигуру к форме, которая делится на меньшую фигуру.

def pad_to_divisible_shape(arr, a_r, b_r):
    div = int(np.ceil(a_r/b_r))
    p = div*b_r-a_r
    return np.pad(arr, ((0,p),(0,0))), div

def broadcast_op(a, b):
    """Where a and b are numpy arrays and a.shape[0]>b.shape[0]"""
    a_r, b_r = a.shape[0], b.shape[0]
    a, div = pad_to_divisible_shape(a, a_r, b_r)
    a, b = a.reshape(div, b_r, -1), b.reshape(1, b_r, -1)
    return ((((a-b).reshape(-1, a.shape[-1]))**2).mean(axis=1))[:a_r]

a = np.random.randn(92334,10)
b = np.random.randn(46, 10)
out = broadcast_op(a,b)

Здесь a дополняется от (92334,10) до (92368 , 10). Затем a и b преобразуются в (2008,46,10) и (1,46,10), после чего операция ab может транслироваться. Фактический результат имеет форму (92368,), из которой вы можете просто удалить лишнюю часть, нарезав [: a_r].

...