Closed dreamhighchina closed 4 years ago
那就是用torch.mul()之类的函数替换*
你可以在重载的_mul函数里加个判断分支,如果为常数,重载为Scale层
x * 1.5这种转换到caffe,我这边有三种思路,假设x维度为(n,c,h,w),第一种把1.5先expand as成相同维度的blob,每个值都是1.5,然后用eltwise实现,需要重载一下expand_as;第二种,把1.5先expand as (n,c,1,1)的blob,每个值都是1.5,然后用双bottom的scale实现,这种稍微绕了一下;第三种,可以将scale的weight设为1.5,具体的可以参考_instance_norm的实现,应该也是可以实现的,不过我没试过。
我觉得还是expand的方式比较好哈哈,回头试试,因为对caffe框架不熟悉,谢谢大佬指导。
x * 1.5这种,可以修改pytorch_to_caffe.py的_mul函数,如下,添加对int值或者float值的判断,用Scale完成乘法/加法/减法操作。关键在layer.scale_param(scale=scale, bias=None)
这一句,如果是乘法,就设置scale,bias设为None或者0,同理如果是加减法,scale要设置为1,bias设置为具体的数值。注意这里的scale和bias的形状是featuremap通道的个数,即scale.shape[0]==featuremap.shape[1]
,可以看下面代码, args[0]就是1.5,要把1.5转为通道长度的ndarray。
def _mul(input, *args):
x = raw__mul__(input, *args)
if not NET_INITTED or log.blobs(input) is None:
return x
if log.blobs(args[0]) is not None and input.shape == args[0].shape:
layer_name = log.add_layer(name='mul')
top_blobs = log.add_blobs([x], name='mul_blob')
layer = caffe_net.Layer_param(name=layer_name, type='Eltwise',
bottom=[log.blobs(input), log.blobs(args[0])], top=top_blobs)
layer.param.eltwise_param.operation = 0 # product is 0
log.cnet.add_layer(layer)
elif isinstance(args[0], int) or isinstance(args[0], float):
layer_name = log.add_layer(name='mul')
top_blobs = log.add_blobs([x], name='mul_blob')
layer = caffe_net.Layer_param(name=layer_name, type='Scale',
bottom=[log.blobs(input)], top=top_blobs)
scale = np.array(args[0],dtype=np.float32).squeeze().repeat(input.shape[1], 0)
layer.scale_param(scale=scale, bias=None)
layer.add_data(scale)
log.cnet.add_layer(layer)
同理,加法_add和减法_sub也可添加相应的判断,代码如下: 加法:
def _add(input, *args):
x = raw__add__(input, *args)
if not NET_INITTED or log.blobs(input) is None:
return x
if log.blobs(args[0]) is not None and input.shape == args[0].shape:
layer_name = log.add_layer(name='add')
top_blobs = log.add_blobs([x], name='add_blob')
layer = caffe_net.Layer_param(name=layer_name, type='Eltwise',
bottom=[log.blobs(input),log.blobs(args[0])], top=top_blobs)
layer.param.eltwise_param.operation = 1 # sum is 1
log.cnet.add_layer(layer)
elif isinstance(args[0], int) or isinstance(args[0], float):
layer_name = log.add_layer(name='sub')
top_blobs = log.add_blobs([x], name='sub_blob')
layer = caffe_net.Layer_param(name=layer_name, type='Scale',
bottom=[log.blobs(input)], top=top_blobs)
bias = np.array(args[0],dtype=np.float32).squeeze().repeat(input.shape[1], 0)
scale = np.ones(bias.shape, dtype=np.float32)
layer.scale_param(scale=scale, bias=bias)
layer.add_data(scale, bias)
log.cnet.add_layer(layer)
减法:
def _sub(input, *args):
x = raw__sub__(input, *args)
if not NET_INITTED or log.blobs(input) is None:
return x
if log.blobs(args[0]) is not None and input.shape == args[0].shape:
layer_name = log.add_layer(name='sub')
top_blobs = log.add_blobs([x], name='sub_blob')
layer = caffe_net.Layer_param(name=layer_name, type='Eltwise',
bottom=[log.blobs(input),log.blobs(args[0])], top=top_blobs)
layer.param.eltwise_param.operation = 1 # sum is 1
layer.param.eltwise_param.coeff.extend([1., -1.])
log.cnet.add_layer(layer)
elif isinstance(args[0], int) or isinstance(args[0], float):
layer_name = log.add_layer(name='add')
top_blobs = log.add_blobs([x], name='add_blob')
layer = caffe_net.Layer_param(name=layer_name, type='Scale',
bottom=[log.blobs(input)], top=top_blobs)
bias = np.array(args[0],dtype=np.float32).squeeze().repeat(input.shape[1], 0)
scale = np.ones(bias.shape, dtype=np.float32)
layer.scale_param(scale=scale, bias=bias)
layer.add_data(scale, -bias)
log.cnet.add_layer(layer)
因为这个1.5并不是什么blob,所以在 layer = caffe_net.Layer_param(name=layer_name, type='Eltwise', bottom=[log.blobs(input), log.blobs(args[0])], top=top_blobs)的时候,会出现 log.blobs(args[0])keyerror的原因,这个该怎么解决???