{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":25563,"databundleVersionId":2094376,"sourceType":"competition"},{"sourceId":2032065,"sourceType":"datasetVersion","datasetId":1216613}],"dockerImageVersionId":30302,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"数据准备和环境","metadata":{}},{"cell_type":"code","source":"#导入相关库\nfrom tensorflow.keras.utils import to_categorical\nimport numpy as np\nfrom glob import glob\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import MultiLabelBinarizer\nfrom skimage import exposure\nimport cv2 as cv\nimport os\nimport itertools\nimport seaborn as sns\nimport os\nimport multiprocessing as mproc\nfrom keras.preprocessing import image\nfrom matplotlib.pyplot import figure\n\n#from tensorflow import keras\n#from tensorflow.keras import layers,models\n\n\nfrom tqdm import tqdm\n%matplotlib inline\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:14:35.19186Z","iopub.execute_input":"2022-11-08T14:14:35.193278Z","iopub.status.idle":"2022-11-08T14:14:40.869129Z","shell.execute_reply.started":"2022-11-08T14:14:35.193139Z","shell.execute_reply":"2022-11-08T14:14:40.868119Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#检查GPU可用性\nimport tensorflow as tf\n\ngpus = tf.config.experimental.list_physical_devices('GPU')\nfor gpu in gpus:\n    print(\"Name:\", gpu.name, \"  Type:\", gpu.device_type)\ntf.test.is_gpu_available()\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:14:40.872918Z","iopub.execute_input":"2022-11-08T14:14:40.874179Z","iopub.status.idle":"2022-11-08T14:14:43.406452Z","shell.execute_reply.started":"2022-11-08T14:14:40.874139Z","shell.execute_reply":"2022-11-08T14:14:43.405344Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#读取数据\n#train_dir= '/kaggle/input/plant-pathology-2021-fgvc8/train_images/'\ntrain_dir = '../input/resized-plant2021/img_sz_256/'\ntest_dir =  '/kaggle/input/plant-pathology-2021-fgvc8/test_images/'\ndf = pd.read_csv('../input/plant-pathology-2021-fgvc8/train.csv')","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:14:43.408229Z","iopub.execute_input":"2022-11-08T14:14:43.409045Z","iopub.status.idle":"2022-11-08T14:14:43.444797Z","shell.execute_reply.started":"2022-11-08T14:14:43.409006Z","shell.execute_reply":"2022-11-08T14:14:43.443917Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_files = glob(train_dir + '/*.jpg')\ntest_files = glob(test_dir + '/*.jpg')\nprint('# files for train',len(train_files))\nprint('# files for train',len(test_files))\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:14:43.447954Z","iopub.execute_input":"2022-11-08T14:14:43.44836Z","iopub.status.idle":"2022-11-08T14:14:43.731949Z","shell.execute_reply.started":"2022-11-08T14:14:43.448321Z","shell.execute_reply":"2022-11-08T14:14:43.730841Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#数据样本\ndef visualize_batch(path,image_ids, labels):\n    plt.figure(figsize=(16, 12))\n    \n    for ind, (image_id, label) in enumerate(zip(image_ids, labels)):\n        plt.subplot(3, 3, ind + 1)\n        image = cv.imread(os.path.join(path, image_id))\n        image = cv.cvtColor(image, cv.COLOR_BGR2RGB)\n\n        plt.imshow(image)\n        plt.title(f\"Класс: {label}\", fontsize=12)\n        plt.axis(\"off\")\n    plt.show()\nts = df.sample(9)\nimage_ids = ts[\"image\"].values\nlabels = ts[\"labels\"].values\nvisualize_batch(train_dir,image_ids,labels)\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:14:43.733431Z","iopub.execute_input":"2022-11-08T14:14:43.733961Z","iopub.status.idle":"2022-11-08T14:14:44.651149Z","shell.execute_reply.started":"2022-11-08T14:14:43.733923Z","shell.execute_reply":"2022-11-08T14:14:44.649939Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 图像处理\n\ndef plot_comparison(original, filtered, title_filtered):\n  fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 6), sharex=True, sharey=True)\n  ax1.imshow(original, cmap=plt.cm.gray) \n  ax1.set_title('original') \n  ax1.axis('off')\n  ax2.imshow(filtered, cmap=plt.cm.gray) \n  ax2.set_title(title_filtered) \n  ax2.axis('off')","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:14:44.652198Z","iopub.execute_input":"2022-11-08T14:14:44.652531Z","iopub.status.idle":"2022-11-08T14:14:44.660625Z","shell.execute_reply.started":"2022-11-08T14:14:44.652501Z","shell.execute_reply":"2022-11-08T14:14:44.659577Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"leaf_image = cv.imread('../input/plant-pathology-2021-fgvc8/train_images/80273091d9e9bddb.jpg')\nleaf_image = cv.cvtColor(leaf_image, cv.COLOR_BGR2RGB)\n\nplt.imshow(leaf_image)","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:14:44.662435Z","iopub.execute_input":"2022-11-08T14:14:44.663074Z","iopub.status.idle":"2022-11-08T14:14:46.639934Z","shell.execute_reply.started":"2022-11-08T14:14:44.663039Z","shell.execute_reply":"2022-11-08T14:14:46.638838Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#直方图均衡化是一种提高图像对比度的方法\nfrom skimage import exposure\nequalized_leaf_image = exposure.equalize_hist(leaf_image)\n\nplot_comparison(leaf_image, equalized_leaf_image, 'Histogram equalization')\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:14:46.641562Z","iopub.execute_input":"2022-11-08T14:14:46.642295Z","iopub.status.idle":"2022-11-08T14:14:53.333089Z","shell.execute_reply.started":"2022-11-08T14:14:46.642243Z","shell.execute_reply":"2022-11-08T14:14:53.331952Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"adapthits_leag_image = exposure.equalize_adapthist(leaf_image)\n\nplot_comparison(leaf_image, adapthits_leag_image, 'Adaptive Histogram equalization')\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:14:53.334718Z","iopub.execute_input":"2022-11-08T14:14:53.335319Z","iopub.status.idle":"2022-11-08T14:15:05.345755Z","shell.execute_reply.started":"2022-11-08T14:14:53.335282Z","shell.execute_reply":"2022-11-08T14:15:05.344809Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#绘制直方图\nred = leaf_image[:, :, 0]\ngreen = leaf_image[:, 0, :]\nblue = leaf_image[0, :, :]\n\n\nplt.hist(red.ravel(), bins=32) \nplt.title('Red Histogram')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:15:05.350887Z","iopub.execute_input":"2022-11-08T14:15:05.351208Z","iopub.status.idle":"2022-11-08T14:15:05.744776Z","shell.execute_reply.started":"2022-11-08T14:15:05.35118Z","shell.execute_reply":"2022-11-08T14:15:05.743761Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.hist(green.ravel(), bins=32) \nplt.title('Green Histogram')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:15:05.746131Z","iopub.execute_input":"2022-11-08T14:15:05.746601Z","iopub.status.idle":"2022-11-08T14:15:05.985577Z","shell.execute_reply.started":"2022-11-08T14:15:05.746564Z","shell.execute_reply":"2022-11-08T14:15:05.984665Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.hist(blue.ravel(), bins=32) \nplt.title('Blue Histogram')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:15:05.987026Z","iopub.execute_input":"2022-11-08T14:15:05.987348Z","iopub.status.idle":"2022-11-08T14:15:06.212875Z","shell.execute_reply.started":"2022-11-08T14:15:05.987322Z","shell.execute_reply":"2022-11-08T14:15:06.211756Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#类别标签\nlabels_all = list(itertools.chain(*[lbs.split(\" \") for lbs in df['labels']]))\nfigure(figsize=(8, 6), dpi=80)\n\nax = sns.countplot(y=sorted(labels_all), orient='x')\nax.grid()\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:15:06.214269Z","iopub.execute_input":"2022-11-08T14:15:06.214861Z","iopub.status.idle":"2022-11-08T14:15:06.473699Z","shell.execute_reply.started":"2022-11-08T14:15:06.214821Z","shell.execute_reply":"2022-11-08T14:15:06.472713Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels_all = list(itertools.chain([lbs for lbs in df['labels']]))\nfigure(figsize=(8, 6), dpi=80)\n\nax = sns.countplot(y=sorted(labels_all), orient='x')\nax.grid()\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:15:06.475082Z","iopub.execute_input":"2022-11-08T14:15:06.47612Z","iopub.status.idle":"2022-11-08T14:15:06.965718Z","shell.execute_reply.started":"2022-11-08T14:15:06.47608Z","shell.execute_reply":"2022-11-08T14:15:06.964718Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#查看数据\nprint(df.head(10))\nprint(df.labels.value_counts())","metadata":{"execution":{"iopub.status.busy":"2024-11-28T14:38:16.443784Z","iopub.execute_input":"2024-11-28T14:38:16.444082Z","iopub.status.idle":"2024-11-28T14:38:16.516927Z","shell.execute_reply.started":"2024-11-28T14:38:16.444008Z","shell.execute_reply":"2024-11-28T14:38:16.515810Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Как видно, labels содержит метки классов, разделенные пробелом. Необходимо преобразовать данные метки в двоичные аттрибуты. Используем копию датафрейма *train*","metadata":{}},{"cell_type":"code","source":"#模型配置\ntrain = df.copy()\ntrain['labels'] = df['labels'].apply(lambda string: string.split(' '))\n\ns = list(train['labels'])\nmlb = MultiLabelBinarizer()\ntrainx = pd.DataFrame(mlb.fit_transform(s), columns=mlb.classes_, index=train.index)\ntrainx['image'] = train['image']\n\nprint(trainx.head(10))\nprint(trainx.columns)","metadata":{"execution":{"iopub.status.busy":"2024-11-28T14:39:39.400485Z","iopub.execute_input":"2024-11-28T14:39:39.401355Z","iopub.status.idle":"2024-11-28T14:39:39.494242Z","shell.execute_reply.started":"2024-11-28T14:39:39.401250Z","shell.execute_reply":"2024-11-28T14:39:39.492745Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TARGET_SIZE = 128\nBATCH_SIZE = 64\nEPOCHS = 50\nDATA_LIMIT = 12000","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:15:07.02733Z","iopub.execute_input":"2022-11-08T14:15:07.028366Z","iopub.status.idle":"2022-11-08T14:15:07.036441Z","shell.execute_reply.started":"2022-11-08T14:15:07.028329Z","shell.execute_reply":"2022-11-08T14:15:07.035238Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"trainx = trainx[:DATA_LIMIT]","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_image = []\nfor i in tqdm(range(trainx.shape[0])):\n    \n    img = image.load_img(train_dir+ trainx['image'][i],target_size=(TARGET_SIZE,TARGET_SIZE,3))\n    #image_data = apply_clahe(img)\n    #ret,thresh1 = cv.threshold(image_data,120, 255, cv.THRESH_TOZERO)\n    \n    #img = apply_clahe(train_dir+ trainx['image'][i])\n    #img = cv.imread(train_dir+z,) #reading the image\n    #img = img/255\n    #ret,thresh1 = cv.threshold(np.asarray(img),110, 255, cv.THRESH_TOZERO)\n    #plt.imshow(thresh1)\n    img = image.img_to_array(img)\n    img = img/255\n    train_image.append(img)\n\nX = np.array(train_image)\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:15:07.03784Z","iopub.execute_input":"2022-11-08T14:15:07.038287Z","iopub.status.idle":"2022-11-08T14:16:49.68314Z","shell.execute_reply.started":"2022-11-08T14:15:07.03825Z","shell.execute_reply":"2022-11-08T14:16:49.681972Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import pickle\n# file = open('x_array', 'wb')\n# pickle.dump(X, file)\n# file.close()\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:16:49.684955Z","iopub.execute_input":"2022-11-08T14:16:49.685375Z","iopub.status.idle":"2022-11-08T14:16:49.690979Z","shell.execute_reply.started":"2022-11-08T14:16:49.685336Z","shell.execute_reply":"2022-11-08T14:16:49.689993Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#检查图像尺寸\nplt.imshow(X[2])\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:16:49.692404Z","iopub.execute_input":"2022-11-08T14:16:49.695125Z","iopub.status.idle":"2022-11-08T14:16:49.940727Z","shell.execute_reply.started":"2022-11-08T14:16:49.695088Z","shell.execute_reply":"2022-11-08T14:16:49.939744Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#查看数据大小 \ny = np.array(trainx.drop(['image'],axis=1))\ny.shape\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:16:49.943791Z","iopub.execute_input":"2022-11-08T14:16:49.94419Z","iopub.status.idle":"2022-11-08T14:16:49.955756Z","shell.execute_reply.started":"2022-11-08T14:16:49.944157Z","shell.execute_reply":"2022-11-08T14:16:49.954708Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#划分数据集\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1)\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:16:49.959295Z","iopub.execute_input":"2022-11-08T14:16:49.959652Z","iopub.status.idle":"2022-11-08T14:16:50.989941Z","shell.execute_reply.started":"2022-11-08T14:16:49.959623Z","shell.execute_reply":"2022-11-08T14:16:50.988832Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**建模**","metadata":{}},{"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten\nfrom keras.layers import Conv2D, MaxPooling2D\n\nmodel = Sequential()\nmodel.add(Conv2D(filters=16, kernel_size=(5, 5), activation=\"relu\", input_shape=(TARGET_SIZE,TARGET_SIZE,3)))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\nmodel.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\nmodel.add(Conv2D(filters=64, kernel_size=(5, 5), activation=\"relu\"))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\nmodel.add(Conv2D(filters=64, kernel_size=(5, 5), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(64, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(6, activation='sigmoid'))\nmodel.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n\n\n# model.add(Conv2D(64,(3,3), padding=\"same\", activation=\"relu\"))\n# model.add(MaxPool2D())\n# model.add(Conv2D(128, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(Conv2D(128, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(MaxPool2D())\n# model.add(Conv2D(256, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(Conv2D(256, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(Conv2D(256, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(MaxPool2D())\n# model.add(Conv2D(512, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(Conv2D(512, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(Conv2D(512, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(MaxPool2D())\n# model.add(Conv2D(512, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(Conv2D(512, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(Conv2D(512, (3,3), padding=\"same\", activation=\"relu\"))\n# model.add(MaxPool2D())\n\n# model.add(Flatten())\n# model.add(Dense(4096,activation=\"relu\"))\n# model.add(Dropout(0.2))\n# model.add(Dense(2048,activation=\"relu\"))\n# model.add(Dropout(0.2))\n\n# model.add(Dropout(0.25))\n# model.add(Flatten())\n# model.add(Dense(128, activation='relu'))\n# model.add(Dropout(0.5))\n# model.add(Dense(64, activation='relu'))\n# model.add(Dropout(0.5))\n# model.add(Dense(6, activation=\"sigmoid\"))\n# model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss='binary_crossentropy', metrics=['accuracy'])\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:16:50.991731Z","iopub.execute_input":"2022-11-08T14:16:50.992189Z","iopub.status.idle":"2022-11-08T14:16:51.696077Z","shell.execute_reply.started":"2022-11-08T14:16:50.992149Z","shell.execute_reply":"2022-11-08T14:16:51.694957Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#模型拟合\nmodel.fit(X_train, y_train, epochs=EPOCHS, validation_data=(X_test, y_test), batch_size=BATCH_SIZE)\n","metadata":{"execution":{"iopub.status.busy":"2022-11-08T14:16:51.700291Z","iopub.execute_input":"2022-11-08T14:16:51.701156Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#在测试数据上检验模型\nclasses = np.array(trainx.columns[:-1])\nproba = model.predict(img.reshape(1,TARGET_SIZE,TARGET_SIZE,3))\ntop_3 = np.argsort(proba[0])[:-4:-1]\nfor i in range(3):\n    print(\"{}\".format(classes[top_3[i]])+\" ({:.3})\".format(proba[0][top_3[i]]))\nplt.imshow(img)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#处理验证图像文件并生成submission.csv\nname = {0: 'complex',\n        1: 'frog_eye_leaf_spot',\n        2: 'healthy',\n        3: 'powdery_mildew',\n        4: 'rust',\n        5: 'scab'}\n\nthreshold = {0: 0.3,\n             1: 0.3,\n             2: 0.4,\n             3: 0.3,\n             4: 0.3,\n            5:0.3}\n\nd = []\n\nfor f in test_files:\n    img = image.load_img(f,target_size=(TARGET_SIZE,TARGET_SIZE,3))\n    img = image.img_to_array(img)\n    img = img/255\n    proba = list(model.predict(img.reshape(1,TARGET_SIZE,TARGET_SIZE,3))[0])\n    filename = f.split('/')[-1]\n    pre = []\n    for i in range(len(proba)):\n        if proba[i] > threshold[i]:\n            pre.append(name[i])\n            \n    d.append({'image': filename, 'labels': ' '.join(pre)})\n    \ndf = pd.DataFrame(d)\ndf.to_csv('submission.csv', index=False)\ndf.head()","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}