【tensorflow2caffe】三、 将tensorflow框架下训练得到的权重转化为caffe框架下的权重参数

在博客开始前,首先郑重感谢博主jiongnima的博客对我的帮助,我按照博主的方法顺利的把bcnn模型的tensorflow版转为caffe版,关于bcnn模型,它是个细粒度分类模型,我将在后续的博客中详细介绍。

首先隆重呈上博主的链接:

https://blog.csdn.net/jiongnima/article/details/78382972

    转模型系列博文的操作主要基于博主的实验探索,中间也穿插着我自己的一些想法以及重新编排,在强烈膜拜原创的基础上,将转模型过程进行了亲自的实践并成功复现,因此暂时(不要脸)的将该系列博文归为原创。

    下面进入正题部分。

    上一篇博客:https://blog.csdn.net/zl3090/article/details/89042717 已经介绍了tensorflow中参数的提取,本篇主要讲述如何将它转为caffe需要的shape.

    tensorflow的卷积层权重shape是[kernel_height, kernel_width, input_channels, output_channels],其中input暂时可以理解为nchw中的c(channel),也就是输入的通道数,output可以暂时看做n,也就是卷积核的个数,也是输出的通道数,当然这里的in和out与nc在意义上有区别,下文会具体介绍二者的不同,此处这么理解是为了和我们熟悉的nchw格式有个对应. 补充介绍tf.nn.conv2d函数的参数:

    这里说明filter中的hwio与data_formate的区别: hwio是指filter的形式,也就是卷积之前设置卷积核以及其输入输出的形式,它影响的是参数weight的数据形式,也就是说weight是按照hwio的形式存储的,也是我们将weight写入caffe中deploy需要依据的数据存储形式; data_formate中的nhwc是指卷积计算后输出数据的形式,也就是[batch_size, height, width, number_of_filters],也即是输出数据和weight和bias计算后的结果存储形式,也就是feature map中的形式,在这里写入deploy不会用到.

    在caffe中,数据按照blob形式存储,对于blob中的数据来说,也就是计算后的数据存储形式是nchw, 也就是[number channel, height,width]; 对于卷积权重来说,也应该按照io来描述,也就是[output_channels, input_channels, kernel_height, kernel_width].

    根据上述理解,我们可以进行shape的转换,代码如下:

#!/usr/bin/python
 
import tensorflow as tf
import numpy as np
 
with tf.Session() as sess:
	new_saver = tf.train.import_meta_graph('.model.meta')
	for var in tf.trainable_variables():
		print var.name
	new_saver.restore(sess, tf.train.latest_checkpoint('./checkpoint_dir/'))
	all_vars = tf.trainable_variables()
	for v in all_vars:
		name = v.name
		fname = name + '.prototxt'
		fname = fname.replace('/','_')
		print fname
		v_4d = np.array(sess.run(v))
		if v_4d.ndim == 4: # conv_w
			#v_4d.shape [ H, W, I, O ]		
			v_4d = np.swapaxes(v_4d, 0, 2) # swap H, I
			v_4d = np.swapaxes(v_4d, 1, 3) # swap W, O
			v_4d = np.swapaxes(v_4d, 0, 1) # swap I, O
			#v_4d.shape [ O, I, H, W ]
			f = open(fname, 'w')
			vshape = v_4d.shape[:]
			v_1d = v_4d.reshape(v_4d.shape[0]*v_4d.shape[1]*v_4d.shape[2]*v_4d.shape[3])
        	f.write('  blobs {\n')
			for vv in v_1d:
				f.write('    data: %8f' % vv)
				f.write('\n')
			f.write('    shape {\n')
			for s in vshape:
				f.write('      dim: ' + str(s))#print dims
				f.write('\n')
			f.write('    }\n')
			f.write('  }\n')
        elif v_4d.ndim == 2: # fc_w
            v_4d = np.swapaxes(v_4d,0,1) # swap IO
            f = open(fname, 'w')
            vshape = v_4d[:]
            v_1d = v_4d.reshape(v_4d.shape[0]*v_4d.shape[1])
            f.write('  blobs {\n')
			for vv in v_1d:
				f.write('    data: %8f' % vv)
				f.write('\n')
			f.write('    shape {\n')
			for s in vshape:
				f.write('      dim: ' + str(s))#print dims
				f.write('\n')
			f.write('    }\n')
			f.write('  }\n')
		elif v_4d.ndim == 1 :#do not swap #all_bias
			f = open(fname, 'w')
			f.write('  blobs {\n')
			for vv in v_4d:
				f.write('    data: %.8f' % vv)
				f.write('\n')
			f.write('    shape {\n')
			f.write('      dim: ' + str(v_4d.shape[0]))#print dims
			f.write('\n')
			f.write('    }\n')
			f.write('  }\n')
		f.close()
 

    上述代码将卷积层与全连接层的w和b分别保存为独立的prototxt,到此我们完成了转换。

     下一篇博客会介绍如何放如deploy.prototxt里和生成caffemodel。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值