{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3649,"databundleVersionId":46718,"sourceType":"competition"}],"dockerImageVersionId":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 데이터 전처리","metadata":{}},{"cell_type":"code","source":"!cd /kaggle/working/\n!mkdir CIFAR-10\n!pwd\n!cd /kaggle/working/CIFAR-10","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-11-09T12:18:52.947535Z","iopub.execute_input":"2024-11-09T12:18:52.947873Z","iopub.status.idle":"2024-11-09T12:18:57.143820Z","shell.execute_reply.started":"2024-11-09T12:18:52.947838Z","shell.execute_reply":"2024-11-09T12:18:57.142370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install py7zr","metadata":{"execution":{"iopub.status.busy":"2024-11-09T12:18:57.146777Z","iopub.execute_input":"2024-11-09T12:18:57.147218Z","iopub.status.idle":"2024-11-09T12:19:12.527132Z","shell.execute_reply.started":"2024-11-09T12:18:57.147168Z","shell.execute_reply":"2024-11-09T12:19:12.526166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install efficientnet","metadata":{"execution":{"iopub.status.busy":"2024-11-10T15:19:27.416898Z","iopub.execute_input":"2024-11-10T15:19:27.417647Z","iopub.status.idle":"2024-11-10T15:19:40.162502Z","shell.execute_reply.started":"2024-11-10T15:19:27.417610Z","shell.execute_reply":"2024-11-10T15:19:40.161407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 필요한 모듈 import\nimport os, shutil\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.preprocessing import image\nfrom sklearn.metrics import classification_report\n\nimport tensorflow as tf\nimport efficientnet\nimport efficientnet.tfkeras as efn\nfrom tensorflow.keras.applications import VGG16, EfficientNetB7, ResNet50, EfficientNetV2S, EfficientNetV2L\nfrom tensorflow.keras.applications.vgg16 import preprocess_input\nfrom tensorflow.keras.models import Sequential, load_model\nfrom tensorflow.keras.layers import Flatten, Dense, Dropout, GlobalAveragePooling2D\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, BatchNormalization\nfrom tensorflow.keras.optimizers import Adam, RMSprop\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau\nfrom tensorflow.keras.regularizers import l2","metadata":{"execution":{"iopub.status.busy":"2024-11-10T15:19:40.164403Z","iopub.execute_input":"2024-11-10T15:19:40.164748Z","iopub.status.idle":"2024-11-10T15:19:40.241789Z","shell.execute_reply.started":"2024-11-10T15:19:40.164710Z","shell.execute_reply":"2024-11-10T15:19:40.241052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import py7zr\n\n# CIFAR-10 데이터셋 압축 해제\ndef extract_7z(file_path, extract_to):\n    # 추출할 디렉토리가 존재하지 않으면 생성\n    if not os.path.exists(extract_to):\n        os.makedirs(extract_to)\n    with py7zr.SevenZipFile(file_path, mode='r') as archive:\n        archive.extractall(path=extract_to)\n    print(f\"{file_path}가 {extract_to}에 성공적으로 압축 해제되었습니다.\")\n\n# 쓰기 모드 권한있는 폴더에 압축 해제\nextract_7z('/kaggle/input/cifar-10/train.7z', '/kaggle/working/CIFAR-10/')\nextract_7z('/kaggle/input/cifar-10/test.7z', '/kaggle/working/CIFAR-10/test_new/')\n\nprint(\"성공적으로 압축 해제되었습니다.\")\n!ls -al /kaggle/working/CIFAR-10/","metadata":{"execution":{"iopub.status.busy":"2024-11-09T12:19:24.440372Z","iopub.execute_input":"2024-11-09T12:19:24.441547Z","iopub.status.idle":"2024-11-09T12:22:31.441654Z","shell.execute_reply.started":"2024-11-09T12:19:24.441504Z","shell.execute_reply":"2024-11-09T12:22:31.440526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 학습 데이터 라벨 로드\ntrain_labels_df = pd.read_csv('/kaggle/input/cifar-10/trainLabels.csv', dtype={'id': int})\n\nsource_dir = '/kaggle/working/CIFAR-10/train'\ndest_dir = '/kaggle/working/CIFAR-10/train_new'\n\n# 목적지 메인 디렉토리 생성\nos.makedirs(dest_dir, exist_ok=True)\n\n# 이미지 ID와 레이블 매핑\nimage_labels = dict(zip(train_labels_df['id'], train_labels_df['label']))\n\n# 이미지 분류 및 이동\nfor filename in os.listdir(source_dir):\n    if filename.endswith('.png'):\n        image_id = int(filename.split('.')[0])\n        label = image_labels.get(image_id)\n        \n        if label:\n            dest_subfolder = os.path.join(dest_dir, label)\n            os.makedirs(dest_subfolder, exist_ok=True)\n            \n            source_path = os.path.join(source_dir, filename)\n            dest_path = os.path.join(dest_subfolder, filename)\n            shutil.move(source_path, dest_path)\n\nprint(\"학습 데이터 이미지 분류 및 이동 완료\")\n!ls -al /kaggle/working/CIFAR-10/train_new","metadata":{"execution":{"iopub.status.busy":"2024-11-09T12:22:31.443172Z","iopub.execute_input":"2024-11-09T12:22:31.443521Z","iopub.status.idle":"2024-11-09T12:22:35.916374Z","shell.execute_reply.started":"2024-11-09T12:22:31.443483Z","shell.execute_reply":"2024-11-09T12:22:35.915263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 전처리된 데이터 로딩\ntrain_dir = '/kaggle/working/CIFAR-10/train_new'\ntest_dir = '/kaggle/working/CIFAR-10/test_new'\n\ntrain_datagen = ImageDataGenerator(\n    rescale=1/255,  # 입력 데이터를 1/255로 스케일 조정\n#     featurewise_center=False,  # 데이터셋 전체의 평균을 0으로 설정\n#     samplewise_center=False,  # 각 샘플의 평균을 0으로 설정\n#     featurewise_std_normalization=False,  # 데이터셋의 표준편차로 입력을 나누기\n#     samplewise_std_normalization=False,  # 각 입력을 그 표준편차로 나누기\n#     zca_whitening=False,  # ZCA 화이트닝 적용\n#     zca_epsilon=1e-06,  # ZCA 화이트닝을 위한 epsilon 값\n#     rotation_range=0,  # 이미지를 (0에서 180도 사이의) 범위 내에서 무작위로 회전\n#     width_shift_range=0.1,  # 이미지를 수평으로 무작위 이동 (전체 너비의 비율)\n#     height_shift_range=0.1,  # 이미지를 수직으로 무작위 이동 (전체 높이의 비율)\n#     shear_range=0.,  # 무작위 전단 변환 범위 설정\n#     zoom_range=0.,  # 무작위 줌 범위 설정\n#     channel_shift_range=0.,  # 무작위 채널 이동 범위 설정\n#     fill_mode='nearest',  # 입력 경계 밖의 포인트를 채우는 모드 설정\n#     cval=0.,  # fill_mode가 \"constant\"일 때 사용되는 값\n#     horizontal_flip=True,  # 이미지를 무작위로 수평 뒤집기\n#     vertical_flip=False,  # 이미지를 무작위로 수직 뒤집기\n#     preprocessing_function=None,  # 각 입력에 적용될 함수 설정\n#     data_format=None,  # 이미지 데이터 형식 설정 (\"channels_first\" 또는 \"channels_last\")\n    validation_split=0.2,\n)\n\ntest_datagen = ImageDataGenerator(\n    rescale=1/255\n)\n\ntrain_generator = train_datagen.flow_from_directory(\n    train_dir,\n    target_size=(224, 224),\n    classes=['airplane', 'automobile', 'bird', 'cat', 'deer',\n               'dog', 'frog', 'horse', 'ship', 'truck'],\n    batch_size=32,\n    class_mode='categorical',\n    subset='training'\n)\n\nvalidation_generator = train_datagen.flow_from_directory(\n    train_dir,\n    target_size=(224, 224),\n    classes=['airplane', 'automobile', 'bird', 'cat', 'deer',\n               'dog', 'frog', 'horse', 'ship', 'truck'],\n    batch_size=32,\n    class_mode='categorical',\n    subset='validation'\n)\n\n# 폴더 안에 폴더가 무조건 있어야 함.. 이미지가 있으면 안됩니다 하하하... ★★★★★\ntest_generator = test_datagen.flow_from_directory(\n    test_dir,\n    target_size=(224, 224),\n    batch_size=32,\n    class_mode=None,  # 라벨이 없으므로 None으로 설정\n    shuffle=False  # 순서를 유지하기 위해 False로 설정\n)\n\n# 여러 이미지 출력\nbatch_images, batch_labels = next(train_generator)\n\nfig, axes = plt.subplots(3, 3, figsize=(4, 4))\nfor i, ax in enumerate(axes.flat):\n    ax.imshow(batch_images[i])\n    ax.axis('off')  # 축 제거\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-10T15:19:40.243082Z","iopub.execute_input":"2024-11-10T15:19:40.243875Z","iopub.status.idle":"2024-11-10T15:19:50.528876Z","shell.execute_reply.started":"2024-11-10T15:19:40.243841Z","shell.execute_reply":"2024-11-10T15:19:50.527961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ResNet50\nResNet50은 Residual Network (ResNet) 아키텍처의 한 변종으로, 50개 레이어로 구성된 딥러닝 모델입니다. ResNet은 2015년 마이크로소프트 리서치(Microsoft Research) 팀이 개발한 네트워크로, ImageNet 대회에서 우승하면서 널리 알려졌습니다. ResNet의 가장 큰 혁신은 **잔차 연결(Residual Connection)**을 도입하여, 매우 깊은 신경망에서도 학습이 가능하도록 한 것입니다.\n\n잔차 연결(Residual Connection)은 딥러닝 모델, 특히 심층 신경망의 학습을 용이하게 하고 성능을 향상시키기 위해 고안된 기술입니다. 이 연결 방식은 신경망 내부에서 정보가 직접적으로 전달될 수 있도록 함으로써, 모델이 더 깊어지더라도 학습이 효과적으로 이루어질 수 있도록 돕습니다.","metadata":{}},{"cell_type":"code","source":"# Pretrained Network\n\nstrategy = tf.distribute.MirroredStrategy()\n\nwith strategy.scope():\n\n    # 모델 로드\n    base_model = ResNet50(\n        weights='imagenet',\n        include_top=False,\n        input_shape=(224, 224, 3)\n    )\n\n    model = Sequential()\n    \n    base_model.trainable=True\n    \n    model.add(base_model)\n    \n    model.add(GlobalAveragePooling2D())\n\n    model.add(Dense(units=10,\n                    activation='softmax'))\n    \n    model.compile(\n        optimizer='Adam',\n        loss='categorical_crossentropy',\n        metrics=['accuracy']\n    )\n\n#     base_model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T12:22:46.116022Z","iopub.execute_input":"2024-11-09T12:22:46.116325Z","iopub.status.idle":"2024-11-09T12:22:50.159582Z","shell.execute_reply.started":"2024-11-09T12:22:46.116292Z","shell.execute_reply":"2024-11-09T12:22:50.158537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"es_cb = EarlyStopping(monitor='val_loss',\n                      patience=6,\n                      restore_best_weights=True)\n\nrlr_cb = ReduceLROnPlateau(\n    monitor='val_loss',\n    factor=0.5,  # 5번 참았는데 성능 개선 효과가 없다 그러면 학습률 50% 감소, \n                 # 0.001의 50% 감소는 0.0005니까. 더 조밀조밀하게 계산(?)\n    patience=3,\n    mode='auto', # 디폴트 값은 auto로 monitor 값에 따라서 'min', 'max' 지정됨\n    min_lr=1e-6\n)\n\nmc_cb = ModelCheckpoint(\n    filepath='resnet50_11091900.keras',  # 모델을 저장할 파일 경로\n    monitor='val_accuracy',       # 모니터링할 지표\n    save_best_only=True,          # 가장 성능이 좋은 모델만 저장\n\n    mode='max',                   # 'val_accuracy'가 최대일 때 저장\n    verbose=1                     # 저장 시 메시지 출력\n)\n\n# 파인 튜닝 모델 학습\nhistory_resnet50 = model.fit(train_generator,\n                    epochs=100,\n                    validation_data=validation_generator,\n                    callbacks=[es_cb, rlr_cb, mc_cb],\n                    verbose=1)","metadata":{"execution":{"iopub.status.busy":"2024-11-09T12:22:50.160956Z","iopub.execute_input":"2024-11-09T12:22:50.161382Z","iopub.status.idle":"2024-11-09T14:10:41.406710Z","shell.execute_reply.started":"2024-11-09T12:22:50.161331Z","shell.execute_reply":"2024-11-09T14:10:41.405834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 그래프 크기 설정\nplt.figure(figsize=(12, 5))\n\n# 첫 번째 subplot: Accuracy\nplt.subplot(1, 2, 1)\nplt.plot(history_resnet50.history['accuracy'], label='Train Accuracy', color='r')\nplt.plot(history_resnet50.history['val_accuracy'], label='Validation Accuracy', color='b')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.title('Model Accuracy')\nplt.legend(loc='lower right')\n\n# 두 번째 subplot: Loss\nplt.subplot(1, 2, 2)\nplt.plot(history_resnet50.history['loss'], label='Train Loss', color='r')\nplt.plot(history_resnet50.history['val_loss'], label='Validation Loss', color='b')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.title('Model Loss')\nplt.legend(loc='upper right')\n\n# 그래프 출력\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T14:10:41.410473Z","iopub.execute_input":"2024-11-09T14:10:41.410810Z","iopub.status.idle":"2024-11-09T14:10:41.921343Z","shell.execute_reply.started":"2024-11-09T14:10:41.410775Z","shell.execute_reply":"2024-11-09T14:10:41.920417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# EfficientNetB7\nEfficientNetB7은 EfficientNet 모델 계열 중 가장 큰 버전으로, Google Brain 팀이 2019년에 발표한 EfficientNet 아키텍처의 일부입니다. EfficientNet은 모델의 크기(깊이, 너비, 해상도)를 균형 있게 확장하는 방법을 제안하여, 성능과 효율성을 동시에 극대화한 모델입니다. 특히 EfficientNetB7은 높은 정확도를 제공하면서도 상대적으로 적은 연산 자원을 사용하는 것이 특징입니다.","metadata":{}},{"cell_type":"code","source":"train_generator = train_datagen.flow_from_directory(\n    train_dir,\n    target_size=(256, 256),\n    classes=['airplane', 'automobile', 'bird', 'cat', 'deer',\n               'dog', 'frog', 'horse', 'ship', 'truck'],\n    batch_size=32,\n    class_mode='categorical',\n    subset='training'\n)\n\nvalidation_generator = train_datagen.flow_from_directory(\n    train_dir,\n    target_size=(256, 256),\n    classes=['airplane', 'automobile', 'bird', 'cat', 'deer',\n               'dog', 'frog', 'horse', 'ship', 'truck'],\n    batch_size=32,\n    class_mode='categorical',\n    subset='validation'\n)\n\n# 폴더 안에 폴더가 무조건 있어야 함.. 이미지가 있으면 안됩니다 하하하... ★★★★★\ntest_generator = test_datagen.flow_from_directory(\n    test_dir,\n    target_size=(256, 256),\n    batch_size=32,\n    class_mode=None,  # 라벨이 없으므로 None으로 설정\n    shuffle=False  # 순서를 유지하기 위해 False로 설정\n)","metadata":{"execution":{"iopub.status.busy":"2024-11-10T13:58:12.491281Z","iopub.execute_input":"2024-11-10T13:58:12.491620Z","iopub.status.idle":"2024-11-10T13:58:22.192496Z","shell.execute_reply.started":"2024-11-10T13:58:12.491586Z","shell.execute_reply":"2024-11-10T13:58:22.191442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Pretrained Network\n\nstrategy = tf.distribute.MirroredStrategy()\n\nprint(f'사용 가능한 GPU 개수: {strategy.num_replicas_in_sync}')\n\nwith strategy.scope():\n\n    # 모델 로드\n    base_model = efn.EfficientNetB7(\n        weights='imagenet',\n        include_top=False,\n        input_shape=(256, 256, 3)\n    )\n\n    base_model.trainable=False #################################\n    \n    model = Sequential()\n    \n    model.add(base_model)\n    \n    model.add(GlobalAveragePooling2D())\n\n    model.add(Dense(units=10,\n                    activation='softmax'))\n    \n    model.compile(\n        optimizer='Adam',\n        loss='categorical_crossentropy',\n        metrics=['accuracy']\n    )\n\n#     base_model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T14:41:46.107367Z","iopub.execute_input":"2024-11-09T14:41:46.107691Z","iopub.status.idle":"2024-11-09T14:41:57.468809Z","shell.execute_reply.started":"2024-11-09T14:41:46.107655Z","shell.execute_reply":"2024-11-09T14:41:57.467991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"es_cb = EarlyStopping(monitor='val_loss',\n                      patience=6,\n                      restore_best_weights=True)\n\nrlr_cb = ReduceLROnPlateau(\n    monitor='val_loss',\n    factor=0.5,  # 5번 참았는데 성능 개선 효과가 없다 그러면 학습률 50% 감소, \n                 # 0.001의 50% 감소는 0.0005니까. 더 조밀조밀하게 계산(?)\n    patience=3,\n    mode='auto', # 디폴트 값은 auto로 monitor 값에 따라서 'min', 'max' 지정됨\n    min_lr=1e-6\n)\n\nmc_cb = ModelCheckpoint(\n    filepath='efficientnetb7_11091900.keras',  # 모델을 저장할 파일 경로\n    monitor='val_accuracy',       # 모니터링할 지표\n    save_best_only=True,          # 가장 성능이 좋은 모델만 저장\n    mode='max',                   # 'val_accuracy'가 최대일 때 저장\n    verbose=1                     # 저장 시 메시지 출력\n)\n\n# 파인 튜닝 모델 학습\nhistory_efficientnetb7 = model.fit(train_generator,\n                    epochs=100,\n                    validation_data=validation_generator,\n                    callbacks=[es_cb, rlr_cb, mc_cb],\n                    verbose=1)","metadata":{"execution":{"iopub.status.busy":"2024-11-09T14:41:57.470037Z","iopub.execute_input":"2024-11-09T14:41:57.470343Z","iopub.status.idle":"2024-11-09T20:07:15.625144Z","shell.execute_reply.started":"2024-11-09T14:41:57.470311Z","shell.execute_reply":"2024-11-09T20:07:15.624291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 그래프 크기 설정\nplt.figure(figsize=(12, 5))\n\n# 첫 번째 subplot: Accuracy\nplt.subplot(1, 2, 1)\nplt.plot(history_efficientnetb7.history['accuracy'], label='Train Accuracy', color='r')\nplt.plot(history_efficientnetb7.history['val_accuracy'], label='Validation Accuracy', color='b')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.title('Model Accuracy')\nplt.legend(loc='lower right')\n\n# 두 번째 subplot: Loss\nplt.subplot(1, 2, 2)\nplt.plot(history_efficientnetb7.history['loss'], label='Train Loss', color='r')\nplt.plot(history_efficientnetb7.history['val_loss'], label='Validation Loss', color='b')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.title('Model Loss')\nplt.legend(loc='upper right')\n\n# 그래프 출력\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T20:07:15.626854Z","iopub.execute_input":"2024-11-09T20:07:15.627171Z","iopub.status.idle":"2024-11-09T20:07:16.288643Z","shell.execute_reply.started":"2024-11-09T20:07:15.627136Z","shell.execute_reply":"2024-11-09T20:07:16.287806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# EfficientNetV2S\n\nEfficientNetV2S는 Google에서 개발한 EfficientNetV2 시리즈 중 소형(Small) 모델로, 이미지 분류 및 기타 컴퓨터 비전 작업에서 높은 성능과 효율성을 제공합니다. EfficientNetV2는 이전 EfficientNet 모델의 확장성과 성능을 개선한 버전으로, 특히 학습 속도와 정확도 면에서 향상된 특징을 가지고 있습니다.","metadata":{}},{"cell_type":"code","source":"# Pretrained Network\n\nstrategy = tf.distribute.MirroredStrategy()\n\nprint(f'사용 가능한 GPU 개수: {strategy.num_replicas_in_sync}')\n\nwith strategy.scope():\n\n    # 모델 로드\n    base_model = EfficientNetV2S(\n        weights='imagenet',\n        include_top=False,\n        input_shape=(256, 256, 3)\n    )\n    \n    base_model.trainable=True #################################\n\n    model = Sequential()\n    \n    model.add(base_model)\n    \n    model.add(GlobalAveragePooling2D())\n\n    model.add(Dense(units=10,\n                    activation='softmax'))\n\n    \n    model.compile(\n        optimizer='Adam',\n        loss='categorical_crossentropy',\n        metrics=['accuracy']\n    )\n\n#     base_model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-11-10T08:42:55.379960Z","iopub.execute_input":"2024-11-10T08:42:55.380278Z","iopub.status.idle":"2024-11-10T08:43:02.137404Z","shell.execute_reply.started":"2024-11-10T08:42:55.380245Z","shell.execute_reply":"2024-11-10T08:43:02.136633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"es_cb = EarlyStopping(monitor='val_loss',\n                      patience=6,\n                      restore_best_weights=True)\n\nrlr_cb = ReduceLROnPlateau(\n    monitor='val_loss',\n    factor=0.5,  # 5번 참았는데 성능 개선 효과가 없다 그러면 학습률 50% 감소, \n                 # 0.001의 50% 감소는 0.0005니까. 더 조밀조밀하게 계산(?)\n    patience=3,\n    mode='auto', # 디폴트 값은 auto로 monitor 값에 따라서 'min', 'max' 지정됨\n    min_lr=1e-6\n)\n\nmc_cb = ModelCheckpoint(\n    filepath='efficientnetv2s_11091900.keras',  # 모델을 저장할 파일 경로\n    monitor='val_accuracy',       # 모니터링할 지표\n    save_best_only=True,          # 가장 성능이 좋은 모델만 저장\n    mode='max',                   # 'val_accuracy'가 최대일 때 저장\n    verbose=1                     # 저장 시 메시지 출력\n)\n\n# 파인 튜닝 모델 학습\nhistory_efficientnetv2s = model.fit(train_generator,\n                    epochs=100,\n                    validation_data=validation_generator,\n                    callbacks=[es_cb, rlr_cb, mc_cb],\n                    verbose=1)","metadata":{"execution":{"iopub.status.busy":"2024-11-10T08:43:02.138683Z","iopub.execute_input":"2024-11-10T08:43:02.139053Z","iopub.status.idle":"2024-11-10T13:34:20.596462Z","shell.execute_reply.started":"2024-11-10T08:43:02.139011Z","shell.execute_reply":"2024-11-10T13:34:20.595386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 그래프 크기 설정\nplt.figure(figsize=(12, 5))\n\n# 첫 번째 subplot: Accuracy\nplt.subplot(1, 2, 1)\nplt.plot(history_efficientnetv2s.history['accuracy'], label='Train Accuracy', color='r')\nplt.plot(history_efficientnetv2s.history['val_accuracy'], label='Validation Accuracy', color='b')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.title('Model Accuracy')\nplt.legend(loc='lower right')\n\n# 두 번째 subplot: Loss\nplt.subplot(1, 2, 2)\nplt.plot(history_efficientnetv2s.history['loss'], label='Train Loss', color='r')\nplt.plot(history_efficientnetv2s.history['val_loss'], label='Validation Loss', color='b')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.title('Model Loss')\nplt.legend(loc='upper right')\n\n# 그래프 출력\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-10T13:34:20.598955Z","iopub.execute_input":"2024-11-10T13:34:20.599421Z","iopub.status.idle":"2024-11-10T13:34:21.193213Z","shell.execute_reply.started":"2024-11-10T13:34:20.599369Z","shell.execute_reply":"2024-11-10T13:34:21.192338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# EfficientNetV2L\n\nEfficientNetV2L은 EfficientNetV2 시리즈 중 대형(Large) 모델로, 이미지 분류 및 기타 컴퓨터 비전 작업에서 높은 성능을 제공하도록 설계되었습니다. EfficientNetV2는 이전 버전인 EfficientNet의 성능을 개선하며, 특히 학습 속도와 정확도를 향상시킨 것이 특징입니다.","metadata":{}},{"cell_type":"code","source":"train_generator = train_datagen.flow_from_directory(\n    train_dir,\n    target_size=(256, 256),\n    classes=['airplane', 'automobile', 'bird', 'cat', 'deer',\n               'dog', 'frog', 'horse', 'ship', 'truck'],\n    batch_size=16,\n    class_mode='categorical',\n    subset='training'\n)\n\nvalidation_generator = train_datagen.flow_from_directory(\n    train_dir,\n    target_size=(256, 256),\n    classes=['airplane', 'automobile', 'bird', 'cat', 'deer',\n               'dog', 'frog', 'horse', 'ship', 'truck'],\n    batch_size=16,\n    class_mode='categorical',\n    subset='validation'\n)\n\n# 폴더 안에 폴더가 무조건 있어야 함.. 이미지가 있으면 안됩니다 하하하... ★★★★★\ntest_generator = test_datagen.flow_from_directory(\n    test_dir,\n    target_size=(256, 256),\n    batch_size=16,\n    class_mode=None,  # 라벨이 없으므로 None으로 설정\n    shuffle=False  # 순서를 유지하기 위해 False로 설정\n)","metadata":{"execution":{"iopub.status.busy":"2024-11-10T15:19:50.530931Z","iopub.execute_input":"2024-11-10T15:19:50.531290Z","iopub.status.idle":"2024-11-10T15:20:00.348443Z","shell.execute_reply.started":"2024-11-10T15:19:50.531255Z","shell.execute_reply":"2024-11-10T15:20:00.347583Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Pretrained Network\n\nstrategy = tf.distribute.MirroredStrategy()\n\nprint(f'사용 가능한 GPU 개수: {strategy.num_replicas_in_sync}')\n\nwith strategy.scope():\n\n    # 모델 로드\n    base_model = EfficientNetV2L(\n        weights='imagenet',\n        include_top=False,\n        input_shape=(256, 256, 3)\n    )\n\n    base_model.trainable=True #################################\n    \n    model = Sequential()\n    \n    model.add(base_model)\n    \n    model.add(GlobalAveragePooling2D())\n\n    model.add(Dense(units=10,\n                    activation='softmax'))\n\n    model.compile(\n        optimizer='Adam',\n        loss='categorical_crossentropy',\n        metrics=['accuracy']\n    )\n\n#     base_model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-11-10T15:20:00.349591Z","iopub.execute_input":"2024-11-10T15:20:00.349976Z","iopub.status.idle":"2024-11-10T15:20:14.091062Z","shell.execute_reply.started":"2024-11-10T15:20:00.349924Z","shell.execute_reply":"2024-11-10T15:20:14.090050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"es_cb = EarlyStopping(monitor='val_loss',\n                      patience=6,\n                      restore_best_weights=True)\n\nrlr_cb = ReduceLROnPlateau(\n    monitor='val_loss',\n    factor=0.5,  # 5번 참았는데 성능 개선 효과가 없다 그러면 학습률 50% 감소, \n                 # 0.001의 50% 감소는 0.0005니까. 더 조밀조밀하게 계산(?)\n    patience=3,\n    mode='auto', # 디폴트 값은 auto로 monitor 값에 따라서 'min', 'max' 지정됨\n    min_lr=1e-6\n)\n\nmc_cb = ModelCheckpoint(\n    filepath='efficientnetv2l_11091900.keras',  # 모델을 저장할 파일 경로\n    monitor='val_accuracy',       # 모니터링할 지표\n    save_best_only=True,          # 가장 성능이 좋은 모델만 저장\n    mode='max',                   # 'val_accuracy'가 최대일 때 저장\n    verbose=1                     # 저장 시 메시지 출력\n)\n\n# 파인 튜닝 모델 학습\nhistory_EfficientNetv2l = model.fit(train_generator,\n                    epochs=100,\n                    validation_data=validation_generator,\n                    callbacks=[es_cb, rlr_cb, mc_cb],\n                    verbose=1)","metadata":{"execution":{"iopub.status.busy":"2024-11-10T15:20:14.092349Z","iopub.execute_input":"2024-11-10T15:20:14.092669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 그래프 크기 설정\nplt.figure(figsize=(12, 5))\n\n# 첫 번째 subplot: Accuracy\nplt.subplot(1, 2, 1)\nplt.plot(history_EfficientNetv2l.history['accuracy'], label='Train Accuracy', color='r')\nplt.plot(history_EfficientNetv2l.history['val_accuracy'], label='Validation Accuracy', color='b')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.title('Model Accuracy')\nplt.legend(loc='lower right')\n\n# 두 번째 subplot: Loss\nplt.subplot(1, 2, 2)\nplt.plot(history_EfficientNetv2l.history['loss'], label='Train Loss', color='r')\nplt.plot(history_EfficientNetv2l.history['val_loss'], label='Validation Loss', color='b')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.title('Model Loss')\nplt.legend(loc='upper right')\n\n# 그래프 출력\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 캐글 제출 파일 생성","metadata":{}},{"cell_type":"code","source":"# 모델 로드\n# model = load_model('my_model.keras')\n\n# 예측 수행\npredictions = model.predict(test_generator, verbose=1)\n\n# 예측된 클래스 인덱스 추출\npredicted_classes = np.argmax(predictions, axis=1)\n\n# 클래스 레이블 정의\nclass_labels = ['airplane', 'automobile', 'bird', 'cat', 'deer',\n               'dog', 'frog', 'horse', 'ship', 'truck']\n\n# 예측된 클래스 인덱스를 레이블로 변환\npredicted_labels = [class_labels[index] for index in predicted_classes]\n\n# 테스트 제너레이터의 파일 이름 추출\nfilenames = test_generator.filenames\n\n# 파일 이름에서 필요한 부분만 추출\nfilenames = test_generator.filenames\nids = [f.split('/')[-1].replace('.png', '') for f in filenames]\n\n# DataFrame 생성\nsubmission_df = pd.DataFrame({\n    'id': ids,\n    'label': predicted_labels\n})\n\nsubmission_df.sort_values(by='id', inplace=True)\nsubmission_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-11-09T14:38:34.507078Z","iopub.status.idle":"2024-11-09T14:38:34.507436Z","shell.execute_reply.started":"2024-11-09T14:38:34.507259Z","shell.execute_reply":"2024-11-09T14:38:34.507278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 사전 학습된 다른 모델들 퍼포먼스 확인\n* https://paperswithcode.com/sota/image-classification-on-cifar-10?tag_filter=3,93\n* https://wikidocs.net/137252 (ResNet)","metadata":{}}]}