{"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        print(os.path.join(dirname, filename))\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 os,shutil\n\noriginal_dataset_dir = 'data/kaggle_original_data'\nbase_dir = 'data/cats_and_dogs_small'\nif not os.path.exists(base_dir):\n    os.mkdir(base_dir)\n\n#分别对应划分后的训练、验证和测试的目录\ntrain_dir = os.path.join(base_dir, 'train')\nif not os.path.exists(train_dir):\n    os.mkdir(train_dir)\n    \n# 猫的训练图像目录\ntrain_cats_dir = os.path.join(train_dir, 'cats')\nif not os.path.exists(train_cats_dir):\n    os.mkdir(train_cats_dir)\n\n# 狗的训练图像目录\ntrain_dogs_dir = os.path.join(train_dir, 'dogs')\nif not os.path.exists(train_dogs_dir):\n    os.mkdir(train_dogs_dir)\n\nvalidation_dir = os.path.join(base_dir, 'validation')\nif not os.path.exists(validation_dir):\n    os.mkdir(validation_dir)\n    \n#猫的验证图像目录\nvalidation_cats_dir = os.path.join(validation_dir, 'cats')\nif not os.path.exists(validation_cats_dir):\n    os.mkdir(validation_cats_dir)\n\n# 狗的验证图像目录\nvalidation_dogs_dir = os.path.join(validation_dir, 'dogs')\nif not os.path.exists(validation_dogs_dir):\n    os.mkdir(validation_dogs_dir)\n    \ntest_dir = os.path.join(base_dir, 'test')\nif not os.path.exists(test_dir):\n    os.mkdir(test_dir)\n    \n# 猫的测试图像目录\ntest_cats_dir = os.path.join(test_dir, 'cats')\nif not os.path.exists(test_cats_dir):\n    os.mkdir(test_cats_dir)\n\n# 狗的测试图像目录\ntest_dogs_dir = os.path.join(test_dir, 'dogs')\nif not os.path.exists(test_dogs_dir):\n    os.mkdir(test_dogs_dir)\n    \n# 将前1000张猫的图像复制到 train_cats_dir\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_cats_dir, fname)\n    shutil.copyfile(src, dst)\n\n# 将接下来 500 张猫的图像复制到 validation_cats_dir\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(validation_cats_dir, fname)\n    shutil.copyfile(src, dst)\n    \n# 将接下来的 500 张猫的图像复制到 test_cats_dir\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_cats_dir, fname)\n    shutil.copyfile(src, dst)\n    \n# 将前 1000 张狗的图像复制到 train_dogs_dir\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_dogs_dir, fname)\n    shutil.copyfile(src, dst)\n    \n# 将接下来 500 张狗的图像复制到 validation_dogs_dir\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(validation_dogs_dir, fname)\n    shutil.copyfile(src, dst)\n    \n# 将接下来 500 张狗的图像复制到 test_dogs_dir\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_dogs_dir, fname)\n    shutil.copyfile(src, dst)\n\n#查看每个分组中（训练/验证/测试）中分别包含多少张图像\nprint('total training cat images:',len(os.listdir(train_cats_dir)))\nprint('total training dog images:',len(os.listdir(train_dogs_dir)))\nprint('total validation cat images:',len(os.listdir(validation_cats_dir)))\nprint('total validation dog images:',len(os.listdir(validation_dogs_dir)))\nprint('total test cat images:',len(os.listdir(test_cats_dir)))\nprint('total test dog images:',len(os.listdir(test_dogs_dir)))\n\n\n\n\n#建立模型\nfrom keras.applications import VGG16\n#weghts指定模型初始化的权重检查点，include_top指定模型的最后是否包含密集连接分类器\n# input_shape是输入到网络中图像张量的形状,这个参数是可选的，如果不传\n#入这个参数，那么网络能够处理任意形状的输入。\nconv_base = VGG16(weights='imagenet',include_top=False,input_shape=(150,150,3))\nfrom keras import layers\nfrom keras import models\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'))\n#查看特征图的维度随每层的变化\nmodel.summary()\n#冻结直到某一层的所有层\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 = Flase\n\n\n\n\n#训练模型\nfrom keras.preprocessing.image import ImageDataGenerator\n#数据增强\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,    #将图像乘以1/255缩放\n    rotation_range=40, #图片随机旋转40度\n    width_shift_range=0.2, #图片在水平方向上平移的距离为图片的总宽度的0.2倍\n    height_shift_range=0.2, #图片在垂直方向上平移的距离为图片的总高度的0.2倍\n    shear_range=0.2,  #随机错切变换的角度\n    zoom_range=0.2,  #图像随机缩放的范围\n    horizontal_flip=True,\n    fill_model='nearest') #随机将一半图像翻转\n\ntest_datagen = ImageDataGenerator(rescale=1./255)  #不能增强验证数据\n\n#数据预处理\ntrain_generator = train_datagen.flow_from_directory(\n    train_dir,  #目标目录\n    target_size = (150,150), #将所有图像的大小调整为150×150\n    batch_size = 20,\n    class_mode = 'binary')  #因为使用binary_crossentropy损失，所以用二进制标签\n\nvalidation_generator = train_datagen.flow_from_directory(\n    validation_dir,\n    target_size = (150,150),\n    batch_size = 20,\n    class_mode = 'binary')\n\n#编译模型\nfrom keras import optimizers\nmodel.compile(loss='binary_crossentropy',\n              optimizer=optimizers.RMSprop(lr=e-5),\n              metrics=['acc'])\n\n#利用批量生成器拟合模型\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\n#保存模型\nmodel.save('cats_and_dogs.h5')\n\n\n\n\n#绘制模型在训练集和验证集上的表现\nimport matplotlib.pyplot as plt\ndef smooth_curve(points, factor=0.8):\n  smoothed_points = []\n  for point in points:\n    if smoothed_points:\n      previous = smoothed_points[-1]\n      smoothed_points.append(previous * factor + point * (1 - factor))\n    else:\n      smoothed_points.append(point)\n  return smoothed_points\n\nplt.plot(epochs,\n         smooth_curve(acc), 'bo', label='Smoothed training acc')\nplt.plot(epochs,\n         smooth_curve(val_acc), 'b', label='Smoothed validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\nplt.figure()\n\nplt.plot(epochs,\n         smooth_curve(loss), 'bo', label='Smoothed training loss')\nplt.plot(epochs,\n         smooth_curve(val_loss), 'b', label='Smoothed validation loss')\nplt.title('Training and validation loss')\nplt.legend()\nplt.show()\n\n\n\n\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)","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":1}