{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 32\nBASE_FILTER_COUNT = 16\nmax_steps = 10\nSAMPLING_RATE = 8000\ninput_length = SAMPLING_RATE*2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np \nnp.random.seed(1001)  # 특정 숫자를 지정하여 난수 설정\nimport os  # 경로 설정 시 사용\nimport shutil  # 파일 및 디렉터리 작업을 수행하는 데 사용할 모듈의 이름\n\nimport IPython\nimport matplotlib\nimport matplotlib.pyplot as plt  # 데이터 시각화를 위한 라이브러리\nimport pandas as pd  # 데이터 분석을 위한 라이브러리 설정\nimport seaborn as sns # matplotlib을 기반으로 하는 데이터 시각화 라이브러리\nfrom tqdm import tqdm_notebook  # 반복문 진행상태를 확인할 수 있는 라이브러리\nfrom sklearn.model_selection import StratifiedKFold\n\n%matplotlib inline \nmatplotlib.style.use('ggplot')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import IPython.display as ipd  # IPython의 display와 관련된 Public API: To play sound in the notebook\nimport wave  # wav 파일을 읽을 수 있는 모듈\nfrom scipy.io import wavfile  #초당 샘플 수의 샘플링 속도와 파일에서 읽은 모든 데이터가 있는 numpy 배열을 반환\nSAMPLE_RATE = 44100\n\nimport seaborn as sns \ncolor = sns.color_palette()\nimport plotly.offline as py  # 데이터 시각화 라이브러리\npy.init_notebook_mode(connected=True)\nimport plotly.graph_objs as go\nimport plotly.offline as offline  # 오프라인에서 차트 작업하기\noffline.init_notebook_mode()\nimport plotly.tools as tls\nfrom plotly.offline import *\n\nimport numpy as np\nfrom scipy.fftpack import fft  # 소리 특징(주파수) 추출을 위한 Discrete Fourier transforms 패키지 \nfrom scipy import signal  # Signal processing 패키지\nimport librosa  # 파이썬 음악 분석 라이브러리","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def audio_norm(data):\n    max_data = np.max(data)\n    min_data = np.min(data)\n    data = (data-min_data)/(max_data-min_data+0.0001)\n    return data-0.5\n\ndef load_audio_file(file_path, input_length=input_length):\n    data = librosa.core.load(file_path, sr=SAMPLING_RATE)[0] #sr=16000\n    if len(data)>input_length:\n        max_offset = len(data)-input_length\n        offset = np.random.randint(max_offset)\n        data = data[offset:(input_length+offset)]\n    else:\n        if input_length > len(data):\n            max_offset = input_length - len(data)\n            offset = np.random.randint(max_offset)\n        else: \n            offset = 0\n        data = np.pad(data, (offset, input_length - len(data) - offset), \"constant\")\n    data = audio_norm(data)\n    return data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import glob  # python에서 파일 리스트를 사용할 때 이용. 특정 이름의 파일을 찾고 파일 리스트를 받아서 처리할 때 유용\ntrain_files = glob.glob(\"../input/audio_train/audio_train/*.wav\")\ntest_files =glob.glob(\"../input/audio_test/audio_test/*.wav\")\ntrain = pd.read_csv(\"../input/train.csv\")   \nprint(len(train_files), 'training', len(test_files), 'testing')\ntrain.groupby(['label']).size().plot.bar()  # label을 기준으로 그룹화\ntrain.sample(3)  # 3개만 제시 ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_audio_path = '../input/audio_train/audio_train'\nfilename = '/e6949d46.wav' \nsample_rate, samples = wavfile.read(str(train_audio_path) + filename)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(samples)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Size of training data\", train.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#제출용이 아니므로 submission.head()를 따로 출력하지 않음","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def clean_filename(fname, string):\n    file_name = fname.split('/')[1]\n    if file_name[:2] == '__':\n        file_name = string + file_name \n    return file_name\n\ndef load_wav_file(name, path):\n    _, b = wavfile.read(path + name)\n    assert _ == SAMPLE_RATE\n    return b","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data = pd.DataFrame({'file_name' : train['fname'], 'target' : train ['label']})\ntrain_data['time_series'] = train_data['file_name'].apply(load_wav_file, \n                                                          path='../input/audio_train/audio_train/')\ntrain_data['nframes'] = train_data['time_series'].apply(len)\n\n# series: numpy array 하나를 표현하는데 데이터 프레임(행렬)의 차원에서 보면 하나의 칼럼에 해당하는 값들의 모음.\n# dataframe: 여러 series들이 모여 하나의 매트릭스를 구성                                                         ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print (\"Size of trainig data after some preprocessing : \", train_data.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# missing data in trainig data set\ntotal = train_data.isnull().sum().sort_values(ascending = False)\npercent = (train_data.isnull().sum()/train_data.isnull().count()).sort_values(ascending = False)\nmissing_train_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])\nmissing_train_data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"temp = train['manually_verified'].value_counts()\nlabels = temp.index\nsizes = (temp / temp.sum())*100\ntrace = go.Pie(labels=labels, values=sizes, hoverinfo='label+percent')\nlayout = go.Layout(title='Manually verification of labels(0 - No, 1 - Yes)')\ndata = [trace]\nfig = go.Figure(data=data, layout=layout)\npy.iplot(fig)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(12,8))\nsns.distplot(train_data.nframes.values, bins=50, kde=False)\nplt.xlabel('nframes', fontsize=12)\nplt.title(\"Histogram of #frames\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(17,8))\nboxplot = sns.boxplot(x=\"target\", y=\"nframes\", data=train_data)\nboxplot.set(xlabel='', ylabel='')\nplt.title('Distribution of audio frames, per label', fontsize=17)\nplt.xticks(rotation=80, fontsize=17)\nplt.yticks(fontsize=17)\nplt.xlabel('Label name')\nplt.ylabel('nframes')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print (\"Total number of labels in trainig data : \",len(train_data['target'].\n                                                      value_counts()))\nprint(\"Labels are : \", train_data['target'].unique())\nplt.figure(figsize=(15,8))\naudio_type = train_data['target'].value_counts().head(30)\nsns.barplot(audio_type.values, audio_type.index)\nfor i, v in enumerate(audio_type.values):\n    plt.text(0.8,i,v,color='k',fontsize=12)\nplt.xticks(rotation='vertical')\nplt.xlabel('Frequency')\nplt.ylabel('Label Name')\nplt.title(\"Top 30 labels woth their frequencies on traing data\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Number of traing examples=\", train.shape[0], \"  NUmber of classes=\", len(train.label.unique()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(train.label.unique())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"category_group = train.groupby(['label', 'manually_verified']).count()\nplot = category_group.unstack().reindex(category_group.unstack().sum(axis=1).sort_values().index)\\\n.plot(kind='bar', stacked=True, title=\"NUmber of Audio Sample per category\", figsize=(16,10))\nplot.set_xlabel(\"Category\")\nplot.set_ylabel(\"Number of Samples\");","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Minimum samples per category = ', min(train.label.value_counts()))\nprint('Maximum samples per category = ', max(train.label.value_counts()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import IPython.display as ipd # To play sound in the notebook\nfname = '../input/audio_train/audio_train/e6949d46.wav'\ntrain_path = '../input/audio_train/audio_train'\ntest_path = '../input/audio_test/audio_test'\nipd.Audio(fname)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import wave\nwav = wave.open(fname)\nprint(\"Sampling (fname) rate = \", wav.getframerate())\nprint(\"Total samples (frames) = \", wav.getnframes())\nprint(\"Duration = \", wav.getnframes()/wav.getframerate())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Using scipy\n# scipy.io.wavfile.read(filename, mmap=False) %rate, data 추출\nfrom scipy.io import wavfile\nrate, data = wavfile.read(fname)\nprint(\"Sampling (frame) rate = \", rate)\nprint(\"Total samples (frames) = \", data.shape)\nprint(data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(data, '-', );","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(16,4))\nplt.plot(data[:500], '-'); plt.plot(data[:500], '-');","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Setup variables\nfrom keras.models import Sequential\nfrom keras.layers import Conv1D, Dense, Dropout, MaxPool1D, Flatten\ninput_length = 44100*10 \nn_classes = train['label'].unique().shape[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Create model\nmodel = Sequential()\nmodel.add(Conv1D(filters=4, kernel_size=16, activation='relu', padding='same', \n                 input_shape=(input_length,1)))\nmodel.add(MaxPool1D(pool_size=5))\nmodel.add(Dropout(rate=0.1))\nmodel.add(Conv1D(filters=6, kernel_size=16, activation='relu', padding='same'))\nmodel.add(MaxPool1D(pool_size=5))\nmodel.add(Dropout(rate=0.1))\nmodel.add(Conv1D(filters=9, kernel_size=16, activation='relu', padding='same'))\nmodel.add(MaxPool1D(pool_size=5))\nmodel.add(Dropout(rate=0.1))\nmodel.add(Conv1D(filters=14, kernel_size=16, activation='relu', padding='same'))\nmodel.add(MaxPool1D(pool_size=5))\nmodel.add(Dropout(rate=0.1))\nmodel.add(Conv1D(filters=21, kernel_size=16, activation='relu', padding='same'))\nmodel.add(MaxPool1D(pool_size=5))\nmodel.add(Dropout(rate=0.1))\nmodel.add(Conv1D(filters=31, kernel_size=16, activation='relu', padding='same'))\nmodel.add(MaxPool1D(pool_size=5))\nmodel.add(Dropout(rate=0.1))\nmodel.add(Conv1D(filters=46, kernel_size=16, activation='relu', padding='same'))\nmodel.add(MaxPool1D(pool_size=5))\nmodel.add(Dropout(rate=0.1))\nmodel.add(Flatten())\nmodel.add(Dense(units=100, activation='relu'))\nmodel.add(Dense(units=n_classes, activation='softmax'))\n\n# Complie model\nmodel.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')\nmodel.summary()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import SVG\nfrom keras.utils.vis_utils import model_to_dot\n\n%matplotlib inline\n\nSVG(model_to_dot(model, show_shapes=True).create(prog='dot',format='svg'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\nfrom scipy.io import wavfile\n#fname, label, verified = train.sample(1).value[0]\n#train.sample(1)\n# train.sample(1).values[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Map files to label\nfile_label_dict = {fname:label for fname, label in train[['fname', 'label']].values}\n\nexample_file = '6a446a35.wav'\nprint('File Label \"{}\":\\n{}'.format(example_file, file_label_dict[example_file]))\n\n# Create vector encoded labels\nLabelEncoder = {}\nfor i, label in enumerate(train['label'].unique()): #리스트에서 유일한 값 찾기\n    label_array = np.zeros(n_classes)\n    label_array[i] = 1\n    LabelEncoder[label] = label_array\n    \nexample_label = 'Cello'\nprint('\\nEncoded Label \"{}\":\\n{}'.format(example_label, LabelEncoder[example_label]))\n\n# Remap predictions to label\nprediction_to_label = {np.argmax(array):label for label, array in LabelEncoder.items()}\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Define batch generator to yield random data batches\ndef batchGenerator(files, batch_size):\n    # Generate infinite random batches\n    while True:\n        # Get random files\n        batch_files = np.random.choice(files, batch_size, replace = False)\n        \n        # Get labels and data\n        batch_label = []\n        batch_data = []\n        # Combine batch\n        for file in batch_files:\n            # Get label and data\n            label = file_label_dict[file]\n            rate, data = wavfile.read(train+file) # 알라라\n            # Trim data to get uniform length\n            data_uniform_length = np.zeros(input_length)\n            minimum = min(input_length, data.shape[0])\n            data_uniform_length[:minimum] = data[:minimum]\n            # Encode label\n            encoded_label = labelEncoder[label]\n            # Create label and data batch\n            batch_label.append(encoded_label)\n            batch_data = np.array(batch_data).reshape(-1, input_length, 1)\n            \n            # Batch normalization\n            minimum, maximum = batch_data.min().astype(float), batch_data.max().astype(float)\n            batch_data = (batch_data - minimum) / (maximum - minimum)\n            \n            # Yield batches for training\n            yield batch_data, batch_label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import warnings\nwarnings.filterwarnings('ignore')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create random maxk to split files in train and validation set\ntrain_val_split_mask = np.zeros(train.shape[0], dtype=bool)\ntrain_val_split_mask[:8500] = True\nnp.random.shuffle(train_val_split_mask)\n\n# Get train and validation files\ntrain_files = train['fname'][train_val_split_mask] #stratifiedkfold cross val 로 했는데 이렇게 써도 되나요?\nval_files = train['fname'][~train_val_split_mask]\n\n# Specify train and validation generators\nbatch_size = 50\ntrain_generator = batchGenerator(train_files, batch_size=batch_size)\nval_generator = batchGenerator(val_files, batch_size=50)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import warnings\nwarnings.filterwarnings('ignore')\nhistory = model.fit_generator(generator=train_generator, \n                              validation_data=val_generator, \n                              validation_steps=10, \n                              use_multiprocessing=True, \n                              epochs=10, \n                              steps_per_epoch=train.shape[0]//batch_size)\n\nplt.plot(history.history['acc'])\nplt.plot(history.history['val_acc'])\nplt.title('Model accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Test'], loc='upper left')\nplt.show()\n\n# Plot training & validation loss values\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Model loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Test'], loc='upper left')\nplt.show()","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}