Python tensorflowjs:编写tensorflowjs自定义层时如何扩展tf.layers.conv2d

Python tensorflowjs:编写tensorflowjs自定义层时如何扩展tf.layers.conv2d,python,tensorflow,keras,tensorflow.js,Python,Tensorflow,Keras,Tensorflow.js,我需要编写一个tensorflowjs自定义层来导入我的模型。在原始python代码中,这是通过扩展Conv2D实现的,但在tfjs代码中似乎不可能实现。请求帮助 错误消息 我是tensorflow的新手,我想知道如何将这个自定义层转换为tfjs代码,这已经困扰了我很长时间,如果有任何帮助,我将不胜感激 下面是python cunstom层代码 从keras.utils导入conv_utils 从keras导入后端为K 从keras.engine导入InputSpec 从keras.laye

我需要编写一个tensorflowjs自定义层来导入我的模型。在原始python代码中,这是通过扩展Conv2D实现的,但在tfjs代码中似乎不可能实现。请求帮助

错误消息

我是tensorflow的新手,我想知道如何将这个自定义层转换为tfjs代码,这已经困扰了我很长时间,如果有任何帮助,我将不胜感激

下面是python cunstom层代码


从keras.utils导入conv_utils
从keras导入后端为K
从keras.engine导入InputSpec
从keras.layers导入Conv2D
PConv2D类(Conv2D类):
定义初始化(self,*args,n_通道=3,mono=False,**kwargs):
super()
self.input_spec=[InputSpec(ndim=4),InputSpec(ndim=4)]
def构建(自我,输入_形状):
“”“改编自Keras的原始_Conv()层
参数输入_形状:[img,掩码]的尺寸列表
"""
如果self.data\u format==“channels\u first”:
通道_轴=1
其他:
通道_轴=-1
如果输入_形状[0][channel_axis]为无:
raise VALUERROR('应定义输入的通道维度。找到'None`.)
self.input\u dim=input\u shape[0][channel\u axis]
#图像核
kernel\u shape=self.kernel\u size+(self.input\u dim,self.filters)
self.kernel=self.add\u weight(shape=kernel\u shape,
初始值设定项=self.kernel\u初始值设定项,
name='img_kernel',
正则化器=self.kernel\u正则化器,
constraint=self.kernel\u约束)
#掩码内核
self.kernel\u mask=K.one(shape=self.kernel\u size+(self.input\u dim,self.filters))
如果使用self.u偏差:
self.bias=self.add_权重(shape=(self.filters,),
初始值设定项=self.bias\u初始值设定项,
name='bias',
正则化器=自偏移正则化器,
约束=自身偏差(约束)
其他:
自我偏见=无
自建=真
def调用(自身、输入、掩码=无):
'''
我们将使用Keras conv2d方法,基本上我们有
这里要做的是在应用
卷积。对于掩码本身,我们对所有权重应用卷积
设置为1。
随后,我们将所有掩码值>0设置为1,否则设置为0
''' 
#必须同时提供图像和遮罩
如果类型(输入)不是列表或len(输入)!=2:
raise Exception('PartialConvolution2D必须在两个张量[img,mask]的列表上调用)。改为GET:'+str(输入))
#创建规范化。与纸张相比,此处略有变化,使用平均遮罩值而不是总和
标准化=K.平均值(输入[1],轴=[1,2],keepdims=真)
规格化=K。重复元素(规格化,输入[1]。形状[1],轴=1)
规格化=K。重复元素(规格化,输入[1]。形状[2],轴=2)
#对图像应用卷积
img_输出=K.conv2d(
(输入[0]*输入[1])/normalization,self.kernel,
步幅,
padding=self.padding,
data\u format=self.data\u format,
膨胀率=自膨胀率
)
#对掩模应用卷积
掩码输出=K.conv2d(
输入[1],self.kernel\u掩码,
步幅,
padding=self.padding,
data\u format=self.data\u format,
膨胀率=自膨胀率
)
#如果发生了什么,则设置为1,否则设置为0
掩码输出=K.cast(K.morer(掩码输出,0),'float32')
#仅对图像应用偏移(如果选择这样做)
如果使用self.u偏差:
img\u输出=K.偏差\u相加(
img_输出,
自我偏见,
数据格式=自。数据格式)
#对图像应用激活
如果self.activation不是None:
img_输出=自激活(img_输出)
返回[img_输出,掩码_输出]
def计算输出形状(自身、输入形状):
如果self.data\u format=='channels\u last':
空格=输入_形[0][1:-1]
新的_空间=[]
对于范围内的i(len(空格)):
新建尺寸=conv_utils.conv_输出长度(
空间[i],
self.kernel_size[i],
padding=self.padding,
步幅=自我。步幅[i],
膨胀=自膨胀率[i])
新建空间。追加(新建空间)
new_shape=(input_shape[0][0],)+元组(new_space)+(self.filters,)
返回[新形状,新形状]
如果self.data\u format==“channels\u first”:
空格=输入_形[2:]
新的_空间=[]
对于范围内的i(len(空格)):
新建尺寸=conv_utils.conv_输出长度(
空间[i],
self.kernel_size[i],
padding=self.padding,
步幅=自我。步幅[i],
膨胀=自膨胀率[i])
新建空间。追加(新建空间)
新的_形状=(输入_形状[0],self.filters)+元组(新的_空间)
返回[新形状,新形状]
这是我的tfjs代码

import*作为tf从'@tensorflow/tfjs'导入;
从“@tensorflow/tfjs layers/dist/utils/conv_utils”导入{convOutputLength,deconvLength,normalizeArray}”;
从“@tensorflow/tfjs layers/dist/engine/topology”导入{InputSpec};
类PConv2D扩展了tf.layers.Layer{
常数
class pconv2d extends tf.layers.conv2d {
  static className = 'MyCustomLayer';

  constructor(config) {
    super(config);
    // add other initialization
  }
  // add computation of the layer
}
tf.serialization.registerClass(pconv2d);
a = tf.ones([16, 16, 16, 16])
b = new MyCustomLayer({kernelSize: 2, filters: 2}).apply(a)
b.print()