我有一些需要转换为PyTorch的Keras代码。我已经做了一些研究,但到目前为止,我无法重现从Keras中获得的结果。我已经在这上面花了很多时间,任何建议或帮助都非常受欢迎。
这是我正在处理的Keras代码。输入形状为(None, 105, 768),其中None是批量大小,我希望对输入应用Conv1D。在Keras中的期望输出是(None, 105)。
x = tf.keras.layers.Dropout(0.2)(input) x = tf.keras.layers.Conv1D(1,1)(x)x = tf.keras.layers.Flatten()(x)x = tf.keras.layers.Activation('softmax')(x)
我尝试过的方法,结果较差:
self.conv1d = nn.Conv1d(768, 1, 1) self.dropout = nn.Dropout(0.2) self.softmax = nn.Softmax()def forward(self, input): x = self.dropout(input) x = x.view(x.shape[0],x.shape[2],x.shape[1]) x = self.conv1d(x) x = torch.squeeze(x, 1) x = self.softmax(x)
回答:
导致问题的关键是你试图交换输入的维度,因为Keras和PyTorch对维度顺序有不同的约定。
x = x.view(x.shape[0],x.shape[2],x.shape[1])
.view()
并不会交换维度,而是改变哪些数据属于某个维度。你可以将其视为一个1D数组,然后你决定采取多少步来覆盖这个维度。一个例子会让它更容易理解。
# 让我们从一个1D张量开始# 这就是内存中底层数据的外观x = torch.arange(6)# => tensor([0, 1, 2, 3, 4, 5])# 使用Keras的约定时张量的外观(期望输入)keras_version = x.view(2, 3)# => tensor([[0, 1, 2],# [3, 4, 5]])# 垂直和水平没有交换,但数据的排列不同# 数字仍然是从左到右递增incorrect_pytorch_version = keras_version.view(3, 2)# => tensor([[0, 1],# [2, 3],# [4, 5]])
要交换维度,你需要使用torch.transpose
。
correct_pytorch_version = keras_version.transpose(0, 1)# => tensor([[0, 3],# [1, 4],# [2, 5]])