Creating a multi-output example by gluoncv, the purpose of this example is predict the color and type of the clothes by a two branches network, my problem is, I don’t know how to convert the symbol to gray scale image in the hybrid_forward function.
My solution is
- create a constant symbol
- convert input symbol to gray scale image with 1 channel
- concat the gray scale image to 3 channels(since I am using pretrained network)
But the program throw error : AssertionError: Unknown input to HybridBlock: rgb_weights
Source codes
from gluoncv import model_zoo
from mxnet import nd
from mxnet.gluon import nn, HybridBlock
from mxnet import init
import mxnet as mx
class mx_symbol_constant(mx.init.Initializer):
def __init__(self, value):
super(mx_symbol_constant, self).__init__(value=value)
self.value = value
def _init_weight(self, _, arr):
arr[:] = mx.nd.array(self.value)
class fashion_net_2_branches(HybridBlock):
def __init__(self, num_clothes, num_colors, ctx):
super(fashion_net_2_branches, self).__init__()
self._features = model_zoo.get_model('ResNet50_v2', pretrained=True, ctx = ctx).features
for _, w in self._features.collect_params().items():
w.grad_req = 'null'
self._flatten = nn.Flatten()
self._dropout = nn.Dropout(0.5)
self._relu = nn.Activation(activation='relu')
self._swish = nn.Swish()
self._rgb_weights = mx.sym.Variable('rgb_weights', shape = (3, 1), init = mx_symbol_constant([0.2989, 0.5870, 0.1140]))
self._clothes_fc_1 = nn.Dense(100)
self._clothes_bn_1 = nn.BatchNorm(center=False, scale=True)
self._clothes_out = nn.Dense(num_clothes)
self._clothes_fc_1.initialize(init=init.Xavier(), ctx=ctx)
self._clothes_bn_1.initialize(init=init.Zero(), ctx=ctx)
self._clothes_out.initialize(init=init.Xavier(), ctx=ctx)
self._color_fc_1 = nn.Dense(100)
self._color_bn_1 = nn.BatchNorm(center=False, scale=True)
self._color_out = nn.Dense(num_colors)
self._color_fc_1.initialize(init=init.Xavier(), ctx=ctx)
self._color_bn_1.initialize(init=init.Zero(), ctx=ctx)
self._color_out.initialize(init=init.Xavier(), ctx=ctx)
def hybrid_forward(self, F, x):
#convert x to gray scale image, 1 channel
tensor_img_gray = mx.sym.dot(self._rgb_weights, x) # the shape become [batch, H, W, 1]
#convert tensor_img_gray to [batch, H, W, 3]
tensor_imgs_gray = mx.sym.concat(tensor_img_gray, tensor_img_gray, tensor_img_gray, dim=1)
#this line throw error : AssertionError: Unknown input to HybridBlock: rgb_weights
tensor_img_gray = self._features(tensor_img_gray)
clothes_result = self._flatten(tensor_img_gray)
clothes_result = self._clothes_fc_1(clothes_result)
clothes_result = self._swish(clothes_result)
clothes_result = self._clothes_bn_1(clothes_result)
clothes_result = self._dropout(clothes_result)
clothes_result = self._clothes_out(clothes_result)
x = self._features(x)
color_result = self._flatten(x)
color_result = self._color_fc_1(color_result)
color_result = self._swish(color_result)
color_result = self._color_bn_1(color_result)
color_result = self._dropout(color_result)
color_result = self._color_out(color_result)
return clothes_result, color_result