{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### Step by Step OIV 452-1 predictor Training" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload 2" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import warnings\n", "from pathlib import Path\n", "import shutil\n", "\n", "from tqdm import tqdm\n", "\n", "import pandas as pd\n", "\n", "from sklearn.metrics import (\n", " confusion_matrix,\n", " mean_squared_error,\n", " ConfusionMatrixDisplay,\n", " classification_report,\n", ")\n", "\n", "import matplotlib.pyplot as plt\n", "import altair as alt\n", "\n", "import panel as pn\n", "\n", "import com_const as cc\n", "import com_func as cf\n", "import com_augmentations as ca\n", "import leaf_patch_oiv_predictor_model as lpopm" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setup" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Remove warnings\n", "warnings.simplefilter(action=\"ignore\", category=UserWarning)\n", "warnings.simplefilter(action=\"ignore\", category=FutureWarning)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "pd.options.display.float_format = \"{:4,.4f}\".format\n", "\n", "pd.set_option(\"display.max_colwidth\", 500)\n", "pd.set_option(\"display.max_columns\", 500)\n", "pd.set_option(\"display.width\", 1000)\n", "pd.set_option(\"display.max_rows\", 16)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DataTransformerRegistry.enable('default')" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "alt.data_transformers.disable_max_rows()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.4.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n var reloading = false;\n var Bokeh = root.Bokeh;\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'plotly': 'https://cdn.plot.ly/plotly-2.31.1.min', 'vega-embed': 'https://cdn.jsdelivr.net/npm/vega-embed@6/build/vega-embed.min', 'vega-lite': 'https://cdn.jsdelivr.net/npm/vega-lite@5/build/vega-lite.min', 'vega': 'https://cdn.jsdelivr.net/npm/vega@5/build/vega.min', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {}});\n require([\"plotly\"], function(Plotly) {\n\twindow.Plotly = Plotly\n\ton_load()\n })\n require([\"vega-embed\"], function(vegaEmbed) {\n\twindow.vegaEmbed = vegaEmbed\n\ton_load()\n })\n require([\"vega-lite\"], function(vl) {\n\twindow.vl = vl\n\ton_load()\n })\n require([\"vega\"], function(vega) {\n\twindow.vega = vega\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 5;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window.Plotly !== undefined) && (!(window.Plotly instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.4.4/dist/bundled/plotlyplot/plotly-2.31.1.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window.vega !== undefined) && (!(window.vega instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.4.4/dist/bundled/vegaplot/vega@5'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window.vegaLite !== undefined) && (!(window.vegaLite instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.4.4/dist/bundled/vegaplot/vega-lite@5'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window.vegaEmbed !== undefined) && (!(window.vegaEmbed instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.4.4/dist/bundled/vegaplot/vega-embed@6'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window.Notyf !== undefined) && (!(window.Notyf instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.4.4/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.holoviz.org/panel/1.4.4/dist/bundled/jquery/jquery.slim.min.js\", \"https://cdn.holoviz.org/panel/1.4.4/dist/bundled/plotlyplot/plotly-2.31.1.min.js\", \"https://cdn.holoviz.org/panel/1.4.4/dist/bundled/vegaplot/vega@5\", \"https://cdn.holoviz.org/panel/1.4.4/dist/bundled/vegaplot/vega-lite@5\", \"https://cdn.holoviz.org/panel/1.4.4/dist/bundled/vegaplot/vega-embed@6\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.4.2.min.js\", \"https://cdn.holoviz.org/panel/1.4.4/dist/bundled/notificationarea/notyf@3/notyf.min.js\", \"https://cdn.holoviz.org/panel/1.4.4/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [\"https://cdn.holoviz.org/panel/1.4.4/dist/bundled/notificationarea/notyf@3/notyf.min.css?v=1.4.4\", \"https://cdn.holoviz.org/panel/1.4.4/dist/bundled/font-awesome/css/all.min.css?v=1.4.4\", \"static/extensions/panel/css/notifications.css?v=1.4.4\"];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n\ttry {\n inline_js[i].call(root, root.Bokeh);\n\t} catch(e) {\n\t if (!reloading) {\n\t throw e;\n\t }\n\t}\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));", "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
oiv_fixed_oiv_hf_swt_t_mae_corn params & values \n", "┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", "┃ Param ┃ Value ┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", "│ backbone │ 'hf_swt_t' │\n", "│ predicted_var │ 'fixed_oiv' │\n", "│ invert_scale │ False │\n", "│ skip_linear │ False │\n", "│ use_sigmoid │ False │\n", "│ monitor_loss │ 'mae' │\n", "│ val_monitor_target │ 'val_monitor' │\n", "│ val_monitor_mode │ 'min' │\n", "│ ordinal_regression_model │ 'corn' │\n", "│ path │ 'microsoft/swin-tiny-patch4-window7-224' │\n", "│ name │ 'Swin Transformer (tiny-sized model)' │\n", "│ link │ 'https://huggingface.co/microsoft/swin-tiny-patch4-window7-224' │\n", "│ batch_size │ 616 │\n", "│ image_size │ 224 │\n", "│ augmentations_kinds │ ['fix_brightness', 'resize', 'affine', 'color', 'to_tensor'] │\n", "│ augmentations_params │ { │\n", "│ │ 'gamma': (60, 120), │\n", "│ │ 'brightness_limit': 0.15, │\n", "│ │ 'contrast_limit': 0.25, │\n", "│ │ 'brightness_target': 115, │\n", "│ │ 'brightness_thresholds': (115, 130), │\n", "│ │ 'mean': (0.5, 0.5, 0.5), │\n", "│ │ 'std': (0.5, 0.5, 0.5) │\n", "│ │ } │\n", "│ Conv output size │ 5 │\n", "│ exclude_if_source │ '[]' │\n", "│ path_to_images │ images/leaf_patches │\n", "│ include_if_source │ ['dark_images' 'good_images' 'water_images'] │\n", "│ weight_loss │ False │\n", "│ learning_rate │ 0.00036253727772139874 │\n", "│ start_lr │ 0.00036253727772139874 │\n", "│ optimizer │ 'adam' │\n", "│ scheduler │ 'steplr' │\n", "│ scheduler_params │ {'step_size': 6, 'gamma': 0.85} │\n", "│ train │ (2414, 37) │\n", "│ val │ (518, 37) │\n", "│ test │ (517, 37) │\n", "│ data_source │ 'raw_dataset' │\n", "└──────────────────────────┴─────────────────────────────────────────────────────────────────┘\n", "\n" ], "text/plain": [ "\u001b[3m oiv_fixed_oiv_hf_swt_t_mae_corn params & values \u001b[0m\n", "┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1m Param\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mValue \u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", "│\u001b[1m \u001b[0m\u001b[1m backbone\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'hf_swt_t'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m predicted_var\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'fixed_oiv'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m invert_scale\u001b[0m\u001b[1m \u001b[0m│ \u001b[3;91mFalse\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m skip_linear\u001b[0m\u001b[1m \u001b[0m│ \u001b[3;91mFalse\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m use_sigmoid\u001b[0m\u001b[1m \u001b[0m│ \u001b[3;91mFalse\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m monitor_loss\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'mae'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m val_monitor_target\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'val_monitor'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m val_monitor_mode\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'min'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1mordinal_regression_model\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'corn'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m path\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'microsoft/swin-tiny-patch4-window7-224'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m name\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'Swin Transformer \u001b[0m\u001b[32m(\u001b[0m\u001b[32mtiny-sized model\u001b[0m\u001b[32m)\u001b[0m\u001b[32m'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m link\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'https://huggingface.co/microsoft/swin-tiny-patch4-window7-224'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m batch_size\u001b[0m\u001b[1m \u001b[0m│ \u001b[1;36m616\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m image_size\u001b[0m\u001b[1m \u001b[0m│ \u001b[1;36m224\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m augmentations_kinds\u001b[0m\u001b[1m \u001b[0m│ \u001b[1m[\u001b[0m\u001b[32m'fix_brightness'\u001b[0m, \u001b[32m'resize'\u001b[0m, \u001b[32m'affine'\u001b[0m, \u001b[32m'color'\u001b[0m, \u001b[32m'to_tensor'\u001b[0m\u001b[1m]\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m augmentations_params\u001b[0m\u001b[1m \u001b[0m│ \u001b[1m{\u001b[0m │\n", "│\u001b[1m \u001b[0m│ \u001b[32m'gamma'\u001b[0m: \u001b[1m(\u001b[0m\u001b[1;36m60\u001b[0m, \u001b[1;36m120\u001b[0m\u001b[1m)\u001b[0m, │\n", "│\u001b[1m \u001b[0m│ \u001b[32m'brightness_limit'\u001b[0m: \u001b[1;36m0.15\u001b[0m, │\n", "│\u001b[1m \u001b[0m│ \u001b[32m'contrast_limit'\u001b[0m: \u001b[1;36m0.25\u001b[0m, │\n", "│\u001b[1m \u001b[0m│ \u001b[32m'brightness_target'\u001b[0m: \u001b[1;36m115\u001b[0m, │\n", "│\u001b[1m \u001b[0m│ \u001b[32m'brightness_thresholds'\u001b[0m: \u001b[1m(\u001b[0m\u001b[1;36m115\u001b[0m, \u001b[1;36m130\u001b[0m\u001b[1m)\u001b[0m, │\n", "│\u001b[1m \u001b[0m│ \u001b[32m'mean'\u001b[0m: \u001b[1m(\u001b[0m\u001b[1;36m0.5\u001b[0m, \u001b[1;36m0.5\u001b[0m, \u001b[1;36m0.5\u001b[0m\u001b[1m)\u001b[0m, │\n", "│\u001b[1m \u001b[0m│ \u001b[32m'std'\u001b[0m: \u001b[1m(\u001b[0m\u001b[1;36m0.5\u001b[0m, \u001b[1;36m0.5\u001b[0m, \u001b[1;36m0.5\u001b[0m\u001b[1m)\u001b[0m │\n", "│\u001b[1m \u001b[0m│ \u001b[1m}\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m Conv output size\u001b[0m\u001b[1m \u001b[0m│ 5 │\n", "│\u001b[1m \u001b[0m\u001b[1m exclude_if_source\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'\u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m path_to_images\u001b[0m\u001b[1m \u001b[0m│ images/leaf_patches │\n", "│\u001b[1m \u001b[0m\u001b[1m include_if_source\u001b[0m\u001b[1m \u001b[0m│ ['dark_images' 'good_images' 'water_images'] │\n", "│\u001b[1m \u001b[0m\u001b[1m weight_loss\u001b[0m\u001b[1m \u001b[0m│ \u001b[3;91mFalse\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m learning_rate\u001b[0m\u001b[1m \u001b[0m│ \u001b[1;36m0.00036253727772139874\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m start_lr\u001b[0m\u001b[1m \u001b[0m│ \u001b[1;36m0.00036253727772139874\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m optimizer\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'adam'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m scheduler\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'steplr'\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m scheduler_params\u001b[0m\u001b[1m \u001b[0m│ \u001b[1m{\u001b[0m\u001b[32m'step_size'\u001b[0m: \u001b[1;36m6\u001b[0m, \u001b[32m'gamma'\u001b[0m: \u001b[1;36m0.85\u001b[0m\u001b[1m}\u001b[0m │\n", "│\u001b[1m \u001b[0m\u001b[1m train\u001b[0m\u001b[1m \u001b[0m│ (2414, 37) │\n", "│\u001b[1m \u001b[0m\u001b[1m val\u001b[0m\u001b[1m \u001b[0m│ (518, 37) │\n", "│\u001b[1m \u001b[0m\u001b[1m test\u001b[0m\u001b[1m \u001b[0m│ (517, 37) │\n", "│\u001b[1m \u001b[0m\u001b[1m data_source\u001b[0m\u001b[1m \u001b[0m│ \u001b[32m'raw_dataset'\u001b[0m │\n", "└──────────────────────────┴─────────────────────────────────────────────────────────────────┘\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "model = lpopm.OivDetPatchesNet.load_from_checkpoint(\n", " cc.path_to_chk_oiv.joinpath(\"oiv_scorer.ckpt\")\n", ")\n", "model.path_to_images = cc.path_to_leaf_patches\n", "model.hr_desc()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Predicting: 100%|██████████| 517/517 [00:25<00:00, 19.94it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "MSE: 0.203\n" ] }, { "data": { "image/png": "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", "text/plain": [ "