【问题标题】:Merge two encoding without lambda layer in order to convert Keras model wiith tfjs合并两个没有 lambda 层的编码,以便使用 tfjs 转换 Keras 模型
【发布时间】:2019-09-19 10:18:23
【问题描述】:

我正在寻找使用 Keras 创建一个连体网络,我发现 this article on Medium 不幸地使用 Lambda 层来计算卷积网络的两个输出编码之间的绝对差异。问题是我不能在我的网络中使用 Lambda 层,因为我想将最终的 Keras 模型转换为 tfjs 模型,并且根据 Tensorflowjs,这些类型的层无法转换。

我的问题是:是否可以使用 Merge Layer 来获得相同的结果或另一个与 tensorlfowjs 兼容的 Keras 层?如果是的话,你能给我举个例子吗,因为我是 Keras 的新手。 我四处寻找其他连体实现,但都使用这个 Lambda 层。

# Define the tensors for the two input images
left_input = Input(input_shape)
right_input = Input(input_shape)

# Convolutional Neural Network
model = Sequential()
model.add(Conv2D(64, (10,10), activation='relu', input_shape=input_shape,
               kernel_initializer=initialize_weights, kernel_regularizer=l2(2e-4)))
model.add(MaxPooling2D())
model.add(Conv2D(128, (7,7), activation='relu',
                 kernel_initializer=initialize_weights,
                 bias_initializer=initialize_bias, kernel_regularizer=l2(2e-4)))
model.add(MaxPooling2D())
model.add(Conv2D(128, (4,4), activation='relu', kernel_initializer=initialize_weights,
                 bias_initializer=initialize_bias, kernel_regularizer=l2(2e-4)))
model.add(MaxPooling2D())
model.add(Conv2D(256, (4,4), activation='relu', kernel_initializer=initialize_weights,
                 bias_initializer=initialize_bias, kernel_regularizer=l2(2e-4)))
model.add(Flatten())
model.add(Dense(4096, activation='sigmoid',
               kernel_regularizer=l2(1e-3),
               kernel_initializer=initialize_weights,bias_initializer=initialize_bias))

# Generate the encodings (feature vectors) for the two images
encoded_l = model(left_input)
encoded_r = model(right_input)

# Add a customized layer to compute the absolute difference between the encodings
L1_layer = Lambda(lambda tensors:K.abs(tensors[0] - tensors[1]))
L1_distance = L1_layer([encoded_l, encoded_r])

# Add a dense layer with a sigmoid unit to generate the similarity score
prediction = Dense(1,activation='sigmoid',bias_initializer=initialize_bias)(L1_distance)

# Connect the inputs with the outputs
siamese_net = Model(inputs=[left_input,right_input],outputs=prediction)

【问题讨论】:

    标签: keras tensorflow.js tensorflowjs-converter


    【解决方案1】:

    可以创建和注册自定义 Lambda 层。

    这里是siamese_net的一个子集(只是为了演示lambda层的使用)

    left_input = tf.keras.Input(shape=(32,)) 
    right_input = tf.keras.Input(shape=(32,))  
    
    L1_layer = Lambda(lambda tensors:tf.abs(tensors[0] - tensors[1]))
    L1_distance = L1_layer([left_input, right_input])
    
    prediction = Dense(1,activation='sigmoid')(L1_distance)
    
    model = Model(inputs=[left_input,right_input],outputs=prediction)
    

    保存模型

    model.save('my_model.h5') 
    

    将模型转成js

    tensorflowjs_converter \
        --input_format=keras \
        my_model.h5 \
        tfjs
    

    在javascript中使用模型

    class Lambda extends tf.layers.Layer {
        constructor() {
          super({})
        }
    
        static get className() {
          return 'Lambda';
        }
    
        computeOutputShape(inputShape) {
          return [inputShape[0]];
        }
    
        call(inputs, kwargs) {
          this.invokeCallHook(inputs, kwargs);
          return tf.abs(inputs[0].sub(inputs[1]))
        }
      }
    
      tf.serialization.SerializationMap.register(Lambda);
    

    这是colab

    【讨论】:

      猜你喜欢
      • 2019-10-11
      • 2017-07-27
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      • 2017-07-26
      相关资源
      最近更新 更多