vbalnt / tfeat

TFeat descriptor models for BMVC 2016 paper "Learning local feature descriptors with triplets and shallow convolutional neural networks"
MIT License
148 stars 45 forks source link

caffe version of the TFeat Liberty #7

Closed ducha-aiki closed 7 years ago

ducha-aiki commented 7 years ago

Weights are manually moved and normalization is hardcoded in .prototxt. It expects as input [0 255] non-normalized grayscale 32x32 patches

edgarriba commented 7 years ago

awesome!

edgarriba commented 7 years ago

could you provide any python or cpp script for running it?

ducha-aiki commented 7 years ago

@edgarriba done

edgarriba commented 7 years ago

@ducha-aiki great!

edgarriba commented 7 years ago

@ducha-aiki I'd really really love to see how did you convert from Pytorch/Tensorflow? to Caffe

ducha-aiki commented 7 years ago

@edgarriba very simple - manually. From lua (lutorpy) :

i = 0
for k in net.net.modules:
    print str(net.net.modules[k])
    if 'cudnn.SpatialConvolution' in str(net.net.modules[k]):
        print str(net.net.modules[k])
        if i == 1:
            w1 = net.net.modules[k].weight.asNumpyArray()
            print w1.shape
            caffenet.params['conv2'][0].data[:] = w1;
            caffenet.params['conv2'][1].data[:] =  net.net.modules[k].bias.asNumpyArray()
            i+=1
        if i == 0:
            w1 = net.net.modules[k].weight.asNumpyArray()
            print w1.shape
            caffenet.params['conv1'][0].data[:] = w1;
            caffenet.params['conv1'][1].data[:] = net.net.modules[k].bias.asNumpyArray()
            i+=1
    if 'Linear' in str(net.net.modules[k]):
        print str(net.net.modules[k])
        w1 = net.net.modules[k].weight.asNumpyArray()
        caffenet.params['ip1'][0].data[:] = w1;
        caffenet.params['ip1'][1].data[:] = net.net.modules[k].bias.asNumpyArray()

For pytorch (and other arch)

gg = {}
gg['counter'] = 1
def copy_weights(m,):
    if isinstance(m, nn.Conv2d):
        counter = gg['counter']
        l_name = 'conv' + str(counter)
        print l_name,  m.weight.data.cpu().numpy().shape;
        net.params[l_name][0].data[:] = np.rollaxis( m.weight.data.cpu().numpy(),3,2);
        net.params[l_name][1].data[:] = m.bias.data.cpu().numpy();
    if isinstance(m, nn.BatchNorm2d):
        counter = gg['counter']
        l_name = 'conv' + str(counter) + '_BN'
        print l_name
        net.params[l_name][0].data[:] = m.running_mean.cpu().numpy();
        net.params[l_name][1].data[:] = m.running_var.cpu().numpy();
        net.params[l_name][2].data[:] = 1.
        gg['counter'] += 1
def copy_last(m):
    if isinstance(m, nn.Conv2d):
        l_name = 'conv7'
        net.params[l_name][0].data[:] =np.rollaxis( m.weight.data.cpu().numpy(),3,2);
        net.params[l_name][1].data[:] = m.bias.data.cpu().numpy();
        print l_name
    if isinstance(m, nn.BatchNorm2d):
        counter = gg['counter']
        l_name = 'conv7_BN'
        print l_name
        net.params[l_name][0].data[:] = m.running_mean.cpu().numpy();
        net.params[l_name][1].data[:] = m.running_var.cpu().numpy();
        net.params[l_name][2].data[:] = 1.
        gg['counter'] += 1

model.features.apply(copy_weights)
model.classifier.apply(copy_last)
ducha-aiki commented 7 years ago

@edgarriba could you please help me with https://github.com/pytorch/pytorch/issues/1661 ?

edgarriba commented 7 years ago

I think you need register_forward_hook http://pytorch.org/docs/nn.html#torch.nn.Module.register_forward_hook

edgarriba commented 7 years ago

BTW, thanks for the script. I'm not very fluent with low level caffe features

ducha-aiki commented 7 years ago

@edgarriba thanks, I will try it.

ducha-aiki commented 7 years ago

@edgarriba here is full version of script https://github.com/DagnyT/hardnet/blob/master/examples/caffe/convert_weights_to_caffe.py It is different architecture, though

edgarriba commented 7 years ago

@ducha-aiki thanks dude! very interesting paper and results.