{"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_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":"2022-03-29T06:16:24.277181Z","iopub.execute_input":"2022-03-29T06:16:24.277493Z","iopub.status.idle":"2022-03-29T06:17:09.552795Z","shell.execute_reply.started":"2022-03-29T06:16:24.277395Z","shell.execute_reply":"2022-03-29T06:17:09.551801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Divide data into various folders train val test\nimport os,shutil\noriginal_dataset_dir='../input/dog-vs-cat-classification/train/train'\nbase_dir='./cats_and_dogs_samll'\nos.mkdir(base_dir)\nos.system('chmod 777 '+base_dir)\n\ntrain_dir=os.path.join(base_dir,'train')\nos.mkdir(train_dir)\nvalidation_dir=os.path.join(base_dir,'validation')\nos.mkdir(validation_dir)\ntest_dir=os.path.join(base_dir,'test')\nos.mkdir(test_dir)\n\ntrain_cats_dir=os.path.join(train_dir,'cat')\nos.mkdir(train_cats_dir)\n\ntrain_dogs_dir=os.path.join(train_dir,'dog')\nos.mkdir(train_dogs_dir)\n\nvalidation_cats_dir=os.path.join(validation_dir,'cat')\nos.mkdir(validation_cats_dir)\n\nvalidation_dogs_dir=os.path.join(validation_dir,'dog')\nos.mkdir(validation_dogs_dir)\n\ntest_cats_dir=os.path.join(test_dir,'cat')\nos.mkdir(test_cats_dir)\n\ntest_dogs_dir=os.path.join(test_dir,'dog')\nos.mkdir(test_dogs_dir)\n\nfnames=['cat.{}.jpg'.format(i) for i in range(1000)]\nfor fname in fnames:\n    src=os.path.join(original_dataset_dir+'/cats/',fname)\n    dst=os.path.join(train_cats_dir,fname)\n    shutil.copyfile(src,dst)\n\nfnames=['cat.{}.jpg'.format(i) for i in range(1000,1500)]\nfor fname in fnames:\n    src=os.path.join(original_dataset_dir+'/cats/',fname)\n    dst=os.path.join(validation_cats_dir,fname)\n    shutil.copyfile(src,dst)\n\nfnames=['cat.{}.jpg'.format(i) for i in range(1500,2000)]\nfor fname in fnames:\n    src=os.path.join(original_dataset_dir+'/cats/',fname)\n    dst=os.path.join(test_cats_dir,fname)\n    shutil.copyfile(src,dst)\n\nfnames=['dog.{}.jpg'.format(i) for i in range(1000)]\nfor fname in fnames:\n    src=os.path.join(original_dataset_dir+'/dogs/',fname)\n    dst=os.path.join(train_dogs_dir,fname)\n    shutil.copyfile(src,dst)\n\nfnames=['dog.{}.jpg'.format(i) for i in range(1000,1500)]\nfor fname in fnames:\n    src=os.path.join(original_dataset_dir+'/dogs/',fname)\n    dst=os.path.join(validation_dogs_dir,fname)\n    shutil.copyfile(src,dst)\n\nfnames=['dog.{}.jpg'.format(i) for i in range(1500,2000)]\nfor fname in fnames:\n    src=os.path.join(original_dataset_dir+'/dogs/',fname)\n    dst=os.path.join(test_dogs_dir,fname)\n    shutil.copyfile(src,dst) ","metadata":{"execution":{"iopub.status.busy":"2022-03-29T06:39:41.114142Z","iopub.execute_input":"2022-03-29T06:39:41.115077Z","iopub.status.idle":"2022-03-29T06:40:12.819083Z","shell.execute_reply.started":"2022-03-29T06:39:41.115038Z","shell.execute_reply":"2022-03-29T06:40:12.818259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras \nfrom keras import  layers\nfrom keras import  models\nfrom tensorflow import optimizers\nfrom keras.preprocessing.image import ImageDataGenerator","metadata":{"execution":{"iopub.status.busy":"2022-03-29T06:40:16.851154Z","iopub.execute_input":"2022-03-29T06:40:16.851647Z","iopub.status.idle":"2022-03-29T06:40:16.85662Z","shell.execute_reply.started":"2022-03-29T06:40:16.851609Z","shell.execute_reply":"2022-03-29T06:40:16.855346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.applications import vgg16\nconv_base=vgg16.VGG16(weights='imagenet',include_top=False,input_shape=(150,150,3))                \nconv_base.summary()","metadata":{"execution":{"iopub.status.busy":"2022-03-29T06:40:19.229098Z","iopub.execute_input":"2022-03-29T06:40:19.22963Z","iopub.status.idle":"2022-03-29T06:40:19.519532Z","shell.execute_reply.started":"2022-03-29T06:40:19.229589Z","shell.execute_reply":"2022-03-29T06:40:19.518802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#enhance the data\nmodel=models.Sequential()\nmodel.add(conv_base)\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(256,activation='relu'))\nmodel.add(layers.Dense(1,activation='sigmoid'))\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-03-29T06:40:22.23555Z","iopub.execute_input":"2022-03-29T06:40:22.235805Z","iopub.status.idle":"2022-03-29T06:40:22.321576Z","shell.execute_reply.started":"2022-03-29T06:40:22.235778Z","shell.execute_reply":"2022-03-29T06:40:22.320877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Freeze the convolutional base before compiling, do not let its trained weights change\nprint(\"how many weights before freezing:\",len(model.trainable_weights))\nconv_base.trainable=False\nprint(\"how many weights after freezing:\",len(model.trainable_weights))","metadata":{"execution":{"iopub.status.busy":"2022-03-29T06:40:24.130219Z","iopub.execute_input":"2022-03-29T06:40:24.130792Z","iopub.status.idle":"2022-03-29T06:40:24.139972Z","shell.execute_reply.started":"2022-03-29T06:40:24.130755Z","shell.execute_reply":"2022-03-29T06:40:24.136848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Data augmentation, training base model\ntrain_datagen=ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=40,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n)\ntest_datagen=ImageDataGenerator(rescale=1./255)#不能增强验证集数据\n\ntrain_generator=train_datagen.flow_from_directory(train_dir,target_size=(150,150),batch_size=20,class_mode='binary')\nvalidation_generator=test_datagen.flow_from_directory(validation_dir,target_size=(150,150),batch_size=20,class_mode='binary')\n\nmodel.compile(loss='binary_crossentropy',optimizer=optimizers.RMSprop(lr=2e-5),metrics=['acc'])\nhistory=model.fit_generator(\n    train_generator,\n    steps_per_epoch=100,\n    epochs=30,\n    validation_data=validation_generator,\n    validation_steps=50\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-29T06:40:56.833706Z","iopub.execute_input":"2022-03-29T06:40:56.833993Z","iopub.status.idle":"2022-03-29T06:49:49.851408Z","shell.execute_reply.started":"2022-03-29T06:40:56.83396Z","shell.execute_reply":"2022-03-29T06:49:49.850513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#draw\nimport matplotlib.pyplot as plt\nacc=history.history['acc']\nval_acc=history.history['val_acc']\nloss=history.history['loss']\nval_loss=history.history['val_loss']\n\nepochs=range(1,len(acc)+1)\nplt.plot(epochs,acc,'bo',label='Training acc')\nplt.plot(epochs,val_acc,'b',label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs,loss,'bo',label='Training loss')\nplt.plot(epochs,val_loss,'b',label='Validation loss')\nplt.title('Traning and Validation loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-29T06:53:03.276153Z","iopub.execute_input":"2022-03-29T06:53:03.27684Z","iopub.status.idle":"2022-03-29T06:53:03.657879Z","shell.execute_reply.started":"2022-03-29T06:53:03.276804Z","shell.execute_reply":"2022-03-29T06:53:03.657174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Fine-tune the model and feature extraction to complement each other Unfreeze the top convolutional layers for training\nconv_base.trainable=True\nset_trainable=False\nfor layer in conv_base.layers:\n  if layer.name=='block5_conv1':\n    set_trainable=True\n  if set_trainable:\n    layer.trainable=True\n  else:\n    layer.trainable=False","metadata":{"execution":{"iopub.status.busy":"2022-03-29T06:53:35.482002Z","iopub.execute_input":"2022-03-29T06:53:35.482294Z","iopub.status.idle":"2022-03-29T06:53:35.488323Z","shell.execute_reply.started":"2022-03-29T06:53:35.482258Z","shell.execute_reply":"2022-03-29T06:53:35.487498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Model fine-tuning don't change its parameters too much\nmodel.compile(loss='binary_crossentropy',optimizer=optimizers.RMSprop(lr=1e-5),metrics=['acc'])\nhistory=model.fit_generator(\n    train_generator,\n    steps_per_epoch=100,\n    epochs=100,\n    validation_data=validation_generator,\n    validation_steps=50\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-29T06:53:57.303842Z","iopub.execute_input":"2022-03-29T06:53:57.304102Z","iopub.status.idle":"2022-03-29T07:23:34.242603Z","shell.execute_reply.started":"2022-03-29T06:53:57.304073Z","shell.execute_reply":"2022-03-29T07:23:34.241804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc=history.history['acc']\nval_acc=history.history['val_acc']\nloss=history.history['loss']\nval_loss=history.history['val_loss']\n\nepochs=range(1,len(acc)+1)\nplt.plot(epochs,acc,'bo',label='Training acc')\nplt.plot(epochs,val_acc,'b',label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs,loss,'bo',label='Training loss')\nplt.plot(epochs,val_loss,'b',label='Validation loss')\nplt.title('Traning and Validation loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:23:36.865836Z","iopub.execute_input":"2022-03-29T07:23:36.866253Z","iopub.status.idle":"2022-03-29T07:23:37.382686Z","shell.execute_reply.started":"2022-03-29T07:23:36.866201Z","shell.execute_reply":"2022-03-29T07:23:37.381974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Evaluate on test data\ntest_generator=test_datagen.flow_from_directory(\n    test_dir,\n    target_size=(150,150),\n    batch_size=20,\n    class_mode='binary'\n)\ntest_loss,test_acc=model.evaluate_generator(test_generator,steps=50)\nprint('test acc:',test_acc)","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:23:57.482695Z","iopub.execute_input":"2022-03-29T07:23:57.482971Z","iopub.status.idle":"2022-03-29T07:24:00.621607Z","shell.execute_reply.started":"2022-03-29T07:23:57.482941Z","shell.execute_reply":"2022-03-29T07:24:00.620782Z"},"trusted":true},"execution_count":null,"outputs":[]}]}