{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# import libraries\n", "import tensorflow as tf\n", "from tensorflow.keras import layers, models\n", "from matplotlib import pyplot as plt\n", "from tensorflow.keras.preprocessing.image import ImageDataGenerator" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found 1674 images belonging to 8 classes.\n", "Found 157 images belonging to 8 classes.\n", "Found 79 images belonging to 8 classes.\n" ] } ], "source": [ "TRAIN_DIR = 'dataset/train'\n", "TEST_DIR = 'dataset/test'\n", "VAL_DIR = 'dataset/val'\n", "# Load dataset\n", "datagen = ImageDataGenerator(rescale=1./255)\n", "# Load data dari direktori menggunakan flow_from_directory\n", "train_generator = datagen.flow_from_directory(\n", " TRAIN_DIR,\n", " target_size=(224, 224), # Sesuaikan dengan ukuran gambar input model\n", " batch_size=32,\n", " class_mode='categorical'\n", ")\n", "\n", "val_generator = datagen.flow_from_directory(\n", " VAL_DIR,\n", " target_size=(224, 224),\n", " batch_size=32,\n", " class_mode='categorical'\n", ")\n", "\n", "test_generator = datagen.flow_from_directory(\n", " TEST_DIR,\n", " target_size=(224, 224),\n", " batch_size=32,\n", " class_mode='categorical',\n", " shuffle=False # Untuk testing, tidak perlu shuffle\n", ")" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Daun Jambu Biji': 0,\n", " 'Daun Kemangi': 1,\n", " 'Daun Kunyit': 2,\n", " 'Daun Mint': 3,\n", " 'Daun Pepaya': 4,\n", " 'Daun Sirih': 5,\n", " 'Daun Sirsak': 6,\n", " 'Lidah Buaya': 7}" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "train_generator.class_indices" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "model = models.Sequential()\n", "\n", "model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)))\n", "model.add(layers.MaxPooling2D((2, 2)))\n", "model.add(layers.Conv2D(64, (3, 3), activation='relu'))\n", "model.add(layers.MaxPooling2D((2, 2)))\n", "model.add(layers.Conv2D(128, (3, 3), activation='relu'))\n", "model.add(layers.MaxPooling2D((2, 2)))\n", "model.add(layers.Conv2D(128, (3, 3), activation='relu'))\n", "model.add(layers.MaxPooling2D((2, 2)))\n", "\n", "model.add(layers.Flatten())\n", "model.add(layers.Dense(512, activation='relu'))\n", "model.add(layers.Dense(8, activation='softmax'))\n", "\n", "model.compile(optimizer='adam',\n", " loss='categorical_crossentropy',\n", " metrics=['accuracy'])\n", " " ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Model: \"sequential_4\"\n",
       "
\n" ], "text/plain": [ "\u001b[1mModel: \"sequential_4\"\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
       "┃ Layer (type)                     Output Shape                  Param # ┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
       "│ conv2d_13 (Conv2D)              │ (None, 222, 222, 32)   │           896 │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ max_pooling2d_13 (MaxPooling2D) │ (None, 111, 111, 32)   │             0 │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv2d_14 (Conv2D)              │ (None, 109, 109, 64)   │        18,496 │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ max_pooling2d_14 (MaxPooling2D) │ (None, 54, 54, 64)     │             0 │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv2d_15 (Conv2D)              │ (None, 52, 52, 128)    │        73,856 │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ max_pooling2d_15 (MaxPooling2D) │ (None, 26, 26, 128)    │             0 │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv2d_16 (Conv2D)              │ (None, 24, 24, 128)    │       147,584 │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ max_pooling2d_16 (MaxPooling2D) │ (None, 12, 12, 128)    │             0 │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ flatten_4 (Flatten)             │ (None, 18432)          │             0 │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ dense_8 (Dense)                 │ (None, 512)            │     9,437,696 │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ dense_9 (Dense)                 │ (None, 8)              │         4,104 │\n",
       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
       "
\n" ], "text/plain": [ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", "│ conv2d_13 (\u001b[38;5;33mConv2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m222\u001b[0m, \u001b[38;5;34m222\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m896\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ max_pooling2d_13 (\u001b[38;5;33mMaxPooling2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m111\u001b[0m, \u001b[38;5;34m111\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ conv2d_14 (\u001b[38;5;33mConv2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m109\u001b[0m, \u001b[38;5;34m109\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m18,496\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ max_pooling2d_14 (\u001b[38;5;33mMaxPooling2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m54\u001b[0m, \u001b[38;5;34m54\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ conv2d_15 (\u001b[38;5;33mConv2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m52\u001b[0m, \u001b[38;5;34m52\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m73,856\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ max_pooling2d_15 (\u001b[38;5;33mMaxPooling2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m26\u001b[0m, \u001b[38;5;34m26\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ conv2d_16 (\u001b[38;5;33mConv2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m24\u001b[0m, \u001b[38;5;34m24\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m147,584\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ max_pooling2d_16 (\u001b[38;5;33mMaxPooling2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m, \u001b[38;5;34m12\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ flatten_4 (\u001b[38;5;33mFlatten\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m18432\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ dense_8 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m9,437,696\u001b[0m │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", "│ dense_9 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m8\u001b[0m) │ \u001b[38;5;34m4,104\u001b[0m │\n", "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
 Total params: 9,682,632 (36.94 MB)\n",
       "
\n" ], "text/plain": [ "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m9,682,632\u001b[0m (36.94 MB)\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
 Trainable params: 9,682,632 (36.94 MB)\n",
       "
\n" ], "text/plain": [ "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m9,682,632\u001b[0m (36.94 MB)\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
 Non-trainable params: 0 (0.00 B)\n",
       "
\n" ], "text/plain": [ "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "model.summary()" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/20\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2024-10-14 11:16:05.231584: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:117] Plugin optimizer for device_type GPU is enabled.\n", "/Users/edoaurahman/development/anaconda/anaconda3/envs/tensorflow/lib/python3.10/site-packages/keras/src/trainers/data_adapters/py_dataset_adapter.py:122: UserWarning: Your `PyDataset` class should call `super().__init__(**kwargs)` in its constructor. `**kwargs` can include `workers`, `use_multiprocessing`, `max_queue_size`. Do not pass these arguments to `fit()`, as they will be ignored.\n", " self._warn_if_super_not_called()\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m26s\u001b[0m 353ms/step - accuracy: 0.2478 - loss: 2.1296 - val_accuracy: 0.5987 - val_loss: 1.1171\n", "Epoch 2/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 339ms/step - accuracy: 0.6152 - loss: 1.0357 - val_accuracy: 0.6688 - val_loss: 0.8430\n", "Epoch 3/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 322ms/step - accuracy: 0.7471 - loss: 0.7063 - val_accuracy: 0.7898 - val_loss: 0.6230\n", "Epoch 4/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 370ms/step - accuracy: 0.8481 - loss: 0.4345 - val_accuracy: 0.8408 - val_loss: 0.5627\n", "Epoch 5/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m26s\u001b[0m 471ms/step - accuracy: 0.9096 - loss: 0.2562 - val_accuracy: 0.8408 - val_loss: 0.5344\n", "Epoch 6/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 363ms/step - accuracy: 0.9161 - loss: 0.2274 - val_accuracy: 0.8408 - val_loss: 0.8011\n", "Epoch 7/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 367ms/step - accuracy: 0.9671 - loss: 0.0961 - val_accuracy: 0.8408 - val_loss: 0.6227\n", "Epoch 8/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m22s\u001b[0m 403ms/step - accuracy: 0.9832 - loss: 0.0657 - val_accuracy: 0.7898 - val_loss: 0.9990\n", "Epoch 9/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m23s\u001b[0m 420ms/step - accuracy: 0.9750 - loss: 0.0758 - val_accuracy: 0.8344 - val_loss: 0.8001\n", "Epoch 10/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 378ms/step - accuracy: 0.9909 - loss: 0.0312 - val_accuracy: 0.8344 - val_loss: 1.0499\n", "Epoch 11/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m19s\u001b[0m 359ms/step - accuracy: 0.9803 - loss: 0.0627 - val_accuracy: 0.8599 - val_loss: 0.8847\n", "Epoch 12/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 369ms/step - accuracy: 0.9984 - loss: 0.0089 - val_accuracy: 0.8280 - val_loss: 1.0634\n", "Epoch 13/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 377ms/step - accuracy: 0.9980 - loss: 0.0106 - val_accuracy: 0.8217 - val_loss: 1.2077\n", "Epoch 14/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 333ms/step - accuracy: 0.9768 - loss: 0.0614 - val_accuracy: 0.8535 - val_loss: 0.8965\n", "Epoch 15/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m19s\u001b[0m 345ms/step - accuracy: 0.9867 - loss: 0.0368 - val_accuracy: 0.7962 - val_loss: 1.3721\n", "Epoch 16/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m22s\u001b[0m 408ms/step - accuracy: 0.9825 - loss: 0.0534 - val_accuracy: 0.8153 - val_loss: 1.1506\n", "Epoch 17/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 372ms/step - accuracy: 0.9965 - loss: 0.0116 - val_accuracy: 0.8471 - val_loss: 1.2062\n", "Epoch 18/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m20s\u001b[0m 376ms/step - accuracy: 1.0000 - loss: 0.0027 - val_accuracy: 0.8408 - val_loss: 1.2559\n", "Epoch 19/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m22s\u001b[0m 415ms/step - accuracy: 1.0000 - loss: 2.3890e-04 - val_accuracy: 0.8535 - val_loss: 1.3033\n", "Epoch 20/20\n", "\u001b[1m53/53\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m22s\u001b[0m 411ms/step - accuracy: 1.0000 - loss: 1.3011e-04 - val_accuracy: 0.8471 - val_loss: 1.2932\n" ] } ], "source": [ "# Melatih model dengan data train, validasi dilakukan dengan data validation\n", "history = model.fit(\n", " train_generator,\n", " epochs=10, # Sesuaikan jumlah epoch\n", " validation_data=val_generator\n", ")" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] } ], "source": [ "# save model\n", "model.save('model.h5')" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "# save history\n", "import pickle\n", "with open('history.pkl', 'wb') as file_pi:\n", " pickle.dump(history.history, file_pi)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2024-10-14 11:41:05.053908: I metal_plugin/src/device/metal_device.cc:1154] Metal device set to: Apple M1\n", "2024-10-14 11:41:05.053947: I metal_plugin/src/device/metal_device.cc:296] systemMemory: 8.00 GB\n", "2024-10-14 11:41:05.053957: I metal_plugin/src/device/metal_device.cc:313] maxCacheSize: 2.67 GB\n", "2024-10-14 11:41:05.054262: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:305] Could not identify NUMA node of platform GPU ID 0, defaulting to 0. Your kernel may not have been built with NUMA support.\n", "2024-10-14 11:41:05.054278: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:271] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 0 MB memory) -> physical PluggableDevice (device: 0, name: METAL, pci bus id: )\n", "WARNING:absl:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.\n" ] } ], "source": [ "import tensorflow as tf\n", "\n", "# Load model .h5\n", "model = tf.keras.models.load_model('model.h5')" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "import cv2\n", "import numpy as np\n", "from tensorflow.keras.preprocessing.image import img_to_array\n", "\n", "def preprocess_image(image_path, img_size):\n", " # Baca gambar\n", " img = cv2.imread(image_path)\n", " \n", " # Resize gambar sesuai dengan input model\n", " img = cv2.resize(img, (img_size, img_size))\n", " \n", " # Konversi gambar ke array dan normalisasi\n", " \n", " # Tambahkan dimensi batch: (height, width, channels) -> (1, height, width, channels)\n", " img = np.expand_dims(img, axis=0)\n", " \n", " return img\n" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 152ms/step\n", "Predictions: [[0. 0. 0. 1. 0. 0. 0. 0.]]\n", "Predicted class: [3]\n", "Predicted class: Daun Mint\n" ] } ], "source": [ "# Path ke gambar yang ingin diprediksi\n", "image_path = 'lidah-buaya.jpg'\n", "\n", "# Preprocessing gambar (misalnya ukuran gambar input yang diharapkan model adalah 224x224)\n", "img_size = 224\n", "preprocessed_image = preprocess_image(image_path, img_size)\n", "\n", "# Prediksi menggunakan model\n", "predictions = model.predict(preprocessed_image)\n", "\n", "# Tampilkan hasil prediksi\n", "print(\"Predictions:\", predictions)\n", "\n", "# Ambil kelas dengan probabilitas tertinggi\n", "predicted_class = np.argmax(predictions, axis=1)\n", "\n", "# Cetak kelas yang diprediksi\n", "print(\"Predicted class:\", predicted_class)\n", "\n", "class_names = ['Daun Jambu Biji',\n", " 'Daun Kemangi',\n", " 'Daun Kunyit',\n", " 'Daun Mint',\n", " 'Daun Pepaya',\n", " 'Daun Sirih',\n", " 'Daun Sirsak',\n", " 'Lidah Buaya']\n", "# Konversi indeks prediksi menjadi nama kelas\n", "predicted_class_name = class_names[predicted_class[0]]\n", "\n", "print(\"Predicted class:\", predicted_class_name)\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.14" } }, "nbformat": 4, "nbformat_minor": 4 }