{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":44224,"databundleVersionId":5188730,"sourceType":"competition"},{"sourceId":8402193,"sourceType":"datasetVersion","datasetId":4999414}],"dockerImageVersionId":30698,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import sys\nsys.path.append('/kaggle/input/')#/kaggle/input/models/best_model.pth","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-05-14T01:41:11.255877Z","iopub.execute_input":"2024-05-14T01:41:11.256257Z","iopub.status.idle":"2024-05-14T01:41:11.291217Z","shell.execute_reply.started":"2024-05-14T01:41:11.256228Z","shell.execute_reply":"2024-05-14T01:41:11.289961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Default_config(object):\n    # 训练还是测试阶段\n    stage = 'train'\n    # 数据集路径\n    datasets_name = '../dataset'\n    # 种子\n    seed = 0\n    # 批次大小\n    batch_size = 32\n    # epoch\n    all_epoch = 50\n    # 第x个epoch，学习率减小\n    lr_decay_step = 20\n    load_model_path = 'best_model.pth'\n    save_model_path = 'checkpoints'\n    # 分类的类别\n    num_classes = 264\n    # 加载数据进程\n    num_workers = 4\n    # 打印信息 频率\n    print_info_epoch = 1\n    save_model_epoch = 1\n    # 学习率\n    lr = 0.001\n    # 学习率衰减\n    lr_decay_ratio = 0.1\n    # 权重衰减\n    weight_decay = 5e-4\n","metadata":{"execution":{"iopub.status.busy":"2024-05-14T01:41:11.293633Z","iopub.execute_input":"2024-05-14T01:41:11.294612Z","iopub.status.idle":"2024-05-14T01:41:11.302253Z","shell.execute_reply.started":"2024-05-14T01:41:11.294565Z","shell.execute_reply":"2024-05-14T01:41:11.300752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import glob\n\nimport numpy as np\nimport pandas as pd\nimport random\nimport torch\nimport torchaudio\nimport os\n\nfrom librosa.filters import get_window, mel\nfrom matplotlib import pyplot as plt\nfrom scipy.fft import dct\nfrom torchaudio import transforms\nimport torch.nn.functional as F\nfrom torchaudio.transforms import Spectrogram\n\n\nclass AudioUtil():\n    # ----------------------------\n    # Load an audio file. Return the signal as a tensor and the sample rate\n    # ----------------------------\n    @staticmethod\n    def open(audio_file):\n        sig, sr = torchaudio.load(audio_file)\n        return (sig, sr)\n\n    # ----------------------------\n    # Convert the given audio to the desired number of channels\n    # ----------------------------\n    @staticmethod\n    def rechannel(aud, new_channel):\n        sig, sr = aud\n\n        if (sig.shape[0] == new_channel):\n            # Nothing to do\n            return aud\n\n        if (new_channel == 1):\n            # Convert from stereo to mono by selecting only the first channel\n            resig = sig[:1, :]\n        else:\n            # Convert from mono to stereo by duplicating the first channel\n            resig = torch.cat([sig, sig])\n\n        return ((resig, sr))\n\n    # ----------------------------\n    # Since Resample applies to a single channel, we resample one channel at a time\n    # ----------------------------\n    @staticmethod\n    def resample(aud, newsr):\n        sig, sr = aud\n\n        if (sr == newsr):\n            # Nothing to do\n            return aud\n\n        num_channels = sig.shape[0]\n        # Resample first channel\n        resig = torchaudio.transforms.Resample(sr, newsr)(sig[:1, :])\n        if (num_channels > 1):\n            # Resample the second channel and merge both channels\n            retwo = torchaudio.transforms.Resample(sr, newsr)(sig[1:, :])\n            resig = torch.cat([resig, retwo])\n\n        return ((resig, newsr))\n\n    # ----------------------------\n    # Pad (or truncate) the signal to a fixed length 'max_ms' in milliseconds\n    # ----------------------------\n    @staticmethod\n    def pad_trunc(aud, max_ms):\n        sig, sr = aud\n        num_rows, sig_len = sig.shape\n        max_len = sr // 1000 * max_ms\n\n        if (sig_len > max_len):\n            # Truncate the signal to the given length\n            sig = sig[:, :max_len]\n\n        elif (sig_len < max_len):\n            # Length of padding to add at the beginning and end of the signal\n            pad_begin_len = random.randint(0, max_len - sig_len)\n            pad_end_len = max_len - sig_len - pad_begin_len\n\n            # Pad with 0s\n            pad_begin = torch.zeros((num_rows, pad_begin_len))\n            pad_end = torch.zeros((num_rows, pad_end_len))\n\n            sig = torch.cat((pad_begin, sig, pad_end), 1)\n\n        return (sig, sr)\n\n    # ----------------------------\n    # Shifts the signal to the left or right by some percent. Values at the end\n    # are 'wrapped around' to the start of the transformed signal.\n    # ----------------------------\n    @staticmethod\n    def time_shift(aud, shift_limit):\n        sig, sr = aud\n        _, sig_len = sig.shape\n        shift_amt = int(random.random() * shift_limit * sig_len)\n        return (sig.roll(shift_amt), sr)\n\n    # ----------------------------\n    # Generate a Spectrogram\n    # ----------------------------\n\n    # ----------------------------\n    # Augment the Spectrogram by masking out some sections of it in both the frequency\n    # dimension (ie. horizontal bars) and the time dimension (vertical bars) to prevent\n    # overfitting and to help the model generalise better. The masked sections are\n    # replaced with the mean value.\n    # ----------------------------\n    @staticmethod\n    def spectro_augment(spec, max_mask_pct=0.1, n_freq_masks=1, n_time_masks=1):\n        _, n_mels, n_steps = spec.shape\n        mask_value = spec.mean()\n        aug_spec = spec\n\n        freq_mask_param = max_mask_pct * n_mels\n        for _ in range(n_freq_masks):\n            aug_spec = transforms.FrequencyMasking(freq_mask_param)(aug_spec, mask_value)\n\n        time_mask_param = max_mask_pct * n_steps\n        for _ in range(n_time_masks):\n            aug_spec = transforms.TimeMasking(time_mask_param)(aug_spec, mask_value)\n\n        return aug_spec\n\n\ndef spectro_gram(aud, n_mels=64, n_fft=1024, hop_len=None, preemph=0.97, frame_len=20, frame_hop=10, n_mfcc=13):\n    sig, sr = aud  # 解包出sr变量\n    top_db = 80\n\n    # 计算梅尔频谱图\n    mel_spec_transform = torchaudio.transforms.MelSpectrogram(\n        sample_rate=sr,\n        n_fft=n_fft,\n        hop_length=hop_len,\n        n_mels=n_mels\n    )\n    mel_spec = mel_spec_transform(sig)\n\n    # 转换为分贝\n    mel_spec_db = transforms.AmplitudeToDB(top_db=top_db)(mel_spec)\n\n    # 计算一阶差分\n    delta = torch.diff(mel_spec_db, dim=-1)\n    # 裁剪 mel_spec_db，使其长度与 delta 相同\n    mel_spec_db = mel_spec_db[:, :, :delta.shape[-1]]\n\n    # 计算二阶差分\n    delta_delta = torch.diff(delta, dim=-1)\n    # 裁剪 mel_spec_db，使其长度与 delta_delta 相同\n    mel_spec_db = mel_spec_db[:, :, :delta_delta.shape[-1]]\n    mel_spec_db1 = delta[:, :, :delta_delta.shape[-1]]\n\n    mfcc_transform = torchaudio.transforms.MFCC(\n        sample_rate=sr,\n        n_mfcc=64,  # 与梅尔频谱图的通道数相匹配\n    )\n    mfcc = mfcc_transform(sig)\n\n    desired_time_frames = mel_spec_db1.shape[2]  # 使用与其他张量相同的时间帧数\n    mfcc_reduced = F.avg_pool1d(mfcc, kernel_size=mfcc.shape[2] // desired_time_frames)\n    mfcc_reduced1 = mfcc_reduced[:, :, :delta_delta.shape[-1]]\n    #print(\"Mel Spectrogram shape:\", mel_spec_db.shape)\n    #print(\"Delta shape:\", delta.shape)\n    #print(\"Delta Delta shape:\", delta_delta.shape)\n    #print(\"MFCC shape:\", mfcc_reduced1.shape)\n    # 沿着通道维度连接\n    features = torch.cat([mel_spec_db, mel_spec_db1, delta_delta,mfcc_reduced1], dim=0)\n\n    return features\n\n\n\ndef display_spectrograms(spec, aug_spec, title1=\"Original Mel Spectrogram\", title2=\"Augmented Mel Spectrogram\"):\n       fig, axs = plt.subplots(1, 2, figsize=(15, 6))\n       axs[0].set_title(title1)\n       axs[0].imshow(spec[0], aspect='auto', origin='lower', cmap='viridis')\n       axs[1].set_title(title2)\n       axs[1].imshow(aug_spec[0], aspect='auto', origin='lower', cmap='viridis')\n       plt.tight_layout()\n       #plt.savefig('Mel Spectrogram.png' % stage)\n       plt.show()\n\n\nclass mySoundDS():\n    def __init__(self, root, ):\n        classes = os.listdir(root)\n        print(classes)\n        samples = []\n        for label, cla in enumerate(classes):\n            files = glob.glob(os.path.join(root, cla, '*.ogg'))\n            for fname in sorted(files):\n                samples.append([fname, label])\n        self.samples = samples\n\n        self.duration = 4000\n        self.sr = 44100\n        self.channel = 2\n        self.shift_pct = 0.4\n\n    def __len__(self):\n        return len(self.samples)\n\n    def __getitem__(self, index):\n\n        audio_file, class_id = self.samples[index]\n        aud = AudioUtil.open(audio_file)\n        reaud = AudioUtil.resample(aud, self.sr)\n        rechan = AudioUtil.rechannel(reaud, self.channel)\n        dur_aud = AudioUtil.pad_trunc(rechan, self.duration)\n        shift_aud = AudioUtil.time_shift(dur_aud, self.shift_pct)\n        sgram = spectro_gram(shift_aud, n_mels=64, n_fft=1024, hop_len=None)\n        aug_sgram = AudioUtil.spectro_augment(sgram, max_mask_pct=0.1, n_freq_masks=2, n_time_masks=2)\n        inputs_m, inputs_s = aug_sgram.mean(), aug_sgram.std()\n        aug_sgram = (aug_sgram - inputs_m) / inputs_s\n        #display_spectrograms(sgram, aug_sgram, title1=\"Original Mel Spectrogram\", title2=\"Augmented Mel Spectrogram\")\n        return aug_sgram, class_id\n","metadata":{"execution":{"iopub.status.busy":"2024-05-14T01:41:11.304046Z","iopub.execute_input":"2024-05-14T01:41:11.304519Z","iopub.status.idle":"2024-05-14T01:41:20.639510Z","shell.execute_reply.started":"2024-05-14T01:41:11.304480Z","shell.execute_reply":"2024-05-14T01:41:20.638266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torch.hub import load_state_dict_from_url\nfrom torch.nn import init\nimport torch.nn.functional as F\n\nmodel_urls = {\n    'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',\n    'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',\n    'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',\n    'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',\n    'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',\n\n}\n\n\ndef conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):\n    \"\"\"3x3 convolution with padding\"\"\"\n    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,\n                     padding=dilation, groups=groups, bias=False, dilation=dilation)\n\n\ndef conv1x1(in_planes, out_planes, stride=1):\n    \"\"\"1x1 convolution\"\"\"\n    return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)\n\n'''def Conv1(in_planes, out_places, stride=2):\n    return nn.Sequential(\n        nn.Conv2d(in_channels=in_planes, out_channels=out_places, kernel_size=3, stride=1, padding=1, bias=False),\n        nn.BatchNorm2d(out_places),\n        nn.ReLU(inplace=True),\n        # nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n    )\n'''\n\n\nclass BasicBlock(nn.Module):\n    expansion = 1\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,\n                 base_width=64, dilation=1, norm_layer=None):\n        super(BasicBlock, self).__init__()\n        if norm_layer is None:\n            norm_layer = nn.BatchNorm2d\n        if groups != 1 or base_width != 64:\n            raise ValueError('BasicBlock only supports groups=1 and base_width=64')\n        if dilation > 1:\n            raise NotImplementedError(\"Dilation > 1 not supported in BasicBlock\")\n        # Both self.conv1 and self.downsample layers downsample the input when stride != 1\n        self.conv1 = conv3x3(inplanes, planes, stride)\n        self.bn1 = norm_layer(planes)\n        self.relu = nn.ReLU(inplace=True)\n        self.conv2 = conv3x3(planes, planes)\n        self.bn2 = norm_layer(planes)\n        self.downsample = downsample\n        self.stride = stride\n\n    def forward(self, x):\n        identity = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n\n        if self.downsample is not None:\n            identity = self.downsample(x)\n\n        out += identity\n        out = self.relu(out)\n\n        return out\n\n\nclass SE(nn.Module):\n\n    def __init__(self, in_chnls, ratio):\n        super(SE, self).__init__()\n        self.squeeze = nn.AdaptiveAvgPool2d((1, 1))\n        self.compress = nn.Conv2d(in_chnls, in_chnls // ratio, 1, 1, 0)\n        self.excitation = nn.Conv2d(in_chnls // ratio, in_chnls, 1, 1, 0)\n\n    def forward(self, x):\n        out = self.squeeze(x)\n        out = self.compress(out)\n        out = F.relu(out)\n        out = self.excitation(out)\n        return x*F.sigmoid(out)\n\nclass Bottleneck(nn.Module):\n    # Bottleneck in torchvision places the stride for downsampling at 3x3 convolution(self.conv2)\n    # while original implementation places the stride at the first 1x1 convolution(self.conv1)\n    # according to \"Deep residual learning for image recognition\"https://arxiv.org/abs/1512.03385.\n    # This variant is also known as ResNet V1.5 and improves accuracy according to\n    # https://ngc.nvidia.com/catalog/model-scripts/nvidia:resnet_50_v1_5_for_pytorch.\n\n    expansion = 4\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,\n                 base_width=64, dilation=1, norm_layer=None):\n        super(Bottleneck, self).__init__()\n        if norm_layer is None:\n            norm_layer = nn.BatchNorm2d\n        width = int(planes * (base_width / 64.)) * groups\n        # Both self.conv2 and self.downsample layers downsample the input when stride != 1\n        self.conv1 = conv1x1(inplanes, width)\n        self.bn1 = norm_layer(width)\n        self.conv2 = conv3x3(width, width, stride, groups, dilation)\n        self.bn2 = norm_layer(width)\n        self.conv3 = conv1x1(width, planes * self.expansion)\n        self.bn3 = norm_layer(planes * self.expansion)\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n        self.stride = stride\n\n    def forward(self, x):\n        identity = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        if self.downsample is not None:\n            identity = self.downsample(x)\n\n        out += identity\n        out = self.relu(out)\n\n        return out\n\n\nclass ResNet(nn.Module):\n\n    def __init__(self, block, layers, num_classes=1000, zero_init_residual=False,\n                 groups=1, width_per_group=64, replace_stride_with_dilation=None,\n                 norm_layer=None):\n        super(ResNet, self).__init__()\n        if norm_layer is None:\n            norm_layer = nn.BatchNorm2d\n        self._norm_layer = norm_layer\n\n        self.inplanes = 64\n        self.dilation = 1\n        if replace_stride_with_dilation is None:\n            # each element in the tuple indicates if we should replace\n            # the 2x2 stride with a dilated convolution instead\n            replace_stride_with_dilation = [False, False, False]\n        if len(replace_stride_with_dilation) != 3:\n            raise ValueError(\"replace_stride_with_dilation should be None \"\n                             \"or a 3-element tuple, got {}\".format(replace_stride_with_dilation))\n        self.groups = groups\n        self.base_width = width_per_group\n        self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3,\n                               bias=False)\n        self.bn1 = norm_layer(self.inplanes)\n        self.relu = nn.ReLU(inplace=True)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        self.layer1 = self._make_layer(block, 64, layers[0])\n        self.layer2 = self._make_layer(block, 128, layers[1], stride=2,\n                                       dilate=replace_stride_with_dilation[0])\n        self.layer3 = self._make_layer(block, 256, layers[2], stride=2,\n                                       dilate=replace_stride_with_dilation[1])\n        self.layer4 = self._make_layer(block, 512, layers[3], stride=2,\n                                       dilate=replace_stride_with_dilation[2])\n        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))\n        self.fc = nn.Linear(512 * block.expansion, num_classes)\n\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')\n            elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):\n                nn.init.constant_(m.weight, 1)\n                nn.init.constant_(m.bias, 0)\n\n        # Zero-initialize the last BN in each residual branch,\n        # so that the residual branch starts with zeros, and each residual block behaves like an identity.\n        # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677\n        if zero_init_residual:\n            for m in self.modules():\n                if isinstance(m, Bottleneck):\n                    nn.init.constant_(m.bn3.weight, 0)\n                elif isinstance(m, BasicBlock):\n                    nn.init.constant_(m.bn2.weight, 0)\n\n    def _make_layer(self, block, planes, blocks, stride=1, dilate=False):\n        norm_layer = self._norm_layer\n        downsample = None\n        previous_dilation = self.dilation\n        if dilate:\n            self.dilation *= stride\n            stride = 1\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            downsample = nn.Sequential(\n                conv1x1(self.inplanes, planes * block.expansion, stride),\n                norm_layer(planes * block.expansion),\n            )\n\n        layers = []\n        layers.append(block(self.inplanes, planes, stride, downsample, self.groups,\n                            self.base_width, previous_dilation, norm_layer))\n        self.inplanes = planes * block.expansion\n        for _ in range(1, blocks):\n            layers.append(block(self.inplanes, planes, groups=self.groups,\n                                base_width=self.base_width, dilation=self.dilation,\n                                norm_layer=norm_layer))\n\n        return nn.Sequential(*layers)\n\n    def _forward_impl(self, x):\n        # See note [TorchScript super()]\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.relu(x)\n        x = self.maxpool(x)\n\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n\n        # x = self.avgpool(x)\n        # x = torch.flatten(x, 1)\n        # x = self.fc(x)\n\n        return x\n\n    def forward(self, x):\n        return self._forward_impl(x)\n\n\ndef _resnet(arch, block, layers, pretrained, progress, **kwargs):\n    model = ResNet(block, layers, **kwargs)\n    if pretrained:\n        state_dict = load_state_dict_from_url(model_urls[arch],\n                                              progress=progress)\n        model.load_state_dict(state_dict)\n    return model\n\n\ndef resnet18(pretrained=True, progress=True, **kwargs):\n    r\"\"\"ResNet-18 model from\n    `\"Deep Residual Learning for Image Recognition\" <https://arxiv.org/pdf/1512.03385.pdf>`_\n\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n        progress (bool): If True, displays a progress bar of the download to stderr\n    \"\"\"\n    return _resnet('resnet18', BasicBlock, [2, 2, 2, 2], pretrained, progress,\n                   **kwargs)\n\n\ndef resnet34(pretrained=True, progress=True, **kwargs):\n    r\"\"\"ResNet-34 model from\n    `\"Deep Residual Learning for Image Recognition\" <https://arxiv.org/pdf/1512.03385.pdf>`_\n\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n        progress (bool): If True, displays a progress bar of the download to stderr\n    \"\"\"\n    return _resnet('resnet34', BasicBlock, [3, 4, 6, 3], pretrained, progress,\n                   **kwargs)\n\n\ndef resnet50(pretrained=True, progress=True, **kwargs):\n    r\"\"\"ResNet-50 model from\n    `\"Deep Residual Learning for Image Recognition\" <https://arxiv.org/pdf/1512.03385.pdf>`_\n\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n        progress (bool): If True, displays a progress bar of the download to stderr\n    \"\"\"\n    return _resnet('resnet50', Bottleneck, [3, 4, 6, 3], pretrained, progress,\n                   **kwargs)\n\n\ndef resnet101(pretrained=True, progress=True, **kwargs):\n    r\"\"\"ResNet-101 model from\n    `\"Deep Residual Learning for Image Recognition\" <https://arxiv.org/pdf/1512.03385.pdf>`_\n\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n        progress (bool): If True, displays a progress bar of the download to stderr\n    \"\"\"\n    return _resnet('resnet101', Bottleneck, [3, 4, 23, 3], pretrained, progress,\n                   **kwargs)\n\n\ndef resnet152(pretrained=True, progress=True, **kwargs):\n    r\"\"\"ResNet-152 model from\n    `\"Deep Residual Learning for Image Recognition\" <https://arxiv.org/pdf/1512.03385.pdf>`_\n\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n        progress (bool): If True, displays a progress bar of the download to stderr\n    \"\"\"\n    return _resnet('resnet152', Bottleneck, [3, 8, 36, 3], pretrained, progress,\n                   **kwargs)\n\n\n# 重写的class 构建网络用的\nclass Net(nn.Module):\n    def __init__(self, num_classes=264):\n        super().__init__()\n        self.conv1 = nn.Conv2d(8, 16, kernel_size=(5, 5), stride=(2, 2), padding=(2, 2))\n        self.relu1 = nn.ReLU()\n        self.bn1 = nn.BatchNorm2d(16)\n        self.self_attention = SE(16, 16)\n        # Second Convolution Block\n        self.conv2 =nn.Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n        self.relu2 = nn.ReLU()\n        self.bn2 = nn.BatchNorm2d(32)\n        self.self_attention = SE(32, 32)\n        # Second Convolution Block\n        self.conv3 = nn.Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n        self.relu3 = nn.ReLU()\n        self.bn3 = nn.BatchNorm2d(64)\n        self.self_attention =SE(64, 64)\n\n        # Second Convolution Block\n        self.conv4 = nn.Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n        self.relu4 = nn.ReLU()\n        self.bn4 = nn.BatchNorm2d(128)\n        self.self_attention = SE(128, 128)\n\n        # Linear Classifier\n        self.ap = nn.AdaptiveAvgPool2d(output_size=1)\n        self.lin = nn.Linear(in_features=128, out_features=num_classes)\n\n    def forward(self, x):\n        x = self.relu1(self.bn1(self.conv1(x)))\n        x = self.relu2(self.bn2(self.conv2(x)))\n        x = self.relu3(self.bn3(self.conv3(x)))\n        x = self.relu4(self.bn4(self.conv4(x)))\n        x = self.ap(x)\n        x = x.view(x.shape[0], -1)\n        x = self.lin(x)\n        return x\n","metadata":{"execution":{"iopub.status.busy":"2024-05-14T01:41:20.642057Z","iopub.execute_input":"2024-05-14T01:41:20.642592Z","iopub.status.idle":"2024-05-14T01:41:20.716266Z","shell.execute_reply.started":"2024-05-14T01:41:20.642561Z","shell.execute_reply":"2024-05-14T01:41:20.714968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.append('/kaggle/input/codeme/')\nimport os\nimport argparse\n\nimport pandas as pd\nimport torch\nimport torchaudio\nfrom torch.backends import cudnn\nfrom torch.cuda.random import manual_seed_all\n\nimport numpy as np\nclass Process():\n    def __init__(self):\n        self.duration = 5000\n        self.sr = 44100\n        self.channel = 2\n        self.shift_pct = 0.4\n\n    def get_f(self, audio_file):\n        aud = AudioUtil.open(audio_file)\n        reaud = AudioUtil.resample(aud, self.sr)\n        rechan = AudioUtil.rechannel(reaud, self.channel)\n        dur_aud = AudioUtil.pad_trunc(rechan, self.duration)\n        shift_aud = AudioUtil.time_shift(dur_aud, self.shift_pct)\n        sgram = spectro_gram(shift_aud, n_mels=64, n_fft=1024, hop_len=None)\n        aug_sgram = AudioUtil.spectro_augment(sgram, max_mask_pct=0.1, n_freq_masks=2, n_time_masks=2)\n        inputs_m, inputs_s = aug_sgram.mean(), aug_sgram.std()\n        aug_sgram = (aug_sgram - inputs_m) / inputs_s\n\n        return aug_sgram\n\n\ndef classification(folder_path, device, net):\n    net.eval()\n    model_root_path = os.path.join(os.path.curdir, '/kaggle/input/models')\n    target_model_path = os.path.join(model_root_path, 'best_model.pth')\n    net.load_state_dict(torch.load(target_model_path, map_location=torch.device('cpu')))\n    results = os.path.join('results')\n    os.makedirs(results, exist_ok=True)\n    cls_names = ['abethr1', 'abhori1', 'abythr1', 'afbfly1', 'afdfly1', 'afecuc1', 'affeag1', 'afgfly1', 'afghor1', 'afmdov1', 'afpfly1', 'afpkin1', 'afpwag1', 'afrgos1', 'afrgrp1', 'afrjac1', 'afrthr1', 'amesun2', 'augbuz1', 'bagwea1', 'barswa', 'bawhor2', 'bawman1', 'bcbeat1', 'beasun2', 'bkctch1', 'bkfruw1', 'blacra1', 'blacuc1', 'blakit1', 'blaplo1', 'blbpuf2', 'blcapa2', 'blfbus1', 'blhgon1', 'blhher1', 'blksaw1', 'blnmou1', 'blnwea1', 'bltapa1', 'bltbar1', 'bltori1', 'blwlap1', 'brcale1', 'brcsta1', 'brctch1', 'brcwea1', 'brican1', 'brobab1', 'broman1', 'brosun1', 'brrwhe3', 'brtcha1', 'brubru1', 'brwwar1', 'bswdov1', 'btweye2', 'bubwar2', 'butapa1', 'cabgre1', 'carcha1', 'carwoo1', 'categr', 'ccbeat1', 'chespa1', 'chewea1', 'chibat1', 'chtapa3', 'chucis1', 'cibwar1', 'cohmar1', 'colsun2', 'combul2', 'combuz1', 'comsan', 'crefra2', 'crheag1', 'crohor1', 'darbar1', 'darter3', 'didcuc1', 'dotbar1', 'dutdov1', 'easmog1', 'eaywag1', 'edcsun3', 'egygoo', 'equaka1', 'eswdov1', 'eubeat1', 'fatrav1', 'fatwid1', 'fislov1', 'fotdro5', 'gabgos2', 'gargan', 'gbesta1', 'gnbcam2', 'gnhsun1', 'gobbun1', 'gobsta5', 'gobwea1', 'golher1', 'grbcam1', 'grccra1', 'grecor', 'greegr', 'grewoo2', 'grwpyt1', 'gryapa1', 'grywrw1', 'gybfis1', 'gycwar3', 'gyhbus1', 'gyhkin1', 'gyhneg1', 'gyhspa1', 'gytbar1', 'hadibi1', 'hamerk1', 'hartur1', 'helgui', 'hipbab1', 'hoopoe', 'huncis1', 'hunsun2', 'joygre1', 'kerspa2', 'klacuc1', 'kvbsun1', 'laudov1', 'lawgol', 'lesmaw1', 'lessts1', 'libeat1', 'litegr', 'litswi1', 'litwea1', 'loceag1', 'lotcor1', 'lotlap1', 'luebus1', 'mabeat1', 'macshr1', 'malkin1', 'marsto1', 'marsun2', 'mcptit1', 'meypar1', 'moccha1', 'mouwag1', 'ndcsun2', 'nobfly1', 'norbro1', 'norcro1', 'norfis1', 'norpuf1', 'nubwoo1', 'pabspa1', 'palfly2', 'palpri1', 'piecro1', 'piekin1', 'pitwhy', 'purgre2', 'pygbat1', 'quailf1', 'ratcis1', 'raybar1', 'rbsrob1', 'rebfir2', 'rebhor1', 'reboxp1', 'reccor', 'reccuc1', 'reedov1', 'refbar2', 'refcro1', 'reftin1', 'refwar2', 'rehblu1', 'rehwea1', 'reisee2', 'rerswa1', 'rewsta1', 'rindov', 'rocmar2', 'rostur1', 'ruegls1', 'rufcha2', 'sacibi2', 'sccsun2', 'scrcha1', 'scthon1', 'shesta1', 'sichor1', 'sincis1', 'slbgre1', 'slcbou1', 'sltnig1', 'sobfly1', 'somgre1', 'somtit4', 'soucit1', 'soufis1', 'spemou2', 'spepig1', 'spewea1', 'spfbar1', 'spfwea1', 'spmthr1', 'spwlap1', 'squher1', 'strher', 'strsee1', 'stusta1', 'subbus1', 'supsta1', 'tacsun1', 'tafpri1', 'tamdov1', 'thrnig1', 'trobou1', 'varsun2', 'vibsta2', 'vilwea1', 'vimwea1', 'walsta1', 'wbgbir1', 'wbrcha2', 'wbswea1', 'wfbeat1', 'whbcan1', 'whbcou1', 'whbcro2', 'whbtit5', 'whbwea1', 'whbwhe3', 'whcpri2', 'whctur2', 'wheslf1', 'whhsaw1', 'whihel1', 'whrshr1', 'witswa1', 'wlwwar', 'wookin1', 'woosan', 'wtbeat1', 'yebapa1', 'yebbar1', 'yebduc1', 'yebere1', 'yebgre1', 'yebsto1', 'yeccan1', 'yefcan', 'yelbis1', 'yenspu1', 'yertin1', 'yesbar1', 'yespet1', 'yetgre1', 'yewgre1']\n    pro = Process()\n\n    max_num_segments = 0  # 用于记录最大的 num_segments\n    probabilities_list = []  # 用于存储每个文件的概率矩阵\n\n    df = pd.DataFrame(columns=['row_id'] + cls_names)  # 创建空的 DataFrame\n\n    for filename in os.listdir(folder_path):\n        if filename.endswith(\".ogg\") or filename.endswith(\".wav\"):  # Filter audio files\n            file_name_without_extension = os.path.splitext(filename)[0]\n            file_path = os.path.join(folder_path, filename)\n            # print(\"Processing file:\", file_path)  # Added print statement for debugging\n            waveform, sample_rate = torchaudio.load(file_path)\n            num_samples = waveform.size(1)\n            audio_length = num_samples / sample_rate\n\n            img_np = pro.get_f(file_path)\n\n            with torch.no_grad():\n                img = img_np.unsqueeze(0)\n                img = img.to(device)\n                output = net(img)\n                probabilities = torch.softmax(output, dim=1)[0].tolist()  # 获取每个类别的概率\n\n            probabilities_list.append(probabilities)\n\n            num_segments = int(audio_length / 5) + 1  # Calculate number of 5-second segments\n            if num_segments > max_num_segments:\n                max_num_segments = num_segments\n\n            row_ids = [f\"{file_name_without_extension}_{j * 5}\" for j in\n                       range(1, num_segments)]  # Generating row_ids dynamically + 1\n            # 调整概率列表的长度，使其与类别名称列表的长度相匹配\n            probabilities_adjusted = probabilities + [0] * (len(cls_names) - len(probabilities))\n            df_result = pd.DataFrame({'row_id': row_ids,\n                                      **{cls_names[k]: [probabilities_adjusted[k]] * len(row_ids) for k in\n                                         range(len(cls_names))}})\n            df = pd.concat([df, df_result], ignore_index=True)  # 使用 concat 方法合并 DataFrame\n\n            # print(\"Probabilities saved for file:\", file_path)  # Added print statement for debugging\n    df[df.columns.difference(['row_id'])] = df[df.columns.difference(['row_id'])].astype(np.float32)\n    print(df.info())\n    df.to_csv('submission.csv', index=False)\n    \n    \n    print(\"All files processed. Probabilities saved to class_probabilities.csv\")\n\n\nif __name__ == '__main__':\n    # 同train\n    config = Default_config()\n    config.target_folder = '/kaggle/input/birdclef-2023/test_soundscapes'\n    cudnn.benchmark = True\n\n    use_cuda = torch.cuda.is_available()\n    device = torch.device('cpu')\n    if use_cuda:\n        manual_seed_all(config.seed)\n    else:\n        torch.manual_seed(config.seed)\n\n    # 模型加载\n    net = Net(num_classes=config.num_classes).to(device)\n    # 训练 测试\n    classification(config.target_folder, device=device, net=net)\n","metadata":{"execution":{"iopub.status.busy":"2024-05-14T01:41:20.718021Z","iopub.execute_input":"2024-05-14T01:41:20.718507Z","iopub.status.idle":"2024-05-14T01:41:23.315929Z","shell.execute_reply.started":"2024-05-14T01:41:20.718464Z","shell.execute_reply":"2024-05-14T01:41:23.314661Z"},"trusted":true},"execution_count":null,"outputs":[]}]}