{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"},{"sourceId":9900,"sourceType":"datasetVersion","datasetId":6209}],"dockerImageVersionId":31089,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"导入打开zip文件夹","metadata":{}},{"cell_type":"code","source":"import zipfile\nimport os\n\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip', 'r') as z:\n    z.extractall('.')\n    train_image_list = z.namelist()\n    train_image_list = os.listdir(\"./train/\")\n\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip', 'r') as z:\n    z.extractall('.')\n    test_image_list = z.namelist()\n    test_image_list = os.listdir(\"./test/\")\n\n\nprint(train_image_list[0],test_image_list[0]) # train格式 类别+数字  test只有数字","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-08-29T06:22:58.327151Z","iopub.execute_input":"2025-08-29T06:22:58.327735Z","iopub.status.idle":"2025-08-29T06:23:09.093874Z","shell.execute_reply.started":"2025-08-29T06:22:58.327711Z","shell.execute_reply":"2025-08-29T06:23:09.093064Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"训练集2.5w张图片，猫狗对半","metadata":{}},{"cell_type":"code","source":"import seaborn as sns\nimport matplotlib.pyplot as plt\ndef plot_image_list_count(data_image_list):\n    labels = []\n    for img in data_image_list:\n        labels.append(img.split('.')[0])\n    sns.countplot(x=labels)\n    plt.title('Cats and Dogs')\n    \nplot_image_list_count(train_image_list)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T06:23:44.111054Z","iopub.execute_input":"2025-08-29T06:23:44.111683Z","iopub.status.idle":"2025-08-29T06:23:44.306663Z","shell.execute_reply.started":"2025-08-29T06:23:44.111659Z","shell.execute_reply":"2025-08-29T06:23:44.305899Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"提取出 train和test图像和标签","metadata":{}},{"cell_type":"code","source":"from random import shuffle\nfrom tqdm import tqdm\nimport cv2\nimport numpy as np\nimport pandas as pd\n\nRANDOM_STATE = 2018\nIMG_SIZE = 224\ndef process_data(data_image_list, DATA_FOLDER, isTrain):\n    data_df = []\n    for img in tqdm(data_image_list):\n        if(isTrain):\n            label = [1,0] if img.split('.')[0] == 'cat' else [0,1] # 根据文件名 转换独热标签\n        else:\n            label = img.split('.')[0]\n            \n        path = os.path.join(DATA_FOLDER,img) # 拼接为完整路径\n        img = cv2.imread(path,cv2.IMREAD_COLOR)\n        img = cv2.resize(img, (IMG_SIZE,IMG_SIZE))\n        data_df.append([np.array(img),np.array(label)])\n        \n    shuffle(data_df)\n    return data_df\n\ntrain = process_data(train_image_list, './train/', True)\ntest = process_data(test_image_list, './test/', False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T06:34:20.456842Z","iopub.execute_input":"2025-08-29T06:34:20.457215Z","iopub.status.idle":"2025-08-29T06:35:08.342272Z","shell.execute_reply.started":"2025-08-29T06:34:20.457193Z","shell.execute_reply":"2025-08-29T06:35:08.341389Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"展示几张训练集图片和测试集图片","metadata":{}},{"cell_type":"code","source":"def show_images(data, isTest=False):\n    f, ax = plt.subplots(5,5, figsize=(15,15))\n    for i,data in enumerate(data[:25]):\n        img_data,img_num = data[0],data[1]\n        label = np.argmax(img_num) # 独热向量 [0,1] 为狗 转换为文字标签\n        if label == 1: \n            str_label='Dog'\n        elif label == 0: \n            str_label='Cat'\n        if(isTest):\n            str_label=\"None\"\n        ax[i//5, i%5].imshow(img_data)\n        ax[i//5, i%5].axis('off')\n        ax[i//5, i%5].set_title(\"Label: {}\".format(str_label))\n    plt.show()\n\nshow_images(train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T06:35:12.197147Z","iopub.execute_input":"2025-08-29T06:35:12.1975Z","iopub.status.idle":"2025-08-29T06:35:14.20922Z","shell.execute_reply.started":"2025-08-29T06:35:12.197476Z","shell.execute_reply":"2025-08-29T06:35:14.208388Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_images(test,True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T06:35:20.078625Z","iopub.execute_input":"2025-08-29T06:35:20.078956Z","iopub.status.idle":"2025-08-29T06:35:22.198299Z","shell.execute_reply.started":"2025-08-29T06:35:20.078932Z","shell.execute_reply":"2025-08-29T06:35:22.196958Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"model建立","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense\n\nmodel = Sequential()\nmodel.add(ResNet50(\n    include_top=False,\n    pooling='max',\n    weights='imagenet'\n))\nmodel.add(Dense(2, activation='softmax'))\n\nmodel.layers[0].trainable = True\nmodel.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T07:11:32.614009Z","iopub.execute_input":"2025-08-29T07:11:32.615736Z","iopub.status.idle":"2025-08-29T07:11:37.382021Z","shell.execute_reply.started":"2025-08-29T07:11:32.615685Z","shell.execute_reply":"2025-08-29T07:11:37.380781Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"准备训练数据并训练","metadata":{}},{"cell_type":"code","source":"X = np.array([data[0] for data in train]).reshape(-1,IMG_SIZE,IMG_SIZE,3)\ny = np.array([data[1] for data in train])\nfrom sklearn.model_selection import train_test_split\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.25, random_state=RANDOM_STATE)\ntrain_model = model.fit(X_train, y_train,\n                  batch_size=64,\n                  epochs=20,\n                  verbose=1,\n                  validation_data=(X_val, y_val))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T07:13:22.713473Z","iopub.execute_input":"2025-08-29T07:13:22.714307Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"验证集分数；模型评估","metadata":{}},{"cell_type":"code","source":"score = model.evaluate(X_val, y_val, verbose=0)\nprint('Validation loss:', score[0])\nprint('Validation accuracy:', score[1])\n\npredicted_classes = model.predict_classes(X_val)\ny_true = np.argmax(y_val,axis=1)\n\ncorrect = np.nonzero(predicted_classes==y_true)[0]\nincorrect = np.nonzero(predicted_classes!=y_true)[0]\n\ntarget_names = [\"Class {}:\".format(i) for i in range(2)]\nfrom sklearn.metrics import classification_report\nprint(classification_report(y_true, predicted_classes, target_names=target_names))","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"可视化部分验证集结果","metadata":{}},{"cell_type":"code","source":"f, ax = plt.subplots(5,5, figsize=(15,15))\nfor i,data in enumerate(test[:25]):\n    img_num = data[1]\n    img_data = data[0]\n    orig = img_data\n    data = img_data.reshape(-1,IMG_SIZE,IMG_SIZE,3)\n    model_out = model.predict([data])[0]\n    \n    if np.argmax(model_out) == 1: \n        str_predicted='Dog'\n    else: \n        str_predicted='Cat'\n    ax[i//5, i%5].imshow(orig)\n    ax[i//5, i%5].axis('off')\n    ax[i//5, i%5].set_title(\"Predicted:{}\".format(str_predicted))    \nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"预测并保存结果","metadata":{}},{"cell_type":"code","source":"pred_list = []\nimg_list = []\nfor img in tqdm(test):\n    data = img[0].reshape(-1,IMG_SIZE,IMG_SIZE,3)\n    pred_list.append(model.predict([data])[0][1])\n    img_list.append(img_idx[1])\n    \nsubmission = pd.DataFrame({'id':img_list , 'label':pred_list})\nsubmission.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}