{"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":"# Prototype Deep Learning Architecture\nThis is a test notebook, it fetches melspectograms from Google Drive. Can't be used for submission because Noteboks with Internet enabled aren't valid# Prototype Deep Learning Architecture\nThis is a test notebook, it fetches melspectograms from Google Drive. Can't be used for submission because Noteboks with Internet enabled aren't valid","metadata":{}},{"cell_type":"code","source":"# When starting a session, install this and restart the kernel and clean the output\n!pip install torchaudio==0.8","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LOAD THE DEPENDENCIES\n\nimport os\nimport glob\nimport warnings\nwarnings.filterwarnings(action='ignore')\n\nimport pandas as pd\nimport librosa\nimport numpy as np\n\nfrom sklearn.utils import shuffle\nfrom PIL import Image\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\nfrom pathlib import Path\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom torch.utils.data import Dataset\nfrom torch.utils.tensorboard import SummaryWriter\n\nimport torchaudio\nimport torchaudio.transforms as T\nfrom torchvision import models, transforms\nfrom skimage import io, transform","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make sure that torchaudio version is 0.8.0 Otherwise the dataloader will fail\nprint(torch.__version__)\nprint(torchaudio.__version__)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_spectrogram(spec, title=None, ylabel='freq_bin', aspect='auto', xmax=None):\n  fig, axs = plt.subplots(1, 1)\n  axs.set_title(title or 'Spectrogram (db)')\n  axs.set_ylabel(ylabel)\n  axs.set_xlabel('frame')\n  im = axs.imshow(librosa.power_to_db(spec), origin='lower', aspect=aspect)\n  if xmax:\n    axs.set_xlim((0, xmax))\n  fig.colorbar(im, ax=axs)\n  plt.show(block=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Global vars\nRANDOM_SEED = 1337\nSAMPLE_RATE = 32000\nSIGNAL_LENGTH = 5 # seconds\nSPEC_SHAPE = (48, 128) # height x width\nFMIN = 500\nFMAX = 12500","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load metadata file\ntrain = pd.read_csv('../input/birdclef-2021/train_metadata.csv',)\n\n# Second, assume that birds with the most training samples are also the most common\n# A species needs at least 200 recordings with a rating above 4 to be considered common\nbirds_count = {}\nfor bird_species, count in zip(train.primary_label.unique(), \n                               train.groupby('primary_label')['primary_label'].count().values):\n    birds_count[bird_species] = count\nmost_represented_birds = [key for key,value in birds_count.items()] \n\nTRAIN = train.query('primary_label in @most_represented_birds')\nLABELS = sorted(TRAIN.primary_label.unique())\n\n# Let's see how many species and samples we have left\nprint('NUMBER OF SPECIES IN TRAIN DATA:', len(LABELS))\nprint('NUMBER OF SAMPLES IN TRAIN DATA:', len(TRAIN))\nprint('LABELS:', most_represented_birds)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.read_csv('../input/birdclef-2021/test.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta = pd.read_csv('../input/birdclef-2021/train_metadata.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"configuration_dict = {'number_of_epochs': 3, 'batch_size': 8, 'dropout': 0.3, 'base_lr': 0.005, \n                      'number_of_mel_filters': 64, 'resample_freq': 22050}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_to_int = {x: i for i,x in enumerate(LABELS)}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"int_to_label = {i: x for i,x in enumerate(LABELS)}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_to_int['acafly']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"int_to_label[0]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Melspectrogram(Dataset):\n    def __init__(self, csv_path, base_path, resample_freq=0):\n        self.file_path = base_path\n        self.file_names = []\n        self.labels = []\n        self.folders = []\n        self.n_mels = configuration_dict.get('number_of_mel_filters', 64)\n        self.resample = resample_freq\n        \n        csvData = pd.read_csv(csv_path)\n        for i in range(0,len(csvData)):\n            self.file_names.append(csvData.iloc[i, 9])\n            self.labels.append(csvData.iloc[i, 0])\n            self.folders.append(csvData.iloc[i, 0])\n    \n    def __getitem__(self, index):\n        #format the file path and load the file\n        path = os.path.join(self.file_path, self.folders[index] +\"/\"+self.file_names[index])\n        sig, rate = librosa.load(path, sr=32000, offset=None, duration=10)\n    \n        hop_length = int(SIGNAL_LENGTH * SAMPLE_RATE / (SPEC_SHAPE[1] - 1))\n        mel_spec = librosa.feature.melspectrogram(y=sig, \n                                                  sr=SAMPLE_RATE, \n                                                  n_fft=1024, \n                                                  hop_length=hop_length, \n                                                  n_mels=SPEC_SHAPE[0], \n                                                  fmin=FMIN, \n                                                  fmax=FMAX)\n    \n        mel_spec = librosa.power_to_db(mel_spec, ref=np.max) \n        \n        # Normalize\n        mel_spec -= mel_spec.min()\n        mel_spec /= mel_spec.max()\n        \n        mel = torch.tensor([mel_spec])\n        mel = transforms.functional.resize(mel, [48, 224])\n        return mel, labels_to_int[self.labels[index]]\n    \n    def __len__(self):\n        return len(self.file_names)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"csv_path = '../input/birdclef-2021/train_metadata.csv'\nbase_path = '../input/birdclef-2021/train_short_audio'\ntrain_set = Melspectrogram(csv_path, base_path)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loader = torch.utils.data.DataLoader(train_set, batch_size = 128, \n                                           shuffle = True, pin_memory=True, num_workers=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model(num_classes):\n    model = models.resnet18(pretrained=True)\n    model.conv1=nn.Conv2d(1, model.conv1.out_channels, kernel_size=model.conv1.kernel_size[0], \n                      stride=model.conv1.stride[0], padding=model.conv1.padding[0])\n    if hasattr(model, \"fc\"):\n        nb_ft = model.fc.in_features\n        model.fc = nn.Linear(nb_ft, num_classes)\n    elif hasattr(model, \"_fc\"):\n        nb_ft = model._fc.in_features\n        model._fc = nn.Linear(nb_ft, num_classes)\n    elif hasattr(model, \"classifier\"):\n        nb_ft = model.classifier.in_features\n        model.classifier = nn.Linear(nb_ft, num_classes)\n    elif hasattr(model, \"last_linear\"):\n        nb_ft = model.last_linear.in_features\n        model.last_linear = nn.Linear(nb_ft, num_classes)\n\n    return model\n\nmodel = get_model(397)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = optim.SGD(model.parameters(), lr = configuration_dict.get('base_lr', 0.001), momentum = 0.9)\nscheduler = optim.lr_scheduler.StepLR(optimizer, step_size = configuration_dict.get('number_of_epochs')//3, gamma = 0.1)\ncriterion = nn.CrossEntropyLoss()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.cuda.current_device() if torch.cuda.is_available() else torch.device('cpu')\nprint('Device to use: {}'.format(device))\nmodel.to(device)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(model, epoch):\n    model.train()\n    for batch_idx, (inputs, labels) in enumerate(train_loader):\n        inputs = inputs.to(device)\n        labels = labels.to(device)\n\n        # zero the parameter gradients\n        optimizer.zero_grad()\n\n        # forward + backward + optimize\n        outputs = model(inputs)\n        _, predicted = torch.max(outputs, 1)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n        \n        iteration = epoch * len(train_loader) + batch_idx\n        if batch_idx % 20 == 0: #print training stats\n            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'\n                  .format(epoch, batch_idx * len(inputs), len(train_loader.dataset), \n                          100. * batch_idx / len(train_loader), loss))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(10)):\n    train(model, epoch)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}