Spaces:
Running
on
Zero
Running
on
Zero
import torch.nn as nn | |
import torch.nn.functional as F | |
import torch as th | |
import numpy as np | |
import os | |
class UniDeepFsmn(nn.Module): | |
"""UniDeepFsmn is a neural network module implementing a unified deep | |
Feedforward Sequential Memory Network (FSMN) for sequence-to-sequence tasks. | |
Args: | |
input_dim (int): The number of input features. | |
output_dim (int): The number of output features. | |
lorder (int, optional): The order of the linear filter. If None, the filter order is not used. | |
hidden_size (int, optional): The number of hidden units in the first linear layer. | |
Attributes: | |
input_dim (int): The dimension of the input features. | |
output_dim (int): The dimension of the output features. | |
lorder (int): The order of the linear filter. | |
hidden_size (int): The number of hidden units. | |
linear (nn.Linear): Linear transformation layer from input_dim to hidden_size. | |
project (nn.Linear): Linear transformation layer from hidden_size to output_dim without bias. | |
conv1 (nn.Conv2d): Convolutional layer for processing the output of the project layer. | |
""" | |
def __init__(self, input_dim, output_dim, lorder=None, hidden_size=None): | |
"""Initializes the UniDeepFsmn model. | |
Args: | |
input_dim (int): The number of input features. | |
output_dim (int): The number of output features. | |
lorder (int, optional): The order of the linear filter. Default is None. | |
hidden_size (int, optional): The number of hidden units. Default is None. | |
""" | |
super(UniDeepFsmn, self).__init__() | |
self.input_dim = input_dim # Store input dimension | |
self.output_dim = output_dim # Store output dimension | |
if lorder is None: | |
return # Exit if no filter order is specified | |
self.lorder = lorder # Store the linear filter order | |
self.hidden_size = hidden_size # Store hidden layer size | |
# Define linear transformation from input to hidden layer | |
self.linear = nn.Linear(input_dim, hidden_size) | |
# Define linear transformation from hidden layer to output | |
self.project = nn.Linear(hidden_size, output_dim, bias=False) | |
# Define convolutional layer for processing output with specified filter order | |
self.conv1 = nn.Conv2d(output_dim, output_dim, [lorder + lorder - 1, 1], [1, 1], groups=output_dim, bias=False) | |
def forward(self, input): | |
"""Forward pass of the UniDeepFsmn model. | |
Args: | |
input (torch.Tensor): The input tensor with shape (batch_size, input_dim). | |
Returns: | |
torch.Tensor: The output tensor after processing through the model. | |
""" | |
# Apply ReLU activation after linear transformation | |
f1 = F.relu(self.linear(input)) | |
# Project to output dimension | |
p1 = self.project(f1) | |
# Unsqueeze to add a new dimension for the convolution operation | |
x = th.unsqueeze(p1, 1) | |
# Permute dimensions for the convolutional layer input | |
x_per = x.permute(0, 3, 2, 1) | |
# Pad the input for convolutional layer | |
y = F.pad(x_per, [0, 0, self.lorder - 1, self.lorder - 1]) | |
# Apply convolution and add the result back to the original input | |
out = x_per + self.conv1(y) | |
# Permute dimensions back to original format for output | |
out1 = out.permute(0, 3, 2, 1) | |
# Return the combined output | |
return input + out1.squeeze() | |