python - 混合 mxnet.np.concatenate
问题描述
我正在尝试使在线书籍d2l.ai中的 GoogLeNet/InceptionV1 实现与杂交兼容。但是,我目前面临mx.np.concatenate
. 这是网络实现的完整最小示例:
import d2l # d2l.ai book code
import mxnet as mx
from mxnet import gluon, metric, np, npx
from mxnet.gluon import nn
npx.set_np()
ctx_list = [npx.gpu(i) for i in range(npx.num_gpus())]
mx.random.seed(42, ctx='all')
class Inception(nn.HybridBlock):
# c1- c4 are the number of output channels for each layer in the path
def __init__(self, c1, c2, c3, c4, **kwargs):
super().__init__(**kwargs)
# Path 1 is a single 1 x 1 convolutional layer
self.p1_1 = nn.Conv2D(c1, kernel_size=1, activation='relu')
# Path 2 is a 1 x 1 convolutional layer followed by a 3 x 3
# convolutional layer
self.p2_1 = nn.Conv2D(c2[0], kernel_size=1, activation='relu')
self.p2_2 = nn.Conv2D(c2[1], kernel_size=3, padding=1, activation='relu')
# Path 3 is a 1 x 1 convolutional layer followed by a 5 x 5
# convolutional layer
self.p3_1 = nn.Conv2D(c3[0], kernel_size=1, activation='relu')
self.p3_2 = nn.Conv2D(c3[1], kernel_size=5, padding=2,
activation='relu')
# Path 4
self.p4_1 = nn.MaxPool2D(pool_size=3, strides=1, padding=1)
self.p4_2 = nn.Conv2D(c4, kernel_size=1, activation='relu')
def hybrid_forward(self, F, x):
p1 = self.p1_1(x)
p2 = self.p2_2(self.p2_1(x))
p3 = self.p3_2(self.p3_1(x))
p4 = self.p4_2(self.p4_1(x))
# Concatenate the outputs on the channel dimension
return np.concatenate((p1, p2, p3, p4), axis=1)
#return F.concat(p1, p2, p3, p4, dim=1) # doesn't work either
class GoogLeNet(nn.HybridBlock):
"""
GoogLeNet uses a stack of a total of 9 inception blocks and global average pooling
"""
def __init__(self, classes=1000, **kwargs):
super().__init__(**kwargs)
self.net = nn.HybridSequential()
# First component uses a 64-channel 7 x 7 convolutional layer
self.net.add(
nn.Conv2D(64, kernel_size=7, strides=2, padding=3, activation='relu'),
nn.MaxPool2D(pool_size=3, strides=2, padding=1)
)
# Second component uses two convolutional layers:
# first a 64-channel 1 x 1 convolutional layer,
# then a 3 x 3 convolutional layer that triples the number of channels.
# This corresponds to the second path in the Inception block.
self.net.add(
nn.Conv2D(64, kernel_size=1, activation='relu'),
nn.Conv2D(192, kernel_size=3, padding=1, activation='relu'),
nn.MaxPool2D(pool_size=3, strides=2, padding=1)
)
# Third component connects to complete Inception blocks in series
# The number of output channels of the first block is 64+128+32+32=256
# and the ratio to the output channels of the four paths is 2:4:1:1.
# The number of output channels of the second block is 128+192+96+64=480
# and the ratio to the output channels per path is 4:6:3:2
self.net.add(
Inception(64, (96, 128), (16, 32), 32),
Inception(128, (128, 192), (32, 96), 64)
)
# Fourth component connects five Inception blocks in series
self.net.add(
Inception(196, (96, 208), (16, 48), 64),
Inception(160, (112, 224), (24, 64), 64),
Inception(128, (128, 256), (24, 64), 64),
Inception(112, (144, 288), (32, 64), 64),
Inception(256, (160, 320), (32, 128), 128),
nn.MaxPool2D(pool_size=3, strides=2, padding=1)
)
# Fifth component has two Inception blocks followed by output layer
self.net.add(
Inception(256, (160, 320), (32, 128), 128),
Inception(384, (192, 384), (48, 128), 128),
nn.Dense(classes)
)
def hybrid_forward(self, F, x):
x = self.net(x)
return x
net = GoogLeNet(classes=10)
net.initialize()
net.hybridize()
train_dl, valid_dl = d2l.load_data_fashion_mnist(batch_size=128, resize=96)
loss = gluon.loss.SoftmaxCrossEntropyLoss()
optimizer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.1})
d2l.train_ch13(net, train_iter=train_dl, test_iter=valid_dl,
loss=loss, trainer=optimizer,
num_epochs=10, ctx_list=ctx_list)
随着return np.concatenate((p1, p2, p3, p4), axis=1)
我得到错误:
AssertionError:位置参数必须具有 NDArray 类型,但得到 <_Symbol conv3_relu_fwd>
我return F.concat(p1, p2, p3, p4, dim=1)
得到了错误:
TypeError: 在后端注册的运算符 concat 在 Python 中称为 concat。这是一个传统的运算符,它只能接受传统的 ndarray,同时接收一个 MXNet numpy ndarray。请在 numpy ndarray 上调用 as_nd_ndarray() 将其转换为旧版 ndarray,然后将转换后的数组提供给此运算符。
源实现使用mxnet.gluon.contrib.nn.HybridConcurrent
,但我认为这可能是旧的,现在应该可以在没有 contrib 的情况下实现混合 concat 吗?
任何关于我如何修改它以进行杂交的建议将不胜感激!
解决方案
事实证明这是F.np.concatenate
有效的。
推荐阅读
- python - 如何在 matplotlib 绘图中正确设置 cartopy geoaxes 中的投影和转换
- html - 在 div 容器之前查找和替换代码
- python - 从python中的数据框中提取文件夹和文件名
- javascript - 如何在 vue 中声明 javascript 类实例?
- php - HTML 表单不发送 POST 请求
- centos - 为什么 Saxon 会在 CentOS 分发的 saxon.jar 中抛出错误,而不是来自 sourceforge 的 saxon 代码?
- c# - 如何使用 emguCV c# 在人脸识别中识别未知人脸?
- c# - C#数据表列删除问题
- mysql - 将我的数据库的访问权限从 root 用户授予另一台计算机以进行远程访问
- angular - 如何绑定到另一个指令中的指令输入?