Tensorflow2 加载别人模型权重失败时的一种解决方法:每一层分别设置值

有时自己建立模型导入别人模型参数时会因为版本等各个问题导致导入失败,这时可以一层一层的给网络赋值权重。

 本人在加载某个模型的权重通过load_weights方式加载时报错,但是我拥有别人已加载完权重的model。所以试了下手动一层一层的加载权重,结果还是可行的,就是比较麻烦。

tensorflow2的模型权重可以以set_weights方式进行设置权重。比如要改以下自己定义的模型每层加载权重:

from tensorflow.keras import Sequential, layers, Model
import numpy as np

class SetWeights(Model):
    def __init__(self):
        super(SetWeights, self).__init__()
        self.c = layers.Conv2D(filters = 32,kernel_size=(3,3),strides=(1,1),padding='same')
        self.bn = layers.BatchNormalization()
        self.ac = layers.LeakyReLU(0.1)

    def call(self, inputs, training=None, mask=None):
        x = self.ac(self.bn(self.c(inputs)))
        return x

首先初始化模型,查看可训练参数结构,如下:

model = SetWeights()
model.build((None,32,32,3))

# 查看所有可训练的参数
# 以列表的方式保存,长度4,包含卷积层的w,b,BN的gamma,beta
model.trainable_variables

通过以下方法设置权重

# model.属性.set_weights方法
# 需要注意的是传入的参数是一个list
model.c.set_weights()

比如我们实例化两个model (model1相当于自己建立的模型,model2相当于拥有的别人已加载好的模型,因为结构顺序或者版本等原因,不能save_weights再load_weights加载别人的权重)

将model2的参数设置到model1中方法:  

model1 = SetWeights()
model1.build((None,32,32,3))

model2 = SetWeights()
model2.build((None,32,32,3))

# 卷积层的权重设置(w、b)
# 传入的list顺序是kernel、bias
model1.c.set_weights([model2.trainable_variables[0].numpy(),model2.trainable_variables[1].numpy()])

# BN层参数设置
# 传入的list顺序是gamma、beta、moving_mean、moving_variance

# 获得BN层每个参数长度
bn_len = model2.trainable_variables[2].shape[0]
model1.bn.set_weights([model2.trainable_variables[2].numpy(),model2.trainable_variables[3].numpy(),np.zeros((bn_len),dtype=np.float32),np.ones((bn_len),dtype=np.float32)])

# 这样model1里的权重已经变成model2中的了

 

 

你可能感兴趣的:(深度学习笔记,tensorflow2,权重加载,深度学习)