|
|
|
|
|
|
|
import os
|
|
|
|
os.environ["NUMBA_CACHE_DIR"] = "/tmp/"
|
|
|
|
import torch
|
|
import torch.nn as nn
|
|
import torch.nn.functional as F
|
|
from torchlibrosa.stft import Spectrogram, LogmelFilterBank
|
|
from torchlibrosa.augmentation import SpecAugmentation
|
|
|
|
from .utils import do_mixup, interpolate
|
|
from .feature_fusion import iAFF, AFF, DAF
|
|
|
|
|
|
def init_layer(layer):
|
|
"""Initialize a Linear or Convolutional layer."""
|
|
nn.init.xavier_uniform_(layer.weight)
|
|
|
|
if hasattr(layer, "bias"):
|
|
if layer.bias is not None:
|
|
layer.bias.data.fill_(0.0)
|
|
|
|
|
|
def init_bn(bn):
|
|
"""Initialize a Batchnorm layer."""
|
|
bn.bias.data.fill_(0.0)
|
|
bn.weight.data.fill_(1.0)
|
|
|
|
|
|
class ConvBlock(nn.Module):
|
|
def __init__(self, in_channels, out_channels):
|
|
super(ConvBlock, self).__init__()
|
|
|
|
self.conv1 = nn.Conv2d(
|
|
in_channels=in_channels,
|
|
out_channels=out_channels,
|
|
kernel_size=(3, 3),
|
|
stride=(1, 1),
|
|
padding=(1, 1),
|
|
bias=False,
|
|
)
|
|
|
|
self.conv2 = nn.Conv2d(
|
|
in_channels=out_channels,
|
|
out_channels=out_channels,
|
|
kernel_size=(3, 3),
|
|
stride=(1, 1),
|
|
padding=(1, 1),
|
|
bias=False,
|
|
)
|
|
|
|
self.bn1 = nn.BatchNorm2d(out_channels)
|
|
self.bn2 = nn.BatchNorm2d(out_channels)
|
|
|
|
self.init_weight()
|
|
|
|
def init_weight(self):
|
|
init_layer(self.conv1)
|
|
init_layer(self.conv2)
|
|
init_bn(self.bn1)
|
|
init_bn(self.bn2)
|
|
|
|
def forward(self, input, pool_size=(2, 2), pool_type="avg"):
|
|
x = input
|
|
x = F.relu_(self.bn1(self.conv1(x)))
|
|
x = F.relu_(self.bn2(self.conv2(x)))
|
|
if pool_type == "max":
|
|
x = F.max_pool2d(x, kernel_size=pool_size)
|
|
elif pool_type == "avg":
|
|
x = F.avg_pool2d(x, kernel_size=pool_size)
|
|
elif pool_type == "avg+max":
|
|
x1 = F.avg_pool2d(x, kernel_size=pool_size)
|
|
x2 = F.max_pool2d(x, kernel_size=pool_size)
|
|
x = x1 + x2
|
|
else:
|
|
raise Exception("Incorrect argument!")
|
|
|
|
return x
|
|
|
|
|
|
class ConvBlock5x5(nn.Module):
|
|
def __init__(self, in_channels, out_channels):
|
|
super(ConvBlock5x5, self).__init__()
|
|
|
|
self.conv1 = nn.Conv2d(
|
|
in_channels=in_channels,
|
|
out_channels=out_channels,
|
|
kernel_size=(5, 5),
|
|
stride=(1, 1),
|
|
padding=(2, 2),
|
|
bias=False,
|
|
)
|
|
|
|
self.bn1 = nn.BatchNorm2d(out_channels)
|
|
|
|
self.init_weight()
|
|
|
|
def init_weight(self):
|
|
init_layer(self.conv1)
|
|
init_bn(self.bn1)
|
|
|
|
def forward(self, input, pool_size=(2, 2), pool_type="avg"):
|
|
x = input
|
|
x = F.relu_(self.bn1(self.conv1(x)))
|
|
if pool_type == "max":
|
|
x = F.max_pool2d(x, kernel_size=pool_size)
|
|
elif pool_type == "avg":
|
|
x = F.avg_pool2d(x, kernel_size=pool_size)
|
|
elif pool_type == "avg+max":
|
|
x1 = F.avg_pool2d(x, kernel_size=pool_size)
|
|
x2 = F.max_pool2d(x, kernel_size=pool_size)
|
|
x = x1 + x2
|
|
else:
|
|
raise Exception("Incorrect argument!")
|
|
|
|
return x
|
|
|
|
|
|
class AttBlock(nn.Module):
|
|
def __init__(self, n_in, n_out, activation="linear", temperature=1.0):
|
|
super(AttBlock, self).__init__()
|
|
|
|
self.activation = activation
|
|
self.temperature = temperature
|
|
self.att = nn.Conv1d(
|
|
in_channels=n_in,
|
|
out_channels=n_out,
|
|
kernel_size=1,
|
|
stride=1,
|
|
padding=0,
|
|
bias=True,
|
|
)
|
|
self.cla = nn.Conv1d(
|
|
in_channels=n_in,
|
|
out_channels=n_out,
|
|
kernel_size=1,
|
|
stride=1,
|
|
padding=0,
|
|
bias=True,
|
|
)
|
|
|
|
self.bn_att = nn.BatchNorm1d(n_out)
|
|
self.init_weights()
|
|
|
|
def init_weights(self):
|
|
init_layer(self.att)
|
|
init_layer(self.cla)
|
|
init_bn(self.bn_att)
|
|
|
|
def forward(self, x):
|
|
|
|
norm_att = torch.softmax(torch.clamp(self.att(x), -10, 10), dim=-1)
|
|
cla = self.nonlinear_transform(self.cla(x))
|
|
x = torch.sum(norm_att * cla, dim=2)
|
|
return x, norm_att, cla
|
|
|
|
def nonlinear_transform(self, x):
|
|
if self.activation == "linear":
|
|
return x
|
|
elif self.activation == "sigmoid":
|
|
return torch.sigmoid(x)
|
|
|
|
|
|
class Cnn14(nn.Module):
|
|
def __init__(
|
|
self,
|
|
sample_rate,
|
|
window_size,
|
|
hop_size,
|
|
mel_bins,
|
|
fmin,
|
|
fmax,
|
|
classes_num,
|
|
enable_fusion=False,
|
|
fusion_type="None",
|
|
):
|
|
super(Cnn14, self).__init__()
|
|
|
|
window = "hann"
|
|
center = True
|
|
pad_mode = "reflect"
|
|
ref = 1.0
|
|
amin = 1e-10
|
|
top_db = None
|
|
|
|
self.enable_fusion = enable_fusion
|
|
self.fusion_type = fusion_type
|
|
|
|
|
|
self.spectrogram_extractor = Spectrogram(
|
|
n_fft=window_size,
|
|
hop_length=hop_size,
|
|
win_length=window_size,
|
|
window=window,
|
|
center=center,
|
|
pad_mode=pad_mode,
|
|
freeze_parameters=True,
|
|
)
|
|
|
|
|
|
self.logmel_extractor = LogmelFilterBank(
|
|
sr=sample_rate,
|
|
n_fft=window_size,
|
|
n_mels=mel_bins,
|
|
fmin=fmin,
|
|
fmax=fmax,
|
|
ref=ref,
|
|
amin=amin,
|
|
top_db=top_db,
|
|
freeze_parameters=True,
|
|
)
|
|
|
|
|
|
self.spec_augmenter = SpecAugmentation(
|
|
time_drop_width=64,
|
|
time_stripes_num=2,
|
|
freq_drop_width=8,
|
|
freq_stripes_num=2,
|
|
)
|
|
|
|
self.bn0 = nn.BatchNorm2d(64)
|
|
|
|
if (self.enable_fusion) and (self.fusion_type == "channel_map"):
|
|
self.conv_block1 = ConvBlock(in_channels=4, out_channels=64)
|
|
else:
|
|
self.conv_block1 = ConvBlock(in_channels=1, out_channels=64)
|
|
self.conv_block2 = ConvBlock(in_channels=64, out_channels=128)
|
|
self.conv_block3 = ConvBlock(in_channels=128, out_channels=256)
|
|
self.conv_block4 = ConvBlock(in_channels=256, out_channels=512)
|
|
self.conv_block5 = ConvBlock(in_channels=512, out_channels=1024)
|
|
self.conv_block6 = ConvBlock(in_channels=1024, out_channels=2048)
|
|
|
|
self.fc1 = nn.Linear(2048, 2048, bias=True)
|
|
self.fc_audioset = nn.Linear(2048, classes_num, bias=True)
|
|
|
|
if (self.enable_fusion) and (
|
|
self.fusion_type in ["daf_1d", "aff_1d", "iaff_1d"]
|
|
):
|
|
self.mel_conv1d = nn.Sequential(
|
|
nn.Conv1d(64, 64, kernel_size=5, stride=3, padding=2),
|
|
nn.BatchNorm1d(64),
|
|
)
|
|
if self.fusion_type == "daf_1d":
|
|
self.fusion_model = DAF()
|
|
elif self.fusion_type == "aff_1d":
|
|
self.fusion_model = AFF(channels=64, type="1D")
|
|
elif self.fusion_type == "iaff_1d":
|
|
self.fusion_model = iAFF(channels=64, type="1D")
|
|
|
|
if (self.enable_fusion) and (
|
|
self.fusion_type in ["daf_2d", "aff_2d", "iaff_2d"]
|
|
):
|
|
self.mel_conv2d = nn.Sequential(
|
|
nn.Conv2d(1, 64, kernel_size=(5, 5), stride=(6, 2), padding=(2, 2)),
|
|
nn.BatchNorm2d(64),
|
|
nn.ReLU(inplace=True),
|
|
)
|
|
|
|
if self.fusion_type == "daf_2d":
|
|
self.fusion_model = DAF()
|
|
elif self.fusion_type == "aff_2d":
|
|
self.fusion_model = AFF(channels=64, type="2D")
|
|
elif self.fusion_type == "iaff_2d":
|
|
self.fusion_model = iAFF(channels=64, type="2D")
|
|
self.init_weight()
|
|
|
|
def init_weight(self):
|
|
init_bn(self.bn0)
|
|
init_layer(self.fc1)
|
|
init_layer(self.fc_audioset)
|
|
|
|
def forward(self, input, mixup_lambda=None, device=None):
|
|
"""
|
|
Input: (batch_size, data_length)"""
|
|
|
|
if self.enable_fusion and input["longer"].sum() == 0:
|
|
|
|
input["longer"][torch.randint(0, input["longer"].shape[0], (1,))] = True
|
|
|
|
if not self.enable_fusion:
|
|
x = self.spectrogram_extractor(
|
|
input["waveform"].to(device=device, non_blocking=True)
|
|
)
|
|
x = self.logmel_extractor(x)
|
|
|
|
x = x.transpose(1, 3)
|
|
x = self.bn0(x)
|
|
x = x.transpose(1, 3)
|
|
else:
|
|
longer_list = input["longer"].to(device=device, non_blocking=True)
|
|
x = input["mel_fusion"].to(device=device, non_blocking=True)
|
|
longer_list_idx = torch.where(longer_list)[0]
|
|
x = x.transpose(1, 3)
|
|
x = self.bn0(x)
|
|
x = x.transpose(1, 3)
|
|
if self.fusion_type in ["daf_1d", "aff_1d", "iaff_1d"]:
|
|
new_x = x[:, 0:1, :, :].clone().contiguous()
|
|
|
|
if len(longer_list_idx) > 0:
|
|
fusion_x_local = x[longer_list_idx, 1:, :, :].clone().contiguous()
|
|
FB, FC, FT, FF = fusion_x_local.size()
|
|
fusion_x_local = fusion_x_local.view(FB * FC, FT, FF)
|
|
fusion_x_local = torch.permute(
|
|
fusion_x_local, (0, 2, 1)
|
|
).contiguous()
|
|
fusion_x_local = self.mel_conv1d(fusion_x_local)
|
|
fusion_x_local = fusion_x_local.view(
|
|
FB, FC, FF, fusion_x_local.size(-1)
|
|
)
|
|
fusion_x_local = (
|
|
torch.permute(fusion_x_local, (0, 2, 1, 3))
|
|
.contiguous()
|
|
.flatten(2)
|
|
)
|
|
if fusion_x_local.size(-1) < FT:
|
|
fusion_x_local = torch.cat(
|
|
[
|
|
fusion_x_local,
|
|
torch.zeros(
|
|
(FB, FF, FT - fusion_x_local.size(-1)),
|
|
device=device,
|
|
),
|
|
],
|
|
dim=-1,
|
|
)
|
|
else:
|
|
fusion_x_local = fusion_x_local[:, :, :FT]
|
|
|
|
new_x = new_x.squeeze(1).permute((0, 2, 1)).contiguous()
|
|
new_x[longer_list_idx] = self.fusion_model(
|
|
new_x[longer_list_idx], fusion_x_local
|
|
)
|
|
x = new_x.permute((0, 2, 1)).contiguous()[:, None, :, :]
|
|
else:
|
|
x = new_x
|
|
elif self.fusion_type in ["daf_2d", "aff_2d", "iaff_2d", "channel_map"]:
|
|
x = x
|
|
|
|
if self.training:
|
|
x = self.spec_augmenter(x)
|
|
|
|
if self.training and mixup_lambda is not None:
|
|
x = do_mixup(x, mixup_lambda)
|
|
if (self.enable_fusion) and (
|
|
self.fusion_type in ["daf_2d", "aff_2d", "iaff_2d"]
|
|
):
|
|
global_x = x[:, 0:1, :, :]
|
|
|
|
|
|
B, C, H, W = global_x.shape
|
|
global_x = self.conv_block1(global_x, pool_size=(2, 2), pool_type="avg")
|
|
if len(longer_list_idx) > 0:
|
|
local_x = x[longer_list_idx, 1:, :, :].contiguous()
|
|
TH = global_x.size(-2)
|
|
|
|
B, C, H, W = local_x.shape
|
|
local_x = local_x.view(B * C, 1, H, W)
|
|
local_x = self.mel_conv2d(local_x)
|
|
local_x = local_x.view(
|
|
B, C, local_x.size(1), local_x.size(2), local_x.size(3)
|
|
)
|
|
local_x = local_x.permute((0, 2, 1, 3, 4)).contiguous().flatten(2, 3)
|
|
TB, TC, _, TW = local_x.size()
|
|
if local_x.size(-2) < TH:
|
|
local_x = torch.cat(
|
|
[
|
|
local_x,
|
|
torch.zeros(
|
|
(TB, TC, TH - local_x.size(-2), TW),
|
|
device=global_x.device,
|
|
),
|
|
],
|
|
dim=-2,
|
|
)
|
|
else:
|
|
local_x = local_x[:, :, :TH, :]
|
|
|
|
global_x[longer_list_idx] = self.fusion_model(
|
|
global_x[longer_list_idx], local_x
|
|
)
|
|
x = global_x
|
|
else:
|
|
x = self.conv_block1(x, pool_size=(2, 2), pool_type="avg")
|
|
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block2(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block3(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block4(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block5(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block6(x, pool_size=(1, 1), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = torch.mean(x, dim=3)
|
|
|
|
latent_x1 = F.max_pool1d(x, kernel_size=3, stride=1, padding=1)
|
|
latent_x2 = F.avg_pool1d(x, kernel_size=3, stride=1, padding=1)
|
|
latent_x = latent_x1 + latent_x2
|
|
latent_x = latent_x.transpose(1, 2)
|
|
latent_x = F.relu_(self.fc1(latent_x))
|
|
latent_output = interpolate(latent_x, 32)
|
|
|
|
(x1, _) = torch.max(x, dim=2)
|
|
x2 = torch.mean(x, dim=2)
|
|
x = x1 + x2
|
|
x = F.dropout(x, p=0.5, training=self.training)
|
|
x = F.relu_(self.fc1(x))
|
|
embedding = F.dropout(x, p=0.5, training=self.training)
|
|
clipwise_output = torch.sigmoid(self.fc_audioset(x))
|
|
|
|
output_dict = {
|
|
"clipwise_output": clipwise_output,
|
|
"embedding": embedding,
|
|
"fine_grained_embedding": latent_output,
|
|
}
|
|
return output_dict
|
|
|
|
|
|
class Cnn6(nn.Module):
|
|
def __init__(
|
|
self,
|
|
sample_rate,
|
|
window_size,
|
|
hop_size,
|
|
mel_bins,
|
|
fmin,
|
|
fmax,
|
|
classes_num,
|
|
enable_fusion=False,
|
|
fusion_type="None",
|
|
):
|
|
super(Cnn6, self).__init__()
|
|
|
|
window = "hann"
|
|
center = True
|
|
pad_mode = "reflect"
|
|
ref = 1.0
|
|
amin = 1e-10
|
|
top_db = None
|
|
|
|
self.enable_fusion = enable_fusion
|
|
self.fusion_type = fusion_type
|
|
|
|
|
|
self.spectrogram_extractor = Spectrogram(
|
|
n_fft=window_size,
|
|
hop_length=hop_size,
|
|
win_length=window_size,
|
|
window=window,
|
|
center=center,
|
|
pad_mode=pad_mode,
|
|
freeze_parameters=True,
|
|
)
|
|
|
|
|
|
self.logmel_extractor = LogmelFilterBank(
|
|
sr=sample_rate,
|
|
n_fft=window_size,
|
|
n_mels=mel_bins,
|
|
fmin=fmin,
|
|
fmax=fmax,
|
|
ref=ref,
|
|
amin=amin,
|
|
top_db=top_db,
|
|
freeze_parameters=True,
|
|
)
|
|
|
|
|
|
self.spec_augmenter = SpecAugmentation(
|
|
time_drop_width=64,
|
|
time_stripes_num=2,
|
|
freq_drop_width=8,
|
|
freq_stripes_num=2,
|
|
)
|
|
|
|
self.bn0 = nn.BatchNorm2d(64)
|
|
|
|
self.conv_block1 = ConvBlock5x5(in_channels=1, out_channels=64)
|
|
self.conv_block2 = ConvBlock5x5(in_channels=64, out_channels=128)
|
|
self.conv_block3 = ConvBlock5x5(in_channels=128, out_channels=256)
|
|
self.conv_block4 = ConvBlock5x5(in_channels=256, out_channels=512)
|
|
|
|
self.fc1 = nn.Linear(512, 512, bias=True)
|
|
self.fc_audioset = nn.Linear(512, classes_num, bias=True)
|
|
|
|
self.init_weight()
|
|
|
|
def init_weight(self):
|
|
init_bn(self.bn0)
|
|
init_layer(self.fc1)
|
|
init_layer(self.fc_audioset)
|
|
|
|
def forward(self, input, mixup_lambda=None, device=None):
|
|
"""
|
|
Input: (batch_size, data_length)"""
|
|
|
|
x = self.spectrogram_extractor(input)
|
|
x = self.logmel_extractor(x)
|
|
|
|
x = x.transpose(1, 3)
|
|
x = self.bn0(x)
|
|
x = x.transpose(1, 3)
|
|
|
|
if self.training:
|
|
x = self.spec_augmenter(x)
|
|
|
|
|
|
if self.training and mixup_lambda is not None:
|
|
x = do_mixup(x, mixup_lambda)
|
|
|
|
x = self.conv_block1(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block2(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block3(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block4(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = torch.mean(x, dim=3)
|
|
|
|
latent_x1 = F.max_pool1d(x, kernel_size=3, stride=1, padding=1)
|
|
latent_x2 = F.avg_pool1d(x, kernel_size=3, stride=1, padding=1)
|
|
latent_x = latent_x1 + latent_x2
|
|
latent_x = latent_x.transpose(1, 2)
|
|
latent_x = F.relu_(self.fc1(latent_x))
|
|
latent_output = interpolate(latent_x, 16)
|
|
|
|
(x1, _) = torch.max(x, dim=2)
|
|
x2 = torch.mean(x, dim=2)
|
|
x = x1 + x2
|
|
x = F.dropout(x, p=0.5, training=self.training)
|
|
x = F.relu_(self.fc1(x))
|
|
embedding = F.dropout(x, p=0.5, training=self.training)
|
|
clipwise_output = torch.sigmoid(self.fc_audioset(x))
|
|
|
|
output_dict = {
|
|
"clipwise_output": clipwise_output,
|
|
"embedding": embedding,
|
|
"fine_grained_embedding": latent_output,
|
|
}
|
|
|
|
return output_dict
|
|
|
|
|
|
class Cnn10(nn.Module):
|
|
def __init__(
|
|
self,
|
|
sample_rate,
|
|
window_size,
|
|
hop_size,
|
|
mel_bins,
|
|
fmin,
|
|
fmax,
|
|
classes_num,
|
|
enable_fusion=False,
|
|
fusion_type="None",
|
|
):
|
|
super(Cnn10, self).__init__()
|
|
|
|
window = "hann"
|
|
center = True
|
|
pad_mode = "reflect"
|
|
ref = 1.0
|
|
amin = 1e-10
|
|
top_db = None
|
|
|
|
self.enable_fusion = enable_fusion
|
|
self.fusion_type = fusion_type
|
|
|
|
|
|
self.spectrogram_extractor = Spectrogram(
|
|
n_fft=window_size,
|
|
hop_length=hop_size,
|
|
win_length=window_size,
|
|
window=window,
|
|
center=center,
|
|
pad_mode=pad_mode,
|
|
freeze_parameters=True,
|
|
)
|
|
|
|
|
|
self.logmel_extractor = LogmelFilterBank(
|
|
sr=sample_rate,
|
|
n_fft=window_size,
|
|
n_mels=mel_bins,
|
|
fmin=fmin,
|
|
fmax=fmax,
|
|
ref=ref,
|
|
amin=amin,
|
|
top_db=top_db,
|
|
freeze_parameters=True,
|
|
)
|
|
|
|
|
|
self.spec_augmenter = SpecAugmentation(
|
|
time_drop_width=64,
|
|
time_stripes_num=2,
|
|
freq_drop_width=8,
|
|
freq_stripes_num=2,
|
|
)
|
|
|
|
self.bn0 = nn.BatchNorm2d(64)
|
|
|
|
self.conv_block1 = ConvBlock(in_channels=1, out_channels=64)
|
|
self.conv_block2 = ConvBlock(in_channels=64, out_channels=128)
|
|
self.conv_block3 = ConvBlock(in_channels=128, out_channels=256)
|
|
self.conv_block4 = ConvBlock(in_channels=256, out_channels=512)
|
|
self.conv_block5 = ConvBlock(in_channels=512, out_channels=1024)
|
|
|
|
self.fc1 = nn.Linear(1024, 1024, bias=True)
|
|
self.fc_audioset = nn.Linear(1024, classes_num, bias=True)
|
|
|
|
self.init_weight()
|
|
|
|
def init_weight(self):
|
|
init_bn(self.bn0)
|
|
init_layer(self.fc1)
|
|
init_layer(self.fc_audioset)
|
|
|
|
def forward(self, input, mixup_lambda=None, device=None):
|
|
"""
|
|
Input: (batch_size, data_length)"""
|
|
|
|
x = self.spectrogram_extractor(input)
|
|
x = self.logmel_extractor(x)
|
|
|
|
x = x.transpose(1, 3)
|
|
x = self.bn0(x)
|
|
x = x.transpose(1, 3)
|
|
|
|
if self.training:
|
|
x = self.spec_augmenter(x)
|
|
|
|
|
|
if self.training and mixup_lambda is not None:
|
|
x = do_mixup(x, mixup_lambda)
|
|
|
|
x = self.conv_block1(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block2(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block3(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block4(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = self.conv_block5(x, pool_size=(2, 2), pool_type="avg")
|
|
x = F.dropout(x, p=0.2, training=self.training)
|
|
x = torch.mean(x, dim=3)
|
|
|
|
latent_x1 = F.max_pool1d(x, kernel_size=3, stride=1, padding=1)
|
|
latent_x2 = F.avg_pool1d(x, kernel_size=3, stride=1, padding=1)
|
|
latent_x = latent_x1 + latent_x2
|
|
latent_x = latent_x.transpose(1, 2)
|
|
latent_x = F.relu_(self.fc1(latent_x))
|
|
latent_output = interpolate(latent_x, 32)
|
|
|
|
(x1, _) = torch.max(x, dim=2)
|
|
x2 = torch.mean(x, dim=2)
|
|
x = x1 + x2
|
|
x = F.dropout(x, p=0.5, training=self.training)
|
|
x = F.relu_(self.fc1(x))
|
|
embedding = F.dropout(x, p=0.5, training=self.training)
|
|
clipwise_output = torch.sigmoid(self.fc_audioset(x))
|
|
|
|
output_dict = {
|
|
"clipwise_output": clipwise_output,
|
|
"embedding": embedding,
|
|
"fine_grained_embedding": latent_output,
|
|
}
|
|
|
|
return output_dict
|
|
|
|
|
|
def create_pann_model(audio_cfg, enable_fusion=False, fusion_type="None"):
|
|
try:
|
|
ModelProto = eval(audio_cfg.model_name)
|
|
model = ModelProto(
|
|
sample_rate=audio_cfg.sample_rate,
|
|
window_size=audio_cfg.window_size,
|
|
hop_size=audio_cfg.hop_size,
|
|
mel_bins=audio_cfg.mel_bins,
|
|
fmin=audio_cfg.fmin,
|
|
fmax=audio_cfg.fmax,
|
|
classes_num=audio_cfg.class_num,
|
|
enable_fusion=enable_fusion,
|
|
fusion_type=fusion_type,
|
|
)
|
|
return model
|
|
except:
|
|
raise RuntimeError(
|
|
f"Import Model for {audio_cfg.model_name} not found, or the audio cfg parameters are not enough."
|
|
)
|
|
|