DCN和DCNV2(tensorflow keras实现)

# coding:utf-8


import tensorflow as tf

print(tf.__version__)

# class DCNV2(tf.keras)

from tensorflow.python.keras import layers
from tensorflow.python.keras.regularizers import l2

# DCNV2模型的特征交叉部分
class CrossLayer(layers.Layer):

    def __init__(self, input_feature_dim, num_layer, parameterization="vector", l2_reg=0, seed=42, **kwargs):
        super(CrossLayer, self).__init__(**kwargs)
        self.input_feature_dim = input_feature_dim
        self.num_layer = num_layer
        self.parameteriation = parameterization
        self.seed = seed
        self.l2_reg = l2_reg

    def build(self, input_shape):
        if len(input_shape) != 2:
            raise ValueError("Unexcepted input dimensions %d, except to be 2 dimension" %(len(input_shape),))

        dim = int(input_shape[-1])
        if self.parameteriation == "vector":
            self.kernels = [self.add_weight(name="kernel" + str(i), shape=(dim, 1), initializer=tf.keras.initializers.glorot_normal(seed=self.seed),
                                            regularizer=l2(l2=self.l2_reg)) for i in range(self.num_layer)]
        elif self.parameteriation == "matrix":
            self.kernels = [self.add_weight(name="kernel" + str(i), shape=(dim, dim),
                                            initializer=tf.keras.initializers.glorot_normal(self.seed),
                                            regularizer=l2(self.l2_reg)) for i in range(self.num_layer)]

        else:
            raise ValueError("parameterization should be 'vector' or 'matrix' ")
        # 偏置bias每个维度都不一样, 不是共享的bias
        self.bias = [self.add_weight(name="bias" + str(i), shape=(dim, 1), initializer=tf.keras.initializers.Zeros()) for i in range(self.num_layer)]
        super(CrossLayer, self).build(input_shape)


    def call(self, inputs, *args, **kwargs):
        """

        :param inputs:  shape=[batch, input_feature_dim]
        :param args:
        :param kwargs:
        :return:
        """
        if tf.keras.backend.ndim(inputs) != 2:
            raise ValueError(" inputs should be 2 dimension, but input dimension is %"(tf.keras.backend.ndim(inputs)))

        x0 = tf.expand_dims(inputs, axis=2)  # shape=[batch, input_feature_dim ,1]
        xl = x0
        for i in range(self.num_layer):
            if self.parameteriation == "vector":
                # (batch, feature_dim, 1) * (feature_dim, 1)
                xl_w = tf.tensordot(xl, self.kernels[i], axes=(1, 0))  # 即矩阵相乘
                # (batch, feature_dim, 1) * (batch, feature_dim, 1)
                dot_ = tf.matmul(x0, xl_w)
                xl = dot_ + xl + self.bias[i]
            elif self.parameteriation == "matrix":
                # (feature_dim, feature_dim) * (batch, feature_dim, 1)
                xl_w = tf.einsum("ij, bjk->bik", self.kernels[i], xl)  # wx= (batch, feature_dim, 1)
                dot_ = xl_w + self.bias[i]  # wx+b
                xl = x0 * dot_ + xl  # x0 * (wxi+b) + xl,  Hadamard-product
            else:
                raise ValueError("parameterization should be 'vector' or 'matrix' ")

        xl = tf.squeeze(xl, axis=2)  # (batch, feature_dim)
        return xl

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值