{"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":"code","source":"import os\nimport sys\nimport pandas as pd\nimport torch\nimport torchaudio\nimport random\nfrom torch import nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader\nfrom transformers import BertForMaskedLM\n\nfrom IPython.display import display\nfrom tqdm import tqdm\nimport numpy as np\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport librosa\nimport librosa.display\nimport sklearn\nfrom sklearn.utils import shuffle\nfrom sklearn.metrics import confusion_matrix\nimport seaborn as sns\nimport IPython.display as ipd\nfrom keras.callbacks import EarlyStopping\nimport math\nfrom enum import Enum\nimport warnings\nwarnings.filterwarnings('ignore')\n\nparameters = {'batch_size': 256,\n              'epochs':10,\n              'learning_rate':0.001,\n              'shuffle': True,\n              'sample_rate': 48000,\n              'num_samples': 67000,\n              'num_freq': 10000,\n              'device': None,\n              'total_sample_size':1216,\n              'test_size':0.4,\n              'run_once':True\n             }\n\n\nclass DataType(Enum):\n    Train = 'Train'\n    Test = 'Test'\n    \nif torch.cuda.is_available():\n        'Eger GPU kullanabiliyorsak'\n        parameters['device'] = 'cuda'\nelse:\n        parameters['device'] = 'cpu'\n        print('Proccess works on',parameters['device'])\n\ndataset_dir = '../input/rfcx-species-audio-detection/train'\ncsv_path = '../input/rfcx-species-audio-detection/train_tp.csv'","metadata":{"_cell_guid":"30939367-3078-4360-8029-a5c5213ae6f5","_uuid":"c66af257-b6ae-43e8-a9e1-204eda03c174","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:10:52.606474Z","iopub.execute_input":"2022-10-30T08:10:52.606897Z","iopub.status.idle":"2022-10-30T08:10:56.588817Z","shell.execute_reply.started":"2022-10-30T08:10:52.606810Z","shell.execute_reply":"2022-10-30T08:10:56.587649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Exploratory Data Analysis (EDA)","metadata":{"_cell_guid":"55db4c06-8428-404c-916c-f334d06b831e","_uuid":"fda6273d-f687-4b74-96e8-2df5332bbdb5"}},{"cell_type":"markdown","source":"Dataset Summary of General Image of Dataset","metadata":{"_cell_guid":"ac24a5ee-4373-43c1-ad68-b9d4bb4c2ffd","_uuid":"ae4b2bb6-ea84-4f0f-99c6-c105d5478a4b"}},{"cell_type":"code","source":"#Read Dataset\ncsv_items = pd.read_csv(csv_path)\ndisplay(csv_items)\ncsv_items.describe()","metadata":{"_cell_guid":"66079f68-0876-49c0-9c9a-e1732c3a2151","_uuid":"27cd9362-9565-4009-93a5-99ac7fc3bc05","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:10:56.591527Z","iopub.execute_input":"2022-10-30T08:10:56.592704Z","iopub.status.idle":"2022-10-30T08:10:56.650833Z","shell.execute_reply.started":"2022-10-30T08:10:56.592662Z","shell.execute_reply":"2022-10-30T08:10:56.649684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Check the duplicated datas in the dataset","metadata":{"_cell_guid":"d40c60c1-7072-4ccf-9fb4-9d40bcb58279","_uuid":"4d45ddec-5439-4e7d-8adb-25c443298854"}},{"cell_type":"code","source":"duplicated_datas = csv_items[csv_items.duplicated()]\ndisplay(duplicated_datas, \"Number of duplicated data: %d\" % len(duplicated_datas))","metadata":{"_cell_guid":"c1ac0dc1-a97d-42ea-add0-b97e233534e5","_uuid":"e95a8f77-2756-4337-b51b-c1314016977c","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:10:56.652659Z","iopub.execute_input":"2022-10-30T08:10:56.653090Z","iopub.status.idle":"2022-10-30T08:10:56.670929Z","shell.execute_reply.started":"2022-10-30T08:10:56.653042Z","shell.execute_reply":"2022-10-30T08:10:56.669839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Check the balance of classes in the dataset","metadata":{"_cell_guid":"002195ff-c07e-4929-8f79-5a4e5003d189","_uuid":"6c57f2a7-3892-4251-b5ff-8f11a21c2fdf"}},{"cell_type":"code","source":"plt.title(\"Species Count\")\nsns.countplot(x = 'species_id', data=csv_items)\nmin_count = csv_items['species_id'].value_counts().min()\ncsv_items['species_id'].value_counts()","metadata":{"_cell_guid":"514044dd-8e8a-4558-89cd-55530d8a897a","_uuid":"9c2ddda4-f47e-4eb5-af59-45255e43d318","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:10:56.672408Z","iopub.execute_input":"2022-10-30T08:10:56.674003Z","iopub.status.idle":"2022-10-30T08:10:57.017141Z","shell.execute_reply.started":"2022-10-30T08:10:56.673968Z","shell.execute_reply":"2022-10-30T08:10:57.016077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The dataset isn't balanced, thus removing data from majority classes with undersampling can balance the dataset. Yet making it completely balanced will cause major data loss so i undersampled only classes that has over 50 sample count. (class 17 and class 23)","metadata":{"_cell_guid":"f5493fc0-69bc-452f-a61e-5b006183e7cb","_uuid":"50876116-657c-472a-8368-aa477264ce79"}},{"cell_type":"code","source":"min_count = csv_items['species_id'].value_counts().min()\nmajorities = csv_items['species_id'].value_counts().loc[lambda x : x>min_count].index.tolist()\nspecies = csv_items['species_id']\nindex_17 = list()\nindex_23 = list()\n\nfor i, species_id in (enumerate(species)):\n    if species_id == 17:\n        index_17.append(i)\n    if species_id == 23:\n        index_23.append(i)\n        \nsize_17 = len(index_17)\nsize_23 = len(index_23)\ncsv_items = csv_items.drop(index_17[0:size_17-50])\ncsv_items= csv_items.drop(index_23[0:size_23-50])\n\nplt.title(\"Species Count\")\nsns.countplot(x = 'species_id', data=csv_items)\ncsv_items['species_id'].value_counts()","metadata":{"_cell_guid":"12cceb7e-c91c-476a-965f-c1caefdec831","_uuid":"6576ff52-41d6-439a-8764-adf5ca4334c4","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:10:57.020418Z","iopub.execute_input":"2022-10-30T08:10:57.021153Z","iopub.status.idle":"2022-10-30T08:10:57.358656Z","shell.execute_reply.started":"2022-10-30T08:10:57.021123Z","shell.execute_reply":"2022-10-30T08:10:57.357718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"null_exist = csv_items.isnull().values.any()\ndisplay(f\"Null values exist : {null_exist}\" )\nif null_exist:\n    display(csv_items.isnull().sum(axis=0))","metadata":{"_cell_guid":"f3c83875-296c-4d02-af4d-e4babd22962c","_uuid":"a9b9b46d-bfe7-4778-a459-cca18d883890","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:10:57.360250Z","iopub.execute_input":"2022-10-30T08:10:57.360603Z","iopub.status.idle":"2022-10-30T08:10:57.369524Z","shell.execute_reply.started":"2022-10-30T08:10:57.360567Z","shell.execute_reply":"2022-10-30T08:10:57.368370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Check general image of a recording sample from the dataset and listen the audio","metadata":{"_cell_guid":"15d9f13c-c8f2-4d93-b260-c104bae77298","_uuid":"f4c60f50-017b-4058-bc24-a703cec2d594"}},{"cell_type":"code","source":"no = 40\ncsv_info = csv_items.loc[no]\nrecording = csv_info['recording_id']\ndisplay(csv_info) \nprint(\"\\n\")\n\nsample = str(recording) + '.flac'\nsample_path = os.path.join(dataset_dir,sample)\nsignal, sample_rate = torchaudio.load(sample_path,normalize=True)\nipd.Audio(data = signal[0,0:10*48000],rate = sample_rate)# ilk 10 sn","metadata":{"_cell_guid":"1ada3e36-81f6-4cb8-8cdc-af3cfe1efb60","_uuid":"aa52b319-69f1-47b1-93fe-2e1c406df3d6","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:10:57.371373Z","iopub.execute_input":"2022-10-30T08:10:57.372112Z","iopub.status.idle":"2022-10-30T08:10:57.495724Z","shell.execute_reply.started":"2022-10-30T08:10:57.372073Z","shell.execute_reply":"2022-10-30T08:10:57.494497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Find the max of f_max and minimum of f_min of dataset's audio recordings","metadata":{"_cell_guid":"d3dd1870-19c3-48d0-9f80-0cee96b2ebcf","_uuid":"5cc5a5cd-746c-4ccb-83c7-013287d256a1"}},{"cell_type":"code","source":"f_max = csv_items['f_max']\nf_min = csv_items['f_min']\nnum_freq = f_max - f_min\nprint(\"Maximum f_max value:   \",f_max.max()) \nprint(\"Minimum f_min value:   \",f_min.min())\nprint(\"Maximum frequency gap: \",num_freq.max())\n\nt_max = csv_items['t_max']\nt_min = csv_items['t_min']\nt_gap = t_max - t_min\nprint(\"Maximum time gap: \",t_gap.max())","metadata":{"_cell_guid":"e715fdc5-230f-47ce-a0fc-5d5288a36d47","_uuid":"7e9f9989-346a-4509-8f86-0454fff07557","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:10:57.496827Z","iopub.execute_input":"2022-10-30T08:10:57.497135Z","iopub.status.idle":"2022-10-30T08:10:57.508617Z","shell.execute_reply.started":"2022-10-30T08:10:57.497107Z","shell.execute_reply":"2022-10-30T08:10:57.507182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"It will be enough to set the frequency window to 10 kHz when extracting Mel-Spectrogram as feature.","metadata":{"_cell_guid":"8aa4bccf-94f2-42a4-bef7-922c91d48fad","_uuid":"2c7cc9e0-364a-4ff9-819f-9c4aa42d62c0"}},{"cell_type":"markdown","source":"Examine the time-domain plot of that recording and some other stats","metadata":{"_cell_guid":"150239b5-fd52-4f56-b805-9fcac02a8d62","_uuid":"d14c7244-83a6-4f42-b2df-d212f916be3d"}},{"cell_type":"code","source":"def print_sound_infos(signal,sample_rate,csv_info):\n    recording_id = csv_info['recording_id'] + '.flac'\n    sample_size = signal.size()[1]\n    sound_duration = sample_size / sample_rate\n    print(f\"\\n- Recording File: {recording_id}\\n- Sample Rate: {sample_rate}\\n\"\n          f\"- Sample Size: {sample_size}\\n- Sound Duration: {sound_duration} seconds\\n\")\n    \ndef plot_time_domain(signal,csv_info,sound):\n    sample_size = signal.size()[1]\n    t = np.linspace(0,sample_size,sample_size)/sample_rate\n    fig = plt.figure(figsize=(14,5))\n    plt.plot(t,signal.t().numpy())\n    plt.xlabel('seconds')\n    t_min, t_max = csv_info['t_min'],csv_info['t_max']\n    fig.suptitle(f\"Labeled {str(sound)} sound is at {t_min} sec - {t_max} sec\",fontsize=15)\n    \nprint_sound_infos(signal,sample_rate,csv_info)\nplot_time_domain(signal,csv_info,sound='original')\nsignal = signal + torch.randn(signal.size()) * 0.005\nplot_time_domain(signal,csv_info,sound='noise added')","metadata":{"_cell_guid":"8e9afd7d-3fed-4d97-8d6d-8ca648149e00","_uuid":"6ed4dcb9-de91-41bf-8a85-3b937b3cfbc4","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:10:57.511010Z","iopub.execute_input":"2022-10-30T08:10:57.512352Z","iopub.status.idle":"2022-10-30T08:10:59.838308Z","shell.execute_reply.started":"2022-10-30T08:10:57.512315Z","shell.execute_reply":"2022-10-30T08:10:59.837185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The frequencies gap between 50-10000 has ploted in time-frequency-energy domain using Mel Spectrogram. Mel Spectrogram will be used as feature in model training.","metadata":{"_cell_guid":"34e0641e-ba25-4c2d-9bef-ffb2055329b1","_uuid":"053e2162-66f0-4377-92e8-230f282e3272"}},{"cell_type":"code","source":"\nmel_spec = librosa.feature.melspectrogram(signal.numpy()[0], sr=sample_rate,n_mels=128,n_fft = 2048, hop_length = 512,fmin =50, fmax= 10000)\nmel_spec_log = librosa.power_to_db(mel_spec, ref=np.max)\ndef plot_spec(mel_spec_log):\n   \n    fig = plt.figure(figsize=(14,5))\n    img = librosa.display.specshow(mel_spec_log,y_axis='mel')\n    plt.colorbar(img, format = \"%+2.0f dB\")\n    fig.suptitle('Mel-Frequency Spectrogram',fontsize=15)\n    plt.tight_layout()\n    \n    \nplot_spec(mel_spec_log)","metadata":{"_cell_guid":"2feba160-e0b5-470a-8916-1c97a7a74e0d","_uuid":"603e5974-f08d-4023-9677-13fb63329069","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:10:59.840191Z","iopub.execute_input":"2022-10-30T08:10:59.840649Z","iopub.status.idle":"2022-10-30T08:11:01.201612Z","shell.execute_reply.started":"2022-10-30T08:10:59.840609Z","shell.execute_reply":"2022-10-30T08:11:01.200606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Signal Preprocessing and Building a Tensor Data from Dataset","metadata":{"_cell_guid":"a7b3b4ec-d32d-4598-ae4e-228c858f7f8a","_uuid":"93608a5d-2884-4628-bfda-1afc0edb8692"}},{"cell_type":"code","source":"mask_tok = 103","metadata":{"execution":{"iopub.status.busy":"2022-10-30T08:11:01.203326Z","iopub.execute_input":"2022-10-30T08:11:01.204076Z","iopub.status.idle":"2022-10-30T08:11:01.209256Z","shell.execute_reply.started":"2022-10-30T08:11:01.204021Z","shell.execute_reply":"2022-10-30T08:11:01.208096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class RFCx_Dataset(Dataset):\n  \n    def __init__(self,data_dir, csv_items,parameters,sample_range, noise,noise_std=None):\n        self.data_dir = data_dir\n        self.parameters = parameters\n        self.sample_range = sample_range\n        self.csv_items = csv_items\n        if self.parameters['shuffle'] == True: \n            self.csv_items= shuffle(self.csv_items)\n        self.csv_items = self.csv_items[self.sample_range[0]:self.sample_range[1]]\n        index = np.linspace(0,self.csv_items.shape[0]-1,self.csv_items.shape[0],dtype=int).tolist()\n        indexed_csv = self.csv_items.set_axis(index)\n        display(self.csv_items)\n        self.csv_items = indexed_csv\n        self.noise = noise\n        self.noise_std = noise_std\n        \n\n    def __len__(self):\n        'Toplam sample sayısını bul'\n        return len(self.csv_items)\n\n    def __getitem__(self, index):\n        'Datasetten belli indexte bir sample al'\n        sample_path = self.get_path(index)\n        label = self.get_label(index)\n        signal, sample_rate = torchaudio.load(sample_path,normalize=True)\n        #plot_time_domain(signal,self.csv_items.loc[index])\n        sample_size = signal.size()[1]\n        signal = signal.to(self.parameters['device'])\n        signal = self.resample(signal,sample_rate)\n        signal = self.make_mono(signal)\n        signal = self.cut_a_time_period(signal,sample_rate,index,sample_size)\n        signal = self.cut_signal(signal)\n        signal = self.right_padding(signal)\n        signal = self.add_noise(signal)\n        #plot_time_domain(signal.cpu(),self.csv_items.loc[index])\n        signal = self.mel_spec(signal,sample_rate,index)\n        signal,labels = self.prepare_mlm_input_and_labels(np.array(signal))\n        \n        return signal, label\n        \n    def get_path(self, index):\n        recordings = self.csv_items['recording_id']\n        sample = str(recordings[index]) + '.flac'\n        sample_path = os.path.join(self.data_dir,sample)\n        return sample_path\n    \n    def get_label(self, index):\n        labels = self.csv_items['species_id']\n        label = labels[index]\n        return label\n    \n    def make_mono(self,signal):\n        if signal.shape[0] > 1: \n            signal = torch.mean(signal,dim=0,keepdim=True).to(self.parameters['device']) \n        return signal\n    \n    \n    def resample(self, signal, sample_rate):\n        if not self.parameters['sample_rate'] == sample_rate:\n            resampler = torchaudio.transforms.Resample(sample_rate,self.parameters['sample_rate']).to(parameters['device'])\n            signal = resampler(signal)\n        return signal\n    \n    def cut_signal(self, signal):\n        'Eger beklenen sample sayısından fazla varsa sinyali kes'\n        if signal.shape[1] > self.parameters['num_samples']:\n            signal = signal[:,0:self.parameters['num_samples']]\n        return signal\n    \n    def right_padding(self, signal):\n        'Eger beklenen sample sayısından az varsa sağa 0 ekler'\n        if signal.shape[1] < self.parameters['num_samples']:\n            left_pad = 0\n            right_pad = self.parameters['num_samples'] - signal.shape[1]\n            signal = torch.nn.functional.pad(signal,(left_pad, right_pad)).to(self.parameters['device'])\n        return signal\n    \n    def cut_a_time_period(self,signal,sample_rate,index,sample_size):\n        t_min = float(self.csv_items['t_min'][index]) * sample_rate\n        t_max = float(self.csv_items['t_max'][index]) * sample_rate\n        #print(t_min,t_max)\n        #print('Old Sample size: ',sample_size)\n        #print(\"Old Duration:\" ,(1/sample_rate)*sample_size)\n        start = np.round((t_min + t_max) / 2) - self.parameters['num_samples'] / 2\n        if start < 0:\n            start = 0\n    \n        end = start + self.parameters['num_samples']\n        if end > sample_size:\n            end = sample_size\n            start = end - sample_size\n\n        signal = signal[:,int(start): int(end)] # sure aralıgı min 10 sn\n        #print('New Sample size: ',signal.size()[1])\n        #print(\"New Duration:\" ,(1/sample_rate)*signal.size()[1])\n        return signal \n                                                        \n    \n    def mel_spec(self,signal,sample_rate,index):\n        f_max = float(self.csv_items['f_max'][index])\n        f_min = float(self.csv_items['f_min'][index])\n        \n        start = np.round((f_min + f_max) / 2) - self.parameters['num_freq'] / 2\n        if start < 0:\n            start = 90\n    \n        end = start + self.parameters['num_freq']\n     \n        mel_spectrogram = librosa.feature.melspectrogram(signal.cpu().numpy(), sr=sample_rate,n_mels=128,n_fft = 2048, hop_length = 512,fmin = start, fmax= end)\n        mel_spectrogram_dB = librosa.power_to_db(mel_spectrogram, ref=np.max)/14\n        if parameters['run_once']:\n            plot_spec(mel_spectrogram_dB[0])\n            parameters['run_once']  = False\n        signal = torch.from_numpy(mel_spectrogram_dB)\n        return signal\n    \n    def add_noise(self,signal):\n        if self.noise == True:\n            mean = 0.0\n            signal = signal + torch.randn(signal.size()).to(parameters['device']) * self.noise_std + mean\n        return signal\n    \n    def prepare_mlm_input_and_labels(self,X):\n        # 15% BERT masking\n        inp_mask = np.random.rand(*X.shape)<0.15 \n        # do not mask special tokens\n        inp_mask[X<=2] = False\n        # set targets to -1 by default, it means ignore\n        labels = -100 * np.ones(X.shape, dtype=int)\n        # set labels for masked tokens\n        labels[inp_mask] = X[inp_mask]\n        \n        # prepare input\n        X_mlm = np.copy(X)\n        # set input to [MASK] which is the last token for the 90% of tokens\n        # this means leaving 10% unchanged\n        inp_mask_2mask = inp_mask  & (np.random.rand(*X.shape)<0.90)\n        X_mlm[inp_mask_2mask] = mask_tok\n\n        # set 10% to a random token\n        inp_mask_2random = inp_mask_2mask  & (np.random.rand(*X.shape) < 1/9)\n        X_mlm[inp_mask_2random] = np.random.randint(3, 128, inp_mask_2random.sum())\n\n        return X_mlm, labels","metadata":{"_cell_guid":"3a208bbf-ab8a-4a0e-b204-8693b7ade3da","_uuid":"44bc56a0-b189-4a3f-a998-0d3ac855691d","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:11:01.211218Z","iopub.execute_input":"2022-10-30T08:11:01.211643Z","iopub.status.idle":"2022-10-30T08:11:01.243744Z","shell.execute_reply.started":"2022-10-30T08:11:01.211605Z","shell.execute_reply":"2022-10-30T08:11:01.242662Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Veriyi neural network için hazır hale getirmek için bazı transformlar yapılmıştır. Bunlar sırasıyla; sinyalin resample edilmesi, eğer mono değilse mono hale getirilmesi, csv de verilen t_min ve t_max değerlerine göre sinyali zaman düzleminde bölerek belli sample'ların alınması, tüm verilerin aynı sample boyutunda olup olmadığının kontrolü, değilse kesilmesi, right padding işlemiyle yine sample boyut kontrolü ve son olarak mel spectrogramının alınarak feature çıkarmaktır.","metadata":{"_cell_guid":"66b981bb-8bfe-4cc2-8c76-b62a7124875b","_uuid":"a70c12ce-503d-4517-b951-825797bf8d15"}},{"cell_type":"markdown","source":"# Designing a Model inspired from Hubert","metadata":{"_cell_guid":"846f22bd-19d9-4c71-aa16-1d94e623ac68","_uuid":"5752aa05-6b14-4356-9efe-9fc7bcf0ec2c"}},{"cell_type":"code","source":"class CnnNet(nn.Module):\n    def __init__(self):\n        super(CnnNet,self).__init__()\n        self.Fc_features = 128\n        self.conv1 = nn.Conv2d(\n                    in_channels =1,\n                    out_channels=32,\n                    kernel_size = 5,\n                    stride = 1,\n                    padding=1)\n        self.conv2 = nn.Conv2d(\n                    in_channels =32,\n                    out_channels=32,\n                    kernel_size = 5,\n                    stride = 1,\n                    padding=1)\n        self.conv3 = nn.Conv2d(\n                    in_channels =32,\n                    out_channels=64,\n                    kernel_size = 5,\n                    stride = 1,\n                    padding=1)\n        self.conv4 = nn.Conv2d(\n                    in_channels =64,\n                    out_channels=64,\n                    kernel_size = 5,\n                    stride = 1,\n                    padding=1)\n        \n        self.batchN1 = nn.BatchNorm2d(32)\n        self.batchN2 = nn.BatchNorm2d(64)\n        self.batchN3 = nn.BatchNorm2d(64)\n        self.maxpool1 = nn.MaxPool2d(2,2)\n        self.maxpool2 = nn.MaxPool2d((1,2),(1,2))\n        \n        self.linear1 = nn.Linear(64*8*8,128)\n        self.dropout = nn.Dropout(0.4)\n        self.BatchN = nn.BatchNorm1d(128)\n        self.encoder_layer = nn.TransformerEncoderLayer(d_model=128, nhead=8)\n        self.transformer_encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=6)\n\n\n    def forward(self,layer):\n        # ReLu aktivasyon fonksiyonuyla convolutional ve max pooling katmanları\n        layer = F.relu(self.batchN1(self.conv1(layer)))\n        layer = self.maxpool1(F.relu(self.batchN1(self.conv2(layer))))\n        layer = F.relu(self.batchN2(self.conv3(layer)))\n        layer = self.maxpool1(F.relu(self.batchN2(self.conv4(layer))))\n        layer = F.relu(self.batchN2(self.conv4(layer)))\n        layer = self.maxpool1(F.relu(self.batchN2(self.conv4(layer))))\n        layer = F.relu(self.batchN2(self.conv4(layer)))\n        layer = F.relu(self.batchN3(self.conv4(layer)))\n        # flatten \n        layer = self.dropout(layer.view(-1,64*8*8))\n        # dropout layer\n        layer =  self.dropout(self.linear1(layer))\n        layer = self.transformer_encoder(layer)\n        return layer\n    \nprint(CnnNet().to(parameters['device']))","metadata":{"_cell_guid":"41834d30-1d4e-49b1-bbc8-846878ac9cd2","_uuid":"7d423ff6-66ad-42ab-9bcc-3ccb027e0906","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:11:55.556917Z","iopub.execute_input":"2022-10-30T08:11:55.557324Z","iopub.status.idle":"2022-10-30T08:12:04.652741Z","shell.execute_reply.started":"2022-10-30T08:11:55.557281Z","shell.execute_reply":"2022-10-30T08:12:04.651650Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Spliting the Datas as Train and Test","metadata":{"_cell_guid":"50793ba5-fbbc-4ef8-981b-4242c26ac5b8","_uuid":"220fdaf7-ff01-4eed-8128-bdd98bdae9a7"}},{"cell_type":"code","source":"def train_test_split(dataset_dir,csv_items,parameters):\n    total_sample_size= parameters['total_sample_size']\n    test_size = parameters['test_size']\n    train_end = round(total_sample_size*(1-test_size))\n    train_range = [0, train_end]\n    test_range = [train_end,total_sample_size]\n    print(\"Train Data: \\n\")\n    train_dataset = RFCx_Dataset(dataset_dir,csv_items,parameters,train_range,noise = True,noise_std=0.015)\n    print(\"Test Data: \\n\")\n    test_dataset = RFCx_Dataset(dataset_dir,csv_items,parameters,test_range,noise = True,noise_std = 0.015)\n    return train_dataset,test_dataset","metadata":{"_cell_guid":"eda80614-0b06-40f2-b574-a061d28802b2","_uuid":"15a33d7a-fd48-4698-b7e0-a3df2429f72e","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:12:04.664189Z","iopub.execute_input":"2022-10-30T08:12:04.664799Z","iopub.status.idle":"2022-10-30T08:12:04.676253Z","shell.execute_reply.started":"2022-10-30T08:12:04.664742Z","shell.execute_reply":"2022-10-30T08:12:04.675236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train and Prediction Function","metadata":{"_cell_guid":"c51d8fa4-d427-40b1-a8df-1863a6c2aeeb","_uuid":"9cfc1c61-1df6-4f06-9512-d402fc01f6d2"}},{"cell_type":"code","source":"def train(model, training_data,test_data, loss_function,optimiser, device, epochs,classes):\n    training_accuracies, training_losses, test_accuracies, test_losses = list(), list(), list(), list()\n    for i in range(epochs):\n        loop= tqdm(training_data,leave=True)\n        for training_model_input, training_target in loop:\n            for test_model_input, test_target in test_data:\n\n                training_model_input, training_target = training_model_input.to(device), training_target.to(device)\n                test_model_input, test_target = test_model_input.to(device), test_target.to(device)\n                \n                training_prediction = model(training_model_input)\n                training_loss = loss_function(training_prediction, training_target)\n\n                test_prediction = model(test_model_input)\n                test_loss = loss_function(test_prediction, test_target)\n\n\n                training_accuracy, test_accuracy = inference(model, [training_model_input, training_target],[test_model_input, test_target],mode=DataType.Train)\n\n                optimiser.zero_grad()\n                training_loss.backward()\n                test_loss.backward()\n                optimiser.step()\n\n                training_accuracies.append(training_accuracy)\n                training_losses.append(training_loss.item())\n\n                test_accuracies.append(test_accuracy)                                                                      \n                test_losses.append(test_loss.item())\n                \n\n            loop.set_description(f\"Epoch [{i}/{epochs}]\")\n            loop.set_postfix(train_loss = training_loss.item(),train_acc= f\"{training_accuracy}\",\n                             test_loss = test_loss.item(),test_acc= f\"{test_accuracy}\")\n                \n    print(\"Finished training\")\n    return training_accuracies, training_losses, test_accuracies, test_losses\n\ndef predict(model, inputs, target, classes):\n    model.eval() #batch evaluation kapalı\n    with torch.no_grad(): # gradient kullanma\n        predictions = model(inputs)\n\n        predicted = predictions[0].argmax(0)\n        expected = target\n    return predicted, expected","metadata":{"_cell_guid":"62f450eb-9c78-417d-8a68-f4cd0add3716","_uuid":"f892a3e6-c825-4336-839a-ace0348e4c43","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:12:04.678865Z","iopub.execute_input":"2022-10-30T08:12:04.679508Z","iopub.status.idle":"2022-10-30T08:12:04.692733Z","shell.execute_reply.started":"2022-10-30T08:12:04.679471Z","shell.execute_reply":"2022-10-30T08:12:04.691821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Calculate Accuracy","metadata":{"_cell_guid":"eb60087f-af69-45c1-9930-f9e8fed0de4c","_uuid":"280726de-94cd-4f91-a2c5-d5bdf23cca5b"}},{"cell_type":"code","source":"def inference (model, training_datas,test_datas,mode):\n    correct_prediction = 0\n    total_prediction = 0\n    device = parameters['device']\n    \n    if not isinstance(mode,Enum):\n         raise TypeError('mode must be an instance of DataType Enum')\n            \n    if mode.value == 'Test':\n        # Disable gradient updates\n        predictions ,true_labels = list(), list()\n        with torch.no_grad():\n            for test_data in test_datas:\n            \n                inputs, labels = test_data[0].to(device), test_data[1].to(device)\n\n                # Normalize et\n                inputs_m, inputs_s = inputs.mean(), inputs.std()\n\n                inputs = (inputs - inputs_m) / inputs_s\n\n                # predictions\n                outputs = model(inputs)\n\n                # En yüksek rekorlu prediction class'ı al\n                _, prediction = torch.max(outputs,1)\n                \n                predictions.append(prediction.tolist())\n                true_labels.append(labels.tolist())\n                \n                correct_prediction += (prediction == labels).sum().item()\n                total_prediction += prediction.shape[0]\n\n                acc = (correct_prediction/total_prediction)\n\n        print(f'Accuracy: {acc:.2f}, Total items: {total_prediction}')\n        return acc, predictions[0], true_labels[0]\n        \n    if mode.value == 'Train':\n    \n        training_correct_prediction = 0\n        training_total_prediction = 0\n        test_correct_prediction = 0\n        test_total_prediction = 0\n        \n         # Disable gradient updates\n        with torch.no_grad():\n            \n            training_inputs, training_labels = training_datas[0].to(device), training_datas[1].to(device)\n            test_inputs, test_labels = test_datas[0].to(device), test_datas[1].to(device)\n            \n            # Normalize et\n            training_inputs_m, training_inputs_s = training_inputs.mean(), training_inputs.std()\n            training_inputs = (training_inputs - training_inputs_m) / training_inputs_s\n            \n            test_inputs_m, test_inputs_s = test_inputs.mean(), test_inputs.std()\n            test_inputs = (test_inputs - test_inputs_m) / test_inputs_s\n\n            # predictions\n            training_outputs = model(training_inputs)\n            test_outputs = model(test_inputs)\n\n            # En yüksek rekorlu prediction class'ı al\n            _, training_prediction = torch.max(training_outputs,1)\n            _, test_prediction = torch.max(test_outputs,1)\n            \n            training_correct_prediction += (training_prediction == training_labels).sum().item()\n            training_total_prediction += training_prediction.shape[0]\n            \n            test_correct_prediction += (test_prediction == test_labels).sum().item()\n            test_total_prediction += test_prediction.shape[0]\n\n\n            training_acc = training_correct_prediction/training_total_prediction\n            test_acc = test_correct_prediction/test_total_prediction\n        return training_acc, test_acc","metadata":{"_cell_guid":"c27ca708-f8e1-4e30-a2df-db4341f78c34","_uuid":"56b6198d-8577-4849-97fe-78846b8827c5","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:12:04.694567Z","iopub.execute_input":"2022-10-30T08:12:04.695115Z","iopub.status.idle":"2022-10-30T08:12:04.711609Z","shell.execute_reply.started":"2022-10-30T08:12:04.695082Z","shell.execute_reply":"2022-10-30T08:12:04.710677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"# Loss","metadata":{}},{"cell_type":"code","source":"def masked_categorical_crossentropy(output,target):\n    y_true_masked = target[target!= -100]\n    y_pred_masked = output[target!= -100]\n    loss =  nn.CrossEntropyLoss()(y_pred_masked,y_true_masked)\n    return loss","metadata":{"execution":{"iopub.status.busy":"2022-10-30T08:12:04.713276Z","iopub.execute_input":"2022-10-30T08:12:04.713671Z","iopub.status.idle":"2022-10-30T08:12:04.726665Z","shell.execute_reply.started":"2022-10-30T08:12:04.713638Z","shell.execute_reply":"2022-10-30T08:12:04.725642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train the Model","metadata":{"_cell_guid":"2cd10317-f825-43c7-a7ab-beec592ca797","_uuid":"3e732093-412d-40e4-99a6-863c54d4b224"}},{"cell_type":"markdown","source":"Preprocess yaparak tensor hale getirdiğim train verisini modele vererek eğitiyorum.","metadata":{"_cell_guid":"508b4332-1575-44c2-8349-24a1bc41bf1e","_uuid":"23577e5d-bd8f-4912-8d67-93a33a01a6cf"}},{"cell_type":"code","source":"    csv_items = csv_items[0:parameters['total_sample_size']]\n    classes = np.unique(csv_items['species_id']) # class degerlerini al (0-23)\n    class_size = classes.size\n    \n    test_dataset,train_dataset = train_test_split(dataset_dir,csv_items,parameters)\n   \n    train_data = DataLoader(train_dataset,batch_size=parameters['batch_size'])\n    test_data = DataLoader(test_dataset,batch_size=parameters['batch_size'])\n\n    model = CnnNet().to(parameters['device'])\n   \n    loss_function = masked_categorical_crossentropy\n    optimiser = torch.optim.Adam(model.parameters(),lr=parameters['learning_rate'],weight_decay=1e-5) # L2 regularization\n    \n    training_accuracies, training_losses, test_accuracies, test_losses = train(model, train_data, test_data, loss_function, optimiser, parameters['device'],parameters['epochs'],classes)\n\n    torch.save(model.state_dict(),\"RFCx_CNN.pth\")\n    print(\"Trained RFCx in CNN saved at RFCx_CNN.pth\")","metadata":{"_cell_guid":"de086241-d628-4018-a065-708e5f15a7e8","_uuid":"9445158d-f3e6-432b-a915-ab648ec94343","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:15:18.635514Z","iopub.execute_input":"2022-10-30T08:15:18.636206Z","iopub.status.idle":"2022-10-30T09:03:40.264474Z","shell.execute_reply.started":"2022-10-30T08:15:18.636145Z","shell.execute_reply":"2022-10-30T09:03:40.263521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Accuracy Result","metadata":{"_cell_guid":"9f2844c7-18fd-4466-8ad1-694b10873b31","_uuid":"7a7143ff-d474-4930-ac44-24012dec89bd"}},{"cell_type":"code","source":"# modeli geri yükle\nstate_dict = torch.load(\"RFCx_CNN.pth\")\nmodel.load_state_dict(state_dict)\n\naccuracy ,predictions, true_labels = inference(model,None,test_data,mode=DataType.Test)","metadata":{"_cell_guid":"c0c705a8-aae4-402d-8c21-24b075e899c3","_uuid":"a69b965e-d40e-41e1-855a-b24a1f6bcbd0","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:11:01.724673Z","iopub.status.idle":"2022-10-30T08:11:01.726001Z","shell.execute_reply.started":"2022-10-30T08:11:01.725683Z","shell.execute_reply":"2022-10-30T08:11:01.725712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Confusion Matrix","metadata":{"_cell_guid":"f80a5f30-9fdc-4168-9832-94dfa55b1ae2","_uuid":"75ffe728-6436-4171-a021-69f467aca7fa"}},{"cell_type":"code","source":"matrix = confusion_matrix(y_true = true_labels, y_pred = predictions,labels=classes)\ndf_cm = pd.DataFrame(matrix, range(class_size), range(class_size))\nsns.set(font_scale=1.4) # for label size\nax = sns.heatmap(df_cm, annot=True, cmap='Blues') # font size\nax.set_title('Confusion Matrix with labels\\n\\n');\nax.set_xlabel('\\nPredicted Values')\nax.set_ylabel('Actual Values ')\nplt.show()","metadata":{"_cell_guid":"291ebb0c-c1b5-4217-8c7a-62a64e9c7328","_uuid":"96cb6578-796b-49dc-8afe-3913c7e6cdb1","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:11:01.727321Z","iopub.status.idle":"2022-10-30T08:11:01.728238Z","shell.execute_reply.started":"2022-10-30T08:11:01.727955Z","shell.execute_reply":"2022-10-30T08:11:01.727981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train/Test Accuracy Plot","metadata":{"_cell_guid":"4d493cb3-6557-466f-8eb8-78fbb01e62ab","_uuid":"48659799-2f72-40af-b85f-d5e808c15771"}},{"cell_type":"code","source":"x_axis_train_acc = np.linspace(0,parameters['epochs'],len(training_accuracies))\nx_axis_train_loss = np.linspace(0,parameters['epochs'],len(training_losses))\nx_axis_test_acc = np.linspace(0,parameters['epochs'],len(test_accuracies))\nx_axis_test_loss = np.linspace(0,parameters['epochs'],len(test_losses))\nfig, ax = plt.subplots(nrows=1, ncols=2,figsize=(14,5)) \nax[0].plot(x_axis_train_acc,training_accuracies,'-r',label='Train')\nax[0].plot(x_axis_test_acc,test_accuracies,'-b',label= 'Test')\nax[0].set_title('Accuracy')\nax[1].plot(x_axis_train_loss,training_losses,'-r',label='Train')\nax[1].plot(x_axis_test_loss,test_losses,'-b',label='Test')\nax[1].set_title('Loss')\nax[0].legend()\nax[1].legend()\n\nplt.show()","metadata":{"_cell_guid":"beaf8449-0ca3-42e5-87b7-4750bcb36deb","_uuid":"9bb59206-9308-4667-a6dd-b3560255860a","jupyter":{"outputs_hidden":false},"collapsed":false,"execution":{"iopub.status.busy":"2022-10-30T08:11:01.730024Z","iopub.status.idle":"2022-10-30T08:11:01.730938Z","shell.execute_reply.started":"2022-10-30T08:11:01.730631Z","shell.execute_reply":"2022-10-30T08:11:01.730656Z"},"trusted":true},"execution_count":null,"outputs":[]}]}