{"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":"import glob\nimport pandas as pd\nimport plotly.graph_objects as go\nimport re\nimport numpy as np\nfrom PIL import Image\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras import datasets, layers, models\nimport matplotlib.pyplot as plt\nfrom keras_preprocessing import image\nfrom tensorflow.keras import callbacks\nimport os \nimport shutil\nimg_height=224\nimg_width=224","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:29:51.385739Z","iopub.execute_input":"2022-07-10T06:29:51.386046Z","iopub.status.idle":"2022-07-10T06:29:57.061979Z","shell.execute_reply.started":"2022-07-10T06:29:51.385969Z","shell.execute_reply":"2022-07-10T06:29:57.061050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# traning data handle\ndata_path='../input/classification-of-plants-of-southeast-asia/bali-26_train/bali-26_train'\ndata=[]\nfor folder_path in glob.glob('{}/*'.format(data_path)):\n    label=folder_path.split('/')[-1]\n    for file_path in glob.glob('{}/*.jpg'.format(folder_path)):\n        data.append([file_path,label])\ndf = pd.DataFrame(columns=['filepath', 'label'], data=data)\ndf.to_csv('data.csv',index=False)\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:29:57.066993Z","iopub.execute_input":"2022-07-10T06:29:57.067367Z","iopub.status.idle":"2022-07-10T06:30:10.344268Z","shell.execute_reply.started":"2022-07-10T06:29:57.067296Z","shell.execute_reply":"2022-07-10T06:30:10.343529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n                                  ","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"max_size= 1600\n\n\nsample_list=[]\ngroups=df.groupby('label')\nfor label in df['label'].unique():                 \n    group=groups.get_group(label)\n    sample_count=len(group)    \n    if sample_count> max_size:\n        samples=group.sample(max_size, replace=False, weights=None, random_state=123, axis=0).reset_index(drop=True)\n    else:\n        samples=group.sample(frac=1.0, replace=False, random_state=123, axis=0).reset_index(drop=True)\n    sample_list.append(samples)\ndf=pd.concat(sample_list, axis=0).reset_index(drop=True)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:30:10.345583Z","iopub.execute_input":"2022-07-10T06:30:10.345837Z","iopub.status.idle":"2022-07-10T06:30:10.397671Z","shell.execute_reply.started":"2022-07-10T06:30:10.345801Z","shell.execute_reply":"2022-07-10T06:30:10.397039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"working_dir=r'./'\naug_dir=os.path.join(working_dir, 'aug')\nif os.path.isdir(aug_dir):\n    shutil.rmtree(aug_dir)\nos.mkdir(aug_dir)\nfor label in df['label'].unique():\n    dir_path=os.path.join(aug_dir,label)    \n    os.mkdir(dir_path)\nprint(os.listdir(aug_dir))","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:30:10.399306Z","iopub.execute_input":"2022-07-10T06:30:10.399502Z","iopub.status.idle":"2022-07-10T06:30:10.411588Z","shell.execute_reply.started":"2022-07-10T06:30:10.399477Z","shell.execute_reply":"2022-07-10T06:30:10.410906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"target = max_size\ngen=ImageDataGenerator(horizontal_flip=True,\n                       rotation_range=20,\n                       width_shift_range=.2,\n                       height_shift_range=.2,\n                       zoom_range=.2)\ngroups=df.groupby('label')\nfor label in df['label'].unique():  # for every class            \n    group=groups.get_group(label)  # a dataframe holding only rows with the specified label \n    sample_count=len(group)   # determine how many samples there are in this class  \n    if sample_count< target: # if the class has less than target number of images\n        aug_img_count=0\n        delta=target-sample_count  # number of augmented images to create\n        target_dir=os.path.join(aug_dir, label)  # define where to write the images    \n        aug_gen=gen.flow_from_dataframe( group,  x_col='filepath', y_col=None, target_size=(img_height,img_width), class_mode=None, batch_size=1,\n                                         shuffle=False, save_to_dir=target_dir, save_prefix='aug-',save_format='jpg')\n        while aug_img_count<delta:\n            images=next(aug_gen)            \n            aug_img_count += len(images) ","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:30:10.413112Z","iopub.execute_input":"2022-07-10T06:30:10.413582Z","iopub.status.idle":"2022-07-10T06:33:04.912690Z","shell.execute_reply.started":"2022-07-10T06:30:10.413547Z","shell.execute_reply":"2022-07-10T06:33:04.911842Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"aug_fpaths=[]\naug_labels=[]\nclasslist=os.listdir(aug_dir)\nfor klass in classlist:\n    classpath=os.path.join(aug_dir, klass)     \n    flist=os.listdir(classpath)    \n    for f in flist:        \n        fpath=os.path.join(classpath,f)         \n        aug_fpaths.append(fpath)\n        aug_labels.append(klass)\nFseries=pd.Series(aug_fpaths, name='filepath')\nLseries=pd.Series(aug_labels, name='label')\naug_df=pd.concat([Fseries, Lseries], axis=1)\nprint ('length of aug_df\" ', len(aug_df))\nbalance_df=pd.concat([df,aug_df], axis=0).reset_index(drop=True)\nbalance_df=balance_df.sample(frac=1.0, replace=False, random_state=123, axis=0).reset_index(drop=True)\nprint ('length of df is: ', len(df)) \n\n# draw a histogram of the labels\nfig=go.Figure(data=[go.Histogram(x=balance_df['label'],xbins=dict(start=0,end=26,size=1))])\nfig.update_layout(title='Histogram of labels')\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:33:04.914532Z","iopub.execute_input":"2022-07-10T06:33:04.914862Z","iopub.status.idle":"2022-07-10T06:33:05.235512Z","shell.execute_reply.started":"2022-07-10T06:33:04.914820Z","shell.execute_reply":"2022-07-10T06:33:05.233348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import keras.backend as K\ndef f1_metric(y_true, y_pred):\n    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))\n    precision = true_positives / (predicted_positives + K.epsilon())\n    recall = true_positives / (possible_positives + K.epsilon())\n    f1_val = 2*(precision*recall)/(precision+recall+K.epsilon())\n    return f1_val","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:33:05.236820Z","iopub.execute_input":"2022-07-10T06:33:05.237742Z","iopub.status.idle":"2022-07-10T06:33:05.246648Z","shell.execute_reply.started":"2022-07-10T06:33:05.237703Z","shell.execute_reply":"2022-07-10T06:33:05.245727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for gpu in tf.config.experimental.list_physical_devices('GPU'):    \n    print(\"Name:\", gpu.name, \"  Type:\", gpu.device_type)\n    tf.compat.v2.config.experimental.set_memory_growth(gpu, True)","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:33:05.248186Z","iopub.execute_input":"2022-07-10T06:33:05.248883Z","iopub.status.idle":"2022-07-10T06:33:05.427635Z","shell.execute_reply.started":"2022-07-10T06:33:05.248772Z","shell.execute_reply":"2022-07-10T06:33:05.426741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# ImageDataGenerator\ntrain_data_dir='../input/classification-of-plants-of-southeast-asia/bali-26_train/bali-26_train'\nbatch_size=64\n\ntrain_datagen = ImageDataGenerator(rescale=1./255,\n    shear_range=0.2,\n    zoom_range=0.2,\n    rotation_range=30,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    fill_mode='nearest',\n    horizontal_flip=True,\n    validation_split=0.2 ) # set validation split","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:33:05.429061Z","iopub.execute_input":"2022-07-10T06:33:05.429722Z","iopub.status.idle":"2022-07-10T06:33:05.436831Z","shell.execute_reply.started":"2022-07-10T06:33:05.429661Z","shell.execute_reply":"2022-07-10T06:33:05.436041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load data\ntrain_generator = train_datagen.flow_from_dataframe(\n    balance_df,\n    x_col='filepath', y_col='label',\n    target_size=(img_height, img_width),\n    batch_size=batch_size, class_mode='categorical',\n    shuffle=True,\n    subset='training')  # set as training data\n\nvalidation_generator = train_datagen.flow_from_dataframe(\n    balance_df,\n    x_col='filepath', y_col='label',\n    target_size=(img_height, img_width),\n    batch_size=batch_size, class_mode='categorical',\n    subset='validation')  # set as validation data\n\n\nlabels = (train_generator.class_indices)\nlabels = dict((v,k) for k,v in labels.items())","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:33:05.441111Z","iopub.execute_input":"2022-07-10T06:33:05.441712Z","iopub.status.idle":"2022-07-10T06:33:52.315392Z","shell.execute_reply.started":"2022-07-10T06:33:05.441672Z","shell.execute_reply":"2022-07-10T06:33:52.314620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model = tf.keras.applications.resnet50.ResNet50(\n    include_top=False,\n    weights='imagenet',\n)\nbase_model.trainable = False\n\ninputs = tf.keras.Input(shape=(img_height, img_width, 3))\nx = base_model(inputs)\nx = tf.keras.layers.GlobalAveragePooling2D()(x)\noutputs = tf.keras.layers.Dense(26, activation=\"softmax\")(x)\nmodel = tf.keras.Model(inputs=inputs, outputs=outputs, name=\"my_model\")\nmodel.compile(optimizer=\"Adam\", loss=\"categorical_crossentropy\", metrics=[\"accuracy\",tf.keras.metrics.Recall(),tf.keras.metrics.Precision(),f1_metric])\nmodel.summary()\n","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:40:50.148980Z","iopub.execute_input":"2022-07-10T06:40:50.149697Z","iopub.status.idle":"2022-07-10T06:40:51.851054Z","shell.execute_reply.started":"2022-07-10T06:40:50.149659Z","shell.execute_reply":"2022-07-10T06:40:51.850352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## let train =))\n\nhistory = model.fit(\n  train_generator,\n  validation_data=validation_generator,\n  epochs=5)","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:41:04.807294Z","iopub.execute_input":"2022-07-10T06:41:04.807578Z","iopub.status.idle":"2022-07-10T06:41:18.937404Z","shell.execute_reply.started":"2022-07-10T06:41:04.807544Z","shell.execute_reply":"2022-07-10T06:41:18.935240Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('model.h5')","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:34:00.928077Z","iopub.status.idle":"2022-07-10T06:34:00.928380Z","shell.execute_reply.started":"2022-07-10T06:34:00.928220Z","shell.execute_reply":"2022-07-10T06:34:00.928242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''try:\n    # summarize history \n    acc = history.history['accuracy']\n    val_acc = history.history['val_accuracy']\n\n    loss = history.history['loss']\n    val_loss = history.history['val_loss']\n\n    epochs_range = range(len(acc))\n\n    fig=plt.figure(figsize=(8, 8))\n    fig.set_size_inches(18.5, 10.5)\n    plt.subplot(1, 2, 1)\n    plt.plot(epochs_range, acc, label='Training Accuracy')\n    plt.plot(epochs_range, val_acc, label='Validation Accuracy')\n    plt.legend(loc='lower right')\n    plt.title('Training and Validation Accuracy')\n\n    plt.subplot(1, 2, 2)\n    plt.plot(epochs_range, loss, label='Training Loss')\n    plt.plot(epochs_range, val_loss, label='Validation Loss')\n    plt.legend(loc='upper right')\n    plt.title('Training and Validation Loss')\n    plt.show()\nexcept:\n    pass'''","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:34:00.929550Z","iopub.status.idle":"2022-07-10T06:34:00.930439Z","shell.execute_reply.started":"2022-07-10T06:34:00.930181Z","shell.execute_reply":"2022-07-10T06:34:00.930208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs_range = range(len(history.history['accuracy']))\n\nfig=plt.figure()\nfig.set_size_inches(20,20)\nplt.subplot(3, 2, 1)\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\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(3, 2, 2)\nloss = history.history['loss']\nval_loss = history.history['val_loss']\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')\n\nplt.subplot(3, 2, 3)\nloss = history.history['f1_metric']\nval_loss = history.history['val_f1_metric']\nplt.plot(epochs_range, loss, label='Training f1_metric')\nplt.plot(epochs_range, val_loss, label='Validation f1_metric')\nplt.legend(loc='upper right')\nplt.title('Training and Validation f1_metric')\n\nplt.subplot(3, 2, 4)\nloss = history.history['precision']\nval_loss = history.history['val_precision']\nplt.plot(epochs_range, loss, label='Training precision')\nplt.plot(epochs_range, val_loss, label='Validation precision')\nplt.legend(loc='upper right')\nplt.title('Training and Validation precision')\n\nplt.subplot(3, 2, 5)\nloss = history.history['recall']\nval_loss = history.history['val_recall']\nplt.plot(epochs_range, loss, label='Training recall')\nplt.plot(epochs_range, val_loss, label='Validation recall')\nplt.legend(loc='upper right')\nplt.title('Training and Validation recall')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:34:00.931764Z","iopub.status.idle":"2022-07-10T06:34:00.932613Z","shell.execute_reply.started":"2022-07-10T06:34:00.932365Z","shell.execute_reply":"2022-07-10T06:34:00.932391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predict the test for submission\nfolder_path='../input/classification-of-plants-of-southeast-asia/bali-26_test/bali-26_test'\nimages= glob.glob('{}/*.jpg'.format(folder_path))\nsubmissions=[]\n\nfor image_file in images:\n    img = image.load_img(image_file, target_size=(img_height, img_width))\n    x = image.img_to_array(img)\n    x = x / 255.0\n    x = x.reshape((1,)+x.shape)\n    predict=model.predict(x)[0]\n    \n    idd=image_file.split('/')[-1]\n    category=labels[np.argmax(predict)]\n    submissions.append([idd,category])\ndf = pd.DataFrame(columns=['id', 'category'], data=submissions)\ndf.to_csv('submission.csv',index=False)\nplt.imshow(img)\nprint(predict)\nprint(category)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-10T06:34:00.933789Z","iopub.status.idle":"2022-07-10T06:34:00.934228Z","shell.execute_reply.started":"2022-07-10T06:34:00.933980Z","shell.execute_reply":"2022-07-10T06:34:00.934002Z"},"trusted":true},"execution_count":null,"outputs":[]}]}