Source code for tfts.layers.cnn_layer

"""Layer for :py:class:`~tfts.models.wavenet`"""

from typing import Tuple

import tensorflow as tf
from tensorflow.keras import activations, constraints, initializers, regularizers


[docs] class ConvTemp(tf.keras.layers.Layer): """Temporal convolutional layer for time series processing. This layer implements a 1D convolutional layer with optional causal padding, which is commonly used in time series models like WaveNet. The layer can be configured to use dilated convolutions and causal padding to ensure temporal dependencies are properly captured. Parameters ---------- filters : int The number of output filters in the convolution. kernel_size : int The length of the 1D convolution window. strides : int, optional The stride length of the convolution. Defaults to 1. dilation_rate : int, optional The dilation rate to use for dilated convolution. Defaults to 1. activation : str, optional Activation function to use. Defaults to "relu". causal : bool, optional Whether to use causal padding. If True, ensures no information leakage from future timesteps. Defaults to True. kernel_initializer : str, optional Initializer for the kernel weights matrix. Defaults to "glorot_uniform". name : str, optional Name of the layer. Defaults to None. Input shape: - 3D tensor with shape `(batch_size, sequence_length, features)` Output shape: - 3D tensor with shape `(batch_size, new_sequence_length, filters)` """ def __init__( self, filters: int, kernel_size: int, strides: int = 1, dilation_rate: int = 1, activation: str = "relu", causal: bool = True, kernel_initializer: str = "glorot_uniform", name=None, ): super(ConvTemp, self).__init__(name=name) self.filters = filters self.kernel_size = kernel_size self.strides = strides self.dilation_rate = dilation_rate self.causal = causal self.kernel_initializer = kernel_initializer self.activation = activation
[docs] def build(self, input_shape: Tuple[int]) -> None: """Build the layer by creating the convolutional layer. Parameters ---------- input_shape : Tuple[int] Shape of the input tensor """ super(ConvTemp, self).build(input_shape) self.conv = tf.keras.layers.Conv1D( kernel_size=self.kernel_size, kernel_initializer=initializers.get(self.kernel_initializer), filters=self.filters, padding="valid", dilation_rate=self.dilation_rate, activation=activations.get(self.activation), ) self.conv.build(input_shape) self.built = True
[docs] def call(self, inputs): """Forward pass of the layer. Parameters ---------- inputs : tf.Tensor Input tensor with shape (batch_size, sequence_length, features) Returns ------- tf.Tensor Output tensor after applying temporal convolution """ if self.causal: padding_size = (self.kernel_size - 1) * self.dilation_rate # padding: dim 1 is batch, [0,0]; dim 2 is time, [padding_size, 0]; dim 3 is feature [0,0] inputs = tf.pad(inputs, [[0, 0], [padding_size, 0], [0, 0]]) outputs = self.conv(inputs) return outputs
[docs] def get_config(self): """Get the configuration of the layer. Returns ------- dict Configuration dictionary containing layer parameters """ config = { "filters": self.filters, "kernel_size": self.kernel_size, "strides": self.strides, "dilation_rate": self.dilation_rate, "casual": self.causal, } base_config = super(ConvTemp, self).get_config() return dict(list(base_config.items()) + list(config.items()))
# class ConvAttTemp(tf.keras.layers.Layer): # """Temp convolutional attention layer""" # # def __init__(self): # super(ConvAttTemp, self).__init__() # self.temporal_conv = ConvTemp() # self.att = SelfAttention() # # def build(self, input_shape: Tuple[Optional[int], ...]): # super(ConvAttTemp, self).build(input_shape) # # def call(self, inputs): # """_summary_ # # Parameters # ---------- # inputs : _type_ # _description_ # # Returns # ------- # _type_ # _description_ # """ # x = inputs # x = self.temporal_conv(x) # x = self.att(x) # return x # # def get_config(self): # config = { # "units": self.units, # } # base_config = super(ConvAttTemp, self).get_config() # return dict(list(base_config.items()) + list(config.items()))