Buckets:
| { | |
| "cells": [ | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "id": "tYm5pVspx9xd" | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "import os\n", | |
| "import cv2\n", | |
| "import numpy as np\n", | |
| "import pandas as pd\n", | |
| "import matplotlib.pyplot as plt\n", | |
| "from PIL import Image\n", | |
| "from tensorflow.keras import datasets\n", | |
| "import tensorflow as tf\n", | |
| "from datasets import load_dataset\n", | |
| "from tensorflow.keras import layers, models, Input\n", | |
| "from tensorflow.keras.optimizers import Adam\n", | |
| "from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\n", | |
| "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", | |
| "from sklearn.model_selection import train_test_split\n", | |
| "from sklearn.metrics import classification_report" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "id": "uuEHs11CybIY" | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "dataset = load_dataset(\"mssqpi/Arabic-OCR-Dataset\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "id": "Kojidf-t3X33" | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "data = dataset['train'].to_pandas().sample(10000,random_state=42)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 206 | |
| }, | |
| "id": "keRHyPqF3kMp", | |
| "outputId": "b13b6609-5a81-4248-e81c-be11b2bbfda9" | |
| }, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "application/vnd.google.colaboratory.intrinsic+json": { | |
| "summary": "{\n \"name\": \"data\",\n \"rows\": 10000,\n \"fields\": [\n {\n \"column\": \"image\",\n \"properties\": {\n \"dtype\": \"object\",\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"text\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 9637,\n \"samples\": [\n \"\\u0623\\u0648\\u063a\\u0628\\u064a\\u0646\\u0627\",\n \"\\u062a\\u062a\\u062e\\u064a\\u0644\\u0647\\u0627\",\n \"\\u0644\\u0644\\u0645\\u062f\\u0627\\u0631\\u062a\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}", | |
| "type": "dataframe", | |
| "variable_name": "data" | |
| }, | |
| "text/html": [ | |
| "\n", | |
| " <div id=\"df-723630bc-9828-4765-b575-ea70528706e8\" class=\"colab-df-container\">\n", | |
| " <div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>image</th>\n", | |
| " <th>text</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>49403</th>\n", | |
| " <td>{'bytes': b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHD...</td>\n", | |
| " <td>للمنظمين</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>900283</th>\n", | |
| " <td>{'bytes': b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHD...</td>\n", | |
| " <td>تأويلاته</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1972199</th>\n", | |
| " <td>{'bytes': b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHD...</td>\n", | |
| " <td>ومعراجه</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>907367</th>\n", | |
| " <td>{'bytes': b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHD...</td>\n", | |
| " <td>كانجريلور</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>736158</th>\n", | |
| " <td>{'bytes': b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHD...</td>\n", | |
| " <td>الاثينين</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>\n", | |
| " <div class=\"colab-df-buttons\">\n", | |
| "\n", | |
| " <div class=\"colab-df-container\">\n", | |
| " <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-723630bc-9828-4765-b575-ea70528706e8')\"\n", | |
| " title=\"Convert this dataframe to an interactive table.\"\n", | |
| " style=\"display:none;\">\n", | |
| "\n", | |
| " <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n", | |
| " <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n", | |
| " </svg>\n", | |
| " </button>\n", | |
| "\n", | |
| " <style>\n", | |
| " .colab-df-container {\n", | |
| " display:flex;\n", | |
| " gap: 12px;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-convert {\n", | |
| " background-color: #E8F0FE;\n", | |
| " border: none;\n", | |
| " border-radius: 50%;\n", | |
| " cursor: pointer;\n", | |
| " display: none;\n", | |
| " fill: #1967D2;\n", | |
| " height: 32px;\n", | |
| " padding: 0 0 0 0;\n", | |
| " width: 32px;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-convert:hover {\n", | |
| " background-color: #E2EBFA;\n", | |
| " box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n", | |
| " fill: #174EA6;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-buttons div {\n", | |
| " margin-bottom: 4px;\n", | |
| " }\n", | |
| "\n", | |
| " [theme=dark] .colab-df-convert {\n", | |
| " background-color: #3B4455;\n", | |
| " fill: #D2E3FC;\n", | |
| " }\n", | |
| "\n", | |
| " [theme=dark] .colab-df-convert:hover {\n", | |
| " background-color: #434B5C;\n", | |
| " box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n", | |
| " filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n", | |
| " fill: #FFFFFF;\n", | |
| " }\n", | |
| " </style>\n", | |
| "\n", | |
| " <script>\n", | |
| " const buttonEl =\n", | |
| " document.querySelector('#df-723630bc-9828-4765-b575-ea70528706e8 button.colab-df-convert');\n", | |
| " buttonEl.style.display =\n", | |
| " google.colab.kernel.accessAllowed ? 'block' : 'none';\n", | |
| "\n", | |
| " async function convertToInteractive(key) {\n", | |
| " const element = document.querySelector('#df-723630bc-9828-4765-b575-ea70528706e8');\n", | |
| " const dataTable =\n", | |
| " await google.colab.kernel.invokeFunction('convertToInteractive',\n", | |
| " [key], {});\n", | |
| " if (!dataTable) return;\n", | |
| "\n", | |
| " const docLinkHtml = 'Like what you see? Visit the ' +\n", | |
| " '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n", | |
| " + ' to learn more about interactive tables.';\n", | |
| " element.innerHTML = '';\n", | |
| " dataTable['output_type'] = 'display_data';\n", | |
| " await google.colab.output.renderOutput(dataTable, element);\n", | |
| " const docLink = document.createElement('div');\n", | |
| " docLink.innerHTML = docLinkHtml;\n", | |
| " element.appendChild(docLink);\n", | |
| " }\n", | |
| " </script>\n", | |
| " </div>\n", | |
| "\n", | |
| "\n", | |
| " </div>\n", | |
| " </div>\n" | |
| ], | |
| "text/plain": [ | |
| " image text\n", | |
| "49403 {'bytes': b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHD... للمنظمين\n", | |
| "900283 {'bytes': b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHD... تأويلاته\n", | |
| "1972199 {'bytes': b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHD... ومعراجه\n", | |
| "907367 {'bytes': b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHD... كانجريلور\n", | |
| "736158 {'bytes': b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHD... الاثينين" | |
| ] | |
| }, | |
| "execution_count": 19, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "data.head()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "id": "2laa1mfB3pVC" | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "import io\n", | |
| "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", | |
| "\n", | |
| "all_texts = \"\".join(data['text'].astype(str).tolist())\n", | |
| "vocab = sorted(list(set(all_texts)))\n", | |
| "\n", | |
| "char_to_num = layers.StringLookup(vocabulary=vocab, mask_token=None)\n", | |
| "num_to_char = layers.StringLookup(vocabulary=char_to_num.get_vocabulary(), mask_token=None, invert=True)\n", | |
| "\n", | |
| "def preprocess_single_image(image_data, img_width=128, img_height=32):\n", | |
| " img_bytes = image_data['bytes']\n", | |
| " img = Image.open(io.BytesIO(img_bytes)).convert('L')\n", | |
| " img = np.array(img)\n", | |
| "\n", | |
| " img = cv2.resize(img, (img_width, img_height))\n", | |
| "\n", | |
| " img = (img / 255.0).astype(np.float32)\n", | |
| " img = img.T\n", | |
| " return np.expand_dims(img, axis=-1)\n", | |
| "\n", | |
| "max_target_len = data['text'].str.len().max()\n", | |
| "\n", | |
| "def encode_single_text(text):\n", | |
| " tokens = char_to_num(tf.strings.unicode_split(text, input_encoding=\"UTF-8\"))\n", | |
| " return tokens.numpy()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "j5vBWG2R46oH", | |
| "outputId": "f0bdf031-b7fb-4017-daaf-15d8e9c7bece" | |
| }, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Processing images...\n", | |
| "Processing labels...\n", | |
| "Images Shape: (10000, 128, 32, 1)\n", | |
| "Labels Shape: (10000, 10)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "print(\"Processing images...\")\n", | |
| "x_train = np.array([preprocess_single_image(img) for img in data['image']])\n", | |
| "\n", | |
| "print(\"Processing labels...\")\n", | |
| "y_raw = [encode_single_text(t) for t in data['text']]\n", | |
| "y_train = pad_sequences(y_raw, maxlen=max_target_len, padding='post', value=len(vocab))\n", | |
| "\n", | |
| "print(f\"Images Shape: {x_train.shape}\")\n", | |
| "print(f\"Labels Shape: {y_train.shape}\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "id": "AinStU-V5omk" | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "class CTCLayer(layers.Layer):\n", | |
| " def __init__(self, name=None, **kwargs):\n", | |
| " super().__init__(name=name, **kwargs)\n", | |
| " self.loss_fn = tf.keras.backend.ctc_batch_cost\n", | |
| "\n", | |
| " def call(self, y_true, y_pred):\n", | |
| " batch_len = tf.cast(tf.shape(y_true)[0], dtype=\"int64\")\n", | |
| " input_length = tf.cast(tf.shape(y_pred)[1], dtype=\"int64\")\n", | |
| " label_length = tf.cast(tf.shape(y_true)[1], dtype=\"int64\")\n", | |
| "\n", | |
| " input_length = input_length * tf.ones(shape=(batch_len, 1), dtype=\"int64\")\n", | |
| " label_length = label_length * tf.ones(shape=(batch_len, 1), dtype=\"int64\")\n", | |
| "\n", | |
| " loss = self.loss_fn(y_true, y_pred, input_length, label_length)\n", | |
| " self.add_loss(loss)\n", | |
| " return y_pred" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "id": "3k4rtv6h5BWm" | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "def build_model():\n", | |
| " input_img = layers.Input(shape=(128, 32, 1), name=\"image\", dtype=\"float32\")\n", | |
| " labels = layers.Input(name=\"label\", shape=(None,), dtype=\"float32\")\n", | |
| "\n", | |
| " x = layers.Conv2D(32, (3, 3), activation=\"relu\", padding=\"same\", name=\"Conv1\")(input_img)\n", | |
| " x = layers.MaxPooling2D((2, 2), name=\"pool1\")(x)\n", | |
| " x = layers.Conv2D(64, (3, 3), activation=\"relu\", padding=\"same\", name=\"Conv2\")(x)\n", | |
| " x = layers.MaxPooling2D((2, 2), name=\"pool2\")(x)\n", | |
| "\n", | |
| " new_shape = ((128 // 4), (32 // 4) * 64)\n", | |
| " x = layers.Reshape(target_shape=new_shape, name=\"reshape\")(x)\n", | |
| " x = layers.Dense(64, activation=\"relu\", name=\"dense1\")(x)\n", | |
| " x = layers.Dropout(0.2)(x)\n", | |
| "\n", | |
| " x = layers.Bidirectional(layers.LSTM(128, return_sequences=True, dropout=0.25))(x)\n", | |
| " x = layers.Bidirectional(layers.LSTM(64, return_sequences=True, dropout=0.25))(x)\n", | |
| "\n", | |
| " output = layers.Dense(len(char_to_num.get_vocabulary()) + 1, activation=\"softmax\", name=\"dense2\")(x)\n", | |
| "\n", | |
| " output = CTCLayer(name=\"ctc_loss\")(labels, output)\n", | |
| "\n", | |
| " model = models.Model(inputs=[input_img, labels], outputs=output, name=\"ocr_model_v1\")\n", | |
| " model.compile(optimizer=Adam())\n", | |
| " return model\n", | |
| "\n", | |
| "model = build_model()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 28, | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "Xh33RqRg5qMH", | |
| "outputId": "d3884964-b81d-44c0-c1df-ed040e960ccf" | |
| }, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Epoch 1/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m100s\u001b[0m 378ms/step - loss: 893.4581 - val_loss: 806.8996\n", | |
| "Epoch 2/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m90s\u001b[0m 361ms/step - loss: 803.9755 - val_loss: 794.5329\n", | |
| "Epoch 3/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m99s\u001b[0m 395ms/step - loss: 792.0504 - val_loss: 780.9244\n", | |
| "Epoch 4/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m95s\u001b[0m 380ms/step - loss: 782.8115 - val_loss: 775.8701\n", | |
| "Epoch 5/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m139s\u001b[0m 370ms/step - loss: 764.9818 - val_loss: 744.4646\n", | |
| "Epoch 6/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m139s\u001b[0m 358ms/step - loss: 728.6853 - val_loss: 698.3235\n", | |
| "Epoch 7/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m141s\u001b[0m 355ms/step - loss: 693.3535 - val_loss: 667.8795\n", | |
| "Epoch 8/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m88s\u001b[0m 350ms/step - loss: 665.8049 - val_loss: 644.0731\n", | |
| "Epoch 9/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m92s\u001b[0m 368ms/step - loss: 643.9755 - val_loss: 628.8654\n", | |
| "Epoch 10/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 354ms/step - loss: 625.5055 - val_loss: 604.4825\n", | |
| "Epoch 11/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m87s\u001b[0m 347ms/step - loss: 606.0070 - val_loss: 586.3258\n", | |
| "Epoch 12/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m145s\u001b[0m 357ms/step - loss: 587.1037 - val_loss: 561.2293\n", | |
| "Epoch 13/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m144s\u001b[0m 366ms/step - loss: 568.9001 - val_loss: 545.5327\n", | |
| "Epoch 14/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 353ms/step - loss: 552.8441 - val_loss: 526.3984\n", | |
| "Epoch 15/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m87s\u001b[0m 348ms/step - loss: 534.9763 - val_loss: 508.3538\n", | |
| "Epoch 16/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m88s\u001b[0m 351ms/step - loss: 519.3348 - val_loss: 493.4794\n", | |
| "Epoch 17/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m87s\u001b[0m 346ms/step - loss: 504.7605 - val_loss: 481.9464\n", | |
| "Epoch 18/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m89s\u001b[0m 355ms/step - loss: 493.1075 - val_loss: 463.4099\n", | |
| "Epoch 19/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m88s\u001b[0m 351ms/step - loss: 478.4359 - val_loss: 451.6248\n", | |
| "Epoch 20/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m146s\u001b[0m 369ms/step - loss: 468.1871 - val_loss: 442.5357\n", | |
| "Epoch 21/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m87s\u001b[0m 349ms/step - loss: 452.6135 - val_loss: 425.6103\n", | |
| "Epoch 22/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m100s\u001b[0m 401ms/step - loss: 438.2065 - val_loss: 408.8293\n", | |
| "Epoch 23/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m90s\u001b[0m 362ms/step - loss: 427.0221 - val_loss: 404.2673\n", | |
| "Epoch 24/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m138s\u001b[0m 346ms/step - loss: 416.3164 - val_loss: 388.3680\n", | |
| "Epoch 25/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m90s\u001b[0m 361ms/step - loss: 405.0968 - val_loss: 378.8453\n", | |
| "Epoch 26/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m142s\u001b[0m 363ms/step - loss: 396.8438 - val_loss: 371.1644\n", | |
| "Epoch 27/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m87s\u001b[0m 348ms/step - loss: 385.7292 - val_loss: 361.7797\n", | |
| "Epoch 28/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m92s\u001b[0m 368ms/step - loss: 375.9682 - val_loss: 352.3781\n", | |
| "Epoch 29/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m86s\u001b[0m 343ms/step - loss: 370.5939 - val_loss: 347.9097\n", | |
| "Epoch 30/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m143s\u001b[0m 346ms/step - loss: 362.3100 - val_loss: 347.3625\n", | |
| "Epoch 31/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m86s\u001b[0m 342ms/step - loss: 356.1618 - val_loss: 334.2214\n", | |
| "Epoch 32/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m148s\u001b[0m 367ms/step - loss: 348.9220 - val_loss: 334.2940\n", | |
| "Epoch 33/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m86s\u001b[0m 344ms/step - loss: 341.9437 - val_loss: 317.1755\n", | |
| "Epoch 34/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m86s\u001b[0m 345ms/step - loss: 335.2952 - val_loss: 313.2852\n", | |
| "Epoch 35/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m142s\u001b[0m 346ms/step - loss: 329.2745 - val_loss: 309.0245\n", | |
| "Epoch 36/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m90s\u001b[0m 361ms/step - loss: 322.2877 - val_loss: 303.4044\n", | |
| "Epoch 37/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m86s\u001b[0m 344ms/step - loss: 315.3333 - val_loss: 294.5086\n", | |
| "Epoch 38/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m146s\u001b[0m 360ms/step - loss: 309.2329 - val_loss: 291.5176\n", | |
| "Epoch 39/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m86s\u001b[0m 343ms/step - loss: 302.5685 - val_loss: 285.3416\n", | |
| "Epoch 40/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m85s\u001b[0m 339ms/step - loss: 294.5523 - val_loss: 278.5466\n", | |
| "Epoch 41/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m144s\u001b[0m 346ms/step - loss: 291.2484 - val_loss: 276.1341\n", | |
| "Epoch 42/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m90s\u001b[0m 360ms/step - loss: 285.9906 - val_loss: 275.8123\n", | |
| "Epoch 43/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m85s\u001b[0m 339ms/step - loss: 281.0233 - val_loss: 267.3176\n", | |
| "Epoch 44/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m143s\u001b[0m 344ms/step - loss: 276.6860 - val_loss: 265.1184\n", | |
| "Epoch 45/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m86s\u001b[0m 342ms/step - loss: 268.4237 - val_loss: 258.1709\n", | |
| "Epoch 46/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m143s\u001b[0m 345ms/step - loss: 265.9445 - val_loss: 256.2779\n", | |
| "Epoch 47/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m91s\u001b[0m 363ms/step - loss: 261.8499 - val_loss: 253.8873\n", | |
| "Epoch 48/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m86s\u001b[0m 344ms/step - loss: 259.4355 - val_loss: 248.6168\n", | |
| "Epoch 49/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m147s\u001b[0m 366ms/step - loss: 253.6551 - val_loss: 241.9824\n", | |
| "Epoch 50/50\n", | |
| "\u001b[1m250/250\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m87s\u001b[0m 346ms/step - loss: 253.0857 - val_loss: 240.2976\n" | |
| ] | |
| }, | |
| { | |
| "output_type": "execute_result", | |
| "data": { | |
| "text/plain": [ | |
| "<keras.src.callbacks.history.History at 0x7fea9f34b020>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "execution_count": 28 | |
| } | |
| ], | |
| "source": [ | |
| "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", | |
| "\n", | |
| "encoded_labels = [char_to_num(tf.strings.unicode_split(t, \"UTF-8\")).numpy() for t in data['text']]\n", | |
| "\n", | |
| "max_label_len = max([len(l) for l in encoded_labels])\n", | |
| "train_labels = pad_sequences(encoded_labels, maxlen=max_label_len, padding='post', value=0)\n", | |
| "\n", | |
| "train_images = np.array([preprocess_single_image(img) for img in data['image']])\n", | |
| "\n", | |
| "model.fit(\n", | |
| " x=[train_images, train_labels],\n", | |
| " y=np.zeros(len(train_images)),\n", | |
| " batch_size=32,\n", | |
| " epochs=50,\n", | |
| " validation_split=0.2\n", | |
| ")\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "model.save('OCR_model.h5')" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "0O_g9S8XPc_3", | |
| "outputId": "f45c4113-0784-4d98-db42-b5fb31330be1" | |
| }, | |
| "execution_count": 29, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stderr", | |
| "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" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "model.save('OCR_model.keras')" | |
| ], | |
| "metadata": { | |
| "id": "0xCtXCwmR_Tn" | |
| }, | |
| "execution_count": 53, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "07c9a753", | |
| "outputId": "8a5800dc-5eb0-4eba-ccb2-544b2f65a82f" | |
| }, | |
| "source": [ | |
| "import tensorflow as tf\n", | |
| "import numpy as np\n", | |
| "\n", | |
| "\n", | |
| "input_img = layers.Input(shape=(128, 32, 1), name=\"image_inference\")\n", | |
| "x = model.get_layer(\"Conv1\")(input_img)\n", | |
| "x = model.get_layer(\"pool1\")(x)\n", | |
| "x = model.get_layer(\"Conv2\")(x)\n", | |
| "x = model.get_layer(\"pool2\")(x)\n", | |
| "x = model.get_layer(\"reshape\")(x)\n", | |
| "x = model.get_layer(\"dense1\")(x)\n", | |
| "x = model.get_layer(\"dropout\")(x)\n", | |
| "x = model.get_layer(\"bidirectional\")(x)\n", | |
| "x = model.get_layer(\"bidirectional_1\")(x)\n", | |
| "output = model.get_layer(\"dense2\")(x)\n", | |
| "\n", | |
| "prediction_model = models.Model(inputs=input_img, outputs=output)\n", | |
| "\n", | |
| "def decode_batch_predictions(pred):\n", | |
| " input_len = np.ones(pred.shape[0]) * pred.shape[1]\n", | |
| " results = tf.keras.backend.ctc_decode(pred, input_length=input_len, greedy=True)[0][0][:, :max_target_len]\n", | |
| "\n", | |
| " output_text = []\n", | |
| " for res in results:\n", | |
| " res = res[res != -1]\n", | |
| " res = tf.strings.reduce_join(num_to_char(res)).numpy().decode(\"utf-8\")\n", | |
| " output_text.append(res)\n", | |
| " return output_text\n", | |
| "\n", | |
| "print(\"Inference model and decoding function defined successfully.\")" | |
| ], | |
| "execution_count": 45, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Inference model and decoding function defined successfully.\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "5e781b42", | |
| "outputId": "e2b1da24-a6c5-4a0e-fa24-28f72c6a2869" | |
| }, | |
| "source": [ | |
| "sample_indices = np.arange(5)\n", | |
| "test_samples = x_train[sample_indices]\n", | |
| "ground_truth = data['text'].iloc[sample_indices].tolist()\n", | |
| "\n", | |
| "preds = prediction_model.predict(test_samples)\n", | |
| "\n", | |
| "decoded_preds = decode_batch_predictions(preds)\n", | |
| "\n", | |
| "print(f\"{'Ground Truth':<20} | {'Prediction':<20}\")\n", | |
| "print(\"-\" * 45)\n", | |
| "for gt, pred in zip(ground_truth, decoded_preds):\n", | |
| " print(f\"{gt:<20} | {pred:<20}\")" | |
| ], | |
| "execution_count": 47, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 54ms/step\n", | |
| "Ground Truth | Prediction \n", | |
| "---------------------------------------------\n", | |
| "للمنظمين | للمتقطمين[UNK] \n", | |
| "تأويلاته | ناويلاته[UNK][UNK] \n", | |
| "ومعراجه | ومداه[UNK][UNK][UNK]\n", | |
| "كانجريلور | كانجيلور[UNK] \n", | |
| "الاثينين | الأنيتين[UNK][UNK] \n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "257645d1", | |
| "outputId": "4e8e7b94-0975-4449-acf5-1bddfded9b53" | |
| }, | |
| "source": [ | |
| "!pip install svglib reportlab" | |
| ], | |
| "execution_count": 55, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Requirement already satisfied: svglib in /usr/local/lib/python3.12/dist-packages (1.6.0)\n", | |
| "Requirement already satisfied: reportlab in /usr/local/lib/python3.12/dist-packages (4.4.10)\n", | |
| "Requirement already satisfied: cssselect2>=0.2.0 in /usr/local/lib/python3.12/dist-packages (from svglib) (0.9.0)\n", | |
| "Requirement already satisfied: lxml>=6.0.0 in /usr/local/lib/python3.12/dist-packages (from svglib) (6.0.2)\n", | |
| "Requirement already satisfied: rlpycairo>=0.4.0 in /usr/local/lib/python3.12/dist-packages (from svglib) (0.4.0)\n", | |
| "Requirement already satisfied: tinycss2>=0.6.0 in /usr/local/lib/python3.12/dist-packages (from svglib) (1.4.0)\n", | |
| "Requirement already satisfied: pillow>=9.0.0 in /usr/local/lib/python3.12/dist-packages (from reportlab) (11.3.0)\n", | |
| "Requirement already satisfied: charset-normalizer in /usr/local/lib/python3.12/dist-packages (from reportlab) (3.4.6)\n", | |
| "Requirement already satisfied: webencodings in /usr/local/lib/python3.12/dist-packages (from cssselect2>=0.2.0->svglib) (0.5.1)\n", | |
| "Requirement already satisfied: pycairo>=1.20.0 in /usr/local/lib/python3.12/dist-packages (from rlpycairo>=0.4.0->svglib) (1.29.0)\n", | |
| "Requirement already satisfied: freetype-py>=2.3 in /usr/local/lib/python3.12/dist-packages (from rlpycairo>=0.4.0->svglib) (2.5.1)\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "00727877", | |
| "outputId": "100c685c-57ac-408d-990e-9108026c0335" | |
| }, | |
| "source": [ | |
| "import io\n", | |
| "from svglib.svglib import svg2rlg\n", | |
| "from reportlab.graphics import renderPM\n", | |
| "\n", | |
| "def preprocess_svg_image(svg_path, img_width=128, img_height=32):\n", | |
| " drawing = svg2rlg(svg_path)\n", | |
| " img_data = renderPM.drawToString(drawing, fmt='PNG')\n", | |
| "\n", | |
| " img = Image.open(io.BytesIO(img_data))\n", | |
| "\n", | |
| " img = img.convert('L')\n", | |
| " img = img.resize((img_width, img_height))\n", | |
| "\n", | |
| " img_array = np.array(img).astype(np.float32) / 255.0\n", | |
| "\n", | |
| " img_array = img_array.T\n", | |
| " img_array = np.expand_dims(img_array, axis=-1)\n", | |
| " return np.expand_dims(img_array, axis=0)\n", | |
| "\n", | |
| "try:\n", | |
| " svg_test_path = '/content/unnamed.png'\n", | |
| " processed_svg = preprocess_svg_image(svg_test_path)\n", | |
| " print(f'Processed SVG shape: {processed_svg.shape}')\n", | |
| " print(f'Data type: {processed_svg.dtype}')\n", | |
| "except Exception as e:\n", | |
| " print(f'Error processing SVG: {e}')" | |
| ], | |
| "execution_count": 58, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Error processing SVG: 'NoneType' object has no attribute 'renderScale'\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 227 | |
| }, | |
| "id": "f9b4e38b", | |
| "outputId": "fd64ba85-1405-4ad0-8d6c-7afda7a1627b" | |
| }, | |
| "source": [ | |
| "import matplotlib.pyplot as plt\n", | |
| "\n", | |
| "preds_svg = prediction_model.predict(processed_svg)\n", | |
| "\n", | |
| "decoded_svg_text = decode_batch_predictions(preds_svg)[0]\n", | |
| "\n", | |
| "vis_image = np.squeeze(processed_svg).T\n", | |
| "\n", | |
| "plt.figure(figsize=(10, 3))\n", | |
| "plt.imshow(vis_image, cmap='gray')\n", | |
| "plt.title(f'OCR Prediction: {decoded_svg_text}', fontsize=16, pad=20)\n", | |
| "plt.axis('off')\n", | |
| "plt.show()\n", | |
| "\n", | |
| "print(f'Decoded Arabic Text: {decoded_svg_text}')" | |
| ], | |
| "execution_count": 57, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 2s/step\n" | |
| ] | |
| }, | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "<Figure size 1000x300 with 1 Axes>" | |
| ], | |
| "image/png": "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XMceO3as7/Gbfh7eZStXrnQdY8yYMb713nzzzXTLGzVqlOEYANKj0AAAGCUnJzvly5d3JDlt27Z19uzZ48s3b97s/OMf/3By587tSHIqV67sxMXFWdnvhQsXnObNmzuSnNq1a6db/tJLL/kOCkuVKuU0a9bMqVu3rlOkSBFfLskJDQ11Bg0a5Fy8eDHdGM8884wjyenbt6/rPA4dOuQ7AP/www/TLPOn0LjR2Sg0bnQUGkDWcOkUAMAoMDBQ06ZNU6tWrbRgwQItWLBAefPmVWJiou/meI/Ho06dOundd9+18o3qu3btUteuXbVx40aFhYUZ78MZO3asatasqREjRmj79u1pukEVLVpUderUUbNmzfTII4+4Xi7Yt29fvffee3rzzTfl8Xj01FNPqWLFivJ4PDpx4oQWL16sl19+WceOHdODDz6oRx55xDhOTEyMr710z549dffdd1/xc3C9eOqpp5SUlJRh16ypU6dq1apVCgwM1H/+85+rNLvs9/333/vu27ganeqAm5HHcbL5a4sBADe0AwcO6I033tDChQt1+PBhhYWFqXLlymrSpIk6deqkSpUqXdH4hw8f1saNGzV//nzNnz9fycnJKlKkiObMmZNhR64jR47o2LFjCg4OVtGiRf26z2Hx4sXq2LGjr01ujhw5FBwcnKZt7iOPPKJp06al+46YVatWpZvbzJkzFR0dnen9X+9CQkLSfKlft27d0twPcumX3gUGBvrdne16NnfuXHXu3DlNtnLlSjVu3PjaTAi4AVFoAACuid69e2vKlClpDk5z586tHj16aPDgwYqIiMhwjLFjx2rs2LHasmWLevXqpWPHjvm+JDMzTpw4oXfeeUdffvmldu3apXPnzqlkyZJq0qSJunfvrvr162fpsQEA6DoFALhGLly4oLCwMJUoUUI1atRQ8+bN1apVK78uwUpMTNTJkyeVkpKiuLg4nTp1yq85REREaOjQoZnqggUA8A9nNAAAAABYxxf2AQAAALCOQgMAAACAdRQaAAAAAKyj0AAAAABgHYUGAAAAAOsoNAAAAABYR6EBAAAAwDoKDQAAAADWUWgAAAAAsI5CAwAAAIB1FBoAAAAArKPQAAAAAGAdhQYAAAAA6yg0AAAAAFhHoQEAAADAOgoNAAAAANZRaAAAAACwjkIDAAAAgHUUGgAAAACso9AAAAAAYB2F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\n" | |
| }, | |
| "metadata": {} | |
| }, | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Decoded Arabic Text: الدرين[UNK][UNK]\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "9049a12d", | |
| "outputId": "91a674e1-1979-4837-c374-31656c03c588" | |
| }, | |
| "source": [ | |
| "def preprocess_local_image(file_path, img_width=128, img_height=32):\n", | |
| " img = Image.open(file_path).convert('L')\n", | |
| "\n", | |
| " img = img.resize((img_width, img_height))\n", | |
| "\n", | |
| " img_array = np.array(img).astype(np.float32) / 255.0\n", | |
| "\n", | |
| " img_array = img_array.T\n", | |
| "\n", | |
| " img_array = np.expand_dims(img_array, axis=-1)\n", | |
| "\n", | |
| " img_tensor = np.expand_dims(img_array, axis=0)\n", | |
| "\n", | |
| " return img_tensor\n", | |
| "\n", | |
| "local_image_path = '/content/unnamed.png'\n", | |
| "\n", | |
| "try:\n", | |
| " processed_png_tensor = preprocess_local_image(local_image_path)\n", | |
| " print(f'Successfully processed local PNG.')\n", | |
| " print(f'Processed PNG tensor shape: {processed_png_tensor.shape}')\n", | |
| "except Exception as e:\n", | |
| " print(f'Error processing local PNG: {e}')" | |
| ], | |
| "execution_count": 59, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Successfully processed local PNG.\n", | |
| "Processed PNG tensor shape: (1, 128, 32, 1)\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 227 | |
| }, | |
| "id": "146294b5", | |
| "outputId": "ef8cce60-13b9-4c39-e3c1-c6def3be5e6b" | |
| }, | |
| "source": [ | |
| "preds_png = prediction_model.predict(processed_png_tensor)\n", | |
| "\n", | |
| "decoded_png_text = decode_batch_predictions(preds_png)[0]\n", | |
| "\n", | |
| "vis_image_png = np.squeeze(processed_png_tensor).T\n", | |
| "\n", | |
| "plt.figure(figsize=(10, 3))\n", | |
| "plt.imshow(vis_image_png, cmap='gray')\n", | |
| "plt.title(f'OCR Prediction: {decoded_png_text}', fontsize=16, pad=20)\n", | |
| "plt.axis('off')\n", | |
| "plt.show()\n", | |
| "\n", | |
| "print(f'Decoded Arabic Text: {decoded_png_text}')" | |
| ], | |
| "execution_count": 60, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 92ms/step\n" | |
| ] | |
| }, | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "<Figure size 1000x300 with 1 Axes>" | |
| ], | |
| "image/png": "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sWOHVqxYoenTp2vTpk366quvdPnyZT344IM6c+aMd7wTJ06od+/eSk5O1uuvv66tW7cqJiZGy5cv18KFC/Xee+/5PP9hw4bp66+/VpkyZbRhwwatXLlSMTExWrBggQ4fPqxFixZ579e4cePUp08fSVL9+vU1efJk75/ng0t6PvjgA02ZMkUFChTQ2rVr9eOPP+rzzz/Xzp07FR0drYSEBHXp0kUnT560bv/qq69q9uzZWrdunT7//HOtXLlSkyZNkvTXUSTPkZcbZcGCBercubPKly+vMmXKqF27dlq4cKF13b59+2rBggWqWLGi3nnnHe3atUt//vlnhhcoz549WyNGjNC7777rDepZ4ciRIxo6dKiqV6+u4sWLq06dOnrttde8FzWnp0aNGmrbtm2Wze3vKlWqlB577LFrPn2oY8eOmjx5sooWLaqlS5eqbt26WTDLrDVw4ECVKFFCK1as0OzZs33adteuXapfv74OHDig+++/X3PnzlV4eHgWzTRr+Pv765VXXpEkvfjiiz7vO95880317dtXAQEBmjZtmvr3758V0wSuO4IGsh3Ph8LMHim4cj3Ptld+sCxUqJBrc4uPj9eCBQvUoUMHJScn69///rdq1ar1t8dNTk7Wnj17NGjQIM2YMUOSrKd75cuXT++8806aIx2nTp3SG2+8oZCQEM2cOVNly5ZNtbxjx47q27evTp8+narN5ccff6yzZ8/qrrvu0uDBg1NtExUVpb59+/p0P37//Xe98847kv46heuOO+5ItdzPz09RUVGuXWvhCVnDhw9X9erVU91OdHS0br/9dp05c0YfffSRdfuBAwemaUvZs2dPVa5cWfHx8Vq3bl2qZUFBQapUqZIqVaqU5demvPDCC2revLm++uor7du3TwcPHtS3336rZs2apWlVeuLECX355ZfKnTu3Vq5cqccee0wVK1ZUrly5MrydJk2aKDY2VgMGDPBe0+S2DRs2qGrVqho3bpw2b96sY8eOac2aNXr66afVunXrDLdPSkr6W6ejXA/PP/+8cufOrVmzZmnVqlU+bev5cuE///mPqlWrlgWzy3qhoaHe9q++nj60atUq/fbbbypWrJimTp2aZv92s2jdurUaNGigo0ePZvqaP49vv/1W0l/XJ3bp0iUrpgfcEAQN3PSy8ltYSerVq5f3dJk8efKoefPm2r17t6ZNm6aXXnrpmsc9ePBgqh7vFSpU0IQJE+Tv768nn3zSGjTuvfde64f02NhYXbhwQfXq1VPx4sWtt+e55uHnn3/21jx91x966CHrNp72iZkVGxury5cvq2bNmt5rTbLKkSNHtHfvXkn2efr5+Xmv/4iNjbWO4fQht0qVKpKko0ePpqoXL15cO3fu1M6dOx0fZzecO3dOo0ePliSNGjVKJ0+e1NmzZ721f//736nWP3z4sFJSUlSxYkXly5fPW09ISNCSJUs0YcIExyMh4eHhmjNnjipUqKB33nlHc+fOdf3+jB07VvHx8WrSpIm2bNmiS5cuacWKFSpSpIgWLVqUYf//LVu2pPndmnXr1mnYsGHWltQ3Qr58+bynDfl6+lDDhg0lSb1799aWLVtcn9v10rNnT916663atm1bum13rxYZGamIiAgdO3ZMnTt31uXLl7NwlllrzJgx3v+eOnUq09t5XgMTJkzQ1KlTs2RuwI1A0EC247nmILMXWf/+++/e/y9YsGCq/169/FrUq1fPe91Ay5YtlStXLiUnJ6tfv35as2bNNY+bM2dO77g9e/bUgAED9NZbb2nPnj0aP36844/k2XhO4/rxxx/T/IiT569z586SUh/t8fzI1tVHQDyc6k4OHjwoSapcubJP210LTwjInz+/tZuY9H+/HXB1YPAoVaqUte4ZLzOn9WSV5ORkhYeH66GHHlKBAgUUHh6uYcOGaenSpZo8eXKqb4wrVaqkkJAQrV+/Xs8995zef/99tW/fXvny5VPjxo01aNCgdC/SjYiI0LvvvitJmbqgedOmTRoxYkSmO+x4uqe1bNlS1apVU44cOVS3bl0tXbpUsbGx3sYKvihZsqTGjx+v3r17+/wDl1e+t9L7ouLKZZm5zmvQoEEqVqyYli1b5tMPes6bN0+NGzfWH3/8oSZNmmjTpk2Z3vZaee5PRl/UeJZn5v4HBAR4Tx+Kjo7O9Pvn9ttv1w8//KDcuXPru+++U/v27XXp0qVMbesGNx+Du+++W+3atdOZM2e8j0VmjBgxQs8884xSUlLUs2dPn4IakJ3RLw3ZTs2aNTVt2jRt2LBBSUlJGV6n4fmwnz9/fu8H8TJlyihfvnw6deqU1q5dqwYNGlzzfPr06ZOqs1N8fLzat2+v2NhYde7cWdu3b1dYWJjP4xYoUMDnH6jz/FjT1TwX/N5yyy3ei6udXI8QcLPw98+e37WEh4erXbt2+uabb1SpUiW1adNGXbt21T/+8Q9rd7SIiAjNmjVLgwYN8h71kP461athw4a6++679Y9//CPd22zatKkqVaqk9evXa/v27br11lsd1w0JCdGLL76ocuXKqX379hnen65du2rmzJkaMmSIPvvsM3Xt2lXdu3dXxYoVr7l1aeHChXXPPfdo8eLFWrhwYabm4ZEzZ07v/58/f97xeoArA0xmrhkIDQ1VdHS0+vbtq+eee04tW7bM1HzCwsI0d+5ctW7dWj/++KOioqK0aNEiRUZGZmr7a+F5DM6fP5/uep7HILPXTLRt21Z169bVzz//rLfffltDhw7N1HZ33XWXFixYoObNm2vevHlq166dZs2apZCQkExtfy1y5syp8+fPu/4YvPLKK5ozZ47effddPfHEE5mez6uvvuoNaw8//LBSUlK8R2WBm1X2/FcW/9Nat24tf39/xcfHe89bdWKM8R5mbtWqlfcbJ39/f+9pMW63Ks2dO7e+/PJL5cuXTwcPHrzmXwZ3U8mSJSX99c32lRdU2/6uvMjac/qPUwclXzsreY4QXEvnHV955h4XF+fYwtVzpCcrT3P6u95//32NGzcuzYedmJgYDRkyRMHBwfrqq6/Utm1bVapUScuWLbOOkytXLu8YBQsW1NixY3X8+HEtWbJEo0ePzlRThNtvv11Sxs9f5cqVFRISon379qW66HX58uUaN25cmiN9ng+Nt956qzZu3KinnnpKJUuWtHbVOXnypDp16pSmbbONJ1T7erqR5/0i/dXtyMnu3but26Snd+/eqlSpkrZu3erTKTChoaGaM2eOmjVrplOnTikqKsrbGCMreN6r6d1/6f8eA6ejfzae04dGjx6dqvlERmrXrq2FCxcqb968mj9/vtq2bZulRxUz8xgYY7ynaGb2MahSpYp69uzp/cV0X4waNUovvPCCUlJS1Lt3b02cONGn7YHshqCBbKd8+fLe03yGDh2a7j9U7733nrZs2aLAwMA035w988wzCgoK0ubNm62tSq+2fPnyTM+xYMGC3vPkx40b59M/plkhKipKOXLk0JIlS3w6VcxzXvBnn31mXe5rSGvSpIly5Mih9evXa8OGDZnaJkeOHJLk848TlihRwntqlO3IkDHGW2/cuLFPY18v69atU//+/RUTE5PqW3bprw+er732mk6cOKFZs2bpgQce0N69e9W+fXtvRzWP9evXq1mzZjpy5Ih69eqlPXv2aOjQoT61B01MTPSesnN1tzMbz7UgV4a8fv36aejQodZvodu1a6dt27Zp3bp1io6OVlhYmF566aU0z93ixYs1Y8YMHT9+PMM5eH5jwfN7M5lVuHBh74+Azpw503E9T2OGqlWrZrqpxJWnDw0fPtynU4BCQ0P17bffqkWLFjp9+rTuvfderV27NtPb+6JJkyaS/gppTh+0ExMTvR2kPOtnRv369dW6dWudPn061RG2zKhVq5YWLVqkfPnyacGCBWrdunWWdX/z3Kf0XgMLFy5UfHy8AgMDfToy/uKLLyo0NFRTpkzRtm3bfJrXyJEjFR0dLWOMHn30UX344Yc+bQ9kJwQNZEvvvvuuypQpo/3796tJkyZpdtRJSUl6/fXXvYelx4wZk+bXw6tUqeI92vDkk0/queee09mzZ9Pc1q+//qouXbr43HGnf//+KlWqlOLj4zV+/HiftnVb4cKFNXDgQJ0/f16tW7fW1q1b06xz6dIlzZ49O9W31b1791Z4eLhWrlypt956K9X6S5Ys0X/+8x+f5lGoUCHvLxl36tRJv/zyS6rlxhgtXrxY8fHx3prnw2J6PyjoZMiQIZKkl156SZs3b051Oy+//LI2bdqkPHny6JFHHvF5bJujR4+qcuXKqly5suN1H77wXJjvCXw2oaGhateunT7//HNVq1ZNp06dSnNUo3///kpISNDgwYP1ySefOF6zcvVtez7ArV+/Xvfdd592796twoUL6+67785we0+49pxO8ueff2rbtm3KkyeP98iITc2aNTVixAg9//zzkpTmOo9Dhw5J+uvoXEYSEhIkXVtDCM+RvfHjx1svgJ8zZ47eeOONVOtmVocOHVSnTh0dOnRIX3/9tU/bhoSE6JtvvlHLli115swZNW3aVKtXr/ZpjMyoVauWoqKiZIxR165d0wS7CxcuqF+/fjp48KAKFiyo3r17+zT+K6+8In9/f7399ts+/5ZLjRo19OOPPyp//vxatGiRWrVq5X2u3fTEE08oJCREP/30k0aOHJmmU9bOnTu9+7OePXuqSJEimR67ePHiGjhwoFJSUtLsWzNjxIgRGjlypIwx+te//qX333/f5zGA7IBrNJAt5cuXTz/99JPatWundevWqVq1aqpVq5bKly+vhIQErVy5UidPnlSOHDk0fvx4x/NgBwwYoJw5c2rgwIEaPXq03njjDdWuXVvFixfXxYsXtXPnTu3YsUOSfP4V3uDgYI0YMUIPP/ywJkyYoMGDB6fq+HO9vfrqqzp+/LhiYmJUvXp13XHHHSpXrpwCAwN15MgRbdq0SefPn9f333/vvU6jWLFi+uijj9S1a1c98cQTmjhxoqpWraqjR49q+fLlGjRokPfDVmaNHTtW+/fv1+zZs3XHHXeoTp06Klu2rP744w9t27ZNR48e1f79+73ds+666y4VK1ZMGzduVI0aNVStWjVvG9mMzu/u27evfv75Z02dOlW1atVSw4YNVahQIW3YsEG7du1SaGioYmJiUjUH+DsSExO1a9cu7///XZ5T/TLTCnTRokXe1+qVTQGOHz+uNWvWKG/evBo1alSmb/vBBx/UoUOHlCNHDu+37sHBwfr4448zPC9+69atSkhIUNmyZb1HYq68UDY5OVkBAQGO2585c8Z7WtHVDQ48p8pk5qiKp/1wuXLlMlz3al27dtXmzZs1btw4tWrVSrfddpv3y4pt27Z5v9wYMmSIY1e29IwZM0aNGjW6pg/IwcHBmjVrlu6//3599913atasmebPn5+pAOiLadOmqVmzZlq9erXKlSununXrqmjRooqPj9fKlSsVFxenfPnyaebMmRn+HsvVqlatqu7du/t8HZpH9erVtXjxYu+P97Vs2VJz585Nc+Tv76hQoYKmTp2qbt26KTo6Wh988IFq166tsLAwHTx4UKtWrVJycrIaNWqUqaPiV3v22Wf10Ucf6fTp09c0vxdeeEEBAQF6/vnn1b9/fyUnJ2vAgAHXNBZwwxggG0tOTjaff/65adu2rSlWrJjJkSOHiYiIMNWqVTNPPfWU2b9/f6bGOXnypHn55ZdNgwYNTMGCBU1gYKAJDw83VatWNY8++qhZunRpmm1Kly5tJJlJkyY5jpuUlGRuvfVWI8kMGzYsU3OZNGmSkWRKly6dqfWNMSY6OtpIMtHR0RmuO2/ePNOhQwdTvHhxExQUZPLkyWOqVKliHnjgARMTE2POnz+fZpvly5eb5s2bm4iICBMWFmYiIyPNBx98YIwxRpKx7So8j4/tOUhJSTExMTGmWbNmJn/+/CYoKMgUKVLENGjQwLz22mvmwoULqdbfunWradOmjSlYsKDx9/c3kkzDhg29y3v06JHucxETE2MaNWpk8uTJY4KCgkzJkiVNz549zc6dO63rpzf39G5v//793scjs689D0kmICAgVW3Tpk3Gz8/P5MqVy/zwww9ptjl79qxZvHix6dOnjwkMDDSSzIMPPphqnZUrVxpJpl69ej7Np0ePHqZAgQImKCjIlClTxvTu3dts27YtU9v26tXLSDK9e/dOVY+MjDSSzKBBg9K8zpKSksz27dvNuHHjTIkSJYwkU7hwYXP48OFU63344YdGkunfv3+6czh16pTJmTOnkWR27NiRallGz++VlixZYrp06WJKly5tQkJCTEhIiClTpozp0qWLdb/g0bBhQyPJTJ061XGdli1bel8vV793Y2NjHd9bHpcuXTJt27Y1kkyuXLnMTz/9lGYd2xiesa98DzlJSEgwb7/9tmnUqJHJnz+/CQwMNBERESYyMtI8++yz5vjx49btPO+Fq1/TVzp06JAJCQlxfM943mc9evRwHGPr1q2mUKFCRpJp0KCBOXv2bKrlnv3p1WNktM+40u7du83jjz9ubrvtNhMeHm4CAwNN4cKFTYsWLcynn35qkpKSrNt59stXvw+uNHbsWO/9tz0fnmWxsbGOY4wZM8a73ptvvplmuee1mN4YwI1C0ACAG2jo0KHeDxGlSpUyzZo1M3Xr1jVFihTx1iWZ0NBQ8+9//9tcvnw51fabN282kkylSpWuy3wnT55sJBk/Pz/zyy+/pFq2cuVKExERYSSZ8PBw06BBA9O0aVNToUIFExQUlOr+REVFmb1796YZf+3atUaSKV68uDUUG/NXkH3ooYeMJNO8efM0y30JGje7vxs0bnZuBI2bHUED2RmnTgHADTR27FhFRkZq1KhR2rZtm/caBUkqWrSo6tSpo2bNmumf//yn9dS8KlWqKCIiQrt27dL06dO9jRScXLp06Zp+efnChQsaOXKkt6PQs88+m+a6qLvuukurV6/W8OHDNWvWrFQNFnLmzKlatWqpcePG6tixo2PrVs86sbGxatKkiUaOHKn69esrLCxMFy9e1IYNGzRq1CjNmzcv1e9/2AwZMkTh4eG67bbbMt1m9Wbw6aefOv4I5ZV27tzp7d7Vt29f10+9upEeeeQRJSYmZtg1a+LEiVqyZIkCAgL08ccfX6fZZb3Vq1d7r9u4Hl3+gGt2o5MOAOAvx48fN5s3bzbbt283p0+fzvR2w4cP957G8vDDD5ulS5emOhpw+vRp8+2335qOHTuaJ598MtPjnjt3zqxYscI8//zzplixYt4jGUOHDjUpKSnpbnv+/Hmzbds2s3nzZnP48OEM17/SyZMnTa1atbzf1vv5+ZmIiAjj5+fnrZUtW9asW7fOur3niIauOHry36Rv376p7t/V/5RfeVqW5y+9U7xuRsHBwanun9MRDc9feqd43Yw+//zzNM8xRzSQHfkZcw3tOgAArhs7dqzGjh2rjRs3ql+/fvr9998z9evzKSkpevbZZzVu3LhUHX7CwsIUEBCQqtva0KFDNXbs2HTHW7FihZo2bZqmrWjjxo314osvZqrN5+HDhxUZGamnn35axYoV06BBgzR37lzVqVMnw20992nmzJmaMmWK1q1bp7i4OEVERKhmzZrq1KmTunbtmqU/5gYA+Ps4dQoAsomEhATFxcUpOTlZZ86c0alTpzK1nb+/v8aMGaNHHnlEkyZN0ooVK/Trr78qPj5eFy5cUKFChXT77berY8eOmfql4aSkJPn5+alUqVK67bbbVL9+fXXo0MGnX5VPTk5WXFycEhISdPHiRcXFxfnUqcvf31+dOnVSp06dMr0NACB74YgGAAAAANfxg30AAAAAXEfQAAAAAOA6ggYAAAAA1xE0AAAAALiOoAEAAADAdQQNAAAAAK4jaAAAAABwHUEDAAAAgOsIGgAAAABcR9AAAAAA4DqCBgAAAADXETQAAAAAuI6gAQAAAMB1BA0AAAAAriNoAAAAAHAdQQMAAACA6wgaAAAAAFxH0AAAAADgOoIGAAAAANcRNAAAAAC4jqABAAAAwHUEDQAAAACuI2gAAAAAcB1BAwAAAIDrCBoAAAAAXEfQAAAAAOA6ggYAAAAA1xE0AAAAALiOoAEAAADAdQQNAAAAAK4jaAAAAABwHUEDAAAAgOsIGgAAAABcR9AAAAAA4DqCBgAAAADXETQAAAAAuI6gAQAAAMB1BA0AAAAAriNoAAAAAHAdQQMAAACA6wgaAAAAAFxH0AAAAADgOoIGAAAAANcRNAAAAAC4jqABAAAAwHUEDQAAAACuI2gAAAAAcB1BAwAAAIDrCBoAAAAAXEfQAAAAAOA6ggYAAAAA1xE0AAAAALiOoAEAAADAdQQNAAAAAK4jaAAAAABwHUEDAAAAgOsIGgAAAABcR9AAAAAA4DqCBgAAAADXETQAAAAAuI6gAQAAAMB1BA0AAAAAriNoAAAAAHAdQQMAAACA6wgaAAAAAFxH0AAAAADgOoIGAAAAANcRNAAAAAC4jqABAAAAwHUEDQAAAACuI2gAAAAAcB1BAwAAAIDrCBoAAAAAXEfQAAAAAOA6ggYAAAAA1xE0AAAAALgu8EZPAAAAANlbcnKytb53715r/eLFiz6Nc8stt1jruXLlysTskF1xRAMAAACA6wgaAAAAAFxH0AAAAADgOoIGAAAAANcRNAAAAAC4jq5TAAAA/2NSUlKs9QkTJljrMTEx1voDDzxgrd95553W+tq1a6313377zVqvX7++tR4eHm6tI3vhiAYAAAAA1xE0AAAAALiOoAEAAADAdQQNAAAAAK4jaAAAAABwHV2nAAAA/sckJSVZ6+fPn7fWQ0JCXBmnVKlS1vq5c+es9bi4OGudrlM3B45oAAAAAHAdQQMAAACA6wgaAAAAAFxH0AAAAADgOoIGAAAAANf5GWPMjZ4EAAAArp8///zTWo+Pj7fWg4ODrfXLly9b65MnT7bWN23aZK3PmDHDWsfNjSMaAAAAAFxH0AAAAADgOoIGAAAAANcRNAAAAAC4jqABAAAAwHV0nbqJOD1V58+ft9aPHTtmrV+8eNFaL1mypLUeERFhrScmJlrrv/32m7V+6tQpa7148eLWet68ea31oKAgax0AAFxfTv/mV6xY0Vp36na1YMECa71p06bXNjFkCxzRAAAAAOA6ggYAAAAA1xE0AAAAALiOoAEAAADAdQQNAAAAAK6j69RNxKnL0/fff2+tT5482VrfsWOHte7U2WHgwIHW+pkzZ6z1iRMnWuvLli2z1qtXr26tP/bYY9Z6vXr1rHVJ8vPzc1wGAACuj+7du1vrU6dOtdbbtGljrX/zzTfWOv/e3xw4ogEAAADAdQQNAAAAAK4jaAAAAABwHUEDAAAAgOsIGgAAAABcR9ep/0Hnzp2z1nPmzGmt+9rZwakbVUBAgLUeFhbm0/qAG86ePetTPSgoyFoPDw+31kNDQ69tYgDwX+CLL76w1rt06WKtO30W2LRpk7VeoUKFa5oXri+OaAAAAABwHUEDAAAAgOsIGgAAAABcR9AAAAAA4DqCBgAAAADXBd7oCeD6c+qSk5KSYq07deHZtm2btd6+fXtr/cEHH7TWX3/9dWsd/+fixYvW+s8//2yt792711rv2LGjtZ43b95rm1g2cuLECWt9ypQp1vqqVausdaeuaU4N+pzeN05dp8qVK2et33vvvdZ6VFSUtZ47d25rPaslJSU5LnN6Do4dO2atHzp0yFrfvXu3tX748GFr/fTp09a60/vGqZNeSEiItZ4rVy5rvWDBgtZ6kSJFrPVixYr5tH6BAgWs9YiICGvdqWtPjhw5rHXJuZtaVnf9c3o/+drlMLtx6uoYGxtrrTu9djt16uR4GzdLR7tbbrnFWvf3t3/HnZCQYK2vX7/eWqfr1M2BIxoAAAAAXEfQAAAAAOA6ggYAAAAA1xE0AAAAALiOoAEAAADAdX7GqfUDbphLly5Z69u3b7fWd+zYYa07dWi5fPmyte70UggMtDcnc+rQsnbtWmv9iy++sNYHDx5srY8fP95av9m7klyLXbt2Wev9+vWz1p06nFSvXt1anzdvnrVetGjRjCeXTTh1GHLqApMzZ05r3anbjlO3pfj4eGv9119/tdZnzZplrX/66afWer58+az1N99801pv3bq1te4Wp8dZkg4cOGCtO+0rnLokOe1znN77TvuuxMREa/38+fPWelxcnLXu1DVrz5491rpTRz6nffW+fft8mo/T4+nUjSq9DmVOna2cOtE5vW+culc5PZedO3e21lu0aGGt3yxWr15trfft29da37x5s7XevHlzx9uYMWOGte7UUfJG2bhxo7Veu3Zta91pH/vBBx9Y648++ui1TQzXFUc0AAAAALiOoAEAAADAdQQNAAAAAK4jaAAAAABwHUEDAAAAgOvoOnUDnTp1ylq/7777rPU1a9b4NH7Dhg2t9T59+ljrRYoUsdadOpw4vXScOiQNGjTIWnfqAOPUpeP555+31iXnTik5cuSw1m+WDlb+/vbvBJw6Kt1zzz3W+pYtW6z1xYsXW+uNGzfOxOwy5vRaT++2GzVqZK07ddBxei6z+jl2Gt/pOXOyadMma71du3bW+okTJ6z1devWWeuVKlXyaT5O0ns8ne6zUzcZXzuFOb2OfvvtN2v9yJEj1rpTRz6n7lJnzpyx1p26WjntM532TwULFrTW8+fPb607dYpy6lCWK1cua11y7lDn1B2tV69e1nqVKlV8mlOZMmWsdafH7mbh1LXu6NGj1vqdd95prTu9piXnf2MrVqyYweyuL6euUzVq1LDW8+TJY607dbK85ZZbrmleuL44ogEAAADAdQQNAAAAAK4jaAAAAABwHUEDAAAAgOsIGgAAAABcR9epG8ipY8k333xjra9cudJad+o+49S5xel2U1JSrPWgoCBr3alDRIkSJaz1+vXrW+tOnV4+/vhja/3y5cvWuiTlzJnTWg8MDLTWfe0M5Cun8Z0ea185dThx6rbj9NxMmTLFWi9atOi1TewqcXFxjsu6detmrZ8+fdpaDw0NdWVO2U1wcLC17vR+deo8U6hQIWvdqVuXr9J7z/ja4ctpfafXtdNjFBERYa07ddIrW7astV65cmVrvVy5cj6N7zTP7Gj//v3W+ksvvWStb9++3Vp3+ijh1PHPaZ98s3QC9JXTa9rp8Y+MjHQca9KkSdZ6eHi47xPLQk7dolq0aGGtT5w40Vpv3769a3PC9ccRDQAAAACuI2gAAAAAcB1BAwAAAIDrCBoAAAAAXEfQAAAAAOA6uk7hpnPmzBnHZQkJCdZ6UlKSte7ry9+pI4pTZ6BLly5Z67ly5fLpdp3mmZyc7NP6Tt1zsqPff//dWr9w4cJ1nsn14dTNKX/+/Na602s6Pj7eWner01l6XaecOus4dR4KCQnxqe7UqcgtsbGx1vrs2bOt9YsXL1rrjRs3ttabNm1qrefNmzcTs8senPYtTl0OnR4jp32j0+v0Rn1UcXpNO3Gav9N7wKlD2c30mnDi1FHSad9evXr1LJwNbhSOaAAAAABwHUEDAAAAgOsIGgAAAABcR9AAAAAA4DqCBgAAAADX0XUK8MHSpUut9Q8++MBa37p1q7XeoEEDa71///7WulO3nffff99aX7x4sbVeqVIla/2RRx6x1p265KTXeQjI7pw6dv3666/W+po1a6z1w4cPW+u1a9e21uvWrWut+9qFDu5z+ig0f/58a33q1KnWutNronnz5tZ69+7drfVSpUpZ68DNhk8LAAAAAFxH0AAAAADgOoIGAAAAANcRNAAAAAC4jqABAAAAwHV0nQJ8kJiYaK2fPn3aWj9y5Ii1nj9/fmu9aNGi1npAQIC1/ueff1rrhw4dstZDQ0Ot9RIlSljrYWFh1joA/Ddx+ijktI89ePCgT/WyZcta6+XLl7fWnfbVwM2GIxoAAAAAXEfQAAAAAOA6ggYAAAAA1xE0AAAAALiOoAEAAADAdXSdAgAAAOA6jmgAAAAAcB1BAwAAAIDrCBoAAAAAXEfQAAAAAOA6ggYAAAAA1xE0AAAAALiOoAEAAADAdQQNAAAAAK4jaAAAAABwHUEDAAAAgOsIGgAAAABcR9AAAAAA4DqCBgAAAADXETQAAAAAuI6gAQAAAMB1BA0AAAAAriNoAAAAAHAdQQMAAACA6wgaAAAAAFxH0AAAAADgOoIGAAAAANcRNAAAAAC4jqABAAAAwHUEDQAAAACuI2gAAAAAcB1BAwAAAIDrCBoAAAAAXEfQAAAAAOA6ggYAAAAA1xE0AAAAALiOoAEAAADAdQQNAAAAAK4jaAAAAABwHUEDAAAAgOsIGgAAAABcR9AAAAAA4DqCBgAAAADXETQAAAAAuI6gAQAAAMB1BA0AAAAAriNoAAAAAHAdQQMAAACA6wgaAAAAAFxH0AAAAADgOoIGAAAAANcRNAAAAAC4jqABAAAAwHUEDQAAAACuI2gAAAAAcB1BAwAAAIDrCBoAAAAAXEfQAAAAAOA6ggYAAAAA1xE0AAAAALiOoAEAAADAdQQNAAAAAK4jaAAAAABwHUEDAAAAgOsIGgAAAABcR9AAAAAA4DqCBgAAAADXETQAAAAAuI6gAQAAAMB1BA0AAAAArvt/2Jtp2rMAn8QAAAAASUVORK5CYII=\n" | |
| }, | |
| "metadata": {} | |
| }, | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Decoded Arabic Text: ايعدرين[UNK][UNK][UNK]\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "6f9d7e8f", | |
| "outputId": "93df8ebe-fcb4-47b6-890f-6154023d6a6a" | |
| }, | |
| "source": [ | |
| "def decode_batch_predictions(pred):\n", | |
| " input_len = np.ones(pred.shape[0]) * pred.shape[1]\n", | |
| " results = tf.keras.backend.ctc_decode(pred, input_length=input_len, greedy=True)[0][0][:, :max_target_len]\n", | |
| "\n", | |
| " output_text = []\n", | |
| " for res in results:\n", | |
| " res = res[res != -1]\n", | |
| " res = tf.strings.reduce_join(num_to_char(res)).numpy().decode(\"utf-8\")\n", | |
| " res = res.replace(\"[UNK]\", \"\")\n", | |
| " output_text.append(res)\n", | |
| " return output_text\n", | |
| "\n", | |
| "print(\"Updated decode_batch_predictions to filter out '[UNK]' tokens.\")" | |
| ], | |
| "execution_count": 61, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Updated decode_batch_predictions to filter out '[UNK]' tokens.\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "329b79d9", | |
| "outputId": "f79a706d-43f3-413c-8f29-8c74929ccefd" | |
| }, | |
| "source": [ | |
| "preds_png_updated = prediction_model.predict(processed_png_tensor)\n", | |
| "cleaned_png_text = decode_batch_predictions(preds_png_updated)[0]\n", | |
| "print(f'Cleaned Arabic Text Prediction: {cleaned_png_text}')" | |
| ], | |
| "execution_count": 62, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 108ms/step\n", | |
| "Cleaned Arabic Text Prediction: ايعدرين\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 191 | |
| }, | |
| "id": "2c8e2660", | |
| "outputId": "d8f87803-8e4c-4c73-d68a-b8d9b2912754" | |
| }, | |
| "source": [ | |
| "vis_image_clean = np.squeeze(processed_png_tensor).T\n", | |
| "\n", | |
| "plt.figure(figsize=(10, 3))\n", | |
| "plt.imshow(vis_image_clean, cmap='gray')\n", | |
| "plt.title(f'OCR Prediction: {cleaned_png_text}', fontsize=16, pad=20)\n", | |
| "plt.axis('off')\n", | |
| "plt.show()" | |
| ], | |
| "execution_count": 63, | |
| "outputs": [ | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "<Figure size 1000x300 with 1 Axes>" | |
| ], | |
| "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxoAAAECCAYAAAB5WqGNAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAJFJJREFUeJzt3Xd0VHX+//FXQioJITQpoYSWRAUhVJUmIMUCgguKCgZU9MDiihTlixyxcZCquLqurgqCYkEBZe0uoKyCGCCAdCnSi4EESAikfH5/uJmfIZ+bZPBDk+fjHI+c19y585nJZMiLm/u+AcYYIwAAAABwKPB8LwAAAADAnw9FAwAAAIBzFA0AAAAAzlE0AAAAADhH0QAAAADgHEUDAAAAgHMUDQAAAADOUTQAAAAAOEfRAAAAAOAcRQMAcEkICAhQUFDQ+V4GAFwyKBoAimSM0Xvvvadbb71VNWrUUFhYmMqVK6fGjRvrkUce0c6dO0u0n9TUVI0fP17XXXedqlSpopCQEEVFRalBgwYaOHCgFi5cWOg+sbGxCggIKPBfaGioqlevrltuuUX//ve/z+g5zZgxo9B+AwMDVbZsWbVo0ULjxo3T8ePHz2jfZ0P+Gk+X//rs2LHjrK+hf//+CggI0IwZM876YwEA/hwoGgA87d27V1dffbX69Omj+fPnq0qVKurRo4fatGmjPXv2aNKkSYqLi9NLL71U5H5mzZql2NhYjR49WsuWLVNcXJz+8pe/qEOHDsrJydFrr72mjh076rbbbrPev1WrVkpKSlJSUpJuvPFGBQUF6eOPP1a3bt00bNiwM35+ERERvv3eddddatCggVasWKExY8aoadOmOnDgwBnv+2KSX7z69+9/vpcCAPgzMQBgcfjwYVOnTh0jySQmJpqffvqpwO3Z2dlm8uTJplSpUkaSmTZtmnU/L7/8spFkAgICzKOPPmrS09MLbbNu3TrTu3dv07hx4wJ5rVq1jCQzffr0Qo89ZMgQI8lIMsuXL/fruU2fPt1IMrVq1Sp02w8//GAiIyONJNOvXz+/9nu25D/P0/38889mw4YN5tSpU39o//mvR1JSkuc2e/fuNRs2bDBpaWl/6LHOJ0mmVKlS53sZAHDJ4IgGAKshQ4Zo27Ztql27thYuXKgrr7yywO1BQUEaPny4pk2bJkkaMWKENmzYUGCbjRs36m9/+5skacqUKXr22WcVFRVV6LGuuOIKvf/++759FScoKEiTJk3y7WvBggV+Pz8vLVq00PDhwyVJc+fOVU5OjrN9u1a3bl0lJCQoODj4rD9W1apVlZCQoLJly571xwIA/DlQNAAUsm3bNr377ruSpMmTJys6Otpz28GDB6tRo0bKzs7WxIkTC9w2YcIEZWdnq1GjRho6dGixj9u2bdsSrzEsLEz169eXJOe/4tS0aVNJUkZGhn799VdJ0hNPPKGAgAA98cQT2rlzp+69917VqFFDwcHBhX7l6IMPPlDXrl1VqVIlhYSEKCYmRn379tX69es9H3Pp0qW64YYbFB0drcjISDVr1kxvvPFGkess6hwNY4zmzp2rm2++2XdOTJUqVdS6dWtNmDBBJ06c8O1jwIABkqQ333yzwHkr1113nW9/xZ2j8e6776pjx44qX768QkNDVatWLd1zzz3avHlzsWtftGiROnfurHLlyik8PFxNmjTRzJkzi3zuF6q8vDzNmTNHffr0UcOGDRUTE6OjR4+e72UBwHnB+A0AhSxYsEB5eXmKjo5W9+7di9w2ICBA/fr10+rVq7VgwQIZYxQQECBjjO9Iw9133209mfmPyv8BrnLlymdlv5IUGhpa4LYtW7YoMTFRISEhatWqlYwxqlixoiQpJydHd911l95//32FhoaqadOmiomJ0ebNm/X2229r7ty5mjt3rrp27Vpgn3PmzNEdd9yh3NxcNWjQQA0bNtSuXbt03333ad26dX6vPzs7W3369NHcuXMVGBioFi1aqEOHDvr111+1fv16jRo1SrfffrtiY2PVq1cvLVu2TN99953q1q2r1q1b+/aTkJBQ7GMZY9S/f3/NnDlTQUFBatu2rS677DKtXLlS06dP13vvvacPP/yw0HPO98Ybb+iZZ55RkyZN1LVrV+3YsUPLli1TUlKSDh8+XKig7tixQ7Vr15Ykbd++XbGxsX6/PmfLsWPH1KtXL3355ZcF8ry8vPO0IgA4z87rL24BuCD169fPSDLt27cv0fbffPON7zyCbdu2GWOM2bp1qy/79ttvz2gdXudoGGPM+vXrfeeH/Pjjj37tt6hzNIwxplevXkaSqVmzpi8bO3as7/n07dvXZGVlFbrf6NGjjSTTsmVL3+uQb86cOaZUqVKmXLly5siRI7583759pkyZMkaSmTp1aoH7fP311yYsLMzzHI3812f79u0F8mHDhhlJJjY21qSkpBS4LS8vz3z99dcFzrUoyTkaSUlJ1q9F/jk4FStWNKtWrSrwOPmvWXR0tDl48KB17cHBwWbBggUFbstfT9myZU1mZmaB27Zv3+57PU5/3sXRGZyj8cUXX5jevXubOnXqmFq1aplbbrnFfPnll9Zt77jjDiPJxMXFmRdffNFs2rTJHD16tNjH+Oijj8zYsWPNiy++aPLy8vxanz927dplRowYYRo1amSqVatmWrRoYSZOnGhOnDhR7H0TExNN9+7dz9raAPw5UTQAFNK1a1cjyfTp06dE22/cuNH3w98PP/xgjDFm2bJlvmzjxo1ntA5b0UhLSzNffPGFSUhIMJLMmDFj/N6vrWjk5OSYLVu2mIceesi37t//4J//Q3P58uWtJ0Snpqaa8PBwExYWZnbv3m193MGDBxtJ5u9//7sve+aZZ4wkc/XVV1vv8/v1nM5WNA4cOGBCQkKMJJOcnFzcS2GM+WNFo27dukaSeeGFFwrdJy8vz1x11VVGkhk3bpx17cOGDbM+Xv7X9/SSunv3bhMfH2/i4+M9X2cv/haNMWPG+F770/+bNWtWgW337dtnAgMDTdmyZU1qaqpf6zp27Jhp27atkWSGDBni131LasWKFaZs2bLW53L99dcXe/+GDRuam2666aysDcCfF+doAPjDjDFndf8DBgzwnTcQHR2tLl26aMuWLXrrrbf09NNPn/F+f/nlF99+g4KCVL9+fU2bNk2BgYEaNmyY9byS66+/3npC9KJFi3TixAm1atVKMTEx1sfLP+fh+++/92WLFy+WJN11113W+yQlJfn1nBYtWqRTp06padOmvnNNzpbdu3dr69atkuzrDAgI8J3/sWjRIus+unXrZs0vv/xySdKePXsK5DExMdq4caM2btzo+Tq7cPz4cY0fP16SNG7cOB06dEjHjh3zZWPGjCmw/a5du5SXl6e4uDiVL1/el2dmZmrx4sWaNm2avvrqK+tjRUZGasGCBapfv75efPFFffLJJ86fz8SJE5Wenq4OHTpozZo1OnnypL777jtVqVJFX3/9te996GXNmjWFrluTnJysUaNG6f3333e+XgB/DpyjAaCQ/HMOSnqS9cGDB31/rlSpUoH/598eHx9/xutp1aqV6tWrJ0k6dOiQlixZomPHjmnQoEGqX7++WrRocUb7jYiIUK9evST99kNxZGSk4uLidPPNN/vOAzid1zkB27ZtkyT95z//KfZ8lEOHDvn+vHv3bknyfDyv3Msvv/wiqWTnV/xR+SWgQoUK1mli0m+TsX6/7elq1qxpzfP3l5WV9UeXecZyc3MVGRmpu+66y/c9MWrUKF177bXKy8tTbm6uSpUqJUmKj49XWFiYVqxYodGjR6tGjRr68ssv9dlnn+nkyZOSpLFjx6pTp07Wx4qKitJLL72kzp07a+zYsbrpppuKXFtKSormz5+vRo0aqWfPnsU+l/zpaTfeeKMaNmwoSbr22mv1zTffaO/evb7BCv6oUaOGpkyZorCwMN14442KjIz0ex8A/twoGgAKadq0qd566y2tXLlSOTk5Cgoq+qNi+fLlkn77gTP/B/HY2FiVL19ehw8f1o8//qg2bdqc8Xruu+++ApOd0tPT1bNnTy1atEi33Xab1q9fr9KlS/u934oVK/p9pevw8HBrnn/Cb7169dSqVasi93EuSsDFIjDwwjywHhkZqR49emj+/PmKj49X9+7d1bdvX910003W6WhRUVGaN2+ehg4d6jvqIUnBwcFq166drrnmmmLLQ6dOnRQfH68VK1Zo/fr1uuKKKzy3DQsL05NPPqk6deqUqGj07dtXH374oUaMGKG3335bffv21d133624uDjFxcUVe3+bypUrq23btlq4cKG++uqrEq0DwKXlwvyEB3BedevWTYGBgUpPT9dHH31U5LbGGM2aNUuSdPPNN/v+NT8wMND3azGuR5WWLVtW7733nsqXL69ffvlFU6dOdbr/M1GjRg1Jv/3L9owZM4r8b9SoUb775f/6j21EbVG5l/wjBBs3bvT/Sfgpf+2pqameI1zzj/SczV9z+qNefvllTZ48WRkZGQXy2bNna8SIEQoNDdWcOXN0yy23KD4+Xt9++611P2XKlPHto1KlSpo4caL27dunxYsXa/z48WrevHmxa7nqqqskFf/1S0hIUFhYmLZt2+YbVSxJS5Ys0eTJk33lP1+PHj00b948XXHFFVq1apWGDx+uGjVq6PHHHy+070OHDql3794lulJ8fqles2ZNsdsCuPRQNAAUUrduXd12222SpJEjRyotLc1z23/84x9as2aNgoKCNHLkyAK3PfroowoODtbq1av1/PPPF/u4S5YsKfEaK1Wq5Ps9+cmT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\n" | |
| }, | |
| "metadata": {} | |
| } | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "accelerator": "GPU", | |
| "colab": { | |
| "gpuType": "T4", | |
| "provenance": [] | |
| }, | |
| "kernelspec": { | |
| "display_name": "Python 3", | |
| "name": "python3" | |
| }, | |
| "language_info": { | |
| "name": "python" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 0 | |
| } |
Xet Storage Details
- Size:
- 90.6 kB
- Xet hash:
- 5490d6cf99f7ff51719acb6b7ad37e7deaff3308e85e0c778312d6f4782191c6
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.