Symulowanie-wizualne/sw-lab9-10_4.ipynb
2023-01-11 16:25:40 +01:00

995 lines
93 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "dd9a88f0",
"metadata": {},
"source": [
"#### Aleksandra Jonas, Aleksandra Gronowska, Iwona Christop"
]
},
{
"cell_type": "markdown",
"id": "acda0087",
"metadata": {},
"source": [
"### Generowanie dodatkowych zdjęć w oparciu o filtry krawędziowe"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "f790226b",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import cv2 as cv\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import json\n",
"from tensorflow import keras\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "44319623",
"metadata": {},
"outputs": [],
"source": [
"def alex(filter_name, train_ds, test_ds, validation_ds):\n",
" from keras.callbacks import ModelCheckpoint, EarlyStopping\n",
" import matplotlib.pyplot as plt\n",
" import tensorflow as tf\n",
"\n",
" alexnet = 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.BatchNormalization(),\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.BatchNormalization(),\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.BatchNormalization(),\n",
" keras.layers.Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), activation='relu', padding=\"same\"),\n",
" keras.layers.BatchNormalization(),\n",
" keras.layers.Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), activation='relu', padding=\"same\"),\n",
" keras.layers.BatchNormalization(),\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.Dropout(.5),\n",
" keras.layers.Dense(4096, activation='relu'),\n",
" keras.layers.Dropout(.5),\n",
" keras.layers.Dense(10, activation='softmax')\n",
" ])\n",
"\n",
" alexnet.compile(loss='sparse_categorical_crossentropy', optimizer=tf.optimizers.SGD(lr=.001), metrics=['accuracy'])\n",
" alexnet.summary()\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 = alexnet.fit_generator(\n",
" steps_per_epoch=len(train_ds), \n",
" generator=train_ds, \n",
" validation_data= validation_ds, \n",
" validation_steps=len(validation_ds), \n",
" epochs=25, \n",
" callbacks=[checkpoint,early])\n",
"\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(f\"Model accuracy - {filter_name}\")\n",
" plt.ylabel(\"Value\")\n",
" plt.xlabel(\"Epoch\")\n",
" plt.legend([\"Accuracy\",\"Validation Accuracy\",\"Loss\",\"Validation Loss\"])\n",
" plt.show()\n",
"\n",
" alexnet.evaluate(test_ds)\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "4e3ebfd0",
"metadata": {},
"outputs": [],
"source": [
"def fix_float_img(img):\n",
" img_normed = 255 * (img - img.min()) / (img.max() - img.min())\n",
" img_normed = np.array(img_normed, np.int)\n",
" return img_normed"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "ffeda62d",
"metadata": {},
"outputs": [],
"source": [
"# directory = r\"train_test_sw/train_sw_kontrast\"\n",
"# subdirs = [r\"/Tomato\", r\"/Lemon\", r\"/Beech\", r\"/Mean\", r\"/Gardenia\"]\n",
"\n",
"# json_entries = []\n",
"\n",
"# for sub in subdirs:\n",
"# path = directory + sub\n",
" \n",
"# for filename in os.listdir(path):\n",
"# f = os.path.join(path, filename)\n",
" \n",
"# if os.path.isfile(f):\n",
"# img = cv.imread(f)\n",
"\n",
"\n",
"# lab= cv.cvtColor(img, cv.COLOR_BGR2LAB)\n",
"# l_channel, a, b = cv.split(lab)\n",
"# # Applying CLAHE to L-channel\n",
"# # feel free to try different values for the limit and grid size:\n",
"# clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))\n",
"# cl = clahe.apply(l_channel)\n",
"# # merge the CLAHE enhanced L-channel with the a and b channel\n",
"# limg = cv.merge((cl,a,b))\n",
"# # Converting image from LAB Color model to BGR color spcae\n",
"# enhanced_img = cv.cvtColor(limg, cv.COLOR_LAB2BGR)\n",
"# filename_edge = f[:-4] + '_kontrast.png'\n",
"# #final_edge = fix_float_img(adjusted)\n",
"# cv.imwrite(filename_edge, enhanced_img)\n",
" \n",
" \n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "72c68d57",
"metadata": {},
"outputs": [],
"source": [
"# directory = r\"train_test_sw/train_sw_saturacja\"\n",
"# subdirs = [r\"/Tomato\", r\"/Lemon\", r\"/Beech\", r\"/Mean\", r\"/Gardenia\"]\n",
"\n",
"# json_entries = []\n",
"\n",
"# for sub in subdirs:\n",
"# path = directory + sub\n",
" \n",
"# for filename in os.listdir(path):\n",
"# f = os.path.join(path, filename)\n",
" \n",
"# if os.path.isfile(f):\n",
"# img = cv.imread(f)\n",
"# hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)\n",
"# greenMask = cv.inRange(hsv, (26, 10, 30), (97, 100, 255))\n",
"# hsv[:,:,1] = greenMask\n",
"# back = cv.cvtColor(hsv, cv.COLOR_HSV2RGB)\n",
"# filename_edge = f[:-4] + '_saturacja.png'\n",
"# #final_edge = fix_float_img(adjusted)\n",
"# cv.imwrite(filename_edge, back)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "4859d197",
"metadata": {},
"outputs": [],
"source": [
"# directory = r\"train_test_sw/train_sw_jezu\"\n",
"# subdirs = [r\"/Tomato\", r\"/Lemon\", r\"/Beech\", r\"/Mean\", r\"/Gardenia\"]\n",
"\n",
"# json_entries = []\n",
"\n",
"# for sub in subdirs:\n",
"# path = directory + sub\n",
" \n",
"# for filename in os.listdir(path):\n",
"# f = os.path.join(path, filename)\n",
" \n",
"# if os.path.isfile(f):\n",
"# img = cv.imread(f)\n",
"\n",
"# img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)\n",
"# ddepth = cv.CV_16S\n",
"# kernel_size = 3\n",
"# laplacian_operator = cv.Laplacian(img_gray, ddepth, ksize=kernel_size)\n",
"# filename_edge = f[:-4] + '_laplacian.png'\n",
"# #final_edge = fix_float_img(adjusted)\n",
"# cv.imwrite(filename_edge, laplacian_operator)\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "aedb7b9f",
"metadata": {},
"outputs": [],
"source": [
"# directory = r\"train_test_sw/train_sw\"\n",
"# subdirs = [r\"/Tomato\", r\"/Lemon\", r\"/Beech\", r\"/Mean\", r\"/Gardenia\"]\n",
"\n",
"# json_entries = []\n",
"\n",
"# for sub in subdirs:\n",
"# path = directory + sub\n",
" \n",
"# for filename in os.listdir(path):\n",
"# f = os.path.join(path, filename)\n",
" \n",
"# if os.path.isfile(f):\n",
"# img = cv.imread(f)\n",
"\n",
"# lab_image = cv.cvtColor(img, cv.COLOR_BGR2LAB)\n",
"# filename_edge = f[:-4] + '_lab.png'\n",
"# #final_edge = fix_float_img(adjusted)\n",
"# cv.imwrite(filename_edge, lab_image)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "dc650af1",
"metadata": {},
"outputs": [],
"source": [
"# directory = r\"train_test_sw/train_sw_emboss\"\n",
"# subdirs = [r\"/Tomato\", r\"/Lemon\", r\"/Beech\", r\"/Mean\", r\"/Gardenia\"]\n",
"\n",
"# json_entries = []\n",
"\n",
"# for sub in subdirs:\n",
"# path = directory + sub\n",
" \n",
"# for filename in os.listdir(path):\n",
"# f = os.path.join(path, filename)\n",
" \n",
"# if os.path.isfile(f):\n",
"# img = cv.imread(f)\n",
"\n",
"# height, width = img.shape[:2]\n",
"# y = np.ones((height, width), np.uint8) * 128\n",
"# output = np.zeros((height, width), np.uint8)\n",
"# # generating the kernels\n",
"# kernel1 = np.array([[0, -1, -1], # kernel for embossing bottom left side\n",
"# [1, 0, -1],\n",
"# [1, 1, 0]])\n",
"# kernel2 = np.array([[-1, -1, 0], # kernel for embossing bottom right side\n",
"# [-1, 0, 1],\n",
"# [0, 1, 1]])\n",
"# # you can generate kernels for embossing top as well\n",
"# gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)\n",
"# output1 = cv.add(cv.filter2D(gray, -1, kernel1), y) # emboss on bottom left side\n",
"# output2 = cv.add(cv.filter2D(gray, -1, kernel2), y) # emboss on bottom right side\n",
"# for i in range(height):\n",
"# for j in range(width):\n",
"# output[i, j] = max(output1[i, j], output2[i, j]) # combining both embosses to produce stronger emboss\n",
"\n",
"# filename_edge = f[:-4] + '_emboss.png'\n",
"# #final_edge = fix_float_img(adjusted)\n",
"# cv.imwrite(filename_edge, output)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "6a3f8c81",
"metadata": {},
"outputs": [],
"source": [
"# directory = r\"train_test_sw/train_sw_cartoon\"\n",
"# subdirs = [r\"/Tomato\", r\"/Lemon\", r\"/Beech\", r\"/Mean\", r\"/Gardenia\"]\n",
"\n",
"# json_entries = []\n",
"\n",
"# for sub in subdirs:\n",
"# path = directory + sub\n",
" \n",
"# for filename in os.listdir(path):\n",
"# f = os.path.join(path, filename)\n",
" \n",
"# if os.path.isfile(f):\n",
"# img = cv.imread(f)\n",
"\n",
"# edges1 = cv.bitwise_not(cv.Canny(img, 100, 200)) # for thin edges and inverting the mask obatined\n",
"# gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)\n",
"# gray = cv.medianBlur(gray, 5) # applying median blur with kernel size of 5\n",
"# edges2 = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 7, 7) # thick edges\n",
"# dst = cv.edgePreservingFilter(img, flags=2, sigma_s=20, sigma_r=0.1) # you can also use bilateral filter but that is slow\n",
"# # flag = 1 for RECURS_FILTER (Recursive Filtering) and 2 for NORMCONV_FILTER (Normalized Convolution). NORMCONV_FILTER produces sharpening of the edges but is slower.\n",
"# # sigma_s controls the size of the neighborhood. Range 1 - 200\n",
"# # sigma_r controls the how dissimilar colors within the neighborhood will be averaged. A larger sigma_r results in large regions of constant color. Range 0 - 1\n",
"# cartoon = cv.bitwise_and(dst, dst, mask=edges1) # adding thin edges to smoothened imag\n",
"\n",
"\n",
"# filename_edge = f[:-4] + '_cartoon.png'\n",
"# #final_edge = fix_float_img(adjusted)\n",
"# cv.imwrite(filename_edge, cartoon)\n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "0c0cd453",
"metadata": {},
"source": [
"## Data"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "c4f0f653",
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"import subprocess\n",
"import pkg_resources\n",
"import numpy as np\n",
"peachy = []\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_train_data(input_dir, newSize=(227,227)):\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",
" train_img = []\n",
" categories_count=[]\n",
" labels=[]\n",
" for i, direc in enumerate(folders):\n",
" count = 0\n",
" \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",
" if img.shape[-1] == 256:\n",
" img = np.repeat(img[..., np.newaxis], 3, axis=2)\n",
" elif img.shape[-1] == 4:\n",
" img = img[:, :, :3]\n",
" img = cv.resize(img, newSize, interpolation=cv.INTER_AREA)# zwraca ndarray\n",
" img = img / 255#normalizacja\n",
" train_img.append(img)\n",
" categories_count.append(count)\n",
" X={}\n",
" X[\"values\"] = np.array(train_img)\n",
" X[\"categories_name\"] = categories_name\n",
" X[\"categories_count\"] = categories_count\n",
" X[\"labels\"]=labels\n",
" return X\n",
"\n",
"def load_test_data(input_dir, newSize=(227,227)):\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_path = Path(input_dir)\n",
"\n",
" labels_path = image_path.parents[0] / 'test_labels.json'\n",
"\n",
" jsonString = labels_path.read_text()\n",
" objects = json.loads(jsonString)\n",
"\n",
" categories_name = []\n",
" categories_count=[]\n",
" count = 0\n",
" c = objects[0]['value']\n",
" for e in objects:\n",
" if e['value'] != c:\n",
" categories_count.append(count)\n",
" c = e['value']\n",
" count = 1\n",
" else:\n",
" count += 1\n",
" if not e['value'] in categories_name:\n",
" categories_name.append(e['value'])\n",
"\n",
" categories_count.append(count)\n",
" \n",
" test_img = []\n",
"\n",
" labels=[]\n",
" for e in objects:\n",
" p = image_path / e['filename']\n",
" img = imread(p)#zwraca ndarry postaci xSize x ySize x colorDepth\n",
" img = cv.resize(img, newSize, interpolation=cv.INTER_AREA)# zwraca ndarray\n",
" img = img / 255#normalizacja\n",
" test_img.append(img)\n",
" labels.append(e['value'])\n",
"\n",
" X={}\n",
" X[\"values\"] = np.array(test_img)\n",
" X[\"categories_name\"] = categories_name\n",
" X[\"categories_count\"] = categories_count\n",
" X[\"labels\"]=labels\n",
" return X\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "b0dceacc",
"metadata": {},
"outputs": [],
"source": [
"def data_prep_alex(filter_name):\n",
" from sklearn.model_selection import train_test_split\n",
" from sklearn.preprocessing import LabelEncoder\n",
" import tensorflow as tf\n",
"\n",
" data_train = load_train_data(f\"./train_test_sw/train_sw_{filter_name}\")\n",
" values_train = data_train['values']\n",
" labels_train = data_train['labels']\n",
" data_test = load_test_data(\"./train_test_sw/test_sw\")\n",
" X_test = data_test['values']\n",
" y_test = data_test['labels']\n",
"\n",
" X_train, X_validate, y_train, y_validate = train_test_split(values_train, labels_train, test_size=0.2, 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",
" train_ds = (train_ds\n",
" .shuffle(buffer_size=train_ds_size)\n",
" .batch(batch_size=32, drop_remainder=True))\n",
" test_ds = (test_ds\n",
" .shuffle(buffer_size=train_ds_size)\n",
" .batch(batch_size=32, drop_remainder=True))\n",
" validation_ds = (validation_ds\n",
" .shuffle(buffer_size=train_ds_size)\n",
" .batch(batch_size=32, drop_remainder=True))\n",
"\n",
" return train_ds, test_ds, validation_ds\n",
" "
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "b1aa7ac3",
"metadata": {},
"source": [
"### Emboss"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "adf27f44",
"metadata": {},
"outputs": [],
"source": [
"# train_ds\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5333a4e6",
"metadata": {},
"outputs": [],
"source": [
"\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "b4ff7bba",
"metadata": {},
"outputs": [],
"source": [
"# 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",
"# print(\"Training data size:\", train_ds_size)\n",
"# print(\"Test data size:\", test_ds_size)\n",
"# print(\"Validation data size:\", validation_ds_size)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "5dd609ea",
"metadata": {},
"outputs": [],
"source": [
"# alexnet.compile(loss='sparse_categorical_crossentropy', optimizer=tf.optimizers.SGD(lr=.001), metrics=['accuracy'])\n",
"# alexnet.summary()"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "220824d7",
"metadata": {},
"outputs": [],
"source": [
"\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 = alexnet.fit_generator(\n",
"# steps_per_epoch=len(train_ds), \n",
"# generator=train_ds, \n",
"# validation_data= validation_ds, \n",
"# validation_steps=len(validation_ds), \n",
"# epochs=25, \n",
"# callbacks=[checkpoint,early])"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "f87a88e9",
"metadata": {},
"outputs": [],
"source": [
"# model_flat_drop.fit(train_ds,\n",
"# epochs=100,\n",
"# validation_data=validation_ds,\n",
"# validation_freq=1,\n",
"# callbacks=[tensorboard_cb])"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "f7a72530",
"metadata": {},
"source": [
"### Saturacja"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "6148789c",
"metadata": {},
"outputs": [],
"source": [
"# from sklearn.preprocessing import LabelEncoder\n",
"\n",
"# # Data load\n",
"# data_train = load_train_data(\"train_test_sw_kontrast/train_sw\", newSize=(16,16))\n",
"# X_train = data_train['values']\n",
"# y_train = data_train['labels']\n",
"\n",
"# data_test = load_test_data(\"train_test_sw_kontrast/test_sw\", newSize=(16,16))\n",
"# X_test = data_test['values']\n",
"# y_test = data_test['labels']\n",
"\n",
"# class_le = LabelEncoder()\n",
"# y_train_enc = class_le.fit_transform(y_train)\n",
"# y_test_enc = class_le.fit_transform(y_test)\n",
"\n",
"# X_train = X_train.flatten().reshape(X_train.shape[0], int(np.prod(X_train.shape) / X_train.shape[0]))\n",
"# X_test = X_test.flatten().reshape(X_test.shape[0], int(np.prod(X_test.shape) / X_test.shape[0]))"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "47d3b363",
"metadata": {},
"source": [
"# ALEXNET"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "108a46e4",
"metadata": {},
"outputs": [],
"source": [
"filters = ['laplasian', 'kontrast', 'cartoon', 'saturacja', 'emboss']"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "12a16bca",
"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",
" batch_normalization (BatchN (None, 55, 55, 96) 384 \n",
" ormalization) \n",
" \n",
" max_pooling2d (MaxPooling2D (None, 27, 27, 96) 0 \n",
" ) \n",
" \n",
" conv2d_1 (Conv2D) (None, 27, 27, 256) 614656 \n",
" \n",
" batch_normalization_1 (Batc (None, 27, 27, 256) 1024 \n",
" hNormalization) \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",
" batch_normalization_2 (Batc (None, 13, 13, 384) 1536 \n",
" hNormalization) \n",
" \n",
" conv2d_3 (Conv2D) (None, 13, 13, 384) 1327488 \n",
" \n",
" batch_normalization_3 (Batc (None, 13, 13, 384) 1536 \n",
" hNormalization) \n",
" \n",
" conv2d_4 (Conv2D) (None, 13, 13, 256) 884992 \n",
" \n",
" batch_normalization_4 (Batc (None, 13, 13, 256) 1024 \n",
" hNormalization) \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",
" dropout (Dropout) (None, 4096) 0 \n",
" \n",
" dense_1 (Dense) (None, 4096) 16781312 \n",
" \n",
" dropout_1 (Dropout) (None, 4096) 0 \n",
" \n",
" dense_2 (Dense) (None, 10) 40970 \n",
" \n",
"=================================================================\n",
"Total params: 58,327,818\n",
"Trainable params: 58,325,066\n",
"Non-trainable params: 2,752\n",
"_________________________________________________________________\n",
"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_35367/157534861.py:34: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.\n",
" alex = alexnet.fit_generator(\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/25\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2023-01-11 15:57:37.093304: W tensorflow/tsl/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"51/51 [==============================] - ETA: 0s - loss: 3.5934 - accuracy: 0.3903\n",
"Epoch 1: val_accuracy improved from -inf to 0.24740, saving model to alex_2.h5\n",
"51/51 [==============================] - 46s 888ms/step - loss: 3.5934 - accuracy: 0.3903 - val_loss: 1.9219 - val_accuracy: 0.2474\n",
"Epoch 2/25\n",
"51/51 [==============================] - ETA: 0s - loss: 1.2680 - accuracy: 0.5699\n",
"Epoch 2: val_accuracy did not improve from 0.24740\n",
"51/51 [==============================] - 45s 890ms/step - loss: 1.2680 - accuracy: 0.5699 - val_loss: 2.9384 - val_accuracy: 0.2370\n",
"Epoch 3/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.8801 - accuracy: 0.6930\n",
"Epoch 3: val_accuracy did not improve from 0.24740\n",
"51/51 [==============================] - 51s 1s/step - loss: 0.8801 - accuracy: 0.6930 - val_loss: 4.2987 - val_accuracy: 0.2318\n",
"Epoch 4/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.8070 - accuracy: 0.7181\n",
"Epoch 4: val_accuracy improved from 0.24740 to 0.27604, saving model to alex_2.h5\n",
"51/51 [==============================] - 47s 925ms/step - loss: 0.8070 - accuracy: 0.7181 - val_loss: 5.2133 - val_accuracy: 0.2760\n",
"Epoch 5/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.6284 - accuracy: 0.7714\n",
"Epoch 5: val_accuracy improved from 0.27604 to 0.28906, saving model to alex_2.h5\n",
"51/51 [==============================] - 52s 1s/step - loss: 0.6284 - accuracy: 0.7714 - val_loss: 5.1982 - val_accuracy: 0.2891\n",
"Epoch 6/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.5519 - accuracy: 0.7996\n",
"Epoch 6: val_accuracy improved from 0.28906 to 0.34635, saving model to alex_2.h5\n",
"51/51 [==============================] - 47s 925ms/step - loss: 0.5519 - accuracy: 0.7996 - val_loss: 5.3340 - val_accuracy: 0.3464\n",
"Epoch 7/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.5127 - accuracy: 0.8205\n",
"Epoch 7: val_accuracy did not improve from 0.34635\n",
"51/51 [==============================] - 48s 934ms/step - loss: 0.5127 - accuracy: 0.8205 - val_loss: 4.6689 - val_accuracy: 0.3307\n",
"Epoch 8/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.4584 - accuracy: 0.8364\n",
"Epoch 8: val_accuracy improved from 0.34635 to 0.34896, saving model to alex_2.h5\n",
"51/51 [==============================] - 48s 939ms/step - loss: 0.4584 - accuracy: 0.8364 - val_loss: 4.0851 - val_accuracy: 0.3490\n",
"Epoch 9/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.3952 - accuracy: 0.8585\n",
"Epoch 9: val_accuracy improved from 0.34896 to 0.39844, saving model to alex_2.h5\n",
"51/51 [==============================] - 49s 955ms/step - loss: 0.3952 - accuracy: 0.8585 - val_loss: 2.6378 - val_accuracy: 0.3984\n",
"Epoch 10/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.3141 - accuracy: 0.8811\n",
"Epoch 10: val_accuracy improved from 0.39844 to 0.43750, saving model to alex_2.h5\n",
"51/51 [==============================] - 48s 940ms/step - loss: 0.3141 - accuracy: 0.8811 - val_loss: 2.3606 - val_accuracy: 0.4375\n",
"Epoch 11/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.2889 - accuracy: 0.8922\n",
"Epoch 11: val_accuracy improved from 0.43750 to 0.65625, saving model to alex_2.h5\n",
"51/51 [==============================] - 48s 949ms/step - loss: 0.2889 - accuracy: 0.8922 - val_loss: 1.1387 - val_accuracy: 0.6562\n",
"Epoch 12/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.2696 - accuracy: 0.8977\n",
"Epoch 12: val_accuracy did not improve from 0.65625\n",
"51/51 [==============================] - 48s 933ms/step - loss: 0.2696 - accuracy: 0.8977 - val_loss: 1.1794 - val_accuracy: 0.6328\n",
"Epoch 13/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.2124 - accuracy: 0.9271\n",
"Epoch 13: val_accuracy improved from 0.65625 to 0.83073, saving model to alex_2.h5\n",
"51/51 [==============================] - 50s 973ms/step - loss: 0.2124 - accuracy: 0.9271 - val_loss: 0.4526 - val_accuracy: 0.8307\n",
"Epoch 14/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.1891 - accuracy: 0.9228\n",
"Epoch 14: val_accuracy did not improve from 0.83073\n",
"51/51 [==============================] - 50s 981ms/step - loss: 0.1891 - accuracy: 0.9228 - val_loss: 0.5985 - val_accuracy: 0.7943\n",
"Epoch 15/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.1603 - accuracy: 0.9381\n",
"Epoch 15: val_accuracy improved from 0.83073 to 0.83333, saving model to alex_2.h5\n",
"51/51 [==============================] - 50s 983ms/step - loss: 0.1603 - accuracy: 0.9381 - val_loss: 0.4779 - val_accuracy: 0.8333\n",
"Epoch 16/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.1852 - accuracy: 0.9314\n",
"Epoch 16: val_accuracy improved from 0.83333 to 0.86979, saving model to alex_2.h5\n",
"51/51 [==============================] - 49s 962ms/step - loss: 0.1852 - accuracy: 0.9314 - val_loss: 0.3588 - val_accuracy: 0.8698\n",
"Epoch 17/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.1484 - accuracy: 0.9504\n",
"Epoch 17: val_accuracy improved from 0.86979 to 0.87500, saving model to alex_2.h5\n",
"51/51 [==============================] - 49s 963ms/step - loss: 0.1484 - accuracy: 0.9504 - val_loss: 0.3464 - val_accuracy: 0.8750\n",
"Epoch 18/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.1367 - accuracy: 0.9534\n",
"Epoch 18: val_accuracy did not improve from 0.87500\n",
"51/51 [==============================] - 49s 962ms/step - loss: 0.1367 - accuracy: 0.9534 - val_loss: 0.4452 - val_accuracy: 0.8464\n",
"Epoch 19/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.1089 - accuracy: 0.9638\n",
"Epoch 19: val_accuracy improved from 0.87500 to 0.89062, saving model to alex_2.h5\n",
"51/51 [==============================] - 49s 953ms/step - loss: 0.1089 - accuracy: 0.9638 - val_loss: 0.3376 - val_accuracy: 0.8906\n",
"Epoch 20/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.1115 - accuracy: 0.9596\n",
"Epoch 20: val_accuracy did not improve from 0.89062\n",
"51/51 [==============================] - 49s 954ms/step - loss: 0.1115 - accuracy: 0.9596 - val_loss: 0.3655 - val_accuracy: 0.8854\n",
"Epoch 21/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.0793 - accuracy: 0.9681\n",
"Epoch 21: val_accuracy did not improve from 0.89062\n",
"51/51 [==============================] - 48s 949ms/step - loss: 0.0793 - accuracy: 0.9681 - val_loss: 0.4086 - val_accuracy: 0.8776\n",
"Epoch 22/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.0725 - accuracy: 0.9767\n",
"Epoch 22: val_accuracy improved from 0.89062 to 0.90365, saving model to alex_2.h5\n",
"51/51 [==============================] - 49s 958ms/step - loss: 0.0725 - accuracy: 0.9767 - val_loss: 0.2975 - val_accuracy: 0.9036\n",
"Epoch 23/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.0727 - accuracy: 0.9755\n",
"Epoch 23: val_accuracy did not improve from 0.90365\n",
"51/51 [==============================] - 49s 957ms/step - loss: 0.0727 - accuracy: 0.9755 - val_loss: 0.4552 - val_accuracy: 0.8698\n",
"Epoch 24/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.0659 - accuracy: 0.9737\n",
"Epoch 24: val_accuracy did not improve from 0.90365\n",
"51/51 [==============================] - 49s 952ms/step - loss: 0.0659 - accuracy: 0.9737 - val_loss: 0.3930 - val_accuracy: 0.8854\n",
"Epoch 25/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.0693 - accuracy: 0.9816\n",
"Epoch 25: val_accuracy did not improve from 0.90365\n",
"51/51 [==============================] - 50s 980ms/step - loss: 0.0693 - accuracy: 0.9816 - val_loss: 0.6543 - val_accuracy: 0.8177\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAi8AAAHHCAYAAAB3K7g2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAACS3ElEQVR4nOzdd3wUdf7H8dds3/ROEgi9dwVFQIqCAioKKk0REFBPseudP89+51nOLrbTQxAbioodERGQA6RKL9JLCJCebLJ95/fHZpeEBEggyWySz/Px2Mfuzs7OfHaJ5p1vG0VVVRUhhBBCiDpCp3UBQgghhBBVIeFFCCGEEHWKhBchhBBC1CkSXoQQQghRp0h4EUIIIUSdIuFFCCGEEHWKhBchhBBC1CkSXoQQQghRp0h4EUIIIUSdIuFFiFqgKApPPvlkld+3f/9+FEVh1qxZ1V6TOHtn++9ZFQMHDmTgwIE1cuwlS5agKApLliypkeMLUdMkvIgGY9asWSiKgqIo/O9//yv3uqqqpKWloSgKV111lQYVCiGEqAwJL6LBsVgsfPLJJ+W2L126lMOHD2M2mzWoSoja079/f+x2O/3799e6FCHOioQX0eBcccUVzJ07F4/HU2b7J598Qo8ePUhOTtaosoajqKhI6xIaNJ1Oh8ViQaeTXwGibpKfXNHgjBs3juzsbBYuXBjc5nK5+OKLL7jhhhsqfE9RUREPPPAAaWlpmM1m2rVrx4svvsjJF2V3Op3cd999JCYmEhkZydVXX83hw4crPGZ6ejqTJ0+mUaNGmM1mOnXqxPvvv39WnyknJ4cHH3yQLl26EBERQVRUFMOGDWPjxo3l9nU4HDz55JO0bdsWi8VCSkoK1157LXv27Anu4/P5eO211+jSpQsWi4XExESGDh3K2rVrgdOPxTl5PMiTTz6Joihs27aNG264gdjYWC6++GIANm3axKRJk2jZsiUWi4Xk5GQmT55MdnZ2hd/XlClTSE1NxWw206JFC26//XZcLhd79+5FURReeeWVcu9bsWIFiqLw6aefVvVrrbQDBw5wxx130K5dO6xWK/Hx8YwaNYr9+/eX2S/Qdfnbb79x2223ER8fT1RUFBMmTCA3N/e053C5XDz++OP06NGD6OhowsPD6devH4sXLy6375w5c+jRoweRkZFERUXRpUsXXnvtteDrFY15WbZsGaNGjaJp06aYzWbS0tK47777sNvtZY49adIkIiIiSE9PZ8SIEURERJCYmMiDDz6I1+ut+pcnxFkwaF2AELWtefPm9O7dm08//ZRhw4YBMH/+fPLz8xk7diyvv/56mf1VVeXqq69m8eLFTJkyhe7du7NgwQL++te/kp6eXuYX5tSpU/noo4+44YYb6NOnD7/++itXXnlluRqOHTvGRRddhKIo3HnnnSQmJjJ//nymTJlCQUEB9957b5U+0969e/n6668ZNWoULVq04NixY/znP/9hwIABbNu2jdTUVAC8Xi9XXXUVixYtYuzYsdxzzz0UFhaycOFCtmzZQqtWrQCYMmUKs2bNYtiwYUydOhWPx8OyZcv4/fff6dmzZ5VqCxg1ahRt2rThmWeeCYa+hQsXsnfvXm6++WaSk5PZunUr7777Llu3buX3339HURQAjhw5woUXXkheXh633nor7du3Jz09nS+++ILi4mJatmxJ3759+fjjj7nvvvvKnPfjjz8mMjKSa6655qzqrow1a9awYsUKxo4dS5MmTdi/fz9vv/02AwcOZNu2bYSFhZXZ/8477yQmJoYnn3ySnTt38vbbb3PgwIFgqKhIQUEB//3vfxk3bhy33HILhYWFzJgxgyFDhrB69Wq6d+8O+L/TcePGMWjQIJ5//nkAtm/fzvLly7nnnntO+Rnmzp1LcXExt99+O/Hx8axevZrp06dz+PBh5s6dW2Zfr9fLkCFD6NWrFy+++CK//PILL730Eq1ateL2228/h29SiEpShWggZs6cqQLqmjVr1DfeeEONjIxUi4uLVVVV1VGjRqmXXHKJqqqq2qxZM/XKK68Mvu/rr79WAfXpp58uc7zrr79eVRRF3b17t6qqqrphwwYVUO+4444y+91www0qoD7xxBPBbVOmTFFTUlLUrKysMvuOHTtWjY6ODta1b98+FVBnzpx52s/mcDhUr9dbZtu+fftUs9ms/uMf/whue//991VAffnll8sdw+fzqaqqqr/++qsKqHffffcp9zldXSd/1ieeeEIF1HHjxpXbN/A5S/v0009VQP3tt9+C2yZMmKDqdDp1zZo1p6zpP//5jwqo27dvD77mcrnUhIQEdeLEieXedy5O/owVfY6VK1eqgDp79uzgtsDPYI8ePVSXyxXc/u9//1sF1G+++Sa4bcCAAeqAAQOCzz0ej+p0OsucIzc3V23UqJE6efLk4LZ77rlHjYqKUj0ezynrX7x4sQqoixcvPu1nePbZZ1VFUdQDBw4Et02cOFEFyvxcqaqqnnfeeWqPHj1OeU4hqpN0G4kGafTo0djtdr7//nsKCwv5/vvvT9ll9OOPP6LX67n77rvLbH/ggQdQVZX58+cH9wPK7XdyK4qqqnz55ZcMHz4cVVXJysoK3oYMGUJ+fj7r16+v0ucxm83B8Qter5fs7GwiIiJo165dmWN9+eWXJCQkcNddd5U7RuAv/i+//BJFUXjiiSdOuc/Z+Mtf/lJum9VqDT52OBxkZWVx0UUXAQTr9vl8fP311wwfPrzCVp9ATaNHj8ZisfDxxx8HX1uwYAFZWVmMHz/+rOuujNKfw+12k52dTevWrYmJianw3/LWW2/FaDQGn99+++0YDIbgz1BF9Ho9JpMJ8H8nOTk5eDweevbsWeYcMTExFBUVlekWrepnKCoqIisriz59+qCqKn/88Ue5/U/+9+zXrx979+6t0jmFOFsSXkSDlJiYyODBg/nkk0/46quv8Hq9XH/99RXue+DAAVJTU4mMjCyzvUOHDsHXA/c6nS7Y9RLQrl27Ms8zMzPJy8vj3XffJTExsczt5ptvBuD48eNV+jw+n49XXnmFNm3aYDabSUhIIDExkU2bNpGfnx/cb8+ePbRr1w6D4dQ9xnv27CE1NZW4uLgq1XAmLVq0KLctJyeHe+65h0aNGmG1WklMTAzuF6g7MzOTgoICOnfufNrjx8TEMHz48DIzyT7++GMaN27MpZdeetr3Hj16tMzt5HEeZ2K323n88ceDY6IC339eXl6Z7z+gTZs2ZZ5HRESQkpJSbozMyT744AO6du2KxWIhPj6exMREfvjhhzLnuOOOO2jbti3Dhg2jSZMmTJ48mZ9++umMn+HgwYNMmjSJuLi44DiWAQMGAJT7DIFxUKXFxsaecdyOENVFxryIBuuGG27glltu4ejRowwbNoyYmJhaOa/P5wNg/PjxTJw4scJ9unbtWqVjPvPMMzz22GNMnjyZf/7zn8TFxaHT6bj33nuD56tOp2qBOd2AzdJ/2QeMHj2aFStW8Ne//pXu3bsTERGBz+dj6NChZ1X3hAkTmDt3LitWrKBLly58++233HHHHWecVZOSklLm+cyZM5k0aVKlz3vXXXcxc+ZM7r33Xnr37k10dDSKojB27Nhq+/4/+ugjJk2axIgRI/jrX/9KUlISer2eZ599tsxg66SkJDZs2MCCBQuYP38+8+fPZ+bMmUyYMIEPPvigwmN7vV4uu+wycnJyeOihh2jfvj3h4eGkp6czadKkcp9Br9dXy2cS4mxJeBEN1siRI7ntttv4/fff+eyzz065X7Nmzfjll18oLCws0/qyY8eO4OuBe5/PF2zdCNi5c2eZ4wVmInm9XgYPHlwtn+WLL77gkksuYcaMGWW25+XlkZCQEHzeqlUrVq1ahdvtLtNtUVqrVq1YsGABOTk5p2x9iY2NDR6/tEArVGXk5uayaNEinnrqKR5//PHg9l27dpXZLzExkaioKLZs2XLGYw4dOpTExEQ+/vhjevXqRXFxMTfddNMZ33dyF0unTp0q+Sn8vvjiCyZOnMhLL70U3OZwOMp9PwG7du3ikksuCT632WxkZGRwxRVXnPYcLVu25KuvvioTHivq3jOZTAwfPpzhw4fj8/m44447+M9//sNjjz1G69aty+2/efNm/vzzTz744AMmTJgQ3F7Vrichaot0G4kGKyIigrfffpsnn3yS4cOHn3K/K664Aq/XyxtvvFFm+yuvvIKiKMEZS4H7k2crvfrqq2We6/V6rrvuOr788ssKfyFnZmZW+bPo9fpy07bnzp1Lenp6mW3XXXcdWVlZ5T4LEHz/ddddh6qqPPXUU6fcJyoqioSEBH777bcyr7/11ltVqrn0MQNO/r50Oh0jRozgu+++C07VrqgmAIPBwLhx4/j888+ZNWsWXbp0qVQr1uDBg8vcTm6JqcxnOflzTJ8+/ZQtUe+++y5utzv4/O2338bj8QR/hk51Dij7eVetWsXKlSvL7HfyNHOdThf8DpxOZ6WPrapqmenVQoQSaXkRDdqpum1KGz58OJdccgmPPPII+/fvp1u3bvz8889888033HvvvcExLt27d2fcuHG89dZb5Ofn06dPHxYtWsTu3bvLHfO5555j8eLF9OrVi1tuuYWOHTuSk5PD+vXr+eWXX8jJyanS57jqqqv4xz/+wc0330yfPn3YvHkzH3/8MS1btiyz34QJE5g9ezb3338/q1evpl+/fhQVFfHLL79wxx13cM0113DJJZdw00038frrr7Nr165gF86yZcu45JJLuPPOOwH/tPDnnnuOqVOn0rNnT3777Tf+/PPPStccFRVF//79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/OUvf+Hll1/GbDazfv16Nm/ezDfffFPl+kTtkEgpao03P5+sd/7D7kGDOfrEE7gOHEAXFUX8X26j9a+LSHnqSeKnTgEg9+OPUaU/W4iQsnPnTlavXs24ceMAMBgMjBkzJtj1s2HDBgYNGlThezds2IBer2fAgAHnVEOzZs3KBBeAXbt2MW7cOFq2bElUVBTNmzcH4ODBg8Fzn3feecHgcrIRI0ag1+uZN28e4O/CuuSSS4LHEaFHWl5EjXNnZJAz6wNy585FLS4GwJCSQvykicRcfz268PDgvlHDhnH8xZfwZGZS8NNPRF99tVZlC1FrrEY92/4xRLNzV9aMGTPweDykpqYGt6mqitls5o033gguCV/heU7zGoBOpys3WL+ilVnDS/3/ImD48OE0a9aM9957j9TUVHw+H507dw4O6D3TuU0mExMmTGDmzJlce+21fPLJJ7z22munfY/QloQXUWMcO/8k5/0Z5P/wI3g8AJjbtiV+6hSihg1DMRrLvUcxmYi98UYyX32V7FmziBo+XFYiFfWeoihV6rrRgsfjYfbs2bz00ktcfvnlZV4bMWIEn376KV27dmXRokXcfPPN5d7fpUsXfD4fS5cuDXYblZaYmEhhYSFFRUXBgLJhw4Yz1pWdnc3OnTt577336NevHwD/+9//yuzTtWtX/vvf/5KTk3PK1pepU6fSuXNn3nrrLTweD9dee+0Zzy20E9r/tYg6JzBzKHvGDIqW/hbcHtarF/FTpxB+8cVnDCMxY0aT9c47OLdtp3jNGsIvvLCmyxZCnMH3339Pbm4uU6ZMITo6usxr1113HTNmzOCFF15g0KBBtGrVirFjx+LxePjxxx956KGHaN68ORMnTmTy5MnBAbsHDhzg+PHjjB49ml69ehEWFsbf//537r77blatWlVuJlNFYmNjiY+P59133yUlJYWDBw/yf//3f2X2GTduHM888wwjRozg2WefJSUlhT/++IPU1FR69+4NQIcOHbjooot46KGHmDx58hlba4S2ZMxLA+XYto3cOZ+R/913FP76K0WrVmPfshXnvn24jx/HV1RUpfVWVK+XggU/s3/MWA5OmOgPLjodkUOH0nzu5zT7YBYR/fpVqhXFEBtL9DXXAJDzweyz/oxCiOozY8YMBg8eXC64gD+8rF27lri4OObOncu3335L9+7dufTSS1m9enVw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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"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_1\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" conv2d_5 (Conv2D) (None, 55, 55, 96) 34944 \n",
" \n",
" batch_normalization_5 (Batc (None, 55, 55, 96) 384 \n",
" hNormalization) \n",
" \n",
" max_pooling2d_3 (MaxPooling (None, 27, 27, 96) 0 \n",
" 2D) \n",
" \n",
" conv2d_6 (Conv2D) (None, 27, 27, 256) 614656 \n",
" \n",
" batch_normalization_6 (Batc (None, 27, 27, 256) 1024 \n",
" hNormalization) \n",
" \n",
" max_pooling2d_4 (MaxPooling (None, 13, 13, 256) 0 \n",
" 2D) \n",
" \n",
" conv2d_7 (Conv2D) (None, 13, 13, 384) 885120 \n",
" \n",
" batch_normalization_7 (Batc (None, 13, 13, 384) 1536 \n",
" hNormalization) \n",
" \n",
" conv2d_8 (Conv2D) (None, 13, 13, 384) 1327488 \n",
" \n",
" batch_normalization_8 (Batc (None, 13, 13, 384) 1536 \n",
" hNormalization) \n",
" \n",
" conv2d_9 (Conv2D) (None, 13, 13, 256) 884992 \n",
" \n",
" batch_normalization_9 (Batc (None, 13, 13, 256) 1024 \n",
" hNormalization) \n",
" \n",
" max_pooling2d_5 (MaxPooling (None, 6, 6, 256) 0 \n",
" 2D) \n",
" \n",
" flatten_1 (Flatten) (None, 9216) 0 \n",
" \n",
" dense_3 (Dense) (None, 4096) 37752832 \n",
" \n",
" dropout_2 (Dropout) (None, 4096) 0 \n",
" \n",
" dense_4 (Dense) (None, 4096) 16781312 \n",
" \n",
" dropout_3 (Dropout) (None, 4096) 0 \n",
" \n",
" dense_5 (Dense) (None, 10) 40970 \n",
" \n",
"=================================================================\n",
"Total params: 58,327,818\n",
"Trainable params: 58,325,066\n",
"Non-trainable params: 2,752\n",
"_________________________________________________________________\n",
"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"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/25\n",
"51/51 [==============================] - ETA: 0s - loss: 3.6077 - accuracy: 0.3566\n",
"Epoch 1: val_accuracy improved from -inf to 0.26302, saving model to alex_2.h5\n",
"51/51 [==============================] - 51s 994ms/step - loss: 3.6077 - accuracy: 0.3566 - val_loss: 1.8337 - val_accuracy: 0.2630\n",
"Epoch 2/25\n",
"51/51 [==============================] - ETA: 0s - loss: 1.2408 - accuracy: 0.5803\n",
"Epoch 2: val_accuracy improved from 0.26302 to 0.34375, saving model to alex_2.h5\n",
"51/51 [==============================] - 53s 1s/step - loss: 1.2408 - accuracy: 0.5803 - val_loss: 2.8576 - val_accuracy: 0.3438\n",
"Epoch 3/25\n",
"51/51 [==============================] - ETA: 0s - loss: 0.9538 - accuracy: 0.6550\n",
"Epoch 3: val_accuracy improved from 0.34375 to 0.35677, saving model to alex_2.h5\n",
"51/51 [==============================] - 56s 1s/step - loss: 0.9538 - accuracy: 0.6550 - val_loss: 4.7057 - val_accuracy: 0.3568\n",
"Epoch 4/25\n",
"44/51 [========================>.....] - ETA: 7s - loss: 0.7304 - accuracy: 0.7273"
]
}
],
"source": [
"data_test = load_test_data(\"./train_test_sw/test_sw\")\n",
"X_test = data_test['values']\n",
"y_test = data_test['labels']\n",
"for filter in filters:\n",
" print(f\"{filter} ---------------------------------------\")\n",
" train_ds, test_ds, validation_ds = data_prep_alex(filter)\n",
" alex(filter, train_ds, test_ds, validation_ds)"
]
}
],
"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"
},
"vscode": {
"interpreter": {
"hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}