PyTorch 前向传递使用 Theano 训练的权重

PyTorch forward pass using weights trained by Theano

我在 Theano 中训练了一个小型 CNN 二进制 classifier。为了获得更简单的代码,我想将经过训练的权重移植到 PyTorch 或 numpy 前向传递以进行预测。原始 Theano 程序的预测令人满意,但 PyTorch 前向传递将所有示例预测为一个 class。

以下是我如何使用 h5py 在 Theano 中保存训练好的权重:

layer0_w = layer0.W.get_value(borrow=True)
layer0_b = layer0.b.get_value(borrow=True)
layer1_w = layer1.W.get_value(borrow=True)
layer1_b = layer1.b.get_value(borrow=True)
layer2_w = layer2.W.get_value(borrow=True)
layer2_b = layer2.b.get_value(borrow=True)
sm_w = layer_softmax.W.get_value(borrow=True)
sm_b = layer_softmax.b.get_value(borrow=True)

h5_l0w = h5py.File('./model/layer0_w.h5', 'w')
h5_l0w.create_dataset('layer0_w', data=layer0_w)
h5_l0b = h5py.File('./model/layer0_b.h5', 'w')
h5_l0b.create_dataset('layer0_b', data=layer0_b)
h5_l1w = h5py.File('./model/layer1_w.h5', 'w')
h5_l1w.create_dataset('layer1_w', data=layer1_w)
h5_l1b = h5py.File('./model/layer1_b.h5', 'w')
h5_l1b.create_dataset('layer1_b', data=layer1_b)
h5_l2w = h5py.File('./model/layer2_w.h5', 'w')
h5_l2w.create_dataset('layer2_w', data=layer2_w)
h5_l2b = h5py.File('./model/layer2_b.h5', 'w')
h5_l2b.create_dataset('layer2_b', data=layer2_b)
h5_smw = h5py.File('./model/softmax_w.h5', 'w')
h5_smw.create_dataset('softmax_w', data=sm_w)
h5_smb = h5py.File('./model/softmax_b.h5', 'w')
h5_smb.create_dataset('softmax_b', data=sm_b)

然后加载权重以使用 Pytorch 和 Numpy 构建前向传递:

import torch
import numpy as np
import torch.nn.functional as F
def model(data):

    conv0_out = F.conv2d(input=np2var(data),
                         weight=np2var(layer0_w),
                         bias=np2var(layer0_b)
                        )
    layer0_out = relu(var2np(conv0_out))

    conv1_out = F.conv2d(input=np2var(layer0_out),
                         weight=np2var(layer1_w),
                         bias=np2var(layer1_b)
                        )
    layer1_out = np.max(relu(var2np(conv1_out)), axis=2)

    dense_out=relu(np.matmul(layer1_out, layer2_w) + layer2_b)

    softmax_out = softmax(np.matmul(dense_out, softmax_w) + softmax_b)

    return softmax_out

def relu(x):
    return x * (x > 0)
def np2var(x):
    return torch.autograd.Variable(torch.from_numpy(x))
def var2np(x):
    return x.data.numpy()
def softmax(x):
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum()

conv2d 函数的输入和内核形状对于 Theano 和 PyTorch 是相同的,并且两个框架中的网络结构是相同的。我无法一步一步检测到任何错误。这里会出什么问题?

Theano uses convolutions (by default, filter_flip=True) while PyTorch uses cross-correlation。因此,对于每个卷积层,您需要在 PyTorch 中使用它们之前翻转权重。

您可以使用 Keras 中的 convert_kernel 函数来实现此结果。