{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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 in \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 \"../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 \n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd\nImage_width,Image_height = 400,400\nbatch_size=16\nval_split=0.01\nn_train=25000*(1-val_split)\nn_val=25000*val_split\n\ntrain = pd.DataFrame({\"name\" :os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/train\"), \n                      \"path\" :pd.Series(os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/train\")).apply(lambda x : \"../input/dogs-vs-cats-redux-kernels-edition/train/\" + str(x)), \n                      \"label\" :pd.Series(os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/train\")).apply(lambda x : str(x).split(\".\")[0])})\n\ntest = pd.DataFrame({\"name\" :os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/test\"), \n                      \"path\" :pd.Series(os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/test\")).apply(lambda x : \"../input/dogs-vs-cats-redux-kernels-edition/test/\" + str(x)), \n                     })\nfrom keras.preprocessing.image import ImageDataGenerator\ntrain_image_gen = ImageDataGenerator(rescale=1/255, horizontal_flip=True, validation_split=val_split)\n\ntrain_generator = train_image_gen.flow_from_dataframe(dataframe = train, x_col = \"path\", y_col =\"label\",\n                                                      target_size=(Image_width,Image_height), batch_size=batch_size,seed=19,subset='training',shuffle=True,class_mode='categorical')\nval_generator = train_image_gen.flow_from_dataframe(dataframe = train, x_col = \"path\", y_col =\"label\",\n                                                    target_size=(Image_width,Image_height), batch_size=batch_size,seed=19,subset='validation',shuffle=True,class_mode='categorical')\n\nfrom keras.optimizers import SGD\nfrom keras.layers import Dense, Dropout\nfrom keras.applications.inception_v3 import InceptionV3\nfrom keras.applications.inception_resnet_v2 import InceptionResNetV2\nfrom keras.models import Model\nInceptionV3_base_model = InceptionResNetV2(weights='imagenet', include_top=False, pooling = \"avg\") \n\nx = InceptionV3_base_model.output\nx_dense = Dense(1024,activation='relu')(x)\nfinal_pred = Dense(2,activation='softmax')(x_dense)\nmodel = Model(inputs=InceptionV3_base_model.input, outputs=final_pred)\n\nfrom keras.callbacks import ModelCheckpoint\ncb_checkpoint = ModelCheckpoint('best.hd5', monitor = 'val_loss', save_best_only = True)\n\nfrom keras.optimizers import Adam\nfrom keras.clallbacks import ReDuceLRnplateau  #러닝레이트가 너무 큰 경우, 섬세한 튜닝할 경우, 최적의 순간에 맴돌 때 성능 높일 수 있음\n\n# 1.파라미터 조정\n#(일반적으로 300층 정도 쌓여 있다고 할때, 가중치를 수정하고 업데이트할 때 \n#이미지데이터y를 잘 예측하는 그러한 가중치를 찾아 나가는 과정이 딥러닝 모델이 학습하는 방향이다.\n#이미지넷에서 가중치를 가져와서 학습을 시작하는데, 처음 층 부터 ~150층까지는 직선, 명암 등의 물체와 나눠지는 배경정보를 학습하기 때문에\n#이미지넷에서 쓰는걸 그대로 가져오고 임의로 바꿔주지 않는다.ex 고양이 강아지 모델 나누는 가장 중요한 피쳐를 찾아서 알아서 구분해준다.)\n# 앞에서는 고정해주고 뒤에서는 고정해주지 않는다. fine 튜닝, 172라는 숫자는 어떻게 나온건가? 테스트해보기, \n# and, 레이어층들이 어떤 부분에 초점을 맞춰 학습하는지 확인할 수 있는 코드가 있다.(어떤 픽셀에 맞춰서)\n#conv레이어들이 뒤로 갈 수록 추상적인 내용 학습. \n# 2. 러닝레이트 조정\n#adam optimizer의 러닝레이트 0.001 너무 크다. 러닝 레이트 조절옵션\n#reduce튜닝,  val 로스가 낮을 수족 점수가 높아짐. \n#ss\n\nlayer_to_Freeze=172 \nfor layer in model.layers[:layer_to_Freeze]:\n    layer.trainable =False\nfor layer in model.layers[layer_to_Freeze:]:\n    layer.trainable=True\n\nsgd = SGD(lr = 0.01, decay = 1e-6, momentum = 0.9, nesterov = True)\nmodel.compile(optimizer=Adam(Ir=0.001,decay=1e-6), loss='categorical_crossentropy',metrics=['accuracy'])\n\n\n#몇 번 참아줄거냐(reduce 관련)\nreduceelr= ReduceLROnPl(patience=4,factor=0.1)\n#에폭에 비해 patience는 반이다.에폭 결정이 어려울 경우 - 로스가 클 경우에는 페이션스 크게, 로스가 작으면 페이션스 작게한다.\n#러닝레이트를 얼마나 낮출거냐 하는 옵션=factor, \n\n#val 가 가장 중요하다. 평가셋에서 잘 나와야 우리가 값을 잘 알 수 있다. 새로운 데이터에서 데이터가 잘 나와야 (val los는 새로운 데이터에서 당연히 로스가 안나온다)\n\n\nmodel.fit_generator(train_generator, epochs=3,\n                                                steps_per_epoch=n_train//batch_size,\n                                                validation_data=val_generator,\n                                                validation_steps=n_val//batch_size,\n                                                verbose=1,\n                                                callbacks=[reducelr],)\n#earlystopping은 자동으로 과접합일어나기 전에 멈춘다. 그래서 patient 옵션을 써줘야한다. \n#성능이 오르지 않아도 참아주는게 필요함.이거는 reduc 보다 1,2정도 더 크다 \n#modelchekpoint -> 최적의 상태를 저장할 수 있다(vel가 최적일 때마다 저장, 갱신함. 옵션 2개(파일패스 넣어주기, best_model.h5, save_best_only)\n#callbacks에 반드시 옵션을 넣어줘야함\n#예측하기 전에 하나가 빠졌다. 코드가 하나 더 들어가야함\n\nmodel.load_weights('best.hd5')\n\ntest_image_gen = ImageDataGenerator(rescale=1/255)\ntest_generator = test_image_gen.flow_from_dataframe(dataframe = test, x_col = \"path\", y_col = None,\n                                                    target_size=(Image_width,Image_height), batch_size=batch_size, seed=42, class_mode=None, shuffle=False)\n\nmodel.load.weights(\"best_model.h5\") # 저장한 가중치를 가져와야된다. \ny_pred = model.predict_generator(generator=test_generator, steps=int(np.ceil(len(test)/batch_size)), workers = 2, verbose=1)\n\nsubmission = pd.DataFrame({'id':pd.Series(test_generator.filenames),'label':pd.Series(y_pred.clip(min=0.005, max=0.995)[:,1])})\nsubmission[\"id\"] = submission[\"id\"].apply(lambda x: str(x).split(\"/\")[-1].split(\".\")[0])\nsubmission.to_csv('DogVsCats_submission.csv',index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"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 in \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 \"../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\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.\n\nimport numpy as np # linear algebra\nimport pandas as pd\nImage_width,Image_height = 400,400\nbatch_size=16\nval_split=0.01\nn_train=25000*(1-val_split)\nn_val=25000*val_split\n\ntrain = pd.DataFrame({\"name\" :os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/train\"), \n                      \"path\" :pd.Series(os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/train\")).apply(lambda x : \"../input/dogs-vs-cats-redux-kernels-edition/train/\" + str(x)), \n                      \"label\" :pd.Series(os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/train\")).apply(lambda x : str(x).split(\".\")[0])})\n\ntest = pd.DataFrame({\"name\" :os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/test\"), \n                      \"path\" :pd.Series(os.listdir(\"../input/dogs-vs-cats-redux-kernels-edition/test\")).apply(lambda x : \"../input/dogs-vs-cats-redux-kernels-edition/test/\" + str(x)), \n                     })\nfrom keras.preprocessing.image import ImageDataGenerator\ntrain_image_gen = ImageDataGenerator(rescale=1/255, horizontal_flip=True, validation_split=val_split)\n\ntrain_generator = train_image_gen.flow_from_dataframe(dataframe = train, x_col = \"path\", y_col =\"label\",\n                                                      target_size=(Image_width,Image_height), batch_size=batch_size,seed=19,subset='training',shuffle=True,class_mode='categorical')\nval_generator = train_image_gen.flow_from_dataframe(dataframe = train, x_col = \"path\", y_col =\"label\",\n                                                    target_size=(Image_width,Image_height), batch_size=batch_size,seed=19,subset='validation',shuffle=True,class_mode='categorical')\n\nfrom keras.optimizers import SGD\nfrom keras.layers import Dense, Dropout\nfrom keras.applications.inception_v3 import InceptionV3\nfrom keras.applications.inception_resnet_v2 import InceptionResNetV2\nfrom keras.models import Model\nInceptionV3_base_model = InceptionResNetV2(weights='imagenet', include_top=False, pooling = \"avg\") \n\nx = InceptionV3_base_model.output\nx_dense = Dense(1024,activation='relu')(x)\nfinal_pred = Dense(2,activation='softmax')(x_dense)\nmodel = Model(inputs=InceptionV3_base_model.input, outputs=final_pred)\n\nfrom keras.callbacks import ModelCheckpoint\ncb_checkpoint = ModelCheckpoint('best.hd5', monitor = 'val_loss', save_best_only = True)\n\nlayer_to_Freeze=172 \nfor layer in model.layers[:layer_to_Freeze]:\n    layer.trainable =False\nfor layer in model.layers[layer_to_Freeze:]:\n    layer.trainable=True\n\nsgd = SGD(lr = 0.01, decay = 1e-6, momentum = 0.9, nesterov = True)\nmodel.compile(optimizer=sgd, loss='categorical_crossentropy',metrics=['accuracy'])\n\nmodel.fit_generator(train_generator, epochs=3,\n                                                steps_per_epoch=n_train//batch_size,\n                                                validation_data=val_generator,\n                                                validation_steps=n_val//batch_size,\n                                                verbose=1,\n                                                callbacks=[cb_checkpoint],)\n\n\n\nmodel.load_weights('best.hd5')\n\ntest_image_gen = ImageDataGenerator(rescale=1/255)\ntest_generator = test_image_gen.flow_from_dataframe(dataframe = test, x_col = \"path\", y_col = None,\n                                                    target_size=(Image_width,Image_height), batch_size=batch_size, seed=42, class_mode=None, shuffle=False)\n\ny_pred = model.predict_generator(generator=test_generator, steps=int(np.ceil(len(test)/batch_size)), workers = 2, verbose=1)\n\nsubmission = pd.DataFrame({'id':pd.Series(test_generator.filenames),'label':pd.Series(y_pred.clip(min=0.005, max=0.995)[:,1])})\nsubmission[\"id\"] = submission[\"id\"].apply(lambda x: str(x).split(\"/\")[-1].split(\".\")[0])\nsubmission.to_csv('DogVsCats_submission.csv',index=False)\n\nbatch_size = 50\n\ntrain_path = \"../input/dogs-vs-cats-redux-kernels-edition/train/\"\ntrain = pd.Series(os.listdir(train_path))\ntrain = pd.DataFrame({\"path\" : train.apply(lambda x : train_path + x),\n                      \"label\" : train.apply(lambda x : x.split(\"train/\")[-1][:3])})\n\ntest_path = \"../input/dogs-vs-cats-redux-kernels-edition/test/\"\ntest = pd.Series(os.listdir(test_path))\ntest = pd.DataFrame({\"path\" : test.apply(lambda x : test_path + x)})\n\ntrain.head()\n\nfrom keras.preprocessing.image import ImageDataGenerator\ntrain_gen = ImageDataGenerator(validation_split=0.2)\n\ntrain_generator = train_gen.flow_from_dataframe(train,\n                                                x_col=\"path\",\n                                                y_col=\"label\",\n                                                batch_size=batch_size,\n                                                target_size=(299, 299),\n                                                subset=\"training\")\n\nval_generator = train_gen.flow_from_dataframe(train,\n                                              x_col=\"path\",\n                                              y_col=\"label\",\n                                              batch_size=batch_size,\n                                              target_size=(299, 299),\n                                              subset=\"validation\")\n\nfrom keras.preprocessing.image import ImageDataGenerator\ntrain_gen = ImageDataGenerator(validation_split=0.2,\n                               rescale=1/255,\n                               horizontal_flip=True)\n\ntrain_generator = train_gen.flow_from_dataframe(train,\n                                                x_col=\"path\",\n                                                y_col=\"label\",\n                                                batch_size=batch_size,\n                                                target_size=(299, 299),\n                                                subset=\"training\")\n\nval_generator = train_gen.flow_from_dataframe(train,\n                                              x_col=\"path\",\n                                              y_col=\"label\",\n                                              batch_size=batch_size,\n                                              target_size=(299, 299),\n                                              subset=\"validation\")\n\nfrom keras import Sequential\nfrom keras.layers import Dense\nfrom keras.applications import MobileNetV2\nfrom keras.optimizers import Adam\nfrom keras.callbacks import ReduceLROnPlateau, EarlyStopping, ModelCheckpoint\n\nmodel = Sequential()\nmodel.add(MobileNetV2(weights = \"imagenet\", include_top = False, pooling = \"avg\")) #input\nmodel.add(Dense(2, activation = \"softmax\")) #output\n\nlayer_to_Freeze=172\nfor layer in model.layers[:layer_to_Freeze]:\n    layer.trainable = False\nfor layer in model.layers[layer_to_Freeze:]:\n    layer.trainable = True\n\n# model.compile(loss = \"categorical_crossentropy\", optimizer= Adam(lr=0.001, decay=1e-6), metrics = [\"acc\"])\nmodel.compile(loss = \"categorical_crossentropy\", optimizer= \"adam\", metrics = [\"acc\"])\n\nreducelr = ReduceLROnPlateau(patience=4, factor=0.1, verbose=1)\nearlystop = EarlyStopping(patience=5, verbose=1)\ncheckpoint = ModelCheckpoint(\"best_model.h5\", save_best_only=True, verbose=1)\n\nmodel.fit_generator(train_generator, \n                    epochs = 10,\n                    steps_per_epoch = int(np.ceil(train_generator.n/batch_size)),\n                    validation_data=val_generator,\n                    validation_steps=int(np.ceil(val_generator.n/batch_size)), \n                    callbacks=[reducelr, earlystop, checkpoint])\n\nsub = pd.read_csv(\"../input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv\")\nsub[\"path\"] = sub[\"id\"].apply(lambda x: \"../input/dogs-vs-cats-redux-kernels-edition/test/\" + str(x) + \".jpg\")\n\ntest_gen = ImageDataGenerator()\ntest_generator = test_gen.flow_from_dataframe(sub,\n                                              x_col=\"path\",\n                                              y_col=None,\n                                              target_size=(299, 299),\n                                              batch_size=batch_size,\n                                              class_mode=None,\n                                              shuffle=False)\n\nmodel.load_weights(\"best_model.h5\")\npred = model.predict_generator(test_generator,\n                               steps=int(np.ceil(test_generator.n/batch_size)),\n                               workers=2,\n                               verbose=1)\n\npred = pred[:, 1]\n\nsub.drop(\"path\", 1, inplace=True)\n\nsub[\"label\"] = pred\n\ntrain_generator.class_indices\n\ntest_generator.filenames\n\nsub.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#데이터가 고화질일수록 성능이 오른다. 고화질=타겟사이즈를 올려주면 더 성능이 오르다. 처음에 하면 안되고 뒤에서 해야한다. (픽셀을 더 늘리고 줄여준다)\n#크롭: 이미지를 보고 싶은것만 확대한다.(레이블링해서 바운딩박스를 만들어서 그 자체를 학습해도 된다.)\n#왜 데이터를 50개일때보다 100개씩 넣어줄 때 (배치사이즈,) 모델 점수도 잘나오고, 속도도 빠를까.  램크기에 따라서 최대로 가져올 수 있는 배치사이즈를 가져오는게 좋을까\n# => 곤충을 분류할 때, 50 종류일 때 보다, 100종류의 매미를 구분할 때 더 잘나오는 이유는? \n#= 종류가 많으면 배치사이즈도 커야한다. 가중치가 100개 종류를 모두다 보면서 수정되어야하는데 배치사이즈가 50이면, 50개만 보고 학습되고 나머지는 학습 안된다. \n#종류가 100개이면 최소 250개 배치사이즈가 되면 각각 2,3개 정도는 들어간다.  이미지는 배치사이즈가 클수록 좋고, 텍스트는 작을 수록 좋다. 텍스트는 정답 클래스가 많은 경우가 없다(긍부정등)\n#이미지가 바이너리이면 작게 해줘도 되는데, 속도생각해서 빠르게 해주는게 좋다. \n#VAL 0.9 <VAL 0.1 속도 높다. 모바일넷은 엄청 깊진 않아도 쓸만함 (미국성 OR 영국성인지 성능이 엄청 잘 나오지 않아도 된다. 그러면 모바일넷쓰면 좋다.대회할 때는 다른것 써도 좋다)\n#러닝레이트를 높여주니까 성능이 좋아짐\n#EPOCH : 모든 데이터를 한번 쭉 학습할 때 (1번), 2만개 전체 데이터 보면서 학습하면 / 에폭 1면 = 나무 개수 = 학습 횟수 = 에폭  400 = 2만개의 데이터에서 배치 50개씩 하기위해서는 총 400번을 넣어줘야지 2만번 모두 학습함. \n#-> 가중치가 바뀌면서 로스가 낮아지려고 노력함 \n#딥러닝 모델은 학습을 이어서 할 수 있다. 에폭을 더 높이면 된다. 컴파일, 모델 선언 하지 않고 피쳐엔지니어링만 실행시키면 된다. \n#VAL 가장 낮게 나오고, PATIENCE 5번 참아주고  \n","execution_count":null,"outputs":[]}],"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"}},"nbformat":4,"nbformat_minor":4}