{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":77476,"databundleVersionId":8462666,"sourceType":"competition"}],"dockerImageVersionId":30698,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-05-15T18:32:15.225528Z","iopub.execute_input":"2024-05-15T18:32:15.225977Z","iopub.status.idle":"2024-05-15T18:32:15.235059Z","shell.execute_reply.started":"2024-05-15T18:32:15.225941Z","shell.execute_reply":"2024-05-15T18:32:15.233755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"캐글 덕분에 밤샘에 적응을 해버린 건에 대하여\n==========================================\n앞선 두 데이터와는 다르게, 이번 데이터는 이미지형 데이터라 기존에 쓰던 방식과는 많이 다를 것으로 예상됩니다.    \n원래는 저희가 할 데이터셋이 Flowers Recognition인줄 알았는데, 5월 6일 기준 갑자기 이걸로 바뀌었더라구요... 무슨일인가 물어보니 너무 빡세서 쉬운걸로 바꿨다네요.    \n    \n여튼 이미지 데이터에 대해 MT때 승원이형의 조언 '이미지 데이터를 csv처럼 만들면 된다'를 방향성으로 잡고 최대한 해보겠습니다.    \n목차는 언제나 그렇듯 다음과 같습니다.    \n\n0. 문제 소개\n1. 데이터 분석 및 전처리1\n2. 시각화(EDA)/PCA\n3. 모델링\n4. 제출\n5. 잡소리","metadata":{}},{"cell_type":"code","source":"import numpy as n\nimport pandas as p\nimport seaborn as s\nimport matplotlib as m\nimport matplotlib.pyplot as pp\n\nsample=p.read_csv('/kaggle/input/2024-smarcle-ks-3-fashion-mnist2/sample_submission.csv')\ntest=p.read_csv(\"/kaggle/input/2024-smarcle-ks-3-fashion-mnist2/test.csv\")\ntrain=p.read_csv(\"/kaggle/input/2024-smarcle-ks-3-fashion-mnist2/train.csv\")\n\npp.style.use(\"ggplot\")\n\nprint(\"Setup finish\")","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:15.238648Z","iopub.execute_input":"2024-05-15T18:32:15.239910Z","iopub.status.idle":"2024-05-15T18:32:21.842353Z","shell.execute_reply.started":"2024-05-15T18:32:15.239872Z","shell.execute_reply":"2024-05-15T18:32:21.841078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"엥 왜 파일이 csv지    \n시작도 전에 한시름 놓았네요. 분석 시작!    \n# 0. 문제 소개\n이번 문제는 MNIST 문제로, 몇가지 종류로 구분할 수 있는 28x28 크기의 흑백 이미지들을 분류하는 컴퓨터비전 문제다.    \n문제에 대한 구체적 정보는 깃허브에서 얻을 수 있다. 들어가보면 알겠지만, 이 데이터는 총 10종류의 의류 데이터를 0-9로 레이블을 붙여놓은 데이터로, 그 0~9가 각각 뭐냐 하면,    \n0. T-shirt/top\n1. rouser\n2. Pullover\n3. Dress\n4. Coat\n5. Sandal\n6. Shirt\n7. Sneaker\n8. Bag\n9. Ankle boot    \n    \n대충 이렇다. 원본 MNIST 문제가 숫자 그림을 인식시키는 거란 사실을 감안하면, 0~9의 숫자를 의류로 그대로 대체한 셈이다.    \n따라서 저 csv 파일은 28x28의 이미지의 각 픽셀이 담겨있는 상태라고 보면 편하다.    \n자, 시작하자.","metadata":{}},{"cell_type":"markdown","source":"# 1. 데이터 분석 및 전처리1\n이 csv 파일을 대충 한번 보면 컬럼이 785개가 나온다. 왜 이런 괴랄한 물건이 나왔냐면, 하나는 레이블이고, 다른 784개는 28x28 사이즈의 흑백 이미지의 각 픽셀을 하나하나 숫자로 바꿔서 넣어버린 물건이라 그렇다...    \ntrain 데이터를 보면, 컬럼 중 label 컬럼이 있는데 이게 바로 우리가 최종적으로 구해야 할 답이다. 이걸 이용해 test에서도 적절한 답을 낼 수 있도록 만들어주면 된다.     \n아마도 CNN을 사용하게 될 것 같다. ","metadata":{}},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:21.844346Z","iopub.execute_input":"2024-05-15T18:32:21.844697Z","iopub.status.idle":"2024-05-15T18:32:21.866372Z","shell.execute_reply.started":"2024-05-15T18:32:21.844667Z","shell.execute_reply":"2024-05-15T18:32:21.865159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.info()","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:21.868034Z","iopub.execute_input":"2024-05-15T18:32:21.868511Z","iopub.status.idle":"2024-05-15T18:32:21.918221Z","shell.execute_reply.started":"2024-05-15T18:32:21.868471Z","shell.execute_reply":"2024-05-15T18:32:21.916934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"...? 이전과 다르게 구체적인 컬럼 정보가 나오지 않는다.","metadata":{}},{"cell_type":"code","source":"train.shape","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:21.920934Z","iopub.execute_input":"2024-05-15T18:32:21.921456Z","iopub.status.idle":"2024-05-15T18:32:21.929919Z","shell.execute_reply.started":"2024-05-15T18:32:21.921420Z","shell.execute_reply":"2024-05-15T18:32:21.928526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.describe()","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:21.931321Z","iopub.execute_input":"2024-05-15T18:32:21.931694Z","iopub.status.idle":"2024-05-15T18:32:24.675343Z","shell.execute_reply.started":"2024-05-15T18:32:21.931651Z","shell.execute_reply":"2024-05-15T18:32:24.674441Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"일단 컬럼이 28x28개라 모든 데이터가 바로 보이진 않고, 다행히도 결측값도 확인되지 않는다.    \n그래서, 우리는 저 10개의 레이블 별로 몇개씩 들어가있는지, 그리고 각각 어떤 식의 이미지인지 분류를 할 것이다.    \n바로 아래 코드는 train 데이터를 사진부분과 레이블 부분의 넘파이 배열로 나누는 코드다.     \ntest의 경우 레이블이 없으니 바로 넘파이 배열로 바꿀 수 있다.","metadata":{}},{"cell_type":"code","source":"train_img=train.drop(['label'], axis=1).values\ntrain_lbl=train['label'].values\ntrain_lb=train['label']\n\ntest_img=test.values\n\nprint(\"divided\")","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:24.676868Z","iopub.execute_input":"2024-05-15T18:32:24.677265Z","iopub.status.idle":"2024-05-15T18:32:24.802743Z","shell.execute_reply.started":"2024-05-15T18:32:24.677231Z","shell.execute_reply":"2024-05-15T18:32:24.801533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_img.shape","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:24.805267Z","iopub.execute_input":"2024-05-15T18:32:24.805781Z","iopub.status.idle":"2024-05-15T18:32:24.813699Z","shell.execute_reply.started":"2024-05-15T18:32:24.805728Z","shell.execute_reply":"2024-05-15T18:32:24.812272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_lb.shape","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:24.815444Z","iopub.execute_input":"2024-05-15T18:32:24.815901Z","iopub.status.idle":"2024-05-15T18:32:24.824550Z","shell.execute_reply.started":"2024-05-15T18:32:24.815861Z","shell.execute_reply":"2024-05-15T18:32:24.823404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"이제 이미지 형식으로 바꿀거니까 784개 일렬 나열 형식에서 28x28 꼴로 만들어주자.","metadata":{}},{"cell_type":"code","source":"train_img=train_img.reshape(-1, 28, 28)\ntest_img=test_img.reshape(-1, 28, 28)\nprint(train_img.shape, test_img.shape)","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:24.825838Z","iopub.execute_input":"2024-05-15T18:32:24.826287Z","iopub.status.idle":"2024-05-15T18:32:24.834077Z","shell.execute_reply.started":"2024-05-15T18:32:24.826238Z","shell.execute_reply":"2024-05-15T18:32:24.832811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"잘 바뀌었다. 굿.    \n이제 이걸로 이미지를 만들어보자.     \n# 2. 시각화 / PCA\npyplot에 들어있는 코드 .imshow는 2차원 데이터를 각 픽셀에 맞는 색으로 색칠해줘서 하나의 이미지로 만들어준다. 이때 사용되는 2차원 데이터가 넘파이 배열이기 때문에 반드시 넘파이 배열로 바꿔줘야 사용이 가능하다.","metadata":{}},{"cell_type":"code","source":"pp.imshow(train_img[0], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:24.839038Z","iopub.execute_input":"2024-05-15T18:32:24.839417Z","iopub.status.idle":"2024-05-15T18:32:25.132409Z","shell.execute_reply.started":"2024-05-15T18:32:24.839386Z","shell.execute_reply":"2024-05-15T18:32:25.130990Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"나름 잘 나온다. 이제 이게 0~9가 각각 어떻게 나오는지 한번 보자.    \n","metadata":{}},{"cell_type":"code","source":"pick=[0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000, 6500, 7000, 7500, 8000, 8500, 9000, 9500]\nk=0\nfor i in pick:\n    pp.subplot(4,5,k+1)\n    pp.imshow(train_img[i], cmap='gray')\n    pp.title(train_lbl[i])\n    k+=1\n    \npp.tight_layout()\npp.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:25.134090Z","iopub.execute_input":"2024-05-15T18:32:25.134490Z","iopub.status.idle":"2024-05-15T18:32:28.302064Z","shell.execute_reply.started":"2024-05-15T18:32:25.134457Z","shell.execute_reply":"2024-05-15T18:32:28.300888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"5번이 없지만, 어쨌거나 잘 나온다. ","metadata":{}},{"cell_type":"code","source":"train_img2=train_img.reshape(60000, -1)\ntest_img2=test_img.reshape(10000, -1)\nprint(train_img2.shape, test_img2.shape)\n\nprint(train_img2[0])","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:28.303835Z","iopub.execute_input":"2024-05-15T18:32:28.304332Z","iopub.status.idle":"2024-05-15T18:32:28.316766Z","shell.execute_reply.started":"2024-05-15T18:32:28.304286Z","shell.execute_reply":"2024-05-15T18:32:28.315298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_img2=train_img2.astype('float64')\ntest_img2=test_img2.astype('float64')\ntrain_img2/=255\ntest_img2/=255\n\nprint(train_img2[0])","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:28.318235Z","iopub.execute_input":"2024-05-15T18:32:28.318630Z","iopub.status.idle":"2024-05-15T18:32:28.528804Z","shell.execute_reply.started":"2024-05-15T18:32:28.318599Z","shell.execute_reply":"2024-05-15T18:32:28.527398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"아까 그 티셔츠를 저렇게 나타내보았다.    \n이제 내부 값은 0~1인 상태가 되어, 활용이 좀 더 쉬워졌다.     \n    \n이제부터 할 건 PCA라는 거다. 주성분 분석의 줄임말인데, 데이터가 가진 고유의 특징을 가능한 유지시키면서도 데이터의 차원을 줄여주는 작업이다.    \n즉 세세한 부분보다는 큰 특징만 남기고 간단하게 만든다는 소리.    \n아까 내부 값을 스케일링을 통해 0~1 범위로 맞춘 것도 이걸 하기 위한 밑작업이라고 보면 된다.    \n","metadata":{}},{"cell_type":"code","source":"from sklearn.decomposition import PCA\n\npca=PCA(n_components=0.95)\n\ntrain_img3=pca.fit_transform(train_img2)\n\nprint(train_img3.shape)","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:28.530321Z","iopub.execute_input":"2024-05-15T18:32:28.530818Z","iopub.status.idle":"2024-05-15T18:32:35.951543Z","shell.execute_reply.started":"2024-05-15T18:32:28.530785Z","shell.execute_reply":"2024-05-15T18:32:35.950144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"784에서 187 정도로 사이즈가 줄어들었다.    \n","metadata":{}},{"cell_type":"code","source":"lbls=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\n\npp.figure(figsize=(8, 6))\nscat=pp.scatter(train_img3[:, 0], train_img3[:, 1], c=train_lbl, cmap='inferno')\npp.legend(handles=scat.legend_elements()[0], labels=[lbls[i] for i in n.unique(train_lbl)])#범례 추가\npp.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:35.953524Z","iopub.execute_input":"2024-05-15T18:32:35.954090Z","iopub.status.idle":"2024-05-15T18:32:40.617489Z","shell.execute_reply.started":"2024-05-15T18:32:35.954044Z","shell.execute_reply":"2024-05-15T18:32:40.616273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"대충 이렇게 분포한 것 같다.    \n모델링 시작","metadata":{}},{"cell_type":"markdown","source":"# 3. 모델링    \n이제 실제로 CNN을 써볼 차례다.    \n내가 써볼 수 있는 CNN 사용 방법은 생각보다 많았다. 지난번 모딥 스터디 교재에 나온 방법을 그대로 이용해도 되고, 아니면 최유경 교수님 강의 영상을 보고 따라해도 된다. 추가적으로 용빈이형이 CNN 모델 4가지 정도를 추가적으로 알려주셨는데, 각각 Alexnet, VGG, GoogLeNet, Resnet이다.    \n이 4가지 중에선 개인적으로 VGG가 깊이를 증가시켜 성능을 향상시킨다는 점에서 제일 끌렸던지라 이걸 좀 써볼까 했는데, 이게 크기도 커야 하는데다 시간도 쓸데없이 오래 잡아먹는대서, 무엇보다도 이런 간단한 문제는 오히려 층이 많은게 독이 될수도 있다고 하니 때려치우고 그냥 제미나이 따라하기로 했다.","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ntrain_img2=train_img2.reshape(60000, 28, 28, 1)\ntest_img2=test_img2.reshape(10000, 28, 28, 1)\nprint(train_img2.shape)\n\ntrainx, train0x, trainy, train0y = train_test_split(train_img2, train_lb, test_size = 0.2, random_state = 1234)\nprint(trainx.shape, train0x.shape, trainy.shape, train0y.shape)","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:40.619180Z","iopub.execute_input":"2024-05-15T18:32:40.620037Z","iopub.status.idle":"2024-05-15T18:32:41.231930Z","shell.execute_reply.started":"2024-05-15T18:32:40.619983Z","shell.execute_reply":"2024-05-15T18:32:41.230520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"일단 기존에 내가 가진 데이터를 또 학습용/테스트용으로 쪼개주었다. 여기서 레이블 부분 형태 잘못 설정해서 아래쪽 오류 왜 났는지 몇시간 동안 계속 헤메고 있다가 새벽 3시에 겨우 발견.    \n아래 2개 모델 중 위쪽은 인터넷 코드를, 아래쪽은 제미나이를 참고해본 것이다. 용빈이형이 소개해준 모델 4개 같은 경우는 확실히 알아두면 좋을거 같긴 한데, 위에서 말했듯이 오늘 굳이 필요하진 않을 것 같다.","metadata":{}},{"cell_type":"code","source":"# import tensorflow as t\n# # 베이스라인 모델로 성능 검정을 위해 임의로 만들어보는 CNN모델\n# # Conv, Pooling 레이어를 추가한 후 Dense 레이어가 들어간 일반적인 모델\n\n# model1 = t.keras.models.Sequential([\n#     t.keras.layers.Conv2D(input_shape=(28, 28, 1), kernel_size=3, filters=64),\n#     t.keras.layers.MaxPool2D(pool_size=(2,2), strides=(1,1)),\n#     t.keras.layers.Conv2D(input_shape=(28, 28, 1), kernel_size=3, filters=32),\n#     t.keras.layers.MaxPool2D(pool_size=(2,2), strides=(1,1)),\n#     t.keras.layers.Flatten(),\n\n#     t.keras.layers.Dense(64, activation='relu'),\n#     t.keras.layers.Dropout(0.2),\n#     t.keras.layers.Dense(32, activation='relu'),\n#     t.keras.layers.Dropout(0.2),\n#     t.keras.layers.Dense(10, activation='softmax'),\n# ])\n\n# # 옵티마이저(optimizer)와 손실함수(loss)를 설정하고 정확도 매트릭스가 나오게 컴파일\n# # optimizer -> 'adam'\n# # loss -> sparse_categorical_crossentropy\n\n# model1.compile(optimizer='adam',\n#               loss='sparse_categorical_crossentropy',\n#               metrics=['accuracy'])\n         \n# # 모델의 모습을 표로 출력\n# model1.summary()\n\n# # 위의 레이어를 가진 모델로 5번 학습시킴\n# print(model1.fit(trainx, trainy, epochs=5))\n\n# # 검증을 해봄\n# print(model1.evaluate(train0x, train0y))","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:41.233819Z","iopub.execute_input":"2024-05-15T18:32:41.234801Z","iopub.status.idle":"2024-05-15T18:32:41.242407Z","shell.execute_reply.started":"2024-05-15T18:32:41.234755Z","shell.execute_reply":"2024-05-15T18:32:41.240811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as t\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\nfrom tensorflow.keras.utils import to_categorical\n\ntrainy = to_categorical(trainy)\ntrain0y = to_categorical(train0y)\n\n# CNN 모델 구성\nmodel = Sequential([\n    Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),\n    MaxPooling2D((2, 2)),\n    Conv2D(64, (3, 3), activation='relu'),\n    MaxPooling2D((2, 2)),\n    Flatten(),\n    Dense(128, activation='relu'),\n    Dropout(0.5),  # 과적합 방지\n    Dense(10, activation='softmax')\n])\n\n# 모델 컴파일\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n\n# 모델 학습\nhistory = model.fit(trainx, trainy, epochs=12, validation_data=(train0x, train0y))\n\n# 모델 평가\ntest_loss, test_acc = model.evaluate(train0x, train0y)\nprint('Test accuracy:', test_acc)\n\n# 학습 결과 시각화 (정확도)\npp.plot(history.history['accuracy'], label='accuracy')\npp.plot(history.history['val_accuracy'], label='val_accuracy')\npp.xlabel('Epoch')\npp.ylabel('Accuracy')\npp.legend(loc='lower right')\npp.show()\n\n# 학습 결과 시각화 (손실)\npp.plot(history.history['loss'], label='loss')\npp.plot(history.history['val_loss'], label='val_loss')\npp.xlabel('Epoch')\npp.ylabel('Loss')\npp.legend(loc='upper right')\npp.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-15T18:32:41.244180Z","iopub.execute_input":"2024-05-15T18:32:41.244670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"오...아래쪽이 더 정확도가 높다. 10번 학습 시켜서 그런걸수도 있다.     \n10번 학습 시켰을 때 0.9154 정도에서 머무르는 걸 보니 대충 12~15번 정도 하면 넉넉하게 잘 될 것 같다는 생각이 든다.","metadata":{}},{"cell_type":"code","source":"sample.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 4. 제출    \n이제 사전에 스케일링을 끝마친 test_img2를 돌리고 끝내자.","metadata":{}},{"cell_type":"code","source":"pred = model.predict(test_img2)\npred","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_data = n.argmax(pred, axis=1)\n\nprint(pred_data)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"이거면 됐다. sample에 넣고 끝내자.","metadata":{}},{"cell_type":"code","source":"sample['label']=pred_data\nsample.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample.to_csv(\"submission.csv\", index=False)\nprint(\"GG\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 5. 잡소리\n일단 나만 그런지는 모르겠는데, CNN 자체가 학습이 좀 오래 돌아간다. 아무래도 이미지 데이터를 다루다보니, 처리할 정보량이 좀 많아져서 그런 것 같기도 하다. 단순 컬럼 수로만 봤을 때도 이쪽은 지난번 집값 예측과는 자릿수부터가 다르니까.     \nCNN은 기본적으로 4차원으로 입력받는다. 각각 개수, x, y, 층? 을 의미하는 것 같다. 그리고 뭐...모딥때 배운 대로 이미지 사이즈를 줄이고 줄이고 줄여서 결국 하나의 값으로 나오게 하는...뭐 이런 원리다.    \n결국 이번에도 밤샜다. 왜 캐글만 하면 하루가 날아가는지 모르겠다. 내가 봤을 때 아직 나는 캐글 방식을 이해했다고 보긴 힘든 것 같다. 그래도 전반적인 흐름 자체는 느껴지고, 각각의 코드에 대해 해설도 가능한 레벨까지는...온 것 같으니까 방학 때까지도 계속해서 좀 써보자.    \n목요일 발표다. 원래는 다음주 캐글까지 해서 보여주려고 했는데, 시간상 힘들 것 같다. 방향성을 바꿔서 시계열 데이터 문제 몇개 이용한 시계열 데이터의 특징 소개와 RNN, LLM 소개 정도만 하고 끝내야겠다.     \n    \n그래서 제 점수는요...0.9176","metadata":{}}]}