Symulowanie-wizualne/sw_lab9-10_2.ipynb
2023-01-06 13:34:05 +01:00

1253 lines
132 KiB
Plaintext

{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### Aleksandra Jonas, Aleksandra Gronowska, Iwona Christop\n",
"# Zadanie 9-10 - AlexNet, VGG16, ResNet on village"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### Przygotowanie danych"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Image, display"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"import subprocess\n",
"import pkg_resources\n",
"import numpy as np\n",
"\n",
"required = { 'scikit-image'}\n",
"installed = {pkg.key for pkg in pkg_resources.working_set}\n",
"missing = required - installed\n",
"\n",
"if missing: \n",
" python = sys.executable\n",
" subprocess.check_call([python, '-m', 'pip', 'install', *missing], stdout=subprocess.DEVNULL)\n",
"\n",
"def load_data(input_dir, img_size):\n",
" import numpy as np\n",
" import pandas as pd\n",
" import os\n",
" from skimage.io import imread\n",
" import cv2 as cv\n",
" from pathlib import Path\n",
" import random\n",
" from shutil import copyfile, rmtree\n",
" import json\n",
"\n",
" import seaborn as sns\n",
" import matplotlib.pyplot as plt\n",
"\n",
" import matplotlib\n",
" \n",
" image_dir = Path(input_dir)\n",
" categories_name = []\n",
" for file in os.listdir(image_dir):\n",
" d = os.path.join(image_dir, file)\n",
" if os.path.isdir(d):\n",
" categories_name.append(file)\n",
"\n",
" folders = [directory for directory in image_dir.iterdir() if directory.is_dir()]\n",
" \n",
" ds_img = []\n",
" categories_count=[]\n",
" labels=[]\n",
" for i, direc in enumerate(folders):\n",
" count = 0\n",
" for obj in direc.iterdir():\n",
" if os.path.isfile(obj) and os.path.basename(os.path.normpath(obj)) != 'desktop.ini':\n",
" labels.append(os.path.basename(os.path.normpath(direc)))\n",
" count += 1\n",
" img = imread(obj)#zwraca ndarry postaci xSize x ySize x colorDepth\n",
" img = img[:, :, :3]\n",
" img = cv.resize(img, img_size, interpolation=cv.INTER_AREA)# zwraca ndarray\n",
" img = img / 255 #normalizacja\n",
" ds_img.append(img)\n",
" categories_count.append(count)\n",
" X={}\n",
" X[\"values\"] = np.array(ds_img)\n",
" X[\"categories_name\"] = categories_name\n",
" X[\"categories_count\"] = categories_count\n",
" X[\"labels\"]=labels\n",
" return X"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def get_run_logdir(root_logdir):\n",
" import os\n",
" import time\n",
"\n",
" run_id = time.strftime(\"run_%Y_%m_%d-%H_%M_%S\")\n",
" return os.path.join(root_logdir, run_id)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def diagram_setup(model_name):\n",
" from tensorflow import keras\n",
" import os\n",
" \n",
" root_logdir = os.path.join(os.curdir, f\"logs\\\\fit\\\\{model_name}\\\\\")\n",
" \n",
" run_logdir = get_run_logdir(root_logdir)\n",
" tensorboard_cb = keras.callbacks.TensorBoard(run_logdir)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"def prepare_data(path, img_size, test_size, val_size):\n",
" from sklearn.model_selection import train_test_split\n",
" from sklearn.preprocessing import LabelEncoder\n",
" import tensorflow as tf\n",
"\n",
" data = load_data(path, img_size)\n",
" values = data['values']\n",
" labels = data['labels']\n",
"\n",
" X_train, X_test, y_train, y_test = train_test_split(values, labels, test_size=test_size, random_state=42)\n",
" X_train, X_validate, y_train, y_validate = train_test_split(X_train, y_train, test_size=val_size, random_state=42)\n",
"\n",
" class_le = LabelEncoder()\n",
" y_train_enc = class_le.fit_transform(y_train)\n",
" y_validate_enc = class_le.fit_transform(y_validate)\n",
" y_test_enc = class_le.fit_transform(y_test)\n",
"\n",
" train_ds = tf.data.Dataset.from_tensor_slices((X_train, y_train_enc))\n",
" validation_ds = tf.data.Dataset.from_tensor_slices((X_validate, y_validate_enc))\n",
" test_ds = tf.data.Dataset.from_tensor_slices((X_test, y_test_enc))\n",
"\n",
" train_ds_size = tf.data.experimental.cardinality(train_ds).numpy()\n",
" test_ds_size = tf.data.experimental.cardinality(test_ds).numpy()\n",
" validation_ds_size = tf.data.experimental.cardinality(validation_ds).numpy()\n",
"\n",
" #Rozmiary zbiorów\n",
" print(\"Training:\", train_ds_size)\n",
" print(\"Test:\", test_ds_size)\n",
" print(\"Validation:\", validation_ds_size)\n",
"\n",
" # Mieszanie zriorów\n",
" train_ds = (train_ds.shuffle(buffer_size=train_ds_size).batch(batch_size=32, drop_remainder=True))\n",
" test_ds = (test_ds.shuffle(buffer_size=train_ds_size).batch(batch_size=32, drop_remainder=True))\n",
" validation_ds = (validation_ds.shuffle(buffer_size=train_ds_size).batch(batch_size=32, drop_remainder=True))\n",
"\n",
" return train_ds, test_ds, validation_ds\n",
"\n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# AlexNet"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:absl:`lr` is deprecated, please use `learning_rate` instead, or use the legacy optimizer, e.g.,tf.keras.optimizers.legacy.SGD.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"sequential\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" conv2d (Conv2D) (None, 55, 55, 96) 34944 \n",
" \n",
" max_pooling2d (MaxPooling2D (None, 27, 27, 96) 0 \n",
" ) \n",
" \n",
" conv2d_1 (Conv2D) (None, 27, 27, 256) 614656 \n",
" \n",
" max_pooling2d_1 (MaxPooling (None, 13, 13, 256) 0 \n",
" 2D) \n",
" \n",
" conv2d_2 (Conv2D) (None, 13, 13, 384) 885120 \n",
" \n",
" conv2d_3 (Conv2D) (None, 13, 13, 384) 1327488 \n",
" \n",
" conv2d_4 (Conv2D) (None, 13, 13, 256) 884992 \n",
" \n",
" max_pooling2d_2 (MaxPooling (None, 6, 6, 256) 0 \n",
" 2D) \n",
" \n",
" flatten (Flatten) (None, 9216) 0 \n",
" \n",
" dense (Dense) (None, 4096) 37752832 \n",
" \n",
" dense_1 (Dense) (None, 4096) 16781312 \n",
" \n",
" dense_2 (Dense) (None, 3) 12291 \n",
" \n",
"=================================================================\n",
"Total params: 58,293,635\n",
"Trainable params: 58,293,635\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"from tensorflow import keras\n",
"import tensorflow as tf\n",
"import os\n",
"import time\n",
"\n",
"model = keras.models.Sequential([\n",
" keras.layers.Conv2D(filters=96, kernel_size=(11,11), strides=(4,4), activation='relu', input_shape=(227,227,3)),\n",
" keras.layers.MaxPool2D(pool_size=(3,3), strides=(2,2)),\n",
" keras.layers.Conv2D(filters=256, kernel_size=(5,5), strides=(1,1), activation='relu', padding=\"same\"),\n",
" keras.layers.MaxPool2D(pool_size=(3,3), strides=(2,2)),\n",
" keras.layers.Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), activation='relu', padding=\"same\"),\n",
" keras.layers.Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), activation='relu', padding=\"same\"),\n",
" keras.layers.Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), activation='relu', padding=\"same\"),\n",
" keras.layers.MaxPool2D(pool_size=(3,3), strides=(2,2)),\n",
" keras.layers.Flatten(),\n",
" keras.layers.Dense(4096, activation='relu'),\n",
" keras.layers.Dense(4096, activation='relu'),\n",
" keras.layers.Dense(3, activation='softmax')\n",
"])\n",
"\n",
"model.compile(loss='sparse_categorical_crossentropy', optimizer=tf.optimizers.SGD(lr=.001), metrics=['accuracy'])\n",
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training: 4772\n",
"Test: 1492\n",
"Validation: 1194\n"
]
}
],
"source": [
"train_ds_a, test_ds_a, val_ds_a = prepare_data(\"./plantvillage/color\", (227, 227), 0.2, 0.2)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:`period` argument is deprecated. Please use `save_freq` to specify the frequency in number of batches seen.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:tensorflow:`period` argument is deprecated. Please use `save_freq` to specify the frequency in number of batches seen.\n",
"/var/folders/6b/j4d60ym516x2s6wymzj707rh0000gn/T/ipykernel_9542/953612165.py:6: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.\n",
" alex = model.fit_generator(\n",
"2023-01-06 04:01:52.794677: W tensorflow/tsl/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"149/149 [==============================] - ETA: 0s - loss: 0.5993 - accuracy: 0.7576\n",
"Epoch 1: val_accuracy improved from -inf to 0.41385, saving model to alex_2.h5\n",
"149/149 [==============================] - 167s 1s/step - loss: 0.5993 - accuracy: 0.7576 - val_loss: 0.9947 - val_accuracy: 0.4139\n"
]
}
],
"source": [
"from keras.callbacks import ModelCheckpoint, EarlyStopping\n",
"\n",
"checkpoint = ModelCheckpoint(\"alex_2.h5\", monitor='val_accuracy', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1)\n",
"early = EarlyStopping(monitor='val_accuracy', min_delta=0, patience=20, verbose=1, mode='auto')\n",
"\n",
"alex = model.fit_generator(\n",
" steps_per_epoch=len(train_ds_a), \n",
" generator=train_ds_a, \n",
" validation_data= val_ds_a, \n",
" validation_steps=len(val_ds_a), \n",
" epochs=1, \n",
" callbacks=[checkpoint,early])"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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khSGGyIiIpIUhhsiIiKSFIYbIiIikhSGGyIiIpIUhhsiIiKSFIYbIiIikhSGGyIiIpIUhhsiIiKSFIYbIiIikhSGGyIiIpIUhhsiIiKSFIYbIiIikpR6EW6WLVsGV1dXGBkZoWPHjjh69GilfZOSkiCTyTQmIyOjOqyWiIiI6jOdh5t169YhJiYGsbGxOHnyJLy8vBAYGIibN29WuoyFhQWys7PV05UrV+qwYiIiIqrPdB5uFi1ahKioKERERKBNmzZYsWIFTExMkJCQUOkyMpkMDg4O6sne3r4OKyYiIqL6TKfhprS0FCdOnEBAQIC6TS6XIyAgAGlpaZUuV1RUhKZNm8LFxQV9+/bF77//XmnfkpISFBYWakxEREQkXToNN3l5eVAqleXOvNjb2yMnJ6fCZVq1aoWEhAT89NNP+OGHH6BSqdCpUydcu3atwv7z5s2DpaWlenJxcan1/SAiIqL6Q+eXpWrK398fYWFh8Pb2RpcuXbB582bY2dnhu+++q7D/1KlTUVBQoJ6uXr1axxUTERFRXdLX5cZtbW2hp6eH3Nxcjfbc3Fw4ODhUax0GBgZo3749Ll68WOF8hUIBhULxwrUSERFRw6DTMzeGhobw8fFBamqquk2lUiE1NRX+/v7VWodSqcTp06fh6OiorTKJiIioAdHpmRsAiImJQXh4OHx9feHn54e4uDgUFxcjIiICABAWFgZnZ2fMmzcPADBnzhy8/vrraNGiBfLz8zF//nxcuXIFo0eP1uVuEBERUT2h83ATEhKCW7duYebMmcjJyYG3tzd27typHmSclZUFufz/TjDdvXsXUVFRyMnJgbW1NXx8fHD48GG0adNGV7tARERE9YhMCCF0XURdKiwshKWlJQoKCmBhYaHrcoiIiKgaavL73eDuliIiIiKqCsMNERERSQrDDREREUkKww0RERFJCsMNERERSQrDDREREUkKww0RERFJCsMNERERSQrDDREREUkKww0RERFJCsMNERERSQrDDREREUkKww0RERFJCsMNERERSQrDDREREUkKww0RERFJCsMNERERSQrDDREREUkKww0RERFJCsMNERERSQrDDREREUkKww0RERFJCsMNERERSQrDDREREUkKww0RERFJCsMNERERSQrDDREREUkKww0RERFJCsMNERERSQrDDREREUkKww0RERFJCsMN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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"plt.plot(alex.history[\"accuracy\"])\n",
"plt.plot(alex.history['val_accuracy'])\n",
"plt.plot(alex.history['loss'])\n",
"plt.plot(alex.history['val_loss'])\n",
"plt.title(\"Model accuracy\")\n",
"plt.ylabel(\"Value\")\n",
"plt.xlabel(\"Epoch\")\n",
"plt.legend([\"Accuracy\",\"Validation Accuracy\",\"Loss\",\"Validation Loss\"])\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"46/46 [==============================] - 24s 518ms/step - loss: 1.0025 - accuracy: 0.4137\n"
]
},
{
"data": {
"text/plain": [
"[1.0024936199188232, 0.41372281312942505]"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.evaluate(test_ds_a)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# VGG16"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"sequential_1\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" conv2d_5 (Conv2D) (None, 224, 224, 64) 1792 \n",
" \n",
" conv2d_6 (Conv2D) (None, 224, 224, 64) 36928 \n",
" \n",
" max_pooling2d_3 (MaxPooling (None, 112, 112, 64) 0 \n",
" 2D) \n",
" \n",
" conv2d_7 (Conv2D) (None, 112, 112, 128) 73856 \n",
" \n",
" conv2d_8 (Conv2D) (None, 112, 112, 128) 147584 \n",
" \n",
" max_pooling2d_4 (MaxPooling (None, 56, 56, 128) 0 \n",
" 2D) \n",
" \n",
" conv2d_9 (Conv2D) (None, 56, 56, 256) 295168 \n",
" \n",
" conv2d_10 (Conv2D) (None, 56, 56, 256) 590080 \n",
" \n",
" conv2d_11 (Conv2D) (None, 56, 56, 256) 590080 \n",
" \n",
" max_pooling2d_5 (MaxPooling (None, 28, 28, 256) 0 \n",
" 2D) \n",
" \n",
" conv2d_12 (Conv2D) (None, 28, 28, 512) 1180160 \n",
" \n",
" conv2d_13 (Conv2D) (None, 28, 28, 512) 2359808 \n",
" \n",
" conv2d_14 (Conv2D) (None, 28, 28, 512) 2359808 \n",
" \n",
" max_pooling2d_6 (MaxPooling (None, 14, 14, 512) 0 \n",
" 2D) \n",
" \n",
" conv2d_15 (Conv2D) (None, 14, 14, 512) 2359808 \n",
" \n",
" conv2d_16 (Conv2D) (None, 14, 14, 512) 2359808 \n",
" \n",
" conv2d_17 (Conv2D) (None, 14, 14, 512) 2359808 \n",
" \n",
" flatten_1 (Flatten) (None, 100352) 0 \n",
" \n",
" dense_3 (Dense) (None, 4096) 411045888 \n",
" \n",
" dense_4 (Dense) (None, 4096) 16781312 \n",
" \n",
" dense_5 (Dense) (None, 3) 12291 \n",
" \n",
"=================================================================\n",
"Total params: 442,554,179\n",
"Trainable params: 442,554,179\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/jonas/Library/Python/3.9/lib/python/site-packages/keras/optimizers/optimizer_v2/adam.py:117: UserWarning: The `lr` argument is deprecated, use `learning_rate` instead.\n",
" super().__init__(name, **kwargs)\n"
]
}
],
"source": [
"import keras,os\n",
"from keras.models import Sequential\n",
"from keras.layers import Dense, Conv2D, MaxPool2D , Flatten\n",
"from keras.preprocessing.image import ImageDataGenerator\n",
"from keras.optimizers import Adam\n",
"import numpy as np\n",
"\n",
"model = keras.models.Sequential([\n",
" keras.layers.Conv2D(filters=64, kernel_size=(3,3), activation='relu', input_shape=(224,224,3), padding=\"same\"),\n",
" keras.layers.Conv2D(filters=64, kernel_size=(3,3), activation='relu', input_shape=(224,224,3), padding=\"same\"),\n",
" keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2)),\n",
" keras.layers.Conv2D(filters=128, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.Conv2D(filters=128, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2)),\n",
" keras.layers.Conv2D(filters=256, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.Conv2D(filters=256, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.Conv2D(filters=256, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2)),\n",
" keras.layers.Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2)),\n",
" keras.layers.Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"),\n",
" keras.layers.Flatten(),\n",
" keras.layers.Dense(units = 4096, activation='relu'),\n",
" keras.layers.Dense(units = 4096, activation='relu'),\n",
" keras.layers.Dense(units = 3, activation='softmax')\n",
"])\n",
"\n",
"opt = Adam(lr=0.001)\n",
"model.compile(optimizer=opt, loss=keras.losses.sparse_categorical_crossentropy, metrics=['accuracy'])\n",
"\n",
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training: 4772\n",
"Test: 1492\n",
"Validation: 1194\n"
]
}
],
"source": [
"train_ds_v, test_ds_v, val_ds_v = prepare_data('./plantvillage/color', (224, 224), 0.2, 0.2)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:`period` argument is deprecated. Please use `save_freq` to specify the frequency in number of batches seen.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:tensorflow:`period` argument is deprecated. Please use `save_freq` to specify the frequency in number of batches seen.\n",
"/var/folders/6b/j4d60ym516x2s6wymzj707rh0000gn/T/ipykernel_9542/385174540.py:5: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.\n",
" vgg = model.fit_generator(steps_per_epoch=len(train_ds_v), generator=train_ds_v, validation_data= val_ds_v, validation_steps=len(val_ds_v), epochs=1, callbacks=[checkpoint,early])\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"149/149 [==============================] - ETA: 0s - loss: 0.8037 - accuracy: 0.7024 \n",
"Epoch 1: val_accuracy improved from -inf to 0.72804, saving model to vgg16_2.h5\n",
"149/149 [==============================] - 3159s 21s/step - loss: 0.8037 - accuracy: 0.7024 - val_loss: 0.7223 - val_accuracy: 0.7280\n"
]
}
],
"source": [
"from keras.callbacks import ModelCheckpoint, EarlyStopping\n",
"\n",
"checkpoint = ModelCheckpoint(\"vgg16_2.h5\", monitor='val_accuracy', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1)\n",
"early = EarlyStopping(monitor='val_accuracy', min_delta=0, patience=20, verbose=1, mode='auto')\n",
"vgg = model.fit_generator(steps_per_epoch=len(train_ds_v), generator=train_ds_v, validation_data= val_ds_v, validation_steps=len(val_ds_v), epochs=1, callbacks=[checkpoint,early])"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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h5/bxoABA2BsbIx169Zh7969mDBhQpX2/SoYgIiISOtMTEzg7++PefPmISsrC+PGjZPXtW7dGvHx8Thx4gTS0tLw3nvvlXvnY2W8vb3Rpk0bBAcH49y5czh69Cjmz5+vUad169bIzMxEbGwsrl69itWrV2Pnzp0adVxcXJCRkYGUlBTk5eWhuLi43L7GjBkDAwMDBAcHIzU1FQcPHkRYWBjGjh370g/kvX37Nn744QcEBwfjjTfe0FiCgoKwa9cu3L17F1OnTkVBQQFGjRqFM2fO4PLly/jXv/4lX3pbvHgxvvzyS6xevRqXL19GcnIyvv76awBPztK8+eabWLZsGdLS0nD48GGNOVGVad26NXbs2IGUlBScO3cOo0eP1jib5eLiguDgYEyYMAG7du1CRkYGDh06hK1bt8p1dHR0MG7cOMybNw+tW7euk9dXMQAREVG9EBISgj/++AM+Pj4a83UWLFiAv/zlL/Dx8UHv3r1hb29fracuq1Qq7Ny5Ew8fPoSnpydCQ0M13iAAAIMHD8aMGTMwdepUuLu748SJE1i4cKFGnWHDhqFfv37o06cPbG1tK7wV38jICPv27cPdu3fRtWtXDB8+HH379sWaNWuqdzD+5OmE6orm7/Tt2xeGhob497//DWtra/z8888oLCxEr1690KVLF3z//ffy5bbg4GBERkbim2++QceOHTFo0CBcvnxZbmv9+vV4/PgxunTpgunTp+OTTz6pUv9WrlwJS0tLdO/eHb6+vvDx8cFf/vIXjTrr1q3D8OHD8f7776Ndu3aYOHGixlky4Mk//5KSkjp7dRWfBF0BPgmaiBqahvokaKKnjh49ir59++L69euVni2rqSdBcxI0ERERaU1xcTFu376NxYsXY8SIEXX27k5eAiMiIiKt2bx5M5ydnXHv3j188cUXdbZfBiAiIiLSmnHjxqGsrAxnz55Fs2bN6my/DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxARESkVePGjavWu72IagIDEBERESkOAxAREdVbhw8fhqenJ/T19eHg4IC5c+fi8ePH8vpt27bB1dUVhoaGsLa2hre3t/yW8UOHDsHT0xPGxsawsLBAjx49cO3aNW0NheoZvgyViKiREkLg4eOHWtm3oa4hJEl6pTZu3ryJAQMG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9pVuW1RUhNjYWISEhJRrU1dXFx06dNAob9++faV3genr68PMzExjISIiosZLawFIT08PXbp0QUJCglymVquRkJCAbt26VbptXFwciouLERgYWK7Nrl27Ij09XaP8119/hbOzc811noiIiBo0XW3uPDw8HMHBwfDw8ICnpyciIyNRVFSE8ePHAwCCgoLQrFkzLF26VGO7qKgo+Pn5wdraulybs2fPhr+/P3r27Ik+ffpg7969+OGHH3Do0KG6GBIRERE1AFoNQP7+/rh9+zYWLVqE7OxsuLu7Y+/evfLE6MzMTKhUmiep0tPTcezYMezfv7/CNocOHYpvv/0WS5cuxbRp09C2bVts374db731Vq2Ph4iIiBqGl3oO0OPHj3Ho0CFcvXoVo0ePhqmpKW7dugUzMzOYmJjURj/rFJ8DRERE1PBU5/e72meArl27hn79+iEzMxPFxcX461//ClNTU3z++ecoLi6u9G4rIiIiovqg2pOgP/jgA3h4eOCPP/6AoaGhXD506FCNCc1ERERE9VW1zwAdPXoUJ06cgJ6enka5i4sLbt68WWMdIyIiIqot1T4DpFarUVZWVq78xo0bMDU1rZFOEREREdWmagegv/3tb4iMjJQ/S5KEwsJCREREYMCAATXZNyIiIqJaUe27wG7cuAEfHx8IIXD58mV4eHjg8uXLsLGxwZEjR9C0adPa6mud4V1gREREDU91fr9f+jb42NhYnD9/HoWFhfjLX/6CMWPGaEyKbsgYgIiIiBqeWr0NHgB0dXXLvYaCiIiIqKGodgDasGFDpeuDgoJeujNEREREdaHal8AsLS01PpeWluLBgwfQ09ODkZER7t69W6Md1AZeAiMiImp4qvP7Xe27wP744w+NpbCwEOnp6XjrrbewefPml+40ERERUV2pdgCqSOvWrbFs2TJ88MEHNdEcERERUa2qkQAEPJkYfevWrZpqjoiIiKjWVHsS9O7duzU+CyGQlZWFNWvWoEePHjXWMSIiIqLaUu0A5Ofnp/FZkiTY2trinXfewZdffllT/SIiIiKqNdUOQGq1ujb6QURERFRnamwOEBEREVFDUaUzQOHh4VVucOXKlS/dGSIiIqK6UKUA9H//939VakySpFfqDBEREVFdqFIAOnjwYG33g4iIiKjOcA4QERERKc5LvQ3+zJkz2Lp1KzIzM1FSUqKxbseOHTXSMSIiIqLaUu0zQLGxsejevTvS0tKwc+dOlJaW4pdffsHPP/8Mc3Pz2ugjERERUY2qdgD67LPP8NVXX+GHH36Anp4eVq1ahUuXLmHkyJFo3rx5bfSRiIiIqEZVOwBdvXoVAwcOBADo6emhqKgIkiRhxowZ+O6772q8g0REREQ1rdoByNLSEvfv3wcANGvWDKmpqQCAe/fu4cGDBzXbOyIiIqJaUOUA9DTo9OzZE/Hx8QCAESNG4IMPPsDEiRMREBCAvn371k4viYiIiGpQle8C69SpE7p27Qo/Pz+MGDECADB//nw0adIEJ06cwLBhw7BgwYJa6ygRERFRTZGEEKIqFY8ePYro6Ghs27YNarUaw4YNQ2hoKN5+++3a7mOdKygogLm5OfLz82FmZqbt7hAREVEVVOf3u8qXwN5++22sX78eWVlZ+Prrr/H777+jV69eaNOmDT7//HNkZ2e/cseJiIiI6kK1J0EbGxtj/PjxOHz4MH799VeMGDECa9euRfPmzTF48ODa6CMRERFRjaryJbDnKSoqwsaNGzFv3jzcu3cPZWVlNdU3reElMCIiooanOr/fL/UqDAA4cuQI1q9fj+3bt0OlUmHkyJEICQl52eaIiIiI6ky1AtCtW7cQExODmJgYXLlyBd27d8fq1asxcuRIGBsb11YfiYiIiGpUlQNQ//79ceDAAdjY2CAoKAgTJkxA27Zta7NvRERERLWiygGoSZMm2LZtGwYNGgQdHZ3a7BMRERFRrapyANq9e3dt9oOIiIiozlT7NngiIiKiho4BiIiIiBSHAYiIiIgUhwGIiIiIFIcBiIiIiBSHAYiIiIgUhwGIiIiIFIcBiIiIiBSHAYiIiIgUhwGIiIiIFIcBiIiIiBSHAYiIiIgUhwGIiIiIFIcBiIiIiBSHAYiIiIgUhwGIiIiIFIcBiIiIiBSHAYiIiIgUp14EoLVr18LFxQUGBgbw8vJCUlLSc+v27t0bkiSVWwYOHFhh/cmTJ0OSJERGRtZS74mIiKih0XoA2rJlC8LDwxEREYHk5GS4ubnBx8cHubm5FdbfsWMHsrKy5CU1NRU6OjoYMWJEubo7d+7EyZMn4ejoWNvDICIiogZE6wFo5cqVmDhxIsaPH48OHTrg22+/hZGREdavX19hfSsrK9jb28tLfHw8jIyMygWgmzdvIiwsDBs3bkSTJk3qYihERETUQGg1AJWUlODs2bPw9vaWy1QqFby9vZGYmFilNqKiojBq1CgYGxvLZWq1GmPHjsXs2bPRsWPHF7ZRXFyMgoICjYWIiIgaL60GoLy8PJSVlcHOzk6j3M7ODtnZ2S/cPikpCampqQgNDdUo//zzz6Grq4tp06ZVqR9Lly6Fubm5vDg5OVV9EERERNTgaP0S2KuIioqCq6srPD095bKzZ89i1apViImJgSRJVWpn3rx5yM/Pl5fr16/XVpeJiIioHtBqALKxsYGOjg5ycnI0ynNycmBvb1/ptkVFRYiNjUVISIhG+dGjR5Gbm4vmzZtDV1cXurq6uHbtGmbOnAkXF5cK29LX14eZmZnGQkRERI2XVgOQnp4eunTpgoSEBLlMrVYjISEB3bp1q3TbuLg4FBcXIzAwUKN87NixOH/+PFJSUuTF0dERs2fPxr59+2plHERERNSw6Gq7A+Hh4QgODoaHhwc8PT0RGRmJoqIijB8/HgAQFBSEZs2aYenSpRrbRUVFwc/PD9bW1hrl1tbW5cqaNGkCe3t7tG3btnYHQ0RERA2C1gOQv78/bt++jUWLFiE7Oxvu7u7Yu3evPDE6MzMTKpXmiar09HQcO3YM+/fv10aXiYiIqIGThBBC252obwoKCmBubo78/HzOByIiImogqvP73aDvAiMiIiJ6GQxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOAxAREREpDgMQERERKQ4DEBERESkOPUiAK1duxYuLi4wMDCAl5cXkpKSnlu3d+/ekCSp3DJw4EAAQGlpKebMmQNXV1cYGxvD0dERQUFBuHXrVl0Nh4iIiOo5rQegLVu2IDw8HBEREUhOToabmxt8fHyQm5tbYf0dO3YgKytLXlJTU6Gjo4MRI0YAAB48eIDk5GQsXLgQycnJ2LFjB9LT0zF48OC6HBYRERHVY5IQQmizA15eXujatSvWrFkDAFCr1XByckJYWBjmzp37wu0jIyOxaNEiZGVlwdjYuMI6p0+fhqenJ65du4bmzZu/sM2CggKYm5sjPz8fZmZm1RsQERERaUV1fr+1egaopKQEZ8+ehbe3t1ymUqng7e2NxMTEKrURFRWFUaNGPTf8AEB+fj4kSYKFhcWrdpmIiIgaAV1t7jwvLw9lZWWws7PTKLezs8OlS5deuH1SUhJSU1MRFRX13DqPHj3CnDlzEBAQ8Nw0WFxcjOLiYvlzQUFBFUdAREREDZHW5wC9iqioKLi6usLT07PC9aWlpRg5ciSEEFi3bt1z21m6dCnMzc3lxcnJqba6TERERPWAVgOQjY0NdHR0kJOTo1Gek5MDe3v7SrctKipCbGwsQkJCKlz/NPxcu3YN8fHxlV4LnDdvHvLz8+Xl+vXr1R8MERERNRhaDUB6enro0qULEhIS5DK1Wo2EhAR069at0m3j4uJQXFyMwMDAcuuehp/Lly/jwIEDsLa2rrQtfX19mJmZaSxERETUeGl1DhAAhIeHIzg4GB4eHvD09ERkZCSKioowfvx4AEBQUBCaNWuGpUuXamwXFRUFPz+/cuGmtLQUw4cPR3JyMv773/+irKwM2dnZAAArKyvo6enVzcCIiIio3tJ6APL398ft27exaNEiZGdnw93dHXv37pUnRmdmZkKl0jxRlZ6ejmPHjmH//v3l2rt58yZ2794NAHB3d9dYd/DgQfTu3btWxkFEREQNh9afA1Qf8TlAREREDU+DeQ4QERERkTYwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAARERGR4jAAERERkeIwABEREZHi1IsAtHbtWri4uMDAwABeXl5ISkp6bt3evXtDkqRyy8CBA+U6QggsWrQIDg4OMDQ0hLe3Ny5fvlwXQyEiIqIGQOsBaMuWLQgPD0dERASSk5Ph5uYGHx8f5ObmVlh/x44dyMrKkpfU1FTo6OhgxIgRcp0vvvgCq1evxrfffotTp07B2NgYPj4+ePToUV0Ni4iIiOoxSQghtNkBLy8vdO3aFWvWrAEAqNVqODk5ISwsDHPnzn3h9pGRkVi0aBGysrJgbGwMIQQcHR0xc+ZMzJo1CwCQn58POzs7xMTEYNSoUS9ss6CgAObm5sjPz4eZmdmrDZCIiIjqRHV+v7V6BqikpARnz56Ft7e3XKZSqeDt7Y3ExMQqtREVFYVRo0bB2NgYAJCRkYHs7GyNNs3NzeHl5fXcNouLi1FQUKCxEBERUeOl1QCUl5eHsrIy2NnZaZTb2dkhOzv7hdsnJSUhNTUVoaGhctnT7arT5tKlS2Fubi4vTk5O1R0KERERNSBanwP0KqKiouDq6gpPT89XamfevHnIz8+Xl+vXr9dQD4mIiKg+0moAsrGxgY6ODnJycjTKc3JyYG9vX+m2RUVFiI2NRUhIiEb50+2q06a+vj7MzMw0FiIiImq8tBqA9PT00KVLFyQkJMhlarUaCQkJ6NatW6XbxsXFobi4GIGBgRrlLVq0gL29vUabBQUFOHXq1AvbJCIiImXQ1XYHwsPDERwcDA8PD3h6eiIyMhJFRUUYP348ACAoKAjNmjXD0qVLNbaLioqCn58frK2tNcolScL06dPxySefoHXr1mjRogUWLlwIR0dH+Pn51dWwiIiIqB7TegDy9/fH7du3sWjRImRnZ8Pd3R179+6VJzFnZmZCpdI8UZWeno5jx45h//79Fbb54YcfoqioCJMmTcK9e/fw1ltvYe/evTAwMKj18RAREVH9p/XnANVHfA4QERFRw9NgngNEREREpA1avwRWHz09KcYHIhIRETUcT3+3q3JxiwGoAvfv3wcAPhCRiIioAbp//z7Mzc0rrcM5QBVQq9W4desWTE1NIUmStrujdQUFBXBycsL169c5J6oW8TjXDR7nusHjXDd4nDUJIXD//n04OjqWu4HqWTwDVAGVSoXXXntN292od/iQyLrB41w3eJzrBo9z3eBx/v+96MzPU5wETURERIrDAERERESKwwBEL6Svr4+IiAjo6+truyuNGo9z3eBxrhs8znWDx/nlcRI0ERERKQ7PABEREZHiMAARERGR4jAAERERkeIwABEREZHiMAAR7t69izFjxsDMzAwWFhYICQlBYWFhpds8evQIU6ZMgbW1NUxMTDBs2DDk5ORUWPfOnTt47bXXIEkS7t27VwsjaBhq4zifO3cOAQEBcHJygqGhIdq3b49Vq1bV9lDqnbVr18LFxQUGBgbw8vJCUlJSpfXj4uLQrl07GBgYwNXVFT/++KPGeiEEFi1aBAcHBxgaGsLb2xuXL1+uzSE0CDV5nEtLSzFnzhy4urrC2NgYjo6OCAoKwq1bt2p7GPVeTX+f/2zy5MmQJAmRkZE13OsGSJDi9evXT7i5uYmTJ0+Ko0ePitdff10EBARUus3kyZOFk5OTSEhIEGfOnBFvvvmm6N69e4V1hwwZIvr37y8AiD/++KMWRtAw1MZxjoqKEtOmTROHDh0SV69eFf/617+EoaGh+Prrr2t7OPVGbGys0NPTE+vXrxe//PKLmDhxorCwsBA5OTkV1j9+/LjQ0dERX3zxhbh48aJYsGCBaNKkibhw4YJcZ9myZcLc3Fzs2rVLnDt3TgwePFi0aNFCPHz4sK6GVe/U9HG+d++e8Pb2Flu2bBGXLl0SiYmJwtPTU3Tp0qUuh1Xv1Mb3+akdO3YINzc34ejoKL766qtaHkn9xwCkcBcvXhQAxOnTp+Wyn376SUiSJG7evFnhNvfu3RNNmjQRcXFxcllaWpoAIBITEzXqfvPNN6JXr14iISFB0QGoto/zn73//vuiT58+Ndf5es7T01NMmTJF/lxWViYcHR3F0qVLK6w/cuRIMXDgQI0yLy8v8d577wkhhFCr1cLe3l4sX75cXn/v3j2hr68vNm/eXAsjaBhq+jhXJCkpSQAQ165dq5lON0C1dZxv3LghmjVrJlJTU4WzszMDkBCCl8AULjExERYWFvDw8JDLvL29oVKpcOrUqQq3OXv2LEpLS+Ht7S2XtWvXDs2bN0diYqJcdvHiRXz00UfYsGHDC19K19jV5nF+Vn5+PqysrGqu8/VYSUkJzp49q3GMVCoVvL29n3uMEhMTNeoDgI+Pj1w/IyMD2dnZGnXMzc3h5eVV6XFvzGrjOFckPz8fkiTBwsKiRvrd0NTWcVar1Rg7dixmz56Njh071k7nGyBl/yoRsrOz0bRpU40yXV1dWFlZITs7+7nb6OnplfuPlJ2dnbxNcXExAgICsHz5cjRv3rxW+t6Q1NZxftaJEyewZcsWTJo0qUb6Xd/l5eWhrKwMdnZ2GuWVHaPs7OxK6z/9szptNna1cZyf9ejRI8yZMwcBAQGKfalnbR3nzz//HLq6upg2bVrNd7oBYwBqpObOnQtJkipdLl26VGv7nzdvHtq3b4/AwMBa20d9oO3j/GepqakYMmQIIiIi8Le//a1O9klUE0pLSzFy5EgIIbBu3Tptd6dROXv2LFatWoWYmBhIkqTt7tQrutruANWOmTNnYty4cZXWadmyJezt7ZGbm6tR/vjxY9y9exf29vYVbmdvb4+SkhLcu3dP4+xETk6OvM3PP/+MCxcuYNu2bQCe3FUDADY2Npg/fz6WLFnykiOrX7R9nJ+6ePEi+vbti0mTJmHBggUvNZaGyMbGBjo6OuXuQKzoGD1lb29faf2nf+bk5MDBwUGjjru7ew32vuGojeP81NPwc+3aNfz888+KPfsD1M5xPnr0KHJzczXOxJeVlWHmzJmIjIzE77//XrODaEi0PQmJtOvp5NwzZ87IZfv27avS5Nxt27bJZZcuXdKYnHvlyhVx4cIFeVm/fr0AIE6cOPHcuxkas9o6zkIIkZqaKpo2bSpmz55dewOoxzw9PcXUqVPlz2VlZaJZs2aVThodNGiQRlm3bt3KTYJesWKFvD4/P5+ToGv4OAshRElJifDz8xMdO3YUubm5tdPxBqamj3NeXp7Gf4svXLggHB0dxZw5c8SlS5dqbyANAAMQiX79+onOnTuLU6dOiWPHjonWrVtr3J5948YN0bZtW3Hq1Cm5bPLkyaJ58+bi559/FmfOnBHdunUT3bp1e+4+Dh48qOi7wISoneN84cIFYWtrKwIDA0VWVpa8KOnHJDY2Vujr64uYmBhx8eJFMWnSJGFhYSGys7OFEEKMHTtWzJ07V65//PhxoaurK1asWCHS0tJEREREhbfBW1hYiP/85z/i/PnzYsiQIbwNvoaPc0lJiRg8eLB47bXXREpKisb3t7i4WCtjrA9q4/v8LN4F9gQDEIk7d+6IgIAAYWJiIszMzMT48ePF/fv35fUZGRkCgDh48KBc9vDhQ/H+++8LS0tLYWRkJIYOHSqysrKeuw8GoNo5zhEREQJAucXZ2bkOR6Z9X3/9tWjevLnQ09MTnp6e4uTJk/K6Xr16ieDgYI36W7duFW3atBF6enqiY8eOYs+ePRrr1Wq1WLhwobCzsxP6+vqib9++Ij09vS6GUq/V5HF++n2vaPnzvwNKVNPf52cxAD0hCfH/JmcQERERKQTvAiMiIiLFYQAiIiIixWEAIiIiIsVhACIiIiLFYQAiIiIixWEAIiIiIsVhACIiIiLFYQAiIqoCSZKwa9cubXeDiGoIAxAR1Xvjxo2DJEnlln79+mm7a0TUQPFt8ETUIPTr1w/R0dEaZfr6+lrqDRE1dDwDREQNgr6+Puzt7TUWS0tLAE8uT61btw79+/eHoaEhWrZsiW3btmlsf+HCBbzzzjswNDSEtbU1Jk2ahMLCQo0669evR8eOHaGvrw8HBwdMnTpVY31eXh6GDh0KIyMjtG7dGrt3767dQRNRrWEAIqJGYeHChRg2bBjOnTuHMWPGYNSoUUhLSwMAFBUVwcfHB5aWljh9+jTi4uJw4MABjYCzbt06TJkyBZMmTcKFCxewe/duvP766xr7WLJkCUaOHInz589jwIABGDNmDO7evVun4ySiGqLtt7ESEb1IcHCw0NHREcbGxhrLp59+KoQQAoCYPHmyxjZeXl7i73//uxBCiO+++05YWlqKwsJCef2ePXuESqUS2dnZQgghHB0dxfz585/bBwBiwYIF8ufCwkIBQPz00081Nk4iqjucA0REDUKfPn2wbt06jTIrKyv57926ddNY161bN6SkpAAA0tLS4ObmBmNjY3l9jx49oFarkZ6eDkmScOvWLfTt27fSPnTq1En+u7GxMczMzJCbm/uyQyIiLWIAIqIGwdjYuNwlqZpiaGhYpXpNmjTR+CxJEtRqdW10iYhqGecAEVGjcPLkyXKf27dvDwBo3749zp07h6KiInn98ePHoVKp0LZtW5iamsLFxQUJCQl12mci0h6eASKiBqG4uBjZ2dkaZbq6urCxsQEAxMXFwcPDA2+99RY2btyIpKQkREVFAQDGjBmDiIgIBAcHY/Hixbh9+zbCwsIwduxY2NnZAQAWL16MyZMno2nTpujfvz/u37+P48ePIywsrG4HSkR1ggGIiBqEvXv3wsHBQaOsbdu2uHTpEoAnd2jFxsbi/fffh4ODAzZv3owOHToAAIyMjLBv3z588MEH6Nq1K4yMjDBs2DCsXLlSbis4OBiPHj3CV199hVmzZsHGxgbDhw+vuwESUZ2ShBBC250gInoVkiRh586d8PPz03ZXiKiB4BwgIiIiUhwGICIiIlIczgEiogaPV/KJqLp4BoiIiIgUhwGIiIiIFIcBiIiIiBSHAYiIiIgUhwGIiIiIFIcBiIiIiBSHAYiIiIgUhwGIiIiIFIcBiIiIiBTn/wMGhay0yHPIpAAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"plt.plot(vgg.history[\"accuracy\"])\n",
"plt.plot(vgg.history['val_accuracy'])\n",
"plt.plot(vgg.history['loss'])\n",
"plt.plot(vgg.history['val_loss'])\n",
"plt.title(\"Model accuracy\")\n",
"plt.ylabel(\"Value\")\n",
"plt.xlabel(\"Epoch\")\n",
"plt.legend([\"Accuracy\",\"Validation Accuracy\",\"Loss\",\"Validation Loss\"])\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"46/46 [==============================] - 238s 5s/step - loss: 0.7124 - accuracy: 0.7364\n"
]
},
{
"data": {
"text/plain": [
"[0.7124184966087341, 0.7364130616188049]"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.evaluate(test_ds_v)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# ResNet50"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"model\"\n",
"__________________________________________________________________________________________________\n",
" Layer (type) Output Shape Param # Connected to \n",
"==================================================================================================\n",
" input_1 (InputLayer) [(None, 224, 224, 3 0 [] \n",
" )] \n",
" \n",
" conv1_pad (ZeroPadding2D) (None, 230, 230, 3) 0 ['input_1[0][0]'] \n",
" \n",
" conv1_conv (Conv2D) (None, 112, 112, 64 9472 ['conv1_pad[0][0]'] \n",
" ) \n",
" \n",
" conv1_bn (BatchNormalization) (None, 112, 112, 64 256 ['conv1_conv[0][0]'] \n",
" ) \n",
" \n",
" conv1_relu (Activation) (None, 112, 112, 64 0 ['conv1_bn[0][0]'] \n",
" ) \n",
" \n",
" pool1_pad (ZeroPadding2D) (None, 114, 114, 64 0 ['conv1_relu[0][0]'] \n",
" ) \n",
" \n",
" pool1_pool (MaxPooling2D) (None, 56, 56, 64) 0 ['pool1_pad[0][0]'] \n",
" \n",
" conv2_block1_1_conv (Conv2D) (None, 56, 56, 64) 4160 ['pool1_pool[0][0]'] \n",
" \n",
" conv2_block1_1_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block1_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv2_block1_1_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block1_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv2_block1_2_conv (Conv2D) (None, 56, 56, 64) 36928 ['conv2_block1_1_relu[0][0]'] \n",
" \n",
" conv2_block1_2_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block1_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv2_block1_2_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block1_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv2_block1_0_conv (Conv2D) (None, 56, 56, 256) 16640 ['pool1_pool[0][0]'] \n",
" \n",
" conv2_block1_3_conv (Conv2D) (None, 56, 56, 256) 16640 ['conv2_block1_2_relu[0][0]'] \n",
" \n",
" conv2_block1_0_bn (BatchNormal (None, 56, 56, 256) 1024 ['conv2_block1_0_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv2_block1_3_bn (BatchNormal (None, 56, 56, 256) 1024 ['conv2_block1_3_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv2_block1_add (Add) (None, 56, 56, 256) 0 ['conv2_block1_0_bn[0][0]', \n",
" 'conv2_block1_3_bn[0][0]'] \n",
" \n",
" conv2_block1_out (Activation) (None, 56, 56, 256) 0 ['conv2_block1_add[0][0]'] \n",
" \n",
" conv2_block2_1_conv (Conv2D) (None, 56, 56, 64) 16448 ['conv2_block1_out[0][0]'] \n",
" \n",
" conv2_block2_1_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block2_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv2_block2_1_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block2_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv2_block2_2_conv (Conv2D) (None, 56, 56, 64) 36928 ['conv2_block2_1_relu[0][0]'] \n",
" \n",
" conv2_block2_2_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block2_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv2_block2_2_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block2_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv2_block2_3_conv (Conv2D) (None, 56, 56, 256) 16640 ['conv2_block2_2_relu[0][0]'] \n",
" \n",
" conv2_block2_3_bn (BatchNormal (None, 56, 56, 256) 1024 ['conv2_block2_3_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv2_block2_add (Add) (None, 56, 56, 256) 0 ['conv2_block1_out[0][0]', \n",
" 'conv2_block2_3_bn[0][0]'] \n",
" \n",
" conv2_block2_out (Activation) (None, 56, 56, 256) 0 ['conv2_block2_add[0][0]'] \n",
" \n",
" conv2_block3_1_conv (Conv2D) (None, 56, 56, 64) 16448 ['conv2_block2_out[0][0]'] \n",
" \n",
" conv2_block3_1_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block3_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv2_block3_1_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block3_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv2_block3_2_conv (Conv2D) (None, 56, 56, 64) 36928 ['conv2_block3_1_relu[0][0]'] \n",
" \n",
" conv2_block3_2_bn (BatchNormal (None, 56, 56, 64) 256 ['conv2_block3_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv2_block3_2_relu (Activatio (None, 56, 56, 64) 0 ['conv2_block3_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv2_block3_3_conv (Conv2D) (None, 56, 56, 256) 16640 ['conv2_block3_2_relu[0][0]'] \n",
" \n",
" conv2_block3_3_bn (BatchNormal (None, 56, 56, 256) 1024 ['conv2_block3_3_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv2_block3_add (Add) (None, 56, 56, 256) 0 ['conv2_block2_out[0][0]', \n",
" 'conv2_block3_3_bn[0][0]'] \n",
" \n",
" conv2_block3_out (Activation) (None, 56, 56, 256) 0 ['conv2_block3_add[0][0]'] \n",
" \n",
" conv3_block1_1_conv (Conv2D) (None, 28, 28, 128) 32896 ['conv2_block3_out[0][0]'] \n",
" \n",
" conv3_block1_1_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block1_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block1_1_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block1_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv3_block1_2_conv (Conv2D) (None, 28, 28, 128) 147584 ['conv3_block1_1_relu[0][0]'] \n",
" \n",
" conv3_block1_2_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block1_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block1_2_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block1_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv3_block1_0_conv (Conv2D) (None, 28, 28, 512) 131584 ['conv2_block3_out[0][0]'] \n",
" \n",
" conv3_block1_3_conv (Conv2D) (None, 28, 28, 512) 66048 ['conv3_block1_2_relu[0][0]'] \n",
" \n",
" conv3_block1_0_bn (BatchNormal (None, 28, 28, 512) 2048 ['conv3_block1_0_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block1_3_bn (BatchNormal (None, 28, 28, 512) 2048 ['conv3_block1_3_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block1_add (Add) (None, 28, 28, 512) 0 ['conv3_block1_0_bn[0][0]', \n",
" 'conv3_block1_3_bn[0][0]'] \n",
" \n",
" conv3_block1_out (Activation) (None, 28, 28, 512) 0 ['conv3_block1_add[0][0]'] \n",
" \n",
" conv3_block2_1_conv (Conv2D) (None, 28, 28, 128) 65664 ['conv3_block1_out[0][0]'] \n",
" \n",
" conv3_block2_1_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block2_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block2_1_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block2_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv3_block2_2_conv (Conv2D) (None, 28, 28, 128) 147584 ['conv3_block2_1_relu[0][0]'] \n",
" \n",
" conv3_block2_2_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block2_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block2_2_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block2_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv3_block2_3_conv (Conv2D) (None, 28, 28, 512) 66048 ['conv3_block2_2_relu[0][0]'] \n",
" \n",
" conv3_block2_3_bn (BatchNormal (None, 28, 28, 512) 2048 ['conv3_block2_3_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block2_add (Add) (None, 28, 28, 512) 0 ['conv3_block1_out[0][0]', \n",
" 'conv3_block2_3_bn[0][0]'] \n",
" \n",
" conv3_block2_out (Activation) (None, 28, 28, 512) 0 ['conv3_block2_add[0][0]'] \n",
" \n",
" conv3_block3_1_conv (Conv2D) (None, 28, 28, 128) 65664 ['conv3_block2_out[0][0]'] \n",
" \n",
" conv3_block3_1_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block3_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block3_1_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block3_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv3_block3_2_conv (Conv2D) (None, 28, 28, 128) 147584 ['conv3_block3_1_relu[0][0]'] \n",
" \n",
" conv3_block3_2_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block3_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block3_2_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block3_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv3_block3_3_conv (Conv2D) (None, 28, 28, 512) 66048 ['conv3_block3_2_relu[0][0]'] \n",
" \n",
" conv3_block3_3_bn (BatchNormal (None, 28, 28, 512) 2048 ['conv3_block3_3_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block3_add (Add) (None, 28, 28, 512) 0 ['conv3_block2_out[0][0]', \n",
" 'conv3_block3_3_bn[0][0]'] \n",
" \n",
" conv3_block3_out (Activation) (None, 28, 28, 512) 0 ['conv3_block3_add[0][0]'] \n",
" \n",
" conv3_block4_1_conv (Conv2D) (None, 28, 28, 128) 65664 ['conv3_block3_out[0][0]'] \n",
" \n",
" conv3_block4_1_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block4_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block4_1_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block4_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv3_block4_2_conv (Conv2D) (None, 28, 28, 128) 147584 ['conv3_block4_1_relu[0][0]'] \n",
" \n",
" conv3_block4_2_bn (BatchNormal (None, 28, 28, 128) 512 ['conv3_block4_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block4_2_relu (Activatio (None, 28, 28, 128) 0 ['conv3_block4_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv3_block4_3_conv (Conv2D) (None, 28, 28, 512) 66048 ['conv3_block4_2_relu[0][0]'] \n",
" \n",
" conv3_block4_3_bn (BatchNormal (None, 28, 28, 512) 2048 ['conv3_block4_3_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv3_block4_add (Add) (None, 28, 28, 512) 0 ['conv3_block3_out[0][0]', \n",
" 'conv3_block4_3_bn[0][0]'] \n",
" \n",
" conv3_block4_out (Activation) (None, 28, 28, 512) 0 ['conv3_block4_add[0][0]'] \n",
" \n",
" conv4_block1_1_conv (Conv2D) (None, 14, 14, 256) 131328 ['conv3_block4_out[0][0]'] \n",
" \n",
" conv4_block1_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block1_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block1_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block1_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block1_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block1_1_relu[0][0]'] \n",
" \n",
" conv4_block1_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block1_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block1_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block1_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block1_0_conv (Conv2D) (None, 14, 14, 1024 525312 ['conv3_block4_out[0][0]'] \n",
" ) \n",
" \n",
" conv4_block1_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block1_2_relu[0][0]'] \n",
" ) \n",
" \n",
" conv4_block1_0_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block1_0_conv[0][0]'] \n",
" ization) ) \n",
" \n",
" conv4_block1_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block1_3_conv[0][0]'] \n",
" ization) ) \n",
" \n",
" conv4_block1_add (Add) (None, 14, 14, 1024 0 ['conv4_block1_0_bn[0][0]', \n",
" ) 'conv4_block1_3_bn[0][0]'] \n",
" \n",
" conv4_block1_out (Activation) (None, 14, 14, 1024 0 ['conv4_block1_add[0][0]'] \n",
" ) \n",
" \n",
" conv4_block2_1_conv (Conv2D) (None, 14, 14, 256) 262400 ['conv4_block1_out[0][0]'] \n",
" \n",
" conv4_block2_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block2_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block2_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block2_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block2_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block2_1_relu[0][0]'] \n",
" \n",
" conv4_block2_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block2_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block2_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block2_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block2_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block2_2_relu[0][0]'] \n",
" ) \n",
" \n",
" conv4_block2_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block2_3_conv[0][0]'] \n",
" ization) ) \n",
" \n",
" conv4_block2_add (Add) (None, 14, 14, 1024 0 ['conv4_block1_out[0][0]', \n",
" ) 'conv4_block2_3_bn[0][0]'] \n",
" \n",
" conv4_block2_out (Activation) (None, 14, 14, 1024 0 ['conv4_block2_add[0][0]'] \n",
" ) \n",
" \n",
" conv4_block3_1_conv (Conv2D) (None, 14, 14, 256) 262400 ['conv4_block2_out[0][0]'] \n",
" \n",
" conv4_block3_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block3_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block3_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block3_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block3_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block3_1_relu[0][0]'] \n",
" \n",
" conv4_block3_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block3_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block3_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block3_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block3_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block3_2_relu[0][0]'] \n",
" ) \n",
" \n",
" conv4_block3_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block3_3_conv[0][0]'] \n",
" ization) ) \n",
" \n",
" conv4_block3_add (Add) (None, 14, 14, 1024 0 ['conv4_block2_out[0][0]', \n",
" ) 'conv4_block3_3_bn[0][0]'] \n",
" \n",
" conv4_block3_out (Activation) (None, 14, 14, 1024 0 ['conv4_block3_add[0][0]'] \n",
" ) \n",
" \n",
" conv4_block4_1_conv (Conv2D) (None, 14, 14, 256) 262400 ['conv4_block3_out[0][0]'] \n",
" \n",
" conv4_block4_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block4_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block4_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block4_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block4_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block4_1_relu[0][0]'] \n",
" \n",
" conv4_block4_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block4_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block4_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block4_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block4_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block4_2_relu[0][0]'] \n",
" ) \n",
" \n",
" conv4_block4_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block4_3_conv[0][0]'] \n",
" ization) ) \n",
" \n",
" conv4_block4_add (Add) (None, 14, 14, 1024 0 ['conv4_block3_out[0][0]', \n",
" ) 'conv4_block4_3_bn[0][0]'] \n",
" \n",
" conv4_block4_out (Activation) (None, 14, 14, 1024 0 ['conv4_block4_add[0][0]'] \n",
" ) \n",
" \n",
" conv4_block5_1_conv (Conv2D) (None, 14, 14, 256) 262400 ['conv4_block4_out[0][0]'] \n",
" \n",
" conv4_block5_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block5_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block5_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block5_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block5_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block5_1_relu[0][0]'] \n",
" \n",
" conv4_block5_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block5_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block5_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block5_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block5_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block5_2_relu[0][0]'] \n",
" ) \n",
" \n",
" conv4_block5_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block5_3_conv[0][0]'] \n",
" ization) ) \n",
" \n",
" conv4_block5_add (Add) (None, 14, 14, 1024 0 ['conv4_block4_out[0][0]', \n",
" ) 'conv4_block5_3_bn[0][0]'] \n",
" \n",
" conv4_block5_out (Activation) (None, 14, 14, 1024 0 ['conv4_block5_add[0][0]'] \n",
" ) \n",
" \n",
" conv4_block6_1_conv (Conv2D) (None, 14, 14, 256) 262400 ['conv4_block5_out[0][0]'] \n",
" \n",
" conv4_block6_1_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block6_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block6_1_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block6_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block6_2_conv (Conv2D) (None, 14, 14, 256) 590080 ['conv4_block6_1_relu[0][0]'] \n",
" \n",
" conv4_block6_2_bn (BatchNormal (None, 14, 14, 256) 1024 ['conv4_block6_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv4_block6_2_relu (Activatio (None, 14, 14, 256) 0 ['conv4_block6_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv4_block6_3_conv (Conv2D) (None, 14, 14, 1024 263168 ['conv4_block6_2_relu[0][0]'] \n",
" ) \n",
" \n",
" conv4_block6_3_bn (BatchNormal (None, 14, 14, 1024 4096 ['conv4_block6_3_conv[0][0]'] \n",
" ization) ) \n",
" \n",
" conv4_block6_add (Add) (None, 14, 14, 1024 0 ['conv4_block5_out[0][0]', \n",
" ) 'conv4_block6_3_bn[0][0]'] \n",
" \n",
" conv4_block6_out (Activation) (None, 14, 14, 1024 0 ['conv4_block6_add[0][0]'] \n",
" ) \n",
" \n",
" conv5_block1_1_conv (Conv2D) (None, 7, 7, 512) 524800 ['conv4_block6_out[0][0]'] \n",
" \n",
" conv5_block1_1_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block1_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv5_block1_1_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block1_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv5_block1_2_conv (Conv2D) (None, 7, 7, 512) 2359808 ['conv5_block1_1_relu[0][0]'] \n",
" \n",
" conv5_block1_2_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block1_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv5_block1_2_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block1_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv5_block1_0_conv (Conv2D) (None, 7, 7, 2048) 2099200 ['conv4_block6_out[0][0]'] \n",
" \n",
" conv5_block1_3_conv (Conv2D) (None, 7, 7, 2048) 1050624 ['conv5_block1_2_relu[0][0]'] \n",
" \n",
" conv5_block1_0_bn (BatchNormal (None, 7, 7, 2048) 8192 ['conv5_block1_0_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv5_block1_3_bn (BatchNormal (None, 7, 7, 2048) 8192 ['conv5_block1_3_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv5_block1_add (Add) (None, 7, 7, 2048) 0 ['conv5_block1_0_bn[0][0]', \n",
" 'conv5_block1_3_bn[0][0]'] \n",
" \n",
" conv5_block1_out (Activation) (None, 7, 7, 2048) 0 ['conv5_block1_add[0][0]'] \n",
" \n",
" conv5_block2_1_conv (Conv2D) (None, 7, 7, 512) 1049088 ['conv5_block1_out[0][0]'] \n",
" \n",
" conv5_block2_1_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block2_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv5_block2_1_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block2_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv5_block2_2_conv (Conv2D) (None, 7, 7, 512) 2359808 ['conv5_block2_1_relu[0][0]'] \n",
" \n",
" conv5_block2_2_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block2_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv5_block2_2_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block2_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv5_block2_3_conv (Conv2D) (None, 7, 7, 2048) 1050624 ['conv5_block2_2_relu[0][0]'] \n",
" \n",
" conv5_block2_3_bn (BatchNormal (None, 7, 7, 2048) 8192 ['conv5_block2_3_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv5_block2_add (Add) (None, 7, 7, 2048) 0 ['conv5_block1_out[0][0]', \n",
" 'conv5_block2_3_bn[0][0]'] \n",
" \n",
" conv5_block2_out (Activation) (None, 7, 7, 2048) 0 ['conv5_block2_add[0][0]'] \n",
" \n",
" conv5_block3_1_conv (Conv2D) (None, 7, 7, 512) 1049088 ['conv5_block2_out[0][0]'] \n",
" \n",
" conv5_block3_1_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block3_1_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv5_block3_1_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block3_1_bn[0][0]'] \n",
" n) \n",
" \n",
" conv5_block3_2_conv (Conv2D) (None, 7, 7, 512) 2359808 ['conv5_block3_1_relu[0][0]'] \n",
" \n",
" conv5_block3_2_bn (BatchNormal (None, 7, 7, 512) 2048 ['conv5_block3_2_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv5_block3_2_relu (Activatio (None, 7, 7, 512) 0 ['conv5_block3_2_bn[0][0]'] \n",
" n) \n",
" \n",
" conv5_block3_3_conv (Conv2D) (None, 7, 7, 2048) 1050624 ['conv5_block3_2_relu[0][0]'] \n",
" \n",
" conv5_block3_3_bn (BatchNormal (None, 7, 7, 2048) 8192 ['conv5_block3_3_conv[0][0]'] \n",
" ization) \n",
" \n",
" conv5_block3_add (Add) (None, 7, 7, 2048) 0 ['conv5_block2_out[0][0]', \n",
" 'conv5_block3_3_bn[0][0]'] \n",
" \n",
" conv5_block3_out (Activation) (None, 7, 7, 2048) 0 ['conv5_block3_add[0][0]'] \n",
" \n",
" flatten_2 (Flatten) (None, 100352) 0 ['conv5_block3_out[0][0]'] \n",
" \n",
" dense_6 (Dense) (None, 5) 501765 ['flatten_2[0][0]'] \n",
" \n",
"==================================================================================================\n",
"Total params: 24,089,477\n",
"Trainable params: 501,765\n",
"Non-trainable params: 23,587,712\n",
"__________________________________________________________________________________________________\n"
]
}
],
"source": [
"from keras.layers import Input, Lambda, Dense, Flatten\n",
"from keras.models import Model\n",
"from keras.applications import ResNet50\n",
"from keras.preprocessing import image\n",
"from keras.preprocessing.image import ImageDataGenerator\n",
"from keras.models import Sequential\n",
"import numpy as np\n",
"from glob import glob\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# re-size all the images to this\n",
"IMAGE_SIZE = [224, 224]\n",
"\n",
"# add preprocessing layer to the front of resnet\n",
"resnet = ResNet50(input_shape=IMAGE_SIZE + [3], weights='imagenet', include_top=False)\n",
"\n",
"# don't train existing weights\n",
"for layer in resnet.layers:\n",
" layer.trainable = False\n",
" \n",
" # useful for getting number of classes\n",
"classes = 5\n",
" \n",
"\n",
"# our layers - you can add more if you want\n",
"x = Flatten()(resnet.output)\n",
"# x = Dense(1000, activation='relu')(x)\n",
"prediction = Dense(5, activation='softmax')(x)\n",
"\n",
"# create a model object\n",
"model = Model(inputs=resnet.input, outputs=prediction)\n",
"\n",
"# view the structure of the model\n",
"model.summary()\n",
"\n",
"# tell the model what cost and optimization method to use\n",
"model.compile(\n",
" loss='sparse_categorical_crossentropy',\n",
" optimizer='adam',\n",
" metrics=['accuracy']\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'prepare_data' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m train_ds_r, test_ds_r, val_ds_r \u001b[39m=\u001b[39m prepare_data(\u001b[39m'\u001b[39m\u001b[39m./plantvillage/color\u001b[39m\u001b[39m'\u001b[39m, img_size\u001b[39m=\u001b[39mIMAGE_SIZE, test_size\u001b[39m=\u001b[39m\u001b[39m0.2\u001b[39m, val_size\u001b[39m=\u001b[39m\u001b[39m0.2\u001b[39m)\n",
"\u001b[0;31mNameError\u001b[0m: name 'prepare_data' is not defined"
]
}
],
"source": [
"train_ds_r, test_ds_r, val_ds_r = prepare_data('./plantvillage/color', img_size=IMAGE_SIZE, test_size=0.2, val_size=0.2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"r = model.fit_generator(\n",
" train_ds_r,\n",
" validation_data=val_ds_r,\n",
" epochs=1,\n",
" steps_per_epoch=len(train_ds_r),\n",
" validation_steps=len(val_ds_r)\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.plot(r.history[\"accuracy\"])\n",
"plt.plot(r.history['val_accuracy'])\n",
"plt.plot(r.history['loss'])\n",
"plt.plot(r.history['val_loss'])\n",
"plt.title(\"Model accuracy\")\n",
"plt.ylabel(\"Value\")\n",
"plt.xlabel(\"Epoch\")\n",
"plt.legend([\"Accuracy\",\"Validation Accuracy\",\"Loss\",\"Validation Loss\"])\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model.save('resnet_2.h5')\n",
"model.evaluate(test_ds_r)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.9.6"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}