{"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":"#  解压文件\n# kaggle会将文件解压到根目录下的working路径下\nimport zipfile\nwith zipfile.ZipFile('../input/dogs-vs-cats/train.zip', 'r') as z:\n    z.extractall('.')\nwith zipfile.ZipFile('../input/dogs-vs-cats/test1.zip', 'r') as z:\n    z.extractall('.')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-04-14T14:12:18.867047Z","iopub.execute_input":"2022-04-14T14:12:18.867607Z","iopub.status.idle":"2022-04-14T14:12:34.896109Z","shell.execute_reply.started":"2022-04-14T14:12:18.86752Z","shell.execute_reply":"2022-04-14T14:12:34.895095Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 准备数据集，将原来比较大的数据集进行抽样，形成一个比较小的数据集\nimport os, shutil\noriginal_dataset_dir = '../working/train'\nbase_dir = '../working/cats_and_dogs_small'\nos.mkdir(base_dir)\ntrain_dir = os.path.join(base_dir, 'train')\nvalid_dir = os.path.join(base_dir, 'valid')\ntest_dir = os.path.join(base_dir, 'test')\nos.mkdir(train_dir)\nos.mkdir(valid_dir)\nos.mkdir(test_dir)\n\ntrain_dir_dogs = os.path.join(train_dir, 'dogs')\nvalid_dir_dogs = os.path.join(valid_dir, 'dogs')\ntest_dir_dogs = os.path.join(test_dir, 'dogs')\ntrain_dir_cats = os.path.join(train_dir, 'cats')\nvalid_dir_cats = os.path.join(valid_dir, 'cats')\ntest_dir_cats = os.path.join(test_dir, 'cats')\nos.mkdir(train_dir_cats)\nos.mkdir(valid_dir_cats)\nos.mkdir(test_dir_cats)\nos.mkdir(train_dir_dogs)\nos.mkdir(valid_dir_dogs)\nos.mkdir(test_dir_dogs)\n\n# Copy first 1000 cat images to train_cats\nfnames = ['cat.{}.jpg'.format(i) for i in range(1000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(train_dir_cats, fname)\n    shutil.copyfile(src, dst)\n# Copy next 500 cat images to valid_cats\nfnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(valid_dir_cats, fname)\n    shutil.copyfile(src, dst)\n# Copy next 500 cat images to test_cats\nfnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(test_dir_cats, fname)\n    shutil.copyfile(src, dst)\n# Copy first 1000 dog images to train_dogs\nfnames = ['dog.{}.jpg'.format(i) for i in range(1000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(train_dir_dogs, fname)\n    shutil.copyfile(src, dst)\n# Copy next 500 dog images to valid_dogs\nfnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(valid_dir_dogs, fname)\n    shutil.copyfile(src, dst)\n# Copy next 500 dog images to test_dogs\nfnames = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)]\nfor fname in fnames:\n    src = os.path.join(original_dataset_dir, fname)\n    dst = os.path.join(test_dir_dogs, fname)\n    shutil.copyfile(src, dst)","metadata":{"execution":{"iopub.status.busy":"2022-04-14T14:12:50.899264Z","iopub.execute_input":"2022-04-14T14:12:50.89957Z","iopub.status.idle":"2022-04-14T14:12:51.290268Z","shell.execute_reply.started":"2022-04-14T14:12:50.899538Z","shell.execute_reply":"2022-04-14T14:12:51.289561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 定义卷积基\nfrom keras.applications import vgg16\nconv_base = vgg16.VGG16(weights='imagenet', include_top=False, input_shape=(150, 150, 3))","metadata":{"execution":{"iopub.status.busy":"2022-04-14T14:12:52.01975Z","iopub.execute_input":"2022-04-14T14:12:52.020449Z","iopub.status.idle":"2022-04-14T14:13:00.73332Z","shell.execute_reply.started":"2022-04-14T14:12:52.020411Z","shell.execute_reply":"2022-04-14T14:13:00.732572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"conv_base.trainable = True\nprint(f'Number of trainable layers: {len(conv_base.trainable_weights)}')","metadata":{"execution":{"iopub.status.busy":"2022-04-14T14:13:00.734728Z","iopub.execute_input":"2022-04-14T14:13:00.73651Z","iopub.status.idle":"2022-04-14T14:13:00.744963Z","shell.execute_reply.started":"2022-04-14T14:13:00.736481Z","shell.execute_reply":"2022-04-14T14:13:00.743105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 将卷积基中顶层的几层解冻\nset_trainable = False\nfor layer in conv_base.layers:\n    # 从block5_conv1开始解冻，总共会解冻3个卷积层\n    if layer.name == 'block5_conv1':\n        set_trainable = True\n    if set_trainable:\n        layer.trainable = True\n    else:\n        layer.trainable = False\nprint(f'Number of trainable layers: {len(conv_base.trainable_weights)}')","metadata":{"execution":{"iopub.status.busy":"2022-04-14T14:13:13.068938Z","iopub.execute_input":"2022-04-14T14:13:13.069233Z","iopub.status.idle":"2022-04-14T14:13:13.076127Z","shell.execute_reply.started":"2022-04-14T14:13:13.0692Z","shell.execute_reply":"2022-04-14T14:13:13.075372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 使用卷积基，然后加上全连接层\nfrom keras import models, layers\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-04-14T14:13:28.009318Z","iopub.execute_input":"2022-04-14T14:13:28.009606Z","iopub.status.idle":"2022-04-14T14:13:28.086152Z","shell.execute_reply.started":"2022-04-14T14:13:28.009574Z","shell.execute_reply":"2022-04-14T14:13:28.085398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Number of trainable layers: {len(model.trainable_weights)}')","metadata":{"execution":{"iopub.status.busy":"2022-04-14T14:13:51.844656Z","iopub.execute_input":"2022-04-14T14:13:51.844993Z","iopub.status.idle":"2022-04-14T14:13:51.850501Z","shell.execute_reply.started":"2022-04-14T14:13:51.844957Z","shell.execute_reply":"2022-04-14T14:13:51.84987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 开始准备数据、训练模型\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import optimizers\ntrain_datagen = ImageDataGenerator(rescale=1./255,rotation_range=40,\n                                      width_shift_range=0.2,height_shift_range=0.2,\n                                        shear_range=0.2,zoom_range=0.2,horizontal_flip=True,\n                                        fill_mode='nearest')\ntest_datagen = ImageDataGenerator(rescale=1./255)\ntrain_generator = train_datagen.flow_from_directory(train_dir,target_size=(150,150),batch_size=20,class_mode='binary')\nvalid_generator = test_datagen.flow_from_directory(valid_dir,target_size=(150,150),batch_size=20,class_mode='binary')\nmodel.compile(loss='binary_crossentropy',optimizer='rmsprop',metrics=['acc'])\nhistory = model.fit_generator(train_generator,steps_per_epoch=100,epochs=30,validation_data=valid_generator,validation_steps=50)","metadata":{"execution":{"iopub.status.busy":"2022-04-14T14:14:18.277388Z","iopub.execute_input":"2022-04-14T14:14:18.27765Z","iopub.status.idle":"2022-04-14T14:23:53.556567Z","shell.execute_reply.started":"2022-04-14T14:14:18.277621Z","shell.execute_reply":"2022-04-14T14:23:53.555826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history.history","metadata":{"execution":{"iopub.status.busy":"2022-04-14T14:25:07.540066Z","iopub.execute_input":"2022-04-14T14:25:07.540342Z","iopub.status.idle":"2022-04-14T14:25:07.548858Z","shell.execute_reply.started":"2022-04-14T14:25:07.540305Z","shell.execute_reply":"2022-04-14T14:25:07.548076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nacc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\nepochs = range(1, len(acc) + 1)\n\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()\nplt.figure()\nplt.plot(epochs, loss, 'bo', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-14T14:25:15.864747Z","iopub.execute_input":"2022-04-14T14:25:15.865467Z","iopub.status.idle":"2022-04-14T14:25:16.257328Z","shell.execute_reply.started":"2022-04-14T14:25:15.865431Z","shell.execute_reply":"2022-04-14T14:25:16.256566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}