Skip to main content
 首页 » 编程设计

python之如何将 CNN 从 keras 转换为 mxnet

2025年05月04日11kuangbin

我有以下问题:我在 Keras 中有一个脚本,它非常有用。我现在想将此脚本转换为 MXNet。 Keras 中的 CNN 看起来像这样:

model=Sequential() 
model.add(Convolution2D(128, (3, 3), padding='same', activation='relu', name='block1_conv1', input_shape=(80,120,3))) 
model.add(MaxPooling2D((2, 2), strides=(2, 2))) 
model.add(Convolution2D(256, (3, 3), padding='same', activation='relu', name='block2_conv1')) 
model.add(MaxPooling2D((2, 2), strides=(2, 2))) 
model.add(Flatten()) 
model.add(Dense(2, activation = 'softmax', name='final_fully_connected')) 

我认为转换到 MXNet 并没有那么困难,我查看了相应的文档并尽我所知传输了参数。

model=gluon.nn.Sequential() 
with model.name_scope(): 
    model.add(gluon.nn.Conv2D(channels=128, kernel_size=(3, 3), activation='relu')) 
    model.add(gluon.nn.MaxPool2D(pool_size=(2, 2), strides=(2, 2)))             
    model.add(gluon.nn.Conv2D(channels=256, kernel_size=(3, 3), activation='relu')) 
    model.add(gluon.nn.MaxPool2D(pool_size=(2, 2), strides=(2, 2))) 
    # The Flatten layer collapses all axis, except the first one, into one axis. 
    model.add(gluon.nn.Flatten()) 
    model.add(gluon.nn.Dense(2, activation='relu')) 

但如果我现在尝试训练模型,我会收到以下错误:

“MXNetError: [17:01:34] C:\ci\libmxnet_1533399150922\work\src\operator\nn\pooling.cc:145: 检查失败:param.kernel[1] <= dshape[3] + 2 * param.pad[1] kernel size (2) exceeds input (1 padded to 1)"

我认为它与内核和 MaxPooling2D 层的维度有关,但我不明白这个错误,因为我认为我实际上是在构建与 Keras 中相同的网络。

为了完整起见:我的输入变量 X 的维度为 (80, 120, 3)。

我非常感谢一些 Keras/MXNet 专家的帮助。

请您参考如下方法:

我定义模型的函数:

# DEFINE THE MODEL 
def create_model(load_file=None): 
    num_outputs = 2                   # The number of outputs of the network 
    channels    = [128, 256]          # The number of different filters (each with other entries) in the convolution. 
    kernel_size = (3, 3)              # Specifies the dimensions of the convolution window (i.e., filter). 
    padding     = (kernel_size[0]//2,  
                   kernel_size[1]//2) # To be able to process the border regions of the input layer with the kernel (e.g., a kernel of 3x3 needs an additional neighboring cell), these are surrounded by zeros. 
    pool_size   = (2, 2)              # Specifies the size of the pooling window (i.e. region) from which the maximum value is determined. 
    strides     = (2, 2)              # Determines by how many steps the pooling window moves. A  pooling window of 2x2 and a step size of 2x2 means that the regions won't overlap. 
 
    net = gluon.nn.Sequential(prefix='cnn_') 
    with net.name_scope(): 
        net.add(gluon.nn.Conv2D(channels=channels[0], kernel_size=kernel_size, padding=padding, activation='relu')) 
        net.add(gluon.nn.MaxPool2D(pool_size=pool_size, strides=strides))             
        net.add(gluon.nn.Conv2D(channels=channels[1], kernel_size=kernel_size, padding=padding, activation='relu')) 
        net.add(gluon.nn.MaxPool2D(pool_size=pool_size, strides=strides))            
        # The Flatten layer collapses all axis, except the first one, into one axis. 
        net.add(gluon.nn.Flatten()) 
        # In the keras template the authors used activation='softmax'. In Gluon this activation function does not exist. Therefore, we first break down the output to the desired number of outputs and apply the softmax function after the output of the network. 
        net.add(gluon.nn.Dense(num_outputs)) 
 
    # Initialize the model parameters 
    net.collect_params().initialize(mx.init.Xavier(magnitude=2.24), ctx=ctx) 
#    net.collect_params().initialize(mx.init.Uniform(scale=1.0), ctx=ctx) 
 
 
    # Optional: Load model parameters from a previous run 
    if load_file: 
        net.load_parameters(load_file, ctx=ctx) 
 
    return net 

之后,每当我预测类别时,我都会使用 mxnet 的 softmax 函数:

y_pred = nd.softmax(net(data[0]))