Я хочу использовать Conv1D и MaxPool1D в pytorch для трехмерного тензора в его третьем измерении

#pytorch #convolution #tensor #max-pooling

#pytorch #свертка #тензор #максимальное объединение

Вопрос:

Например, существует трехмерный тензор, я хочу выполнить вычисление conv1d для его третьего измерения,

 import torch
import torch.nn as nn
x = torch.rand(4,5,6)
conv1d =nn.Conv1d(in_channels=1,out_channels=2,kernel_size=5,stride=3,padding=0)
y = conv1d(x)
  

Я надеюсь, что форма y равна (4,5,2, -1), но я получаю сообщение об ошибке

Заданные группы = 1, вес размера [2, 1, 5], ожидаемый ввод [4, 5, 6] для 1 канала, но вместо этого получил 5 каналов

Затем я изменил код,

 import torch
import torch.nn as nn
x = torch.rand(4,5,6)
conv1d =nn.Conv1d(in_channels=1,out_channels=2,kernel_size=5,stride=3,padding=0)
x = x.unsqueeze(2)
y = conv1d(x)
  

Есть еще одна ошибка:

Ожидаемый трехмерный ввод для трехмерного веса [2, 1, 5], но вместо этого получил 4-мерный ввод размера [4, 5, 1, 6]

И если я хочу выполнить вычисление maxpoo1d в тензоре, форма которого равна (4,5,2, -1), в его последних двух измерениях, что мне делать?

Я долго ищу в сети. Но бесполезно. Пожалуйста, помогите или попробуйте дать несколько идей, как этого добиться. Спасибо всем за вашу помощь.

Я предпринял попытку, но я чувствовал, что это не может удовлетворить фактические потребности, я хотел знать, является ли это хорошей практикой для этого и каков наилучший способ сделать это?

 import torch
import torch.nn as nn
x = torch.rand(4,5,6)
conv1d =nn.Conv1d(in_channels=1,out_channels=2,kernel_size=2,stride=3,padding=0)
x = x.unsqueeze(2)
for i in range(4): 
    y = conv1d(x[i,:,:,:])
    y = y.unsqueeze(0)
    if i==0:
        z = y
    else:
        z = torch.cat((z,y),0)
    print(y)
print(z.size())
  

Комментарии:

1. Такая итерация серьезно замедлит скорость вычислений. У вас есть лучший способ?

Ответ №1:

Для использования Conv1d вам нужно, чтобы ваш ввод имел 3 измерения:

 [batch_size, in_channels, data_dimension]
  

Итак, это сработало бы:

 x = torch.rand(4, 1, 50)  # [batch_size=4, in_channels=1, data_dimension=50]
conv1d = nn.Conv1d(in_channels=1,out_channels=2,kernel_size=2,stride=3,padding=0)
x = conv1d(x)
print(x.shape) # Will output [4, 2, 16] 4=batch_size, 2=channels, 16=data_dimension
  

Вы можете использовать MaxPool1d таким же образом:

 maxpool1d = nn.MaxPool1d(5)
x = maxpool1d(x)
print(x.shape) # Will output [4, 2, 3]  4=batch_size, 2=channels, 3=data_dimension
  

Комментарии:

1. Я знаю, что вы имеете в виду, но на практике тензор равен (24 200 512), и мне нужно перенести его на основе Conv1D в (24 200,2, -1), вы знаете, как этого добиться?

2. (24,200,12) соответствует (batch_size, data_length, hidden_length). Фактически, я обрабатываю данные последовательности.

3. что вы подразумеваете под hidden_length? это каналы? Если последовательность имеет data_length, вы можете использовать x.transpose([1, 2]), чтобы получить размеры в правильном порядке. Кроме того, что делает «-1» (24, 200, 2, -1) имею в виду?

4. среднее значение «-1» может быть любой длины, я не уверен, а данные — это скрытые векторы batch_size * data_length, это трехмерный тензор, я хочу использовать conv1d для каждого отдельного скрытого вектора.

Ответ №2:

Я отвечаю на этот вопрос с помощью torch.reshape(). Я поместил код здесь, надеясь, что это может кому-нибудь помочь.

 import torch
import torch.nn as nn
x = torch.rand(4,5,6)
conv1d =nn.Conv1d(in_channels=1,out_channels=2,kernel_size=2,stride=3,padding=0)

y = x.reshape(x.shape[0]*x.shape[1],-1)
y = y.unsqueeze(1)
y = conv1d(y)
z = y.reshape(x.shape[0],x.shape[1],2,-1)
print(z.size())