PyTorch 置换在 RCNN 中的使用
Use of PyTorch permute in RCNN
我正在研究使用 PyTorch 进行文本分类的 RCNN 实现。 Full Code。有两点使用 permute
函数置换张量的维度。第一个是在 LSTM 层之后和 tanh 之前。第二个是在线性层之后和最大池化层之前。
能否请您解释一下为什么排列是必要的或有用的?
相关代码
def forward(self, x):
# x.shape = (seq_len, batch_size)
embedded_sent = self.embeddings(x)
# embedded_sent.shape = (seq_len, batch_size, embed_size)
lstm_out, (h_n,c_n) = self.lstm(embedded_sent)
# lstm_out.shape = (seq_len, batch_size, 2 * hidden_size)
input_features = torch.cat([lstm_out,embedded_sent], 2).permute(1,0,2)
# final_features.shape = (batch_size, seq_len, embed_size + 2*hidden_size)
linear_output = self.tanh(
self.W(input_features)
)
# linear_output.shape = (batch_size, seq_len, hidden_size_linear)
linear_output = linear_output.permute(0,2,1) # Reshaping fot max_pool
max_out_features = F.max_pool1d(linear_output, linear_output.shape[2]).squeeze(2)
# max_out_features.shape = (batch_size, hidden_size_linear)
max_out_features = self.dropout(max_out_features)
final_out = self.fc(max_out_features)
return self.softmax(final_out)
其他存储库中的类似代码
RCNN 的类似实现使用 permute
或 transpose
。以下是示例:
permute
函数所做的是根据所需的顺序重新排列原始张量,注意permute
与reshape
函数不同,因为当应用 permute
时,张量中的元素遵循您提供的索引,而在 reshape
中不是。
示例代码:
import torch
var = torch.randn(2, 4)
pe_var = var.permute(1, 0)
re_var = torch.reshape(var, (4, 2))
print("Original size:\n{}\nOriginal var:\n{}\n".format(var.size(), var) +
"Permute size:\n{}\nPermute var:\n{}\n".format(pe_var.size(), pe_var) +
"Reshape size:\n{}\nReshape var:\n{}\n".format(re_var.size(), re_var))
输出:
Original size:
torch.Size([2, 4])
Original var:
tensor([[ 0.8250, -0.1984, 0.5567, -0.7123],
[-1.0503, 0.0470, -1.9473, 0.9925]])
Permute size:
torch.Size([4, 2])
Permute var:
tensor([[ 0.8250, -1.0503],
[-0.1984, 0.0470],
[ 0.5567, -1.9473],
[-0.7123, 0.9925]])
Reshape size:
torch.Size([4, 2])
Reshape var:
tensor([[ 0.8250, -0.1984],
[ 0.5567, -0.7123],
[-1.0503, 0.0470],
[-1.9473, 0.9925]])
考虑到 permute
的作用,我们可以看到首先 permute
所做的是重新排序连接张量以使其适合 self.W
的输入格式,即批处理为第一维;第二个 permute
做类似的事情,因为我们想沿着序列最大池化 linear_output
,而 F.max_pool1d
将沿着最后一个维度池化。
我添加这个答案是为了提供更多特定于 PyTorch 的详细信息。
需要在nn.LSTM
和nn.Linear
之间使用permute
,因为LSTM的输出形状与Linear的预期输入形状不对应。
nn.LSTM
输出 output, (h_n, c_n)
。张量 output
的形状为 seq_len, batch, num_directions * hidden_size
nn.LSTM. nn.Linear
expects an input tensor with shape N,∗,H
, where N
is batch size and H
is number of input features. nn.Linear.
需要在nn.Linear
和nn.MaxPool1d
之间使用permute
,因为nn.Linear
的输出是N,L,C,其中N是batch size,C是特征的数量,L是序列长度。 nn.MaxPool1d
需要形状为 N、C、L 的输入张量。nn.MaxPool1d
我在 GitHub 和 gitee 上用 PyTorch 回顾了 RCNN 的七种文本分类实现,发现 permute
和 transpose
是将一层的输出转换为后续层的输入。
我正在研究使用 PyTorch 进行文本分类的 RCNN 实现。 Full Code。有两点使用 permute
函数置换张量的维度。第一个是在 LSTM 层之后和 tanh 之前。第二个是在线性层之后和最大池化层之前。
能否请您解释一下为什么排列是必要的或有用的?
相关代码
def forward(self, x):
# x.shape = (seq_len, batch_size)
embedded_sent = self.embeddings(x)
# embedded_sent.shape = (seq_len, batch_size, embed_size)
lstm_out, (h_n,c_n) = self.lstm(embedded_sent)
# lstm_out.shape = (seq_len, batch_size, 2 * hidden_size)
input_features = torch.cat([lstm_out,embedded_sent], 2).permute(1,0,2)
# final_features.shape = (batch_size, seq_len, embed_size + 2*hidden_size)
linear_output = self.tanh(
self.W(input_features)
)
# linear_output.shape = (batch_size, seq_len, hidden_size_linear)
linear_output = linear_output.permute(0,2,1) # Reshaping fot max_pool
max_out_features = F.max_pool1d(linear_output, linear_output.shape[2]).squeeze(2)
# max_out_features.shape = (batch_size, hidden_size_linear)
max_out_features = self.dropout(max_out_features)
final_out = self.fc(max_out_features)
return self.softmax(final_out)
其他存储库中的类似代码
RCNN 的类似实现使用 permute
或 transpose
。以下是示例:
permute
函数所做的是根据所需的顺序重新排列原始张量,注意permute
与reshape
函数不同,因为当应用 permute
时,张量中的元素遵循您提供的索引,而在 reshape
中不是。
示例代码:
import torch
var = torch.randn(2, 4)
pe_var = var.permute(1, 0)
re_var = torch.reshape(var, (4, 2))
print("Original size:\n{}\nOriginal var:\n{}\n".format(var.size(), var) +
"Permute size:\n{}\nPermute var:\n{}\n".format(pe_var.size(), pe_var) +
"Reshape size:\n{}\nReshape var:\n{}\n".format(re_var.size(), re_var))
输出:
Original size:
torch.Size([2, 4])
Original var:
tensor([[ 0.8250, -0.1984, 0.5567, -0.7123],
[-1.0503, 0.0470, -1.9473, 0.9925]])
Permute size:
torch.Size([4, 2])
Permute var:
tensor([[ 0.8250, -1.0503],
[-0.1984, 0.0470],
[ 0.5567, -1.9473],
[-0.7123, 0.9925]])
Reshape size:
torch.Size([4, 2])
Reshape var:
tensor([[ 0.8250, -0.1984],
[ 0.5567, -0.7123],
[-1.0503, 0.0470],
[-1.9473, 0.9925]])
考虑到 permute
的作用,我们可以看到首先 permute
所做的是重新排序连接张量以使其适合 self.W
的输入格式,即批处理为第一维;第二个 permute
做类似的事情,因为我们想沿着序列最大池化 linear_output
,而 F.max_pool1d
将沿着最后一个维度池化。
我添加这个答案是为了提供更多特定于 PyTorch 的详细信息。
需要在nn.LSTM
和nn.Linear
之间使用permute
,因为LSTM的输出形状与Linear的预期输入形状不对应。
nn.LSTM
输出 output, (h_n, c_n)
。张量 output
的形状为 seq_len, batch, num_directions * hidden_size
nn.LSTM. nn.Linear
expects an input tensor with shape N,∗,H
, where N
is batch size and H
is number of input features. nn.Linear.
需要在nn.Linear
和nn.MaxPool1d
之间使用permute
,因为nn.Linear
的输出是N,L,C,其中N是batch size,C是特征的数量,L是序列长度。 nn.MaxPool1d
需要形状为 N、C、L 的输入张量。nn.MaxPool1d
我在 GitHub 和 gitee 上用 PyTorch 回顾了 RCNN 的七种文本分类实现,发现 permute
和 transpose
是将一层的输出转换为后续层的输入。