我正在尝试调整在线书d2l.ai中的GoogLeNet网/InceptionV1 1实现,使其与杂交兼容。然而,我目前正面临着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,但我认为这可能是旧的,现在应该可以实现混合concat了吗?
任何建议,我可以如何修改这个杂交将不胜感激!
发布于 2020-07-01 19:57:11
结果发现,F.np.concatenate可以工作。
https://stackoverflow.com/questions/62677897
复制相似问题