我正在手动将预训练的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

10-04 21:01