{"cells":[{"metadata":{},"cell_type":"markdown","source":"# 实验2：VGG16猫狗图像分类"},{"metadata":{},"cell_type":"markdown","source":"### 18124399冯秦萱"},{"metadata":{},"cell_type":"markdown","source":"导入包，使用tensorflow中的keras实现vgg16网络的构建"},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras\nimport pandas as pd\nimport numpy as np\nimport tensorflow as tf\nimport os\nimport matplotlib.pyplot as plt\nimport cv2\nimport zipfile\nfrom keras import optimizers\nfrom keras import regularizers\nfrom keras.optimizers import SGD\nfrom keras.models import Sequential\nfrom keras.models import load_model\nfrom keras.layers import Dense, Dropout, Activation, Flatten\nfrom keras.layers import Conv2D, MaxPooling2D, BatchNormalization\nfrom keras.preprocessing.image import ImageDataGenerator","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"定义变量，图片宽高，batchsize和训练次数"},{"metadata":{"trusted":true},"cell_type":"code","source":"weight,height = 224,224\nbatch=10\nepochs=100","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"加载猫狗数据集"},{"metadata":{"trusted":true},"cell_type":"code","source":"path_= \"../input/dogs-vs-cats/\"\nwith zipfile.ZipFile(path_+ \"train.zip\",\"r\") as z:\n    z.extractall(\".\")#数据集位置    \npath = \"/kaggle/working/train/\"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"通过opencv进行图片预处理，加载图片数据并设置标签，猫的标签为0，狗的标签为1"},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_data():\n    train_data = np.empty((5000,weight,height, 3), dtype=\"int32\")\n    train_label = np.empty((5000, ), dtype=\"int32\")\n\n    for i in range(5000):\n        if i % 2:\n            train_data[i] = cv2.resize(cv2.imread(path+'/'+'dog.' + str(i) + '.jpg'), (weight,height))\n            train_label[i] = 1\n        else:\n            train_data[i] = cv2.resize(cv2.imread(path+'/' +'cat.' + str(i) + '.jpg'), (weight,height))\n            train_label[i] = 0\n\n    return train_data, train_label","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"定义vgg16网络结构，使用BN，dropout，L2正则化等进行优化"},{"metadata":{"trusted":true},"cell_type":"code","source":"def vgg16():\n    weight_decay = 0.0005\n    # layer1\n    model = Sequential()\n    model.add(Conv2D(64, (3, 3), padding='same',\n                     input_shape=( weight,height, 3), kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(Dropout(0.3))\n    # layer2\n    model.add(Conv2D(64, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    # layer3\n    model.add(Conv2D(128, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(Dropout(0.4))\n    # layer4\n    model.add(Conv2D(128, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    # layer5\n    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(Dropout(0.4))\n    # layer6\n    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(Dropout(0.4))\n    # layer7\n    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    # layer8\n    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(Dropout(0.4))\n    # layer9\n    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(Dropout(0.4))\n    # layer10\n    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    # layer11\n    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(Dropout(0.4))\n    # layer12\n    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(Dropout(0.4))\n    # layer13\n    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Dropout(0.5))\n    # layer14\n    model.add(Flatten())\n    model.add(Dense(512, kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    # layer15\n    model.add(Dense(512, kernel_regularizer=regularizers.l2(weight_decay)))\n    model.add(Activation('relu'))\n    model.add(BatchNormalization())\n    # layer16\n    model.add(Dropout(0.5))\n    model.add(Dense(2))\n    model.add(Activation('softmax'))\n \n    return model","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"规范训练数据，对标签one-hot编码"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data, train_label = load_data()\ntrain_data = train_data.astype('float32')\ntrain_label = keras.utils.to_categorical(train_label, 2)#one-hot编码","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"展示vgg16模型结构"},{"metadata":{"trusted":true},"cell_type":"code","source":"model = vgg16()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"定义损失函数，优化器"},{"metadata":{"trusted":true},"cell_type":"code","source":"sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) #设置优化器为SGD\nmodel.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"模型训练，训练100次，训练集的20%作为验证集，shuffle=True打乱数据"},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(train_data, train_label,\n              batch_size=batch,\n              epochs=epochs,\n              validation_split=0.2,  #把训练集中的五分之一作为验证集\n              shuffle=True)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"保存模型及训练数据"},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save('/kaggle/working/vgg16dogcat.h5')\ndata=pd.DataFrame(history.history)\ndata.to_csv('/kaggle/working/log.csv',index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"画图展示训练过程中精度和loss变化"},{"metadata":{"trusted":true},"cell_type":"code","source":"acc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\n\nepochs_range = range(epochs)\n\n\nplt.figure(figsize=(8, 8))\nplt.subplot(1, 2, 1)\nplt.plot(epochs_range, acc,label='Training Accuracy')\nplt.plot(epochs_range, val_acc, label='Validation Accuracy')\nplt.legend(loc='lower right')\nplt.title('Training and Validation Accuracy')\n\nplt.subplot(1, 2, 2)\nplt.plot(epochs_range, loss, label='Training Loss')\nplt.plot(epochs_range, val_loss, label='Validation Loss')\nplt.legend(loc='upper right')\nplt.title('Training and Validation Loss')\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"测试模型"},{"metadata":{"trusted":true},"cell_type":"code","source":" def judge(predicted):\n    predicted = np.argmax(predicted)\n    if predicted == 0:\n        print('cat')\n    else:\n        print('dog')\nload_model = load_model(\"/kaggle/working/vgg16dogcat.h5\")  # 读取模型\nimg = cv2.imread('../input/testpng/cat.png')  \nplt.imshow(img)\nimg = cv2.resize(img, (weight,height))\nimg = img.reshape(-1,weight,height,3)\nimg = img.astype('float32')\npredicted = load_model.predict(img)  # 输出预测结果\nprint(predicted)\njudge(predicted)","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}