我正在手动将预训练的matconvnet模型转换为张量流模型。我使用scipy.io从matconvnet模型mat文件中提取了权重/偏差,并获得了权重和偏差的numpy矩阵。
代码片段,其中data
是scipy.io返回的字典:
for i in data['net2']['layers']:
if i.type == 'conv':
model.append({'weights': i.weights[0], 'bias': i.weights[1], 'stride': i.stride, 'padding': i.pad, 'momentum': i.momentum,'lr': i.learningRate,'weight_decay': i.weightDecay})
...
weights = {
'wc1': tf.Variable(model[0]['weights']),
'wc2': tf.Variable(model[2]['weights']),
'wc3': tf.Variable(model[4]['weights']),
'wc4': tf.Variable(model[6]['weights'])
}
...
例如,其中
model[0]['weights']
是从matconvnet模型中提取的4x4x60 numpy矩阵用于图层。这就是我为9x9输入定义占位符的方式。X = tf.placeholder(tf.float32, [None, 9, 9]) #also tried with [None, 81] with a tf.reshape, [None, 9, 9, 1]
当前问题:我无法获得与之匹配的排名。我始终getValueError:
ValueError: Shape must be rank 4 but is rank 3 for 'Conv2D' (op: 'Conv2D') with input shapes: [?,9,9], [4,4,60]
摘要
是否可以从numpy数组显式定义Tensorflow模型的权重?
为什么我的体重矩阵排名为4?我的numpy数组应该更像[?,4,4,60],我可以那样做吗?
尝试失败:
旋转的numpy矩阵:我知道matlab和python具有不同的索引(基于0的索引与基于1的索引,以及行主列vs列主列)。即使我相信我已经适当地转换了所有内容,我仍然尝试使用np.rot90()这样的库将4x4x60数组更改为60x4x4。
使用tf.reshape:我尝试用tf.Variable包装器将权重包装后在权重上使用tf.reshape,但是我得到Variable没有属性'reshape'
注意:
请注意,我知道从matconvnet到caffe,从caffe到tensorflow有很多脚本(如此处所述,例如https://github.com/vlfeat/matconvnet/issues/1021)。我的问题与张量流权重初始化选项有关:
https://github.com/zoharby/matconvnet/blob/master/utils/convert_matconvnet_caffe.m
https://github.com/ethereon/caffe-tensorflow
最佳答案
我通过tf.reshape(...)
克服了这一障碍(而不是调用weights['wc1'].reshape(...)
)。我还不确定性能如何,或者这是否是一个非常幼稚的尝试。
更新进一步测试后,这种方法至少在功能上似乎是可行的(因为我创建了一个TensorFlow CNN模型,该模型将运行并产生与MatConvNet模型一致的预测。我对两者之间的准确性没有任何主张)。
我正在分享我的代码。就我而言,这是一个非常小的网络-如果您尝试将此代码用于自己的matconvnet到tensorflow项目,则可能需要进行更多修改:https://github.com/melissadale/MatConv2TensorFlow