Currently, Axis has semantic name like "N" (batch size), "C" (channels), etc. However, it often causes confusion. For example, in Embedding operator, dictionary variable w has 2 dimensions, N and C, but their semantic is unclear. Also sometimes two axes object which represents for different dimensions have same name. In this case, ReinterpretAxis is needed, but it adversely affect optimization.
Solution
Remove axis name from Axis class, and add semantics property to each operator, which holds information on the name of each axis under the context of this operator.
Example
x = Variable([1, 64, 56, 56], Order([Axis(), Axis(), Axis(), Axis()])) # batch_size, channel, height, width
print(x)
>>> <Variable0 shape=(1, 64, 56, 56), order=[?1, ?2, ?3, ?4]>
w = Variable([64, 256, 3, 3], Order([Axis(), Axis(), Axis(), Axis()])) # in_channel, out_channel, height, width
print(w)
>>> <Variable1 shape=(64, 256, 3, 3), order=[?5, ?6, ?7, ?8]>
# both w.order.axes[0] and x.order.axes[1] represent in_channel
w.order.axes[0].unify(x.order.axes[1])
print(w)
>>> <Variable1 shape=(64, 256, 3, 3), order=[?1, ?6, ?7, ?8]>
# Instantiate operator with axis mapping information
conv2d = Convolution2d(None, ksize=3, pad=1, stride=1,
axis_batch_size=x.order.axes[0],
axis_in_channel=x.order.axes[1],
axis_image_height=x.order.axes[2],
axis_image_width=x.order.axes[3],
axis_out_channel=w.order.axes[1],
axis_kernel_height=w.order.axes[2],
axis_kernel_width=x.order.axes[3])
print(conv2d.semantics)
>>> [
<AxisSemantics short_name="N", description="batch size", axis=<Axis ?1>>,
<AxisSemantics short_name="C1", description="input channel", axis=<Axis ?2>>,
<AxisSemantics short_name="H", description="image height", axis=<Axis ?3>>,
<AxisSemantics short_name="W", description="image width", axis=<Axis ?4>>,
<AxisSemantics short_name="C2", description="output channel", axis=<Axis ?6>>,
<AxisSemantics short_name="R", description="kernel height", axis=<Axis ?7>>,
<AxisSemantics short_name="S", description="kernel width", axis=<Axis ?8>>,
]
y, = conv2d(x, w)
print(y)
>>> <Variable2 shape=(1, 256, 56, 56), order=[?1, ?6, ?3, ?4]>
# By using conv2d.semantics, the semantics of orders can be interpreted.
print_with_semantics(y, semantics=conv2d.semantics)
>>> <Variable2 shape=(1, 256, 56, 56), order=[N, C2, H, W]>
# If y is also used as input variable in another operator, semantic name differs
print_with_semantics(y, semantics=another_conv.semantics)
>>> <Variable2 shape=(1, 256, 56, 56), order=[N, C1, H, W]>
Problem
Operator constructor requires enormous arguments
Some arguments can be omitted: ex) axis_batch_size is not important to convolution's semantics.
This is problem for WebDNN developers, not for users.
Background
Currently,
Axis
has semantic name like"N" (batch size)
,"C" (channels)
, etc. However, it often causes confusion. For example, inEmbedding
operator, dictionary variablew
has 2 dimensions,N
andC
, but their semantic is unclear. Also sometimes two axes object which represents for different dimensions have same name. In this case,ReinterpretAxis
is needed, but it adversely affect optimization.Solution
Remove axis name from
Axis
class, and addsemantics
property to each operator, which holds information on the name of each axis under the context of this operator.Example
Problem
Operator constructor requires enormous arguments
axis_batch_size
is not important to convolution's semantics.