{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Prepare Enviroment ","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport math\n\nimport os\nimport cv2\n\nimport IPython.display as ipd \n\nimport librosa \nimport librosa.display\n\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import train_test_split\n\n\nos.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' ","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:40:28.434252Z","iopub.execute_input":"2022-08-28T14:40:28.434666Z","iopub.status.idle":"2022-08-28T14:40:31.006728Z","shell.execute_reply.started":"2022-08-28T14:40:28.434558Z","shell.execute_reply":"2022-08-28T14:40:31.005899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load DataFrame","metadata":{}},{"cell_type":"code","source":"train_path = '../input/freesound-audio-tagging/audio_train/'\n\nprint(len(os.listdir(train_path)))","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:40:37.003910Z","iopub.execute_input":"2022-08-28T14:40:37.004496Z","iopub.status.idle":"2022-08-28T14:40:37.749545Z","shell.execute_reply.started":"2022-08-28T14:40:37.004459Z","shell.execute_reply":"2022-08-28T14:40:37.748743Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv(\"../input/freesound-audio-tagging/train.csv\")\n\nprint('The shape of the training data is: ', train.shape)","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:40:39.208756Z","iopub.execute_input":"2022-08-28T14:40:39.209017Z","iopub.status.idle":"2022-08-28T14:40:39.237462Z","shell.execute_reply.started":"2022-08-28T14:40:39.208986Z","shell.execute_reply":"2022-08-28T14:40:39.236721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-23T14:39:35.137434Z","iopub.execute_input":"2022-07-23T14:39:35.138008Z","iopub.status.idle":"2022-07-23T14:39:35.161978Z","shell.execute_reply.started":"2022-07-23T14:39:35.137947Z","shell.execute_reply":"2022-07-23T14:39:35.161135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Unique Labels","metadata":{}},{"cell_type":"code","source":"uniq_labels = train.label.unique()\nprint('There are a total of', len(uniq_labels), 'unique labels.\\n')\nprint(uniq_labels)","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:40:42.232866Z","iopub.execute_input":"2022-08-28T14:40:42.233451Z","iopub.status.idle":"2022-08-28T14:40:42.247706Z","shell.execute_reply.started":"2022-08-28T14:40:42.233413Z","shell.execute_reply":"2022-08-28T14:40:42.246718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Exploring Samples","metadata":{}},{"cell_type":"code","source":"gunshot = '../input/freesound-audio-tagging/audio_train/0048fd00.wav'\nipd.Audio(gunshot)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T14:40:22.466617Z","iopub.execute_input":"2022-07-23T14:40:22.466979Z","iopub.status.idle":"2022-07-23T14:40:22.490703Z","shell.execute_reply.started":"2022-07-23T14:40:22.466945Z","shell.execute_reply":"2022-07-23T14:40:22.488612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"signal, sr = librosa.load(gunshot)\nprint(type(signal))\nprint(type(sr))","metadata":{"execution":{"iopub.status.busy":"2022-07-23T14:40:25.044103Z","iopub.execute_input":"2022-07-23T14:40:25.044378Z","iopub.status.idle":"2022-07-23T14:40:25.988623Z","shell.execute_reply.started":"2022-07-23T14:40:25.044342Z","shell.execute_reply":"2022-07-23T14:40:25.987745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(signal.shape)\nprint(sr)\nprint(len(signal) / sr)","metadata":{"execution":{"iopub.status.busy":"2022-07-23T14:40:28.804908Z","iopub.execute_input":"2022-07-23T14:40:28.805245Z","iopub.status.idle":"2022-07-23T14:40:28.812538Z","shell.execute_reply.started":"2022-07-23T14:40:28.805216Z","shell.execute_reply":"2022-07-23T14:40:28.811269Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize = [12,3])\nplt.subplot(2,1,1)\nplt.plot(signal)\nplt.subplot(2,1,2)\ninterval = range(2000, 3000)\nplt.plot(interval, signal[interval])\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-23T14:40:34.984324Z","iopub.execute_input":"2022-07-23T14:40:34.984733Z","iopub.status.idle":"2022-07-23T14:40:35.370736Z","shell.execute_reply.started":"2022-07-23T14:40:34.984691Z","shell.execute_reply":"2022-07-23T14:40:35.369867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#音声データをメルスペクトルに変換し可視化\nx1 = librosa.feature.melspectrogram(y=signal, sr=22050)   \nx2 = librosa.power_to_db(x1, ref=np.max)   \n\nprint(x2.shape)\n\nlibrosa.display.specshow(x2, sr=22050, x_axis='time', y_axis='hz')\nplt.colorbar()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-23T14:40:38.643413Z","iopub.execute_input":"2022-07-23T14:40:38.644192Z","iopub.status.idle":"2022-07-23T14:40:38.979761Z","shell.execute_reply.started":"2022-07-23T14:40:38.644143Z","shell.execute_reply":"2022-07-23T14:40:38.978787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Label Encoder","metadata":{}},{"cell_type":"code","source":"#labelを文字列から数字に変換\nlabels = np.unique(train.label.values)\nlabel_encoder = {label:i for i, label in enumerate(labels)}\nprint(label_encoder['Cello'])\nprint(label_encoder['Gunshot_or_gunfire'])","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:40:51.735556Z","iopub.execute_input":"2022-08-28T14:40:51.735831Z","iopub.status.idle":"2022-08-28T14:40:51.746013Z","shell.execute_reply.started":"2022-08-28T14:40:51.735798Z","shell.execute_reply":"2022-08-28T14:40:51.745332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df, test_df = train_test_split(train, test_size=0.2, random_state=1, stratify=train.label)\n\nprint(train_df.shape)\nprint(test_df.shape)","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:40:53.588485Z","iopub.execute_input":"2022-08-28T14:40:53.589268Z","iopub.status.idle":"2022-08-28T14:40:53.612087Z","shell.execute_reply.started":"2022-08-28T14:40:53.589230Z","shell.execute_reply":"2022-08-28T14:40:53.610910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install timm\nimport cv2\nimport torch.utils.data as data\nimport timm\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\n\n#wavデータをメルスペクトグラムに変換したもの\nSPEC_PATH = '../input/freesound-melpec-128-512-2sec/spectrograms'\nIMG_SIZE = (224,224)\n\nclass MYDataset(data.Dataset):\n   \n\n    def __init__(self, file_path_df, transform=None, phase='train'):\n        self.file_path_df = file_path_df  # ファイルパスが格納されているDF       \n        self.transform = transform   \n        self.phase = phase  # train or testの指定\n\n    def __len__(self):\n        \n        return len(self.file_path_df)\n    \n    def __getitem__(self, index):\n        X = np.zeros(shape=(3,IMG_SIZE[0], IMG_SIZE[1]))\n#         X = np.zeros(shape=(IMG_SIZE[0], IMG_SIZE[1],3))\n        y = 0\n        \n        FILE = self.file_path_df.fname.values[index]\n        LABEL = self.file_path_df.label.values[index]\n            \n        SET = 'train_spec'\n        path = f'{SPEC_PATH}/{SET}/{FILE[:-4]}.npy'\n        \n        \n        data_array = np.load(path)\n        #efficientNetの入力に合うように変換\n        resized = cv2.resize(data_array, (IMG_SIZE[0], IMG_SIZE[1]))\n        for j in range(3):\n                X[j,:,:] = resized\n#         for j in range(3):\n#                 X[:,:,j] = resized\n#         img_transformed = self.transform(\n#             X, self.phase) \n\n        y = label_encoder[LABEL]\n        return torch.tensor(X, dtype=torch.float), y\n#         return img_transformed, y","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:41:38.379188Z","iopub.execute_input":"2022-08-28T14:41:38.379849Z","iopub.status.idle":"2022-08-28T14:41:45.888086Z","shell.execute_reply.started":"2022-08-28T14:41:38.379807Z","shell.execute_reply":"2022-08-28T14:41:45.886998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = MYDataset(\n    file_path_df=train_df, phase='train')\ntest_dataset = MYDataset(\n    file_path_df=test_df, phase='test')\n\n\nbatch_size = 32\ntrain_dataloader = torch.utils.data.DataLoader(\n    train_dataset, batch_size=batch_size, shuffle=True)\ntest_dataloader = torch.utils.data.DataLoader(\n    test_dataset, batch_size=batch_size, shuffle=False)\n\n# 辞書オブジェクトにまとめる\ndataloaders_dict = {\"train\": train_dataloader, \"test\": test_dataloader}","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:41:52.623446Z","iopub.execute_input":"2022-08-28T14:41:52.624096Z","iopub.status.idle":"2022-08-28T14:41:52.630445Z","shell.execute_reply.started":"2022-08-28T14:41:52.624036Z","shell.execute_reply":"2022-08-28T14:41:52.629457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#事前学習したefficientnet_b0モデルを使用\nnet = timm.create_model('efficientnet_b0', pretrained=True)\n\n# 最後の出力層の出力ユニットをクラス数(41)に変更\nnet.classifier = nn.Linear(in_features=1280, out_features=41, bias=True)\n\n# 訓練モードに設定\nnet.train()\n\n# 損失関数の設定\ncriterion = nn.CrossEntropyLoss()\n\n# 最適化手法の設定\noptimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:41:55.231030Z","iopub.execute_input":"2022-08-28T14:41:55.231736Z","iopub.status.idle":"2022-08-28T14:41:57.473449Z","shell.execute_reply.started":"2022-08-28T14:41:55.231699Z","shell.execute_reply":"2022-08-28T14:41:57.472361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr_loss_list=[]\ntr_acc_list=[]\n            \nva_loss_list=[]\nva_acc_list=[]\n\ndef train_model(net, dataloaders_dict, criterion, optimizer, num_epochs, \n                model_path):\n    # 初期設定\n    # GPUが使えるかを確認\n    device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n    print(\"使用デバイス：\", device)\n\n    # ネットワークをGPUへ\n    net.to(device)\n\n    # ネットワークがある程度固定であれば、高速化させる\n    torch.backends.cudnn.benchmark = True\n\n    # epochのループ\n    for epoch in range(num_epochs):\n        print('-------------')\n        print('Epoch {}/{}'.format(epoch + 1, num_epochs))\n\n        # epochごとの訓練と検証のループ\n        for phase in ['train', 'test']:\n            if phase == 'train':\n                net.train()  # モデルを訓練モードに\n            else:\n                net.eval()  # モデルを検証モードに\n\n            epoch_loss = 0.0  # epochの損失和\n            epoch_corrects = 0  # epochの正解数\n\n            predlist = torch.zeros(0, dtype=torch.long, device='cpu')\n            lbllist = torch.zeros(0, dtype=torch.long, device='cpu')\n\n            # データローダーからミニバッチを取り出すループ\n            for inputs, labels in dataloaders_dict[phase]:\n                # GPUが使えるならGPUにデータを送る\n                inputs = inputs.to(device)\n                labels = labels.to(device)\n\n                # optimizerを初期化\n                optimizer.zero_grad()\n\n                # 順伝搬（forward）計算\n                with torch.set_grad_enabled(phase == 'train'):\n                    outputs = net(inputs)\n                    loss = criterion(outputs, labels)  # 損失を計算\n                    _, preds = torch.max(outputs, 1)  # ラベルを予測\n\n                    # 訓練時はバックプロパゲーション\n                    if phase == 'train':\n                        loss.backward()\n                        optimizer.step()\n\n                    # 結果の計算\n                    epoch_loss += loss.item() * inputs.size(0)  # lossの合計を更新\n                    # 正解数の合計を更新\n                    epoch_corrects += torch.sum(preds == labels.data)\n\n                    predlist = torch.cat([predlist, preds.detach().view(-1).cpu()])\n                    lbllist = torch.cat([lbllist, labels.view(-1).cpu()])\n\n            # epochごとのlossと正解率を表示\n            epoch_loss = epoch_loss / len(dataloaders_dict[phase].dataset)\n            epoch_acc = epoch_corrects.double().to(torch.device(\"cpu\")) / len(dataloaders_dict[phase].dataset)\n\n            print('  {} Loss: {:.4f} Acc: {:.4f}'.format(\n                phase, epoch_loss, epoch_acc))\n\n            # モデルを保存\n            torch.save(net.state_dict(), model_path)\n\n\n            # epochごとのlossと正解率を表示\n            epoch_loss = epoch_loss / len(dataloaders_dict[phase].dataset)\n            epoch_acc = epoch_corrects.double(\n            ) / len(dataloaders_dict[phase].dataset)\n            \n            # リストに格納\n            if phase == 'train':\n                tr_loss_list.append(epoch_loss)\n                tr_acc_list.append(epoch_acc)\n            elif phase == 'test':\n                va_loss_list.append(epoch_loss)\n                va_acc_list.append(epoch_acc)\n\n            print('  {} Loss: {:.4f} Acc: {:.4f}'.format(\n                phase, epoch_loss, epoch_acc))\n            \n            # モデルを保存\n            torch.save(net.state_dict(), model_path)","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:42:00.347647Z","iopub.execute_input":"2022-08-28T14:42:00.347907Z","iopub.status.idle":"2022-08-28T14:42:00.363299Z","shell.execute_reply.started":"2022-08-28T14:42:00.347876Z","shell.execute_reply":"2022-08-28T14:42:00.362535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_epochs=30\ntrain_model(net, dataloaders_dict, criterion, optimizer, \n            num_epochs=num_epochs, model_path=\"spc_efficient_b0.pth\")","metadata":{"execution":{"iopub.status.busy":"2022-08-28T14:42:04.714641Z","iopub.execute_input":"2022-08-28T14:42:04.714904Z","iopub.status.idle":"2022-08-28T14:46:48.038530Z","shell.execute_reply.started":"2022-08-28T14:42:04.714874Z","shell.execute_reply":"2022-08-28T14:46:48.037002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#tensor型をスカラーに変更\ntr_acc_list_convert = list(map(lambda x: x.to('cpu').detach().item(), tr_acc_list))\nval_acc_list_convert = list(map(lambda x: x.to('cpu').detach().item(), va_acc_list))","metadata":{"execution":{"iopub.status.busy":"2022-07-23T17:18:12.305682Z","iopub.execute_input":"2022-07-23T17:18:12.305999Z","iopub.status.idle":"2022-07-23T17:18:12.357232Z","shell.execute_reply.started":"2022-07-23T17:18:12.305966Z","shell.execute_reply":"2022-07-23T17:18:12.355822Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#  **結果をプロット**","metadata":{}},{"cell_type":"code","source":"epoch_range = range(30)\n\n#accuracyのプロット\nplt.plot(epoch_range, tr_acc_list_convert, label='train_acc')\nplt.plot(epoch_range, val_acc_list_convert, label='test_acc')\nplt.xlabel('Epoch', fontsize=15)\nplt.ylabel(\"accuracy\",fontsize=15)\nplt.title(\"accuracy_efficientnet_b0\",fontsize=17)\nplt.grid()\nplt.legend()\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-23T17:17:09.921260Z","iopub.execute_input":"2022-07-23T17:17:09.921555Z","iopub.status.idle":"2022-07-23T17:17:10.223567Z","shell.execute_reply.started":"2022-07-23T17:17:09.921524Z","shell.execute_reply":"2022-07-23T17:17:10.222609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#lossのプロット\nplt.plot(epoch_range, tr_loss_list, label='train_loss')\nplt.plot(epoch_range, va_loss_list, label='test_loss')\nplt.xlabel('Epoch', fontsize=15)\nplt.ylabel(\"loss\",fontsize=15)\nplt.title(\"loss_efficientnet_b0\",fontsize=17)\nplt.grid()\nplt.legend()\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-23T17:19:10.807076Z","iopub.execute_input":"2022-07-23T17:19:10.807342Z","iopub.status.idle":"2022-07-23T17:19:11.110872Z","shell.execute_reply.started":"2022-07-23T17:19:10.807312Z","shell.execute_reply":"2022-07-23T17:19:11.109791Z"},"trusted":true},"execution_count":null,"outputs":[]}]}