1

在模型的每个前向传递中,我想在 softmax 层的列上实现 l2 归一化,然后根据印记的权重纸和这个pytorch implementation设置权重。我在模型的 call() 函数期间使用 layer.set_weights() 设置归一化权重,但此实现仅适用于急切执行,因为在构建图形时 layer.set_weights() 出现问题。

这是模型在 tf 1.15 中的实现:

import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras import Model
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.layers import Dense

class Extractor(Model):
    def __init__(self, input_shape):
        super(Extractor, self).__init__()
        self.basenet = ResNet50(include_top=False, weights="imagenet", 
                                 pooling="avg", input_shape=input_shape)

    def call(self, x):
        x = self.basenet(x)
        return(x)


class Embedding(Model):
    def __init__(self, num_nodes, norm=True):
        super(Embedding, self).__init__()
        self.fc = Dense(num_nodes, activation="relu")
        self.norm = norm
    
    def call(self, x):
        x = self.fc(x)
        if self.norm:
            x = tf.nn.l2_normalize(x)
        return x

class Classifier(Model):
    def __init__(self, n_classes, norm=True, bias=False):
       super(Classifier, self).__init__()
       self.n_classes = n_classes
       self.norm = norm
       self.bias = bias
    
    def build(self, inputs_shape):
       self.prediction = Dense(self.n_classes, 
                               activation="softmax",use_bias=False)
    
    def call(self, x):
        if self.norm:
            w = self.prediction.trainable_weights
            if w:
                w = tf.nn.l2_normalize(w, axis=2)
                self.prediction.set_weights(w)    
       
        x = self.prediction(x)
        return x 

class Net(Model):
    def __init__(self, input_shape, n_classes, num_nodes, norm=True, 
                 bias=False):
        super(Net, self).__init__()
        self.n_classes = n_classes
        self.num_nodes = num_nodes
        self.norm = norm
        self.bias = bias
        self.extractor = Extractor(input_shape)
        self.embedding = Embedding(self.num_nodes, norm=self.norm)
        self.classifier = Classifier(self.n_classes, norm=self.norm, 
                                     bias=self.bias)
    
    
    def call(self, x):
        x = self.extractor(x)
        x = self.embedding(x)
        x = self.classifier(x)
        return x

权重归一化可以在 Classifier 类的调用步骤中找到,我在归一化后调用 .set_weights() 。

model = Net(input_shape,n_classes, num_nodes)使用和使用创建模型可以工作,model(x)但是会给我关于 .get_weights() 的错误。我可以用梯度带在急切模式下训练模型,但速度非常慢。model.predict()model.fit()

有没有另一种方法可以在每次前向呼叫的训练期间设置密集层的权重,但让我在渴望模式之外使用模型?当我说急切模式时,我的意思是tf.enable_eager_execution()在程序开始时使用。

这是我改用时遇到的错误model.predict(x)

TypeError: len is not well defined for symbolic Tensors. (imprint_net_1/classifier/l2_normalize:0) Please call `x.shape` rather than `len(x)` for shape information.
4

0 回答 0