{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"\"COCLUTION: sparse_categorical_acuracy ALLWAYS!!! returns 0 in validation. will move to a custom function to fix\"\nimport pandas as pd\nimport numpy as np\nimport json\nimport os\nimport random\nimport matplotlib.pyplot as plt\n#from tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport tensorflow as tf\nfrom tensorflow.keras import layers \nfrom sklearn.preprocessing import LabelEncoder\nfrom tensorflow import keras\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:23:30.534073Z","iopub.execute_input":"2022-09-03T18:23:30.534669Z","iopub.status.idle":"2022-09-03T18:23:30.540712Z","shell.execute_reply.started":"2022-09-03T18:23:30.534633Z","shell.execute_reply":"2022-09-03T18:23:30.539699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN_DIR = \"../input/herbarium-2022-fgvc9/train_images/\"\nTEST_DIR = \"../input/herbarium-2022-fgvc9/test_images/\"\n\nwith open(\"../input/herbarium-2022-fgvc9/train_metadata.json\") as json_file:\n    train_meta = json.load(json_file)\nwith open(\"../input/herbarium-2022-fgvc9/test_metadata.json\") as json_file:\n    test_meta = json.load(json_file)\n#Create a meta-data df that can be used to call in images\nids = []\ncategories = []\npaths = []\n\nfor annotation, image in zip(train_meta['annotations'], train_meta['images']):\n    ids.append(image[\"image_id\"])\n    categories.append(annotation['category_id'])\n    paths.append(image[\"file_name\"])\n\ndf_meta = pd.DataFrame({\"id\":ids, \"category\":categories, \"path\":paths})\ndf_meta.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:23:30.740341Z","iopub.execute_input":"2022-09-03T18:23:30.742952Z","iopub.status.idle":"2022-09-03T18:23:40.764889Z","shell.execute_reply.started":"2022-09-03T18:23:30.742898Z","shell.execute_reply":"2022-09-03T18:23:40.763885Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sci_name = {cat[\"category_id\"]:cat[\"scientificName\"] for cat in train_meta['categories']}\nfamily = {cat[\"category_id\"]:cat[\"family\"] for cat in train_meta['categories']}\ngenus = {cat[\"category_id\"]:cat[\"genus\"] for cat in train_meta['categories']}\nspecies = {cat[\"category_id\"]:cat[\"species\"] for cat in train_meta['categories']}\n\ndf_meta[\"scientific_name\"] = df_meta[\"category\"].map(sci_name)\ndf_meta[\"family\"] = df_meta[\"category\"].map(family)\ndf_meta[\"genus\"] = df_meta[\"category\"].map(genus)\ndf_meta[\"species\"] = df_meta[\"category\"].map(species)\npretty_df=df_meta.copy()\ndf_meta.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:23:40.767484Z","iopub.execute_input":"2022-09-03T18:23:40.768129Z","iopub.status.idle":"2022-09-03T18:23:41.210134Z","shell.execute_reply.started":"2022-09-03T18:23:40.768091Z","shell.execute_reply":"2022-09-03T18:23:41.209115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_image(index,func=lambda x: x):\n    path=os.path.join(\"../input/herbarium-2022-fgvc9/train_images\",df_meta[\"path\"][index])\n    #x=plt.imread(path)/255\n    x=tf.keras.preprocessing.image.load_img(path)\n    x=x=tf.keras.utils.img_to_array(x)/255\n    x=func(x)\n    print(f'{df_meta[\"scientific_name\"][index]} shape={x.shape}')\n    plt.figure(figsize = (7,7))\n    plt.imshow(x)\n\nshow_image(20)\nLABEL=len(train_meta['categories'])\nLABEL","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:23:41.211752Z","iopub.execute_input":"2022-09-03T18:23:41.212388Z","iopub.status.idle":"2022-09-03T18:23:41.71832Z","shell.execute_reply.started":"2022-09-03T18:23:41.21235Z","shell.execute_reply":"2022-09-03T18:23:41.717347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"family_id=LabelEncoder()\ngenus_id=LabelEncoder()\nfamily_id.fit([x [\"family\"] for x in train_meta[\"categories\"]])\ngenus_id.fit([x [\"genus\"] for x in train_meta[\"categories\"]])\n#adding sublabels to make this job easier\ndata_df=df_meta.drop(columns=[\"species\",\"scientific_name\"])\ndata_df[\"family\"]=family_id.transform(data_df[\"family\"])\ndata_df[\"genus\"]=genus_id.transform(data_df[\"genus\"])\ndata_df\n","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:23:41.720722Z","iopub.execute_input":"2022-09-03T18:23:41.721619Z","iopub.status.idle":"2022-09-03T18:23:42.696962Z","shell.execute_reply.started":"2022-09-03T18:23:41.721583Z","shell.execute_reply":"2022-09-03T18:23:42.695907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FAM=len(family_id.classes_)\nGEN=len(genus_id.classes_)\nOLD_LABEL=LABEL\nmini=train_meta[\"categories\"]\nmini=[{\"category\":a[\"category_id\"],\"family\":family_id.transform([a[\"family\"]])[0],\"genus\":genus_id.transform([a[\"genus\"]])[0]} for a in mini] \ngenus_family={}\ncategory_genus=[]\nfor a in mini:\n    genus_family.update({a[\"genus\"]:a[\"family\"]})\n    category_genus.append([a[\"category\"],a[\"genus\"]]) \ngenus_family=[[k,v] for k,v in genus_family.items()]\ngenus_family=tf.sparse.SparseTensor(genus_family,[1 for _ in range(len(genus_family))],(GEN,FAM))\ndebug=category_genus\ntoo_big={a[0]:a[1] for a in debug if a[0]>=OLD_LABEL} \nLABEL=max([k  for k in too_big.keys()])+1\ncategory_genus=tf.sparse.SparseTensor(category_genus,[1 for _ in range(len(category_genus))],(LABEL,GEN))\n#print(genus_family)","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:23:42.700309Z","iopub.execute_input":"2022-09-03T18:23:42.70341Z","iopub.status.idle":"2022-09-03T18:24:43.833397Z","shell.execute_reply.started":"2022-09-03T18:23:42.703366Z","shell.execute_reply":"2022-09-03T18:24:43.832302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_size=int(len(data_df)*0.9)\n\"this made an eror thats not a good sign\"\n#val_size=len(data_df)-train_size\n\ntrain_df=data_df.sample(n=train_size)\nval_df=data_df.drop(train_df.index)\n\ntrain_df=train_df.set_index(np.arange(train_size))\nval_df=val_df.set_index(np.arange(len(val_df)))\nval_df","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:24:43.834748Z","iopub.execute_input":"2022-09-03T18:24:43.836181Z","iopub.status.idle":"2022-09-03T18:24:44.301046Z","shell.execute_reply.started":"2022-09-03T18:24:43.836141Z","shell.execute_reply":"2022-09-03T18:24:44.299938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def sample(df,size):\n    return df.sample(min(size,len(df)))\n    \ndef get_samples(df,size):\n    return {i:sample(df[df[\"category\"]==i],size) for i in range(LABEL)}\nlookup=get_samples(train_df,3)\nsmall_df=pd.concat([v for k,v in lookup.items() if v.size>0])\nsmall_df","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:24:44.302834Z","iopub.execute_input":"2022-09-03T18:24:44.303244Z","iopub.status.idle":"2022-09-03T18:25:06.558961Z","shell.execute_reply.started":"2022-09-03T18:24:44.303204Z","shell.execute_reply":"2022-09-03T18:25:06.557914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"HEIGHT=512\nWEITH=340\nf=tf.constant([0.35,0.45,0.2],dtype=tf.float32)\nfor i in range(2):\n    f=tf.expand_dims(f,axis=0)\nhf=tf.expand_dims(f,axis=-1)","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:06.560757Z","iopub.execute_input":"2022-09-03T18:25:06.561586Z","iopub.status.idle":"2022-09-03T18:25:06.569999Z","shell.execute_reply.started":"2022-09-03T18:25:06.561541Z","shell.execute_reply":"2022-09-03T18:25:06.56902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preprocess(img):\n    img=tf.image.central_crop(img,0.8)\n    ratio=min(HEIGHT/img.shape[0],WEITH/img.shape[1])\n    img=tf.image.resize(img,[int(img.shape[0]*ratio),int(img.shape[1]*ratio)])\n    img=tf.image.resize_with_crop_or_pad(img,HEIGHT,WEITH)\n    \n    #grayed=noisey_gray(np.uint8(img*255))\n    #grayed=np.float32(grayed)\n    #grayed=tf.nn.conv2d(tf.expand_dims(grayed,0),hf,1,\"SAME\")[0].numpy()\n    grayed=tf.nn.conv2d(tf.expand_dims(img,0),hf,1,\"SAME\")[0].numpy()\n    \n    \n    x=cv2.medianBlur(grayed,5)\n    x*=255 \n    x=np.uint8(x)\n    x=cv2.Canny(x,40,125)\n    contours,heirarchies =cv2.findContours(x,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)\n    cuted=[x for x in contours if len(x)>20]\n    blank=np.zeros(img.shape,dtype=\"uint8\")\n    cv2.drawContours(blank,cuted,-1 ,(255,255,255),1)\n    \n    x=cv2.GaussianBlur(blank[:,:,0],(9,9),cv2.BORDER_DEFAULT)\n    #x=cv2.medianBlur(x,7)\n    lap=cv2.Laplacian(x,cv2.CV_64F)\n    lap=np.uint8(np.absolute(lap)) \n\n    contours,heirarchies =cv2.findContours(lap,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)\n    #400\n    cuted=[x for x in contours if len(x)>200]\n    hull=[cv2.convexHull(x) for x in cuted if len(x)>700]\n    #cuted.extend(hull)\n    lap=np.zeros(img.shape,dtype=\"uint8\")\n    #cv2.drawContours(lap,cuted,-1 ,(255,255,255),1)\n    cv2.fillPoly(lap,pts =cuted, color=(255,255,255))\n    for x in hull:\n        cv2.fillPoly(lap,pts =x, color=(255,255,255))\n    \n    mask=cv2.cvtColor(lap,cv2.COLOR_BGR2GRAY) \n    mask=np.stack([mask for _ in range(3)],axis=-1)\n    mask=tf.constant(mask,dtype=tf.bool)\n    mask=np.uint8(mask)\n    mask=tf.nn.max_pool2d(tf.expand_dims(mask,0),[7,7],1,padding=\"SAME\")[0]\n    mask=np.float32(mask)\n    x=img*mask\n    inv_mask=1-mask\n    backround=np.ones(img.shape)*0.9\n    backround*=inv_mask\n    \n    x+=backround\n    return x\n\nindex=tf.random.uniform([],0,len(df_meta)-1,dtype=tf.int64).numpy()\nshow_image(index,preprocess)","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:06.571704Z","iopub.execute_input":"2022-09-03T18:25:06.572167Z","iopub.status.idle":"2022-09-03T18:25:08.073856Z","shell.execute_reply.started":"2022-09-03T18:25:06.572129Z","shell.execute_reply":"2022-09-03T18:25:08.072821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"problem=\"../input/herbarium-2022-fgvc9/test_images/001/test-001001.jpg\"\ndef get_x(path):\n    x=tf.keras.preprocessing.image.load_img(path)\n    x=tf.keras.utils.img_to_array(x)/255\n    return preprocess(x)\nx=get_x(problem)\nplt.figure(figsize = (7,7))\nplt.imshow(x)","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:08.07763Z","iopub.execute_input":"2022-09-03T18:25:08.078123Z","iopub.status.idle":"2022-09-03T18:25:08.460733Z","shell.execute_reply.started":"2022-09-03T18:25:08.078086Z","shell.execute_reply":"2022-09-03T18:25:08.45984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_family_numbers(index,data=data_df,prefix=\"../input/herbarium-2022-fgvc9/train_images\"):\n    path=os.path.join(prefix,data[\"path\"][index])\n    cat=data[\"family\"][index]\n    x=get_x(path)\n    \n    return {\"x\":tf.constant(x),\"y\":tf.one_hot(cat,FAM)}\n    \nb=get_family_numbers(3)\nfamily_specs={k:tf.TensorSpec.from_tensor(v) for k,v in b.items()}","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:08.462216Z","iopub.execute_input":"2022-09-03T18:25:08.463244Z","iopub.status.idle":"2022-09-03T18:25:08.584493Z","shell.execute_reply.started":"2022-09-03T18:25:08.463201Z","shell.execute_reply":"2022-09-03T18:25:08.583519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class family_generator():\n    def __init__(self,data):\n        self.cap=len(data)\n        self.data=data \n    def generate(self):\n        for index in range(self.cap):\n            yield get_family_numbers(index,self.data)","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:08.585999Z","iopub.execute_input":"2022-09-03T18:25:08.586349Z","iopub.status.idle":"2022-09-03T18:25:08.592626Z","shell.execute_reply.started":"2022-09-03T18:25:08.586311Z","shell.execute_reply":"2022-09-03T18:25:08.591622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"easy_df=small_df.sample(frac=1.)\neasy_df=easy_df.set_index(np.arange(len(small_df)))","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:08.594187Z","iopub.execute_input":"2022-09-03T18:25:08.59486Z","iopub.status.idle":"2022-09-03T18:25:08.618546Z","shell.execute_reply.started":"2022-09-03T18:25:08.594817Z","shell.execute_reply":"2022-09-03T18:25:08.617556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH=32\n\"naive vertion\"\ntrain_dataset=tf.data.Dataset.from_generator(family_generator(easy_df).generate,output_signature=family_specs)\ntrain_dataset=train_dataset.batch(BATCH).prefetch(tf.data.AUTOTUNE) \n#b=next(train_dataset.as_numpy_iterator())\n#print({k:v.shape for k,v in b.items()})\n\n\nval_dataset=tf.data.Dataset.from_generator(family_generator(val_df).generate,output_signature=family_specs)\nval_dataset=val_dataset.batch(BATCH)\n#b=next(val_dataset.as_numpy_iterator())\n#print({k:v.shape for k,v in b.items()})","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:08.620065Z","iopub.execute_input":"2022-09-03T18:25:08.620423Z","iopub.status.idle":"2022-09-03T18:25:16.766702Z","shell.execute_reply.started":"2022-09-03T18:25:08.620388Z","shell.execute_reply":"2022-09-03T18:25:16.765645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_x=train_dataset.map(lambda x: x[\"x\"])\ntrain_y=train_dataset.map(lambda x: x[\"y\"])\ntrain_dataset=tf.data.Dataset.zip((train_x,train_y)).prefetch(tf.data.AUTOTUNE)\n\nval_x=val_dataset.map(lambda x: x[\"x\"])\nval_y=val_dataset.map(lambda x: x[\"y\"])\nval_dataset=tf.data.Dataset.zip((val_x,val_y)).prefetch(tf.data.AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:16.767998Z","iopub.execute_input":"2022-09-03T18:25:16.768377Z","iopub.status.idle":"2022-09-03T18:25:16.84198Z","shell.execute_reply.started":"2022-09-03T18:25:16.768341Z","shell.execute_reply":"2022-09-03T18:25:16.840988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"latent=tf.keras.applications.EfficientNetB1(include_top=False,input_shape=[HEIGHT,WEITH,3]\n                                           , weights='imagenet')\nlatent.layers[1].scale=1\nlatent.trainable=False","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:16.84368Z","iopub.execute_input":"2022-09-03T18:25:16.844101Z","iopub.status.idle":"2022-09-03T18:25:19.245603Z","shell.execute_reply.started":"2022-09-03T18:25:16.844062Z","shell.execute_reply":"2022-09-03T18:25:19.244599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inputs=layers.Input(latent.layers[0].input.shape[1:])\nx=latent(inputs,training=False)\nx=layers.GlobalMaxPooling2D()(x)\nx=layers.Dense(1024,activation=\"gelu\")(x)\nx=layers.Dense(FAM,activation=\"softmax\")(x)\nmodel=tf.keras.Model(inputs,x)","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:19.246963Z","iopub.execute_input":"2022-09-03T18:25:19.247325Z","iopub.status.idle":"2022-09-03T18:25:20.153044Z","shell.execute_reply.started":"2022-09-03T18:25:19.247291Z","shell.execute_reply":"2022-09-03T18:25:20.151985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001,beta_1=0.95,amsgrad=True)\n              ,loss=\"categorical_crossentropy\",metrics=[\"categorical_accuracy\"]) ","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:20.154359Z","iopub.execute_input":"2022-09-03T18:25:20.154695Z","iopub.status.idle":"2022-09-03T18:25:20.177897Z","shell.execute_reply.started":"2022-09-03T18:25:20.154662Z","shell.execute_reply":"2022-09-03T18:25:20.176967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"steps=4\nval_steps=10\nval_stop=tf.keras.callbacks.EarlyStopping(restore_best_weights=True)\nhistory=model.fit(train_dataset,epochs=len(easy_df)//(steps*BATCH),steps_per_epoch=steps,validation_steps=val_steps,\n                    validation_data=val_dataset\n                  ,validation_freq=10,callbacks=[val_stop])","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:25:20.179337Z","iopub.execute_input":"2022-09-03T18:25:20.179688Z","iopub.status.idle":"2022-09-03T18:30:29.055144Z","shell.execute_reply.started":"2022-09-03T18:25:20.179653Z","shell.execute_reply":"2022-09-03T18:30:29.05398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inputs=layers.Input(latent.layers[0].input.shape[1:])\nx=latent(inputs)\nx=layers.GlobalMaxPooling2D()(x)\nx=model.layers[-2](x)\nx=model.layers[-1](x)\nmodel_2=tf.keras.Model(inputs,x)","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:36:35.466769Z","iopub.execute_input":"2022-09-03T18:36:35.467426Z","iopub.status.idle":"2022-09-03T18:36:36.403394Z","shell.execute_reply.started":"2022-09-03T18:36:35.467387Z","shell.execute_reply":"2022-09-03T18:36:36.402259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"latent.trainable=True\nmodel.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001)\n              ,loss=\"categorical_crossentropy\",metrics=[\"categorical_accuracy\"]) ","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:37:25.784261Z","iopub.execute_input":"2022-09-03T18:37:25.785378Z","iopub.status.idle":"2022-09-03T18:37:25.831737Z","shell.execute_reply.started":"2022-09-03T18:37:25.785329Z","shell.execute_reply":"2022-09-03T18:37:25.830682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH=32\n\"naive vertion\"\ntrain_dataset=tf.data.Dataset.from_generator(family_generator(easy_df.sample(frac=1.)).generate,output_signature=family_specs)\ntrain_dataset=train_dataset.batch(BATCH).prefetch(tf.data.AUTOTUNE) \n#b=next(train_dataset.as_numpy_iterator())\n#print({k:v.shape for k,v in b.items()})\n\n\nval_dataset=tf.data.Dataset.from_generator(family_generator(val_df.sample(frac=1.)).generate,output_signature=family_specs)\nval_dataset=val_dataset.batch(BATCH)\n#b=next(val_dataset.as_numpy_iterator())\n#print({k:v.shape for k,v in b.items()})\n","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:38:46.480936Z","iopub.execute_input":"2022-09-03T18:38:46.48156Z","iopub.status.idle":"2022-09-03T18:38:46.566096Z","shell.execute_reply.started":"2022-09-03T18:38:46.481516Z","shell.execute_reply":"2022-09-03T18:38:46.565083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_x=train_dataset.map(lambda x: x[\"x\"])\ntrain_y=train_dataset.map(lambda x: x[\"y\"])\ntrain_dataset=tf.data.Dataset.zip((train_x,train_y)).prefetch(tf.data.AUTOTUNE)\n\nval_x=val_dataset.map(lambda x: x[\"x\"])\nval_y=val_dataset.map(lambda x: x[\"y\"])\nval_dataset=tf.data.Dataset.zip((val_x,val_y)).prefetch(tf.data.AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:38:47.469376Z","iopub.execute_input":"2022-09-03T18:38:47.470598Z","iopub.status.idle":"2022-09-03T18:38:47.541875Z","shell.execute_reply.started":"2022-09-03T18:38:47.470553Z","shell.execute_reply":"2022-09-03T18:38:47.540894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"steps=10\nval_steps=10\nval_stop=tf.keras.callbacks.EarlyStopping(restore_best_weights=True,patience=1)\nhistory=model.fit(train_dataset,epochs=len(easy_df)//(steps*BATCH),steps_per_epoch=steps,validation_steps=val_steps,\n                    validation_data=val_dataset\n                  ,validation_freq=5,callbacks=[val_stop])","metadata":{"execution":{"iopub.status.busy":"2022-09-03T18:38:48.305196Z","iopub.execute_input":"2022-09-03T18:38:48.305858Z","iopub.status.idle":"2022-09-03T19:04:22.938206Z","shell.execute_reply.started":"2022-09-03T18:38:48.305824Z","shell.execute_reply":"2022-09-03T19:04:22.932011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.evaluate(val_dataset,steps=32)","metadata":{"execution":{"iopub.status.busy":"2022-09-03T19:04:29.205363Z","iopub.execute_input":"2022-09-03T19:04:29.205882Z","iopub.status.idle":"2022-09-03T19:08:51.225947Z","shell.execute_reply.started":"2022-09-03T19:04:29.205846Z","shell.execute_reply":"2022-09-03T19:08:51.224902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}