{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":7634,"databundleVersionId":46676,"sourceType":"competition"}],"dockerImageVersionId":30822,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install py7zr -q","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T06:56:52.161501Z","iopub.execute_input":"2024-12-30T06:56:52.161890Z","iopub.status.idle":"2024-12-30T06:57:00.460744Z","shell.execute_reply.started":"2024-12-30T06:56:52.161861Z","shell.execute_reply":"2024-12-30T06:57:00.459493Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport py7zr\nimport random\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom tensorflow.keras import layers, models\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nimport seaborn as sns\nimport librosa\nimport math\nfrom IPython import display\nfrom IPython.display import Audio, display","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T06:57:03.226557Z","iopub.execute_input":"2024-12-30T06:57:03.226920Z","iopub.status.idle":"2024-12-30T06:57:14.999057Z","shell.execute_reply.started":"2024-12-30T06:57:03.226894Z","shell.execute_reply":"2024-12-30T06:57:14.998019Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 1. 데이터 LOAD\ntensorflow speech recognition challenge 안의 train.7z 파일\nOutput working 주소로 압축을 풀어서 저장","metadata":{}},{"cell_type":"code","source":"data_dir = \"/kaggle/input/tensorflow-speech-recognition-challenge/\"\nextract_dir = '/kaggle/working/extracted_data_train'\n\ndef extract_7z(filepath, dest_dir):\n    with py7zr.SevenZipFile(filepath, mode='r') as z:\n        z.extractall(path=dest_dir)\n\n\nif not os.path.exists(extract_dir):\n    filepath = os.path.join(data_dir, \"train.7z\")\n    print(f\"Extracting files from {filepath} to {extract_dir}...\")\n    extract_7z(filepath, extract_dir)\nelse:\n    print(f\"Data already extracted at {extract_dir}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T06:57:24.361542Z","iopub.execute_input":"2024-12-30T06:57:24.362166Z","iopub.status.idle":"2024-12-30T06:59:56.119660Z","shell.execute_reply.started":"2024-12-30T06:57:24.362134Z","shell.execute_reply":"2024-12-30T06:59:56.118372Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 2. 데이터 전처리 function\n- 라벨링 작업\n- 오디오 디코딩\n- spectogram 생성\n- background noise 첨가\n- 속도 조절","metadata":{}},{"cell_type":"code","source":"#라벨 수집\ncommands = np.array([d for d in tf.io.gfile.listdir(os.path.join(extract_dir, \"train/audio\")) \n                    if d != '_background_noise_'])\nprint('Commands:', commands)\n\n# background noise 주소와 파일 수집\nnoise_dir = os.path.join(extract_dir, \"train/audio/_background_noise_\")\nnoise_files = tf.io.gfile.glob(noise_dir + '/*.wav')\n\n# decode audio files\ndef decode_audio(audio_binary):\n    audio, _ = tf.audio.decode_wav(contents=audio_binary)\n    return tf.squeeze(audio, axis=-1)\n\n# 파일 경로로부터 라벨 추출\ndef get_label(file_path):\n    label = tf.strings.split(input=file_path, sep=os.path.sep)[-2]\n    return tf.cond(tf.reduce_any(tf.equal(commands, label)), lambda: label, lambda: tf.constant(\"unknown\", dtype=tf.string))\n\n# waveform --> spectrogram\ndef get_spectrogram(waveform):\n    input_len = 16000\n    waveform = waveform[:input_len]\n    #오디오 데이터가 16000 샘플보다 작은 경우 0으로 패딩\n    zero_padding = tf.zeros([input_len] - tf.shape(waveform), dtype=tf.float32)\n    waveform = tf.cast(waveform, dtype=tf.float32)\n    equal_length = tf.concat([waveform, zero_padding], 0)\n    \n    spectrogram = tf.signal.stft(equal_length, frame_length=255, frame_step=128)\n    spectrogram = tf.abs(spectrogram)\n    return spectrogram[..., tf.newaxis]\n\n# 데이터 증강에 사용을 위한 background noise \ndef add_background_noise(waveform, noise_files):\n    noise_file = random.choice(noise_files)\n    noise_audio_binary = tf.io.read_file(noise_file)\n    noise_waveform = decode_audio(noise_audio_binary)\n\n    # 잡음이 입력 오디오보다 작은 경우 잡음의 일부만 선택해서 사용\n    waveform_len = tf.shape(waveform)[0]\n    noise_len = tf.shape(noise_waveform)[0]\n    if noise_len > waveform_len:\n        offset = tf.random.uniform(shape=[], minval=0, maxval=noise_len - waveform_len, dtype=tf.int32)\n        noise_waveform = noise_waveform[offset:offset + waveform_len]\n    else:\n        padding = tf.zeros([waveform_len - noise_len], dtype=tf.float32)\n        noise_waveform = tf.concat([noise_waveform, padding], axis=0)\n\n    noise_factor = tf.random.uniform(shape=[], minval=0.0, maxval=0.5)\n    augmented_waveform = waveform + noise_factor * noise_waveform\n    return tf.clip_by_value(augmented_waveform, -1.0, 1.0)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T07:00:03.969574Z","iopub.execute_input":"2024-12-30T07:00:03.969918Z","iopub.status.idle":"2024-12-30T07:00:03.984545Z","shell.execute_reply.started":"2024-12-30T07:00:03.969893Z","shell.execute_reply":"2024-12-30T07:00:03.983276Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 데이터 증강에 사용하기 위한 속도 조절\ndef adjust_speed_and_pad(waveform, speed_factor=1.0, target_length=16000):\n\n    \n    waveform = tf.cast(waveform, dtype=tf.float32)\n\n    # stft(short time fourier transform) 시간-주파수 도메인으로 변환\n    frame_length = 220  # 프레임의 길이를 220 샘플로 설정\n    frame_step = 160    # 프레임 간 간격을 160 샘플로 설정\n    stft = tf.signal.stft(waveform, frame_length=frame_length, frame_step=frame_step, window_fn=tf.signal.hann_window)\n\n    # STFT의 결과가 복소수이므로 분리\n    stft_real = tf.math.real(stft)\n    stft_imag = tf.math.imag(stft)\n\n    # STRETCHING\n    num_frames = tf.shape(stft_real)[0]\n    new_num_frames = tf.cast(tf.cast(num_frames, tf.float32) / speed_factor, tf.int32)\n\n    resized_real = tf.image.resize(stft_real[tf.newaxis, :, :], [new_num_frames, tf.shape(stft_real)[1]])[0]\n    resized_imag = tf.image.resize(stft_imag[tf.newaxis, :, :], [new_num_frames, tf.shape(stft_imag)[1]])[0]\n\n    stretched_stft = tf.complex(resized_real, resized_imag)\n\n    # inverse STFT 오디오 신호 복원\n    waveform_stretched = tf.signal.inverse_stft(\n        stretched_stft,\n        frame_length=frame_length,\n        frame_step=frame_step,\n        window_fn=tf.signal.hann_window\n    )\n\n    # 데이터 길이 맞춤\n    waveform_length = tf.shape(waveform_stretched)[0]\n    if waveform_length < target_length:\n        # 체기기\n        padding = target_length - waveform_length\n        left_pad = padding // 2\n        right_pad = padding - left_pad\n        padded_waveform = tf.pad(waveform_stretched, [[left_pad, right_pad]], constant_values=0.0)\n    else:\n        # 자기기\n        padded_waveform = waveform_stretched[:target_length]\n\n    return padded_waveform\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T07:00:06.760381Z","iopub.execute_input":"2024-12-30T07:00:06.760745Z","iopub.status.idle":"2024-12-30T07:00:06.770071Z","shell.execute_reply.started":"2024-12-30T07:00:06.760716Z","shell.execute_reply":"2024-12-30T07:00:06.768577Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 2.1 전처리 예시\n- NOISE (원본데이터에 NOISE 추가)\n- SPEED ADJUSTMENT (원본데이터의 속도 조절)\n- SPEED ADJUSTMENT + NOISE (원본데이터의 속도 조절 후 NOISE 삽입)","metadata":{}},{"cell_type":"code","source":"#원본 데이터와 증강된 데이터\nfrom IPython.display import Audio, display\n\n# 데이터 경로\naudio_dir = os.path.join(extract_dir, \"train/audio\")\ncommands = [d for d in os.listdir(audio_dir) if os.path.isdir(os.path.join(audio_dir, d)) and d != '_background_noise_']\n\naudio_files = []\nfor command in commands:\n    command_path = os.path.join(audio_dir, command)\n    audio_files += [os.path.join(command_path, f) for f in os.listdir(command_path) if f.endswith('.wav')]\n\n# 랜덤으로 중복 없이 10개 선택\naudio_files = random.sample(audio_files, 10)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T07:00:10.833597Z","iopub.execute_input":"2024-12-30T07:00:10.833933Z","iopub.status.idle":"2024-12-30T07:00:10.956636Z","shell.execute_reply.started":"2024-12-30T07:00:10.833907Z","shell.execute_reply":"2024-12-30T07:00:10.955478Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"1. 노이즈 추가(원본데이터에 노이즈 추가)","metadata":{}},{"cell_type":"code","source":"#노이즈 추가한 데이터\n\naugmented_audio_files = []\n\nplt.figure(figsize=(15, 20))\n\nfor i, file_path in enumerate(audio_files):\n    # original waveform 불러오기 \n    audio_binary = tf.io.read_file(file_path)\n    waveform = decode_audio(audio_binary)\n    spectrogram = get_spectrogram(waveform)\n    label = get_label(file_path).numpy().decode('utf-8')\n\n    # background noise 추가 \n    augmented_waveform = add_background_noise(waveform, noise_files)\n    augmented_spectrogram = get_spectrogram(augmented_waveform)\n\n    # background noise 추가한 augmented waveform 저장\n    augmented_audio_files.append(augmented_waveform)\n\n    # original waveform\n    plt.subplot(10, 4, 4 * i + 1)\n    plt.plot(waveform.numpy())\n    plt.title(f\"Original Waveform: {os.path.basename(file_path)} ({label})\", fontsize=8)\n    \n    # original spectrogram\n    plt.subplot(10, 4, 4 * i + 2)\n    plt.imshow(np.log(np.squeeze(spectrogram.numpy()) + 1e-10).T, aspect='auto', origin='lower')\n    plt.title(f\"Original Spectrogram: {os.path.basename(file_path)} ({label})\", fontsize=8)\n    \n    # backgound noise 추가한 augmented waveform\n    plt.subplot(10, 4, 4 * i + 3)\n    plt.plot(augmented_waveform.numpy())\n    plt.title(f\"Augmented Waveform: {os.path.basename(file_path)} ({label})\", fontsize=8)\n    \n    # backgound noise 추가한 augmented spectrogram\n    plt.subplot(10, 4, 4 * i + 4)\n    plt.imshow(np.log(np.squeeze(augmented_spectrogram.numpy()) + 1e-10).T, aspect='auto', origin='lower')\n    plt.title(f\"Augmented Spectrogram: {os.path.basename(file_path)} ({label})\", fontsize=8)\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T07:02:54.308555Z","iopub.execute_input":"2024-12-30T07:02:54.308913Z","iopub.status.idle":"2024-12-30T07:03:01.705380Z","shell.execute_reply.started":"2024-12-30T07:02:54.308884Z","shell.execute_reply":"2024-12-30T07:03:01.703800Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 원본 데이터와 backgound noise 추가한 증강된 데이터 파일\n# original and backgound noise 추가한 augmented audio files\nprint(\"\\nPlaying original and add backgound noise augmented audio files:\")\n\nfor i, (file_path, augmented_waveform) in enumerate(zip(audio_files, augmented_audio_files)):\n    # original audio\n    print(f\"\\nOriginal audio {i+1}: {os.path.basename(file_path)}\")\n    audio_binary = tf.io.read_file(file_path)\n    original_waveform = decode_audio(audio_binary)  \n    display(Audio(original_waveform.numpy(), rate=16000))\n    \n    # backgound noise 추가한 augmented audio\n    print(f\"Augmented audio {i+1}: {os.path.basename(file_path)}\")\n    display(Audio(augmented_waveform.numpy(), rate=16000))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T07:03:09.923448Z","iopub.execute_input":"2024-12-30T07:03:09.923804Z","iopub.status.idle":"2024-12-30T07:03:10.016594Z","shell.execute_reply.started":"2024-12-30T07:03:09.923778Z","shell.execute_reply":"2024-12-30T07:03:10.015315Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"2.속도 조절(원본 데이터에 속도 조절)","metadata":{}},{"cell_type":"code","source":"augmented_audio_files_speed = []\n\nplt.figure(figsize=(15, 20))\n\nfor i, file_path in enumerate(audio_files):\n    # original waveform\n    audio_binary = tf.io.read_file(file_path)\n    waveform = decode_audio(audio_binary)\n    spectrogram = get_spectrogram(waveform)\n    label = get_label(file_path).numpy().decode('utf-8')\n\n    # 속도 조절 증강\n    speed_factor = random.uniform(0.8, 1.5)  \n    speed_adjusted_waveform = adjust_speed_and_pad(waveform, speed_factor=speed_factor, target_length=16000)\n    speed_adjusted_spectrogram = get_spectrogram(speed_adjusted_waveform)\n\n    # 속도 조절된 데이터 waveform\n    augmented_audio_files_speed.append(speed_adjusted_waveform)\n\n    # original waveform\n    plt.subplot(10, 4, 4 * i + 1)\n    plt.plot(waveform.numpy())\n    plt.title(f\"Original Waveform: {os.path.basename(file_path)} ({label})\", fontsize=8)\n    \n    # original spectrogram\n    plt.subplot(10, 4, 4 * i + 2)\n    plt.imshow(np.log(np.squeeze(spectrogram.numpy()) + 1e-10).T, aspect='auto', origin='lower')\n    plt.title(f\"Original Spectrogram: {os.path.basename(file_path)} ({label})\", fontsize=8)\n    \n    # 속도 조절 증강된 waveform\n    plt.subplot(10, 4, 4 * i + 3)\n    plt.plot(speed_adjusted_waveform.numpy())\n    plt.title(f\"Speed-Adjusted Waveform: {os.path.basename(file_path)}\", fontsize=8)\n    \n    # 속도 조절 증강된 spectrogram\n    plt.subplot(10, 4, 4 * i + 4)\n    plt.imshow(np.log(np.squeeze(speed_adjusted_spectrogram.numpy()) + 1e-10).T, aspect='auto', origin='lower')\n    plt.title(f\"Speed-Adjusted Spectrogram: {os.path.basename(file_path)}\", fontsize=8)\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T07:03:39.868578Z","iopub.execute_input":"2024-12-30T07:03:39.868971Z","iopub.status.idle":"2024-12-30T07:03:47.869780Z","shell.execute_reply.started":"2024-12-30T07:03:39.868939Z","shell.execute_reply":"2024-12-30T07:03:47.868162Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 원본 데이터와 속도 조절 증강된 데이터 파일\nprint(\"\\nPlaying original and speed adjustment augmented audio files:\")\n\nfor i, (file_path, speed_augmented_waveform) in enumerate(zip(audio_files, augmented_audio_files_speed)):\n    # original audio\n    print(f\"\\nOriginal audio {i+1}: {os.path.basename(file_path)}\")\n    audio_binary = tf.io.read_file(file_path)\n    original_waveform = decode_audio(audio_binary)  \n    display(Audio(original_waveform.numpy(), rate=16000))\n    \n    # speed adjustment augmented audio\n    print(f\"Augmented audio {i+1}: {os.path.basename(file_path)}\")\n    display(Audio(speed_augmented_waveform.numpy(), rate=16000))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T07:03:55.962912Z","iopub.execute_input":"2024-12-30T07:03:55.963317Z","iopub.status.idle":"2024-12-30T07:03:56.055897Z","shell.execute_reply.started":"2024-12-30T07:03:55.963256Z","shell.execute_reply":"2024-12-30T07:03:56.054814Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"3.노이즈와 속도 함께 증강","metadata":{}},{"cell_type":"code","source":"augmented_audio_files_speed_noise = []\n\nplt.figure(figsize=(20, 25))\n\nfor i, file_path in enumerate(audio_files):\n    # original waveform\n    audio_binary = tf.io.read_file(file_path)\n    waveform = decode_audio(audio_binary)\n    spectrogram = get_spectrogram(waveform)\n    label = get_label(file_path).numpy().decode('utf-8')\n\n    # speed adjustment 적용\n    speed_factor = random.uniform(0.8, 1.8)  \n    speed_adjusted_waveform = adjust_speed_and_pad(waveform, speed_factor=speed_factor, target_length=16000)\n    speed_adjusted_spectrogram = get_spectrogram(speed_adjusted_waveform)\n\n    # noise도 적용\n    noise_added_waveform = add_background_noise(speed_adjusted_waveform, noise_files)\n    noise_added_spectrogram = get_spectrogram(noise_added_waveform)\n\n    # speed-adjusted + noise-added waveform\n    augmented_audio_files_speed_noise.append(noise_added_waveform)\n\n    # original waveform\n    plt.subplot(10, 6, 6 * i + 1)\n    plt.plot(waveform.numpy())\n    plt.title(f\"Original Waveform: {os.path.basename(file_path)} ({label})\", fontsize=8)\n\n    # original spectrogram\n    plt.subplot(10, 6, 6 * i + 2)\n    plt.imshow(np.log(np.squeeze(spectrogram.numpy()) + 1e-10).T, aspect='auto', origin='lower')\n    plt.title(f\"Original Spectrogram: {os.path.basename(file_path)} ({label})\", fontsize=8)\n\n    # speed-adjusted waveform\n    plt.subplot(10, 6, 6 * i + 3)\n    plt.plot(speed_adjusted_waveform.numpy())\n    plt.title(f\"Speed-Adjusted Waveform: {os.path.basename(file_path)}\", fontsize=8)\n\n    # speed-adjusted spectrogram\n    plt.subplot(10, 6, 6 * i + 4)\n    plt.imshow(np.log(np.squeeze(speed_adjusted_spectrogram.numpy()) + 1e-10).T, aspect='auto', origin='lower')\n    plt.title(f\"Speed-Adjusted Spectrogram: {os.path.basename(file_path)}\", fontsize=8)\n\n    # noise-added waveform\n    plt.subplot(10, 6, 6 * i + 5)\n    plt.plot(noise_added_waveform.numpy())\n    plt.title(f\"Noise-Added Waveform: {os.path.basename(file_path)}\", fontsize=8)\n\n    # noise-added spectrogram\n    plt.subplot(10, 6, 6 * i + 6)\n    plt.imshow(np.log(np.squeeze(noise_added_spectrogram.numpy()) + 1e-10).T, aspect='auto', origin='lower')\n    plt.title(f\"Noise-Added Spectrogram: {os.path.basename(file_path)}\", fontsize=8)\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T07:04:32.259950Z","iopub.execute_input":"2024-12-30T07:04:32.260612Z","iopub.status.idle":"2024-12-30T07:04:44.178224Z","shell.execute_reply.started":"2024-12-30T07:04:32.260564Z","shell.execute_reply":"2024-12-30T07:04:44.176498Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 원본 데이터와 증강된 데이터 파일\n# Play original and 최종 augmented audio files\nprint(\"\\nPlaying original and augmented audio files:\")\n\nfor i, (file_path, noise_added_waveform) in enumerate(zip(audio_files, augmented_audio_files_speed_noise)):\n    # original audio\n    print(f\"\\nOriginal audio {i+1}: {os.path.basename(file_path)}\")\n    audio_binary = tf.io.read_file(file_path)\n    original_waveform = decode_audio(audio_binary)  # Decode the original waveform\n    display(Audio(original_waveform.numpy(), rate=16000))\n    \n    # augmented audio\n    print(f\"FINAL Augmented audio {i+1}: {os.path.basename(file_path)}\")\n    display(Audio(noise_added_waveform.numpy(), rate=16000))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-30T07:04:58.836444Z","iopub.execute_input":"2024-12-30T07:04:58.836845Z","iopub.status.idle":"2024-12-30T07:04:58.931451Z","shell.execute_reply.started":"2024-12-30T07:04:58.836817Z","shell.execute_reply":"2024-12-30T07:04:58.930412Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 3. 데이터 전처리 및 학습","metadata":{}},{"cell_type":"code","source":"def preprocess_dataset(files, augment=False):\n    files_ds = tf.data.Dataset.from_tensor_slices(files)\n\n    # 파일 경로에서 오디오 데이터를 읽고 레이블 추출\n    output_ds = files_ds.map(\n        lambda file_path: (tf.io.read_file(file_path), get_label(file_path)), \n        num_parallel_calls=tf.data.AUTOTUNE\n    )\n\n    # 오디오 데이터를 디코딩\n    output_ds = output_ds.map(\n        lambda audio_binary, label: (decode_audio(audio_binary), label),\n        num_parallel_calls=tf.data.AUTOTUNE\n    )\n\n    if augment:\n    # 데이터 증강: 속도 조절 및 노이즈 추가를 직접 map 함수에서 처리\n        output_ds = output_ds.map(\n            lambda waveform, label: (\n                add_background_noise(  \n                    adjust_speed_and_pad(waveform, speed_factor=tf.random.uniform([], 1.0, 1.3), target_length=16000),\n                    noise_files\n                ), \n                label\n            ), \n            num_parallel_calls=tf.data.AUTOTUNE\n        )\n\n\n    # Waveform을 Spectrogram으로 변환 및 레이블 인코딩\n    output_ds = output_ds.map(\n        lambda waveform, label: (get_spectrogram(waveform), tf.argmax(label == commands)),\n        num_parallel_calls=tf.data.AUTOTUNE\n    )\n\n    return output_ds\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:23:43.218154Z","iopub.execute_input":"2024-12-29T14:23:43.218599Z","iopub.status.idle":"2024-12-29T14:23:43.236838Z","shell.execute_reply.started":"2024-12-29T14:23:43.218551Z","shell.execute_reply":"2024-12-29T14:23:43.235584Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"filepath_data = os.path.join(extract_dir, \"train/audio\")\n\nfilenames = tf.io.gfile.glob([os.path.join(filepath_data, d,  '*') for d in commands])\nfilenames = tf.random.shuffle(filenames)\n\ntotal_samples = len(filenames)\ntrain_size = int(0.7 * total_samples)  # 70% for training\nval_size = int(0.15 * total_samples)  # 15% for validation\ntest_size = total_samples - train_size - val_size  # 15% for testing\n\n# train, validation, and test sets 분할\ntrain_files = filenames[:train_size]\nval_files = filenames[train_size:train_size + val_size]\ntest_files = filenames[train_size + val_size:]\n\nprint('Training set size:', len(train_files))\nprint('Validation set size:', len(val_files))\nprint('Test set size:', len(test_files))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:23:48.019082Z","iopub.execute_input":"2024-12-29T14:23:48.019514Z","iopub.status.idle":"2024-12-29T14:23:48.472007Z","shell.execute_reply.started":"2024-12-29T14:23:48.019484Z","shell.execute_reply":"2024-12-29T14:23:48.470791Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#각각의 dataset 전처리 (train dataset만 증강 처리)\ntrain_ds = preprocess_dataset(train_files, augment=True)\nval_ds = preprocess_dataset(val_files)\ntest_ds = preprocess_dataset(test_files)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:23:49.947542Z","iopub.execute_input":"2024-12-29T14:23:49.947995Z","iopub.status.idle":"2024-12-29T14:23:50.783742Z","shell.execute_reply.started":"2024-12-29T14:23:49.947963Z","shell.execute_reply":"2024-12-29T14:23:50.782445Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 증강된 train dataset 시각화를 위해 랜덤으로 10개의 데이터 가져오기\nnum_samples_to_display = 10\nrandom_ds = train_ds.shuffle(buffer_size=len(train_files)).take(num_samples_to_display)\n\n# 레이블 인덱스를 실제 레이블 이름으로 변환\ndef decode_label(label_index):\n    return commands[label_index]  \n\n# 시각화 \nfor i, (spectrogram, label) in enumerate(random_ds):\n    # Label 및 Spectrogram 추출\n    label_np = decode_label(label.numpy())  \n    spectrogram_np = spectrogram.numpy()[:, :, 0]  \n\n    # Waveform 복구\n    waveform = tf.signal.inverse_stft(\n        tf.cast(spectrogram[:, :, 0], tf.complex64), frame_length=255, frame_step=128\n    ).numpy()\n\n    # 시각화\n    plt.figure(figsize=(15, 5))\n\n    # Waveform \n    plt.subplot(1, 2, 1)\n    plt.plot(waveform)\n    plt.title(f\"Waveform (Label: {label_np})\")\n    plt.xlabel(\"Time\")\n    plt.ylabel(\"Amplitude\")\n\n    # Spectrogram \n    plt.subplot(1, 2, 2)\n    plt.imshow(np.log(spectrogram_np + 1e-10).T, aspect='auto', origin='lower')\n    plt.title(f\"Spectrogram (Label: {label_np})\")\n    plt.xlabel(\"Time\")\n    plt.ylabel(\"Frequency\")\n    plt.colorbar()\n\n\n    # 시각화 보여주기\n    plt.tight_layout()\n    plt.show()\n\n    # 종료 조건\n    if i + 1 >= num_samples_to_display:\n        break\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:23:54.624462Z","iopub.execute_input":"2024-12-29T14:23:54.624929Z","iopub.status.idle":"2024-12-29T14:25:12.009170Z","shell.execute_reply.started":"2024-12-29T14:23:54.624895Z","shell.execute_reply":"2024-12-29T14:25:12.007563Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"batch_size = 32\ntrain_ds = train_ds.batch(batch_size).cache().prefetch(tf.data.AUTOTUNE)\nval_ds = val_ds.batch(batch_size).cache().prefetch(tf.data.AUTOTUNE)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T12:24:46.830248Z","iopub.execute_input":"2024-12-29T12:24:46.830625Z","iopub.status.idle":"2024-12-29T12:24:46.850222Z","shell.execute_reply.started":"2024-12-29T12:24:46.830594Z","shell.execute_reply":"2024-12-29T12:24:46.849138Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(train_ds)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T12:24:46.851356Z","iopub.execute_input":"2024-12-29T12:24:46.851708Z","iopub.status.idle":"2024-12-29T12:24:46.858447Z","shell.execute_reply.started":"2024-12-29T12:24:46.851669Z","shell.execute_reply":"2024-12-29T12:24:46.857216Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Train 데이터 확인\nfor spectrogram, label in train_ds.take(1):\n    print(\"Spectrogram shape:\", spectrogram.shape)  \n    print(\"Label shape:\", label.shape)  \n    print(\"Label sample:\", label.numpy())  \n\n# Validation 데이터 확인\nfor spectrogram, label in val_ds.take(1):\n    print(\"Spectrogram shape:\", spectrogram.shape)\n    print(\"Label shape:\", label.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T12:24:46.859889Z","iopub.execute_input":"2024-12-29T12:24:46.860304Z","iopub.status.idle":"2024-12-29T12:24:47.415717Z","shell.execute_reply.started":"2024-12-29T12:24:46.860276Z","shell.execute_reply":"2024-12-29T12:24:47.414519Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for spectrogram, _ in train_ds.take(1):\n    input_shape = spectrogram.shape[1:]\n\nprint('Input shape:', input_shape)\nnum_labels = len(commands)\n\n# 입력 정규화\nnorm_layer = layers.Normalization()\nnorm_layer.adapt(data=train_ds.map(lambda spec, label: spec))\n\ntimesteps = 16\n\n# model\nmodel = models.Sequential([\n    layers.Input(shape=input_shape),\n    layers.Resizing(32, 32),\n    norm_layer,\n    layers.Conv2D(32, 3, activation='relu'),\n    layers.Conv2D(64, 3, activation='relu'),\n    layers.Conv2D(128, 3, activation='relu'),\n    layers.MaxPooling2D(),\n    layers.Dropout(0.25),\n    layers.Flatten(),\n    layers.Reshape((-1, timesteps, 21632 // timesteps)), \n    tf.keras.layers.Lambda(lambda x: tf.squeeze(x, axis=1)),\n    layers.GRU(64),\n    layers.Dense(128, activation='relu'),\n    layers.Dropout(0.5),\n    layers.Dense(num_labels)\n])\n\nmodel.summary()\n\nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(),\n    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n    metrics=['accuracy']\n)\n\nEPOCHS = 10\nhistory = model.fit(\n    train_ds,\n    validation_data=val_ds,\n    epochs=EPOCHS,\n    callbacks=tf.keras.callbacks.EarlyStopping(verbose=1, patience=2),\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T12:24:47.417191Z","iopub.execute_input":"2024-12-29T12:24:47.417574Z","iopub.status.idle":"2024-12-29T13:06:22.790017Z","shell.execute_reply.started":"2024-12-29T12:24:47.417534Z","shell.execute_reply":"2024-12-29T13:06:22.788608Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 4. 오류 분석\n# 4.1 오차 행렬, classification report","metadata":{}},{"cell_type":"code","source":"metrics = history.history\nplt.plot(history.epoch, metrics['loss'], metrics['val_loss'])\nplt.legend(['loss', 'val_loss'])\nplt.show()\n\ntest_audio = []\ntest_labels = []\n\nfor audio, label in test_ds:\n    test_audio.append(audio.numpy())\n    test_labels.append(label.numpy())\n\ntest_audio = np.array(test_audio)\ntest_labels = np.array(test_labels)\n\ny_pred = np.argmax(model.predict(test_audio), axis=1)\ny_true = test_labels\n\ntest_acc = sum(y_pred == y_true) / len(y_true)\nprint(f'Test set accuracy: {test_acc:.0%}')\n\nconfusion_mtx = tf.math.confusion_matrix(y_true, y_pred)\nplt.figure(figsize=(10, 8))\nsns.heatmap(confusion_mtx, xticklabels=commands, yticklabels=commands, annot=True, fmt='g')\nplt.xlabel('Prediction')\nplt.ylabel('Label')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T13:06:22.792430Z","iopub.execute_input":"2024-12-29T13:06:22.792822Z","iopub.status.idle":"2024-12-29T13:06:52.772560Z","shell.execute_reply.started":"2024-12-29T13:06:22.792793Z","shell.execute_reply":"2024-12-29T13:06:52.771313Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\n\n# 실제 라벨 개수\ntrue_counts = np.array([np.sum(y_true == i) for i in range(len(commands))])\n\n# 맞게 예측한 라벨 개수\ncorrect_predictions = y_true[y_true == y_pred]\ncorrect_counts = np.array([np.sum(correct_predictions == i) for i in range(len(commands))])\n\nx = np.arange(len(commands))  \nwidth = 0.4  \n\n# 그래프 생성\nplt.figure(figsize=(15, 8))\nplt.bar(x - width/2, true_counts, width, label=\"True Counts\", color=\"blue\")  # 실제 라벨 개수\nplt.bar(x + width/2, correct_counts, width, label=\"Correct Predictions\", color=\"green\")  # 맞게 예측한 라벨 개수\n\n# 그래프 제목 및 라벨\nplt.xlabel(\"Labels\", fontsize=12)\nplt.ylabel(\"Count\", fontsize=12)\nplt.title(\"True Counts : Correct Predictions per Label\", fontsize=14)\nplt.xticks(x, commands, rotation=45, ha=\"right\")  \nplt.legend()\n\n# 막대 위에 각각의 수치 입력 \nfor i in range(len(true_counts)):\n    plt.text(x[i] - width/2, true_counts[i] + 5, str(true_counts[i]), ha='center', va='bottom', fontsize=10, color='blue')\n    plt.text(x[i] + width/2, correct_counts[i] + 5, str(correct_counts[i]), ha='center', va='bottom', fontsize=10, color='green')\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T13:06:52.774013Z","iopub.execute_input":"2024-12-29T13:06:52.774379Z","iopub.status.idle":"2024-12-29T13:06:53.433227Z","shell.execute_reply.started":"2024-12-29T13:06:52.774349Z","shell.execute_reply":"2024-12-29T13:06:53.431837Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import classification_report\nimport pandas as pd\n\n# classification report\nreport = classification_report(y_true, y_pred, target_names=commands, output_dict=True)\n\nreport_df = pd.DataFrame(report).transpose()\n\nprint(report_df)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T13:06:53.438490Z","iopub.execute_input":"2024-12-29T13:06:53.438850Z","iopub.status.idle":"2024-12-29T13:06:53.736416Z","shell.execute_reply.started":"2024-12-29T13:06:53.438821Z","shell.execute_reply":"2024-12-29T13:06:53.735264Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 4.1 noise 시각화\n- 데이터의 과적합을 막기 위하여 noise를 사용하여 증강을 함\n- 증강이 된 train dataset에는 노이즈가 포함되어 원래 dataset에 큰 영향을 미쳤을 수도 있다고 생각함\n- 기존 데이터에 가장 많이 영향을 주는 noise file을 찾아 제거하고 증강을 시켜보고자 함","metadata":{}},{"cell_type":"code","source":"def load_waveform(file_path):\n    # WAV file 가져오기 \n    audio_binary = tf.io.read_file(file_path)\n    waveform, _ = tf.audio.decode_wav(audio_binary)\n    return np.array(waveform)\n\n#시각화\ndef visualize_waveforms(noise_files):\n    if not noise_files:\n        print(\"No files to visualize.\")\n        return\n\n    plt.figure(figsize=(15, 10))\n    for i, file_path in enumerate(noise_files):\n        waveform = load_waveform(file_path)\n        plt.subplot(3, 2, i + 1)\n        plt.plot(waveform)\n        plt.title(f\"Waveform: {file_path.split('/')[-1]}\")\n        plt.xlabel(\"Sample Index\")\n        plt.ylabel(\"Amplitude\")\n    plt.tight_layout()\n    plt.show()\n\nvisualize_waveforms(noise_files)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T13:06:53.738595Z","iopub.execute_input":"2024-12-29T13:06:53.739007Z","iopub.status.idle":"2024-12-29T13:06:58.362212Z","shell.execute_reply.started":"2024-12-29T13:06:53.738976Z","shell.execute_reply":"2024-12-29T13:06:58.360808Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#  5. 몇 개의 noise를 제거한 전처리 및 학습","metadata":{}},{"cell_type":"code","source":"for file in noise_files:\n    print(file)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:26:21.766320Z","iopub.execute_input":"2024-12-29T14:26:21.766796Z","iopub.status.idle":"2024-12-29T14:26:21.774509Z","shell.execute_reply.started":"2024-12-29T14:26:21.766762Z","shell.execute_reply":"2024-12-29T14:26:21.773173Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"가장 영향을 많이 미치는 pink noise와 white noise를 제거후 \n\n**add_background_noise --> add_background_noise_remove**\n\n**preprocess_dataset --> preprocess_dataset_remove_noise**\n\n로 수정","metadata":{}},{"cell_type":"code","source":"\nfiltered_noise_files = [file for file in noise_files if \"pink_noise.wav\" not in file and \"white_noise.wav\" not in file]\n\ndef add_background_noise_remove(waveform, noise_files):\n\n    noise_file = random.choice(filtered_noise_files)\n    noise_audio_binary = tf.io.read_file(noise_file)\n    noise_waveform = decode_audio(noise_audio_binary)\n\n    # 오디오 길이 맞기기\n    waveform_len = tf.shape(waveform)[0]\n    noise_len = tf.shape(noise_waveform)[0]\n    if noise_len > waveform_len:\n        offset = tf.random.uniform(shape=[], minval=0, maxval=noise_len - waveform_len, dtype=tf.int32)\n        noise_waveform = noise_waveform[offset:offset + waveform_len]\n    else:\n        padding = tf.zeros([waveform_len - noise_len], dtype=tf.float32)\n        noise_waveform = tf.concat([noise_waveform, padding], axis=0)\n\n    noise_factor = tf.random.uniform(shape=[], minval=0.0, maxval=0.5)\n    augmented_waveform = waveform + noise_factor * noise_waveform\n    return tf.clip_by_value(augmented_waveform, -1.0, 1.0)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:26:33.625880Z","iopub.execute_input":"2024-12-29T14:26:33.626251Z","iopub.status.idle":"2024-12-29T14:26:33.634554Z","shell.execute_reply.started":"2024-12-29T14:26:33.626224Z","shell.execute_reply":"2024-12-29T14:26:33.633109Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for file in filtered_noise_files:\n    print(file)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:26:40.665442Z","iopub.execute_input":"2024-12-29T14:26:40.665919Z","iopub.status.idle":"2024-12-29T14:26:40.672630Z","shell.execute_reply.started":"2024-12-29T14:26:40.665884Z","shell.execute_reply":"2024-12-29T14:26:40.671418Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def preprocess_dataset_remove_noise(files, augment=False):\n    files_ds = tf.data.Dataset.from_tensor_slices(files)\n\n    # 파일 경로에서 오디오 데이터를 읽고 레이블 추출\n    output_ds = files_ds.map(\n        lambda file_path: (tf.io.read_file(file_path), get_label(file_path)), \n        num_parallel_calls=tf.data.AUTOTUNE\n    )\n\n    # 오디오 데이터를 디코딩\n    output_ds = output_ds.map(\n        lambda audio_binary, label: (decode_audio(audio_binary), label),\n        num_parallel_calls=tf.data.AUTOTUNE\n    )\n\n    if augment:\n    # 데이터 증강: 속도 조절 및 노이즈 추가를 직접 map 함수에서 처리\n        output_ds = output_ds.map(\n            lambda waveform, label: (\n                add_background_noise_remove(  \n                    adjust_speed_and_pad(waveform, speed_factor=tf.random.uniform([], 1.0, 1.3), target_length=16000),\n                    filtered_noise_files\n                ), \n                label\n            ), \n            num_parallel_calls=tf.data.AUTOTUNE\n        )\n\n\n    # Waveform을 Spectrogram으로 변환 및 레이블 인코딩\n    output_ds = output_ds.map(\n        lambda waveform, label: (get_spectrogram(waveform), tf.argmax(label == commands)),\n        num_parallel_calls=tf.data.AUTOTUNE\n    )\n\n    return output_ds\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:26:42.418011Z","iopub.execute_input":"2024-12-29T14:26:42.418436Z","iopub.status.idle":"2024-12-29T14:26:42.426741Z","shell.execute_reply.started":"2024-12-29T14:26:42.418403Z","shell.execute_reply":"2024-12-29T14:26:42.425248Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_ds_2 = preprocess_dataset_remove_noise(train_files, augment=True)\nval_ds_2 = preprocess_dataset_remove_noise(val_files)\ntest_ds_2 = preprocess_dataset_remove_noise(test_files)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:26:49.361408Z","iopub.execute_input":"2024-12-29T14:26:49.361831Z","iopub.status.idle":"2024-12-29T14:26:51.244471Z","shell.execute_reply.started":"2024-12-29T14:26:49.361800Z","shell.execute_reply":"2024-12-29T14:26:51.243265Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 랜덤으로 10개의 데이터 가져오기\nnum_samples_to_display = 10\nrandom_ds_2 = train_ds_2.shuffle(buffer_size=len(train_files)).take(num_samples_to_display)\n\n# 레이블 인덱스를 실제 레이블 이름으로 변환\ndef decode_label(label_index):\n    return commands[label_index]  \n\n# 시각화 및 오디오 재생\nfor i, (spectrogram, label) in enumerate(random_ds_2):\n    # Label 및 Spectrogram 추출\n    label_np = decode_label(label.numpy())  \n    spectrogram_np = spectrogram.numpy()[:, :, 0]  \n\n    # Waveform 복구\n    waveform = tf.signal.inverse_stft(\n        tf.cast(spectrogram[:, :, 0], tf.complex64), frame_length=255, frame_step=128\n    ).numpy()\n\n    # 시각화\n    plt.figure(figsize=(15, 5))\n\n    # Waveform \n    plt.subplot(1, 2, 1)\n    plt.plot(waveform)\n    plt.title(f\"Waveform (Label: {label_np})\")\n    plt.xlabel(\"Time\")\n    plt.ylabel(\"Amplitude\")\n\n    # Spectrogram \n    plt.subplot(1, 2, 2)\n    plt.imshow(np.log(spectrogram_np + 1e-10).T, aspect='auto', origin='lower')\n    plt.title(f\"Spectrogram (Label: {label_np})\")\n    plt.xlabel(\"Time\")\n    plt.ylabel(\"Frequency\")\n    plt.colorbar()\n\n\n    # 시각화 \n    plt.tight_layout()\n    plt.show()\n\n    # 종료 조건\n    if i + 1 >= num_samples_to_display:\n        break\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:27:21.154056Z","iopub.execute_input":"2024-12-29T14:27:21.154521Z","iopub.status.idle":"2024-12-29T14:28:37.815907Z","shell.execute_reply.started":"2024-12-29T14:27:21.154491Z","shell.execute_reply":"2024-12-29T14:28:37.814601Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"batch_size = 32\ntrain_ds_2 = train_ds_2.batch(batch_size).cache().prefetch(tf.data.AUTOTUNE)\nval_ds_2 = val_ds_2.batch(batch_size).cache().prefetch(tf.data.AUTOTUNE)\nprint(train_ds_2)\n# Train 데이터 확인\nfor spectrogram, label in train_ds_2.take(1):\n    print(\"Spectrogram shape:\", spectrogram.shape)  \n    print(\"Label shape:\", label.shape)  \n    print(\"Label sample:\", label.numpy())  \n\n# Validation 데이터 확인\nfor spectrogram, label in val_ds_2.take(1):\n    print(\"Spectrogram shape:\", spectrogram.shape)\n    print(\"Label shape:\", label.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:28:40.699876Z","iopub.execute_input":"2024-12-29T14:28:40.700341Z","iopub.status.idle":"2024-12-29T14:28:41.176361Z","shell.execute_reply.started":"2024-12-29T14:28:40.700301Z","shell.execute_reply":"2024-12-29T14:28:41.175069Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for spectrogram, _ in train_ds_2.take(1):\n    input_shape = spectrogram.shape[1:]\n\nprint('Input shape:', input_shape)\nnum_labels = len(commands)\n\n# 입력 정규화\nnorm_layer = layers.Normalization()\nnorm_layer.adapt(data=train_ds_2.map(lambda spec, label: spec))\n\ntimesteps = 16\n\n# model\nmodel = models.Sequential([\n    layers.Input(shape=input_shape),\n    layers.Resizing(32, 32),\n    norm_layer,\n    layers.Conv2D(32, 3, activation='relu'),\n    layers.Conv2D(64, 3, activation='relu'),\n    layers.Conv2D(128, 3, activation='relu'),\n    layers.MaxPooling2D(),\n    layers.Dropout(0.25),\n    layers.Flatten(),\n    layers.Reshape((-1, timesteps, 21632 // timesteps)), \n    tf.keras.layers.Lambda(lambda x: tf.squeeze(x, axis=1)),\n    layers.GRU(64),\n    layers.Dense(128, activation='relu'),\n    layers.Dropout(0.5),\n    layers.Dense(num_labels)\n])\n\nmodel.summary()\n\nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(),\n    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n    metrics=['accuracy']\n)\n\nEPOCHS = 10\nhistory = model.fit(\n    train_ds_2,\n    validation_data=val_ds_2,\n    epochs=EPOCHS,\n    callbacks=tf.keras.callbacks.EarlyStopping(verbose=1, patience=2),\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T14:28:43.629619Z","iopub.execute_input":"2024-12-29T14:28:43.630085Z","iopub.status.idle":"2024-12-29T15:11:00.913836Z","shell.execute_reply.started":"2024-12-29T14:28:43.630047Z","shell.execute_reply":"2024-12-29T15:11:00.912534Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 6. 5번 학습에 대한 오류분석","metadata":{}},{"cell_type":"code","source":"metrics = history.history\nplt.plot(history.epoch, metrics['loss'], metrics['val_loss'])\nplt.legend(['loss', 'val_loss'])\nplt.show()\n\ntest_audio = []\ntest_labels = []\n\nfor audio, label in test_ds_2:\n    test_audio.append(audio.numpy())\n    test_labels.append(label.numpy())\n\ntest_audio = np.array(test_audio)\ntest_labels = np.array(test_labels)\n\ny_pred = np.argmax(model.predict(test_audio), axis=1)\ny_true = test_labels\n\ntest_acc = sum(y_pred == y_true) / len(y_true)\nprint(f'Test set accuracy: {test_acc:.0%}')\n\nconfusion_mtx = tf.math.confusion_matrix(y_true, y_pred)\nplt.figure(figsize=(10, 8))\nsns.heatmap(confusion_mtx, xticklabels=commands, yticklabels=commands, annot=True, fmt='g')\nplt.xlabel('Prediction')\nplt.ylabel('Label')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T15:11:26.321189Z","iopub.execute_input":"2024-12-29T15:11:26.321574Z","iopub.status.idle":"2024-12-29T15:11:52.203596Z","shell.execute_reply.started":"2024-12-29T15:11:26.321547Z","shell.execute_reply":"2024-12-29T15:11:52.202430Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\n\n# 실제 라벨 개수\ntrue_counts = np.array([np.sum(y_true == i) for i in range(len(commands))])\n\n# 맞게 예측한 라벨 개수\ncorrect_predictions = y_true[y_true == y_pred]\ncorrect_counts = np.array([np.sum(correct_predictions == i) for i in range(len(commands))])\n\n\nx = np.arange(len(commands))  \nwidth = 0.4  \n\n\nplt.figure(figsize=(15, 8))\nplt.bar(x - width/2, true_counts, width, label=\"True Counts\", color=\"blue\")  # 실제 라벨 개수\nplt.bar(x + width/2, correct_counts, width, label=\"Correct Predictions\", color=\"green\")  # 맞게 예측한 라벨 개수\n\n\nplt.xlabel(\"Labels\", fontsize=12)\nplt.ylabel(\"Count\", fontsize=12)\nplt.title(\"True Counts : Correct Predictions per Label\", fontsize=14)\nplt.xticks(x, commands, rotation=45, ha=\"right\")  \nplt.legend()\n\n# 막대 위에 각각의 수치 입력 \nfor i in range(len(true_counts)):\n    plt.text(x[i] - width/2, true_counts[i] + 5, str(true_counts[i]), ha='center', va='bottom', fontsize=10, color='blue')\n    plt.text(x[i] + width/2, correct_counts[i] + 5, str(correct_counts[i]), ha='center', va='bottom', fontsize=10, color='green')\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T15:11:58.594699Z","iopub.execute_input":"2024-12-29T15:11:58.595056Z","iopub.status.idle":"2024-12-29T15:11:59.227535Z","shell.execute_reply.started":"2024-12-29T15:11:58.595030Z","shell.execute_reply":"2024-12-29T15:11:59.226520Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import classification_report\nimport pandas as pd\n\n# classification report\nreport = classification_report(y_true, y_pred, target_names=commands, output_dict=True)\n\nreport_df = pd.DataFrame(report).transpose()\n\nprint(report_df)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-29T15:12:03.231356Z","iopub.execute_input":"2024-12-29T15:12:03.231718Z","iopub.status.idle":"2024-12-29T15:12:03.281430Z","shell.execute_reply.started":"2024-12-29T15:12:03.231690Z","shell.execute_reply":"2024-12-29T15:12:03.280374Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}