{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":5441,"databundleVersionId":38425}],"dockerImageVersionId":30042,"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":"2021-05-30T18:00:47.485998Z","iopub.execute_input":"2021-05-30T18:00:47.486581Z","iopub.status.idle":"2021-05-30T18:00:47.496103Z","shell.execute_reply.started":"2021-05-30T18:00:47.486531Z","shell.execute_reply":"2021-05-30T18:00:47.494711Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 상위 15.6%\n\n# 알집파일을 풀자 \n!unzip /kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip\n!unzip /kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2021-05-30T18:00:51.074148Z","iopub.execute_input":"2021-05-30T18:00:51.07475Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# PIL(파이썬 이미지 라이브러리)\nfrom PIL import Image\nImage.open('train/cat.10430.jpg').size","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Image.open('train/dog.10430.jpg').size","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# glob(파일들의 리스트를 뽑을 때 사용. 패턴을 그냥 * 라고 주면 모든 파일과 디렉터리를 볼 수 있어요)\n# *는 all 추출\nimport glob\nglob.glob('train/*')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 데이터프레임 만들기\n# dataframe이라는 단어 쓸 때 대/소문자 구분\ntrain = pd.DataFrame({'path': glob.glob('train/*')})\ntrain","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 나만의 함수\n# lambda(람다 표현식은 다음과 같이 lambda에 매개변수를 지정하고 :(콜론) 뒤에 반환값으로 사용할 식을 지정합니다)\n# lambda 함수는 사용자정의 함수를 문법에 맞추어 작성하는 것보다 훨씬 간단하게 한줄 정도로 해결할 수 있는 함수이다.\ntrain['label'] = train['path'].apply(lambda x: x.split('/')[1].split('.')[0])\ntrain","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# seed값 고정\n# Seed, 즉 난수 값을 설정하는 이유는 컴퓨터는 원래 복잡한 연산을 수행하는 것보다 난수를 만드는 것을 더 어려워 한다고 합니다.\n# 난수(Random Number)란 정의된 범위내에서 무작위로 추출된 수\nfrom sklearn.model_selection import train_test_split\n\n# 층화추출(통계학에서, 층화추출법(Stratified sampling)은 모집단을 먼저 중복되지 않도록 층으로 나눈 다음 \n# 각 층에서 표본을 추출하는 방법이다)\nx_train, x_valid = train_test_split(train, test_size = 0.2, random_state = 42, stratify = train['label'])\n\n# stratify(비율을 동일하게)\nx_valid['label'].value_counts()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 케라스에서 제공하는 이미지데이터\n# Imagedatagenerator: 이미지 데이터 생성\n# flow_from_dataframe(dataframe과 디렉토리의 위치를 전달받아 증강/정규화된 데이터의 배치를 생성합니다)\nfrom keras.preprocessing.image import ImageDataGenerator\nidg = ImageDataGenerator()\nidg2 = ImageDataGenerator()\n\n# target_size? 모든 이미지의 사이즈를 동일하게, 시간 단축을 위해(나중에 다시 키워줘야 한다)\n# batch_size: 몇 개의 샘플로 가중치를 갱신할 것인지 지정, epochs: 학습 반복 횟수\ntrain_generator = idg.flow_from_dataframe(x_train, x_col = 'path', y_col = 'label', target_size = (100,100), batch_size = 256)\ntrain_generator\nvalid_generator = idg2.flow_from_dataframe(x_valid, x_col = 'path', y_col = 'label', target_size = (100,100), batch_size = 256)\nvalid_generator","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 딥러닝 구조(입력층-은닉층-출력층)\n# keras: 파이썬으로 작성된 오픈소스 신경망 라이브러리이다.\n# Conv2D 구글이미지 검색\n# Conv2D\n# Flatten\n# Dense(n)(노드의 갯수가 n이다)\n# softmax(Logistic function을 일반화한 것. n개의 요소를 갖는 확률 벡터에서 각 요소의 값이 0~1 사이이고 전체의 합이 1이다)\n# adam(방향성+스텝사이즈)\n# categorical_crossentropy\nfrom keras import *\nfrom keras.layers import *\nfrom tensorflow.keras.applications.efficientnet import EfficientNetB0\n\nmodel = Sequential()\n# EfficientNetB0(1년 전에 나온 딥러닝 모델)\n# include_top? 네트워크의 최상단에 완전 연결 레이어를 넣을지 여부\nmodel.add(EfficientNetB0(weights = 'imagenet', include_top = False, pooling = 'avg'))\nmodel.add(Dense(2, activation = 'softmax'))\n\n# Activation function: linear, sigmoid(= logistic), softmax, hyper tagen, relu\n# Loss(cost function): loss는 손실함수를 의미합니다. 얼마나 입력데이터가 출력데이터와 일치하는지 평가해주는 함수를 의미합니다.\n# 예시로는 mean squared error(연속형 변수를 예측할 때 사용), cross entropy(범주형 변수를 예측할 때 사용)가 있습니다.\n# Optimizer: optimizer는 손실 함수를 기반으로 네트워크가 어떻게 업데이트될지 결정합니다.\n# 예시로는 gradient descent, momentum, adagrad, RMSprop, adadelta, adam(최근 딥러닝에서 많이 사용)가 있습니다.\n\n\n# 모델 점수를 개선하자!!(Max-pooling, 학습을 많이 시키기)\n\n# # 모델 구성(층을 여러 겹 쌓자)\n# model = Sequential()\n# # 32가지 특징을 추출하겠다. Relu는 비선형적 함수 학습 가능. shape(R,G,B)\n# model.add(Conv2D(32,(3,3), activation = 'relu', input_shape = (100,100,3)))\n# # Max-pooling 구글 이미지 검색(pooling의 정의: the act of sharing or combining two or more things)\n# # Average-pooling도 있다.\n# model.add(MaxPool2D())\n# # 3차원을 1차원으로 만들기 위하여\n# model.add(Flatten())\n# # 정답 클래스가 2개. 확률값이므로 Softmax(맨 마지막층에서만 활용하는 활성화 함수)\n# model.add(Dense(2, activation = 'softmax'))\n\n# 모델 학습설정(Compile(구성))\n# 항상 손실함수는 'categorical_crossentropy'\n# 학습을 3번 시키겠다.\nmodel.compile(metrics = ['acc'], optimizer = 'adam', loss = 'categorical_crossentropy')\nmodel.fit(train_generator, epochs = 3, validation_data = valid_generator)\n\n# 모델 구성을 보고 싶다.\nmodel.summary()\n\n## 실행하는 데 시간이 오래 걸린다(8분에서 1분20초)\n# 계산기를 여러 개 쓰겠다(CPU 대신 GPU)\n## 성능을 향상시키겠다\n# Max-pooling 삽입, epoch 늘리기","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 코드 안 보고 치는 연습\n# Redux(오픈소스 Javascript 라이브러리)\n\n# 예측(이제 test데이터를 삽입해서 예측해보자)\ntest = pd.DataFrame({'path': glob.glob('test/*')})\ntest","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Shift + tab(속성(signature)을 볼 수 있다)\n# test 이미지 데이터 생성(정답 값은 없어야 하므로 none, 검증할 때는 데이터가 섞이지 않게 shuffle을 none으로 지정)\n# 이미지 분류할 때만!\n# Why 'shuffle = False'?\ntest_generator = idg.flow_from_dataframe(test, x_col = 'path', y_col = None, class_mode = None, shuffle = False) \ntest_generator","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# verbose는 시간이 얼마나 걸리는 지를 알게 해준다.(ETA: A(s)) 상세한 로깅을 출력할 지 말 지를 조정하는 parameter\n# 1(True)\nresult = model.predict(test_generator, verbose = 1)\nresult","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# [고양이일 확률, 강아지일 확률]\n# 9.17e-01 = 0.917 = 91.7%\n\n# 12500행 X 2열\n# list와 tuple 모두 여러 데이터를 담을 수 있는 컨테이너형 변수(Ex) [1,2,3,4])\nresult.shape","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# indices는 클래스의 위치(열) 알려준다.(고양이는 1열, 강아지는 2열)\n# 주로 오른쪽 열에 중요한 클래스가 위치한다. 그러므로 오른쪽 열을 가지고 와서 제출한다.\ntrain_generator.class_indices","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 오른쪽 열의 결과(확률) 값\ntest['result'] = result[:,1]\ntest","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 우리 모델 성능 확인(test 데이터로)\nImage.open('test/9055.jpg')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub = pd.read_csv('/kaggle/input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv')\nsub","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub['label'] = result[:,1]\nsub['id'] = test['path'].apply(lambda x: x.split('/')[1].split('.')[0])\nsub","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub.to_csv('redux2.csv',index = 0)\n\n# 205/1314 (등수)","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}