{"id":15663750,"url":"https://github.com/lucacappelletti94/plot_keras_history","last_synced_at":"2025-05-05T23:12:16.255Z","repository":{"id":57453527,"uuid":"185058056","full_name":"LucaCappelletti94/plot_keras_history","owner":"LucaCappelletti94","description":"A simple python package to print a keras NN training history.","archived":false,"fork":false,"pushed_at":"2024-12-09T10:44:44.000Z","size":12556,"stargazers_count":18,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-05T23:12:07.186Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LucaCappelletti94.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"LucaCappelletti94"}},"created_at":"2019-05-05T16:50:09.000Z","updated_at":"2024-12-09T10:38:23.000Z","dependencies_parsed_at":"2025-04-13T15:19:28.863Z","dependency_job_id":"bf6f931b-29e1-417e-be08-9bd019a78a5c","html_url":"https://github.com/LucaCappelletti94/plot_keras_history","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Fplot_keras_history","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Fplot_keras_history/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Fplot_keras_history/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Fplot_keras_history/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LucaCappelletti94","download_url":"https://codeload.github.com/LucaCappelletti94/plot_keras_history/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252590627,"owners_count":21772940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T13:39:44.116Z","updated_at":"2025-05-05T23:12:16.250Z","avatar_url":"https://github.com/LucaCappelletti94.png","language":"Python","readme":"# Plot Keras History\n\n[![PyPI](https://badge.fury.io/py/plot-keras-history.svg)](https://pypi.org/project/plot-keras-history/)\n[![License](https://img.shields.io/github/license/LucaCappelletti94/plot_keras_history)](https://github.com/LucaCappelletti94/plot_keras_history/blob/master/LICENSE)\n[![Downloads](https://pepy.tech/badge/plot-keras-history)](https://pepy.tech/project/plot-keras-history)\n[![Github Actions](https://github.com/LucaCappelletti94/plot_keras_history/actions/workflows/python.yml/badge.svg)](https://github.com/LucaCappelletti94/plot_keras_history/actions/)\n\nA Python package to print a [`Keras model training history`](https://keras.io/callbacks/#history).\n\n## How do I install this package?\n\nAs usual, just download it using pip:\n\n```bash\npip install plot_keras_history\n```\n\n## Usage\n\nLet's say you have a model generated by the function `my_keras_model`.\n\n### Plotting a training history\n\nIn the following example, we will see how to plot and either show or save the training history:\n\n![Standard](https://github.com/LucaCappelletti94/plot_keras_history/blob/master/plots/normal.png?raw=true)\n\n```python\nfrom keras.models import Sequential\nfrom keras.layers import Dense\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom plot_keras_history import show_history, plot_history\n\nmodel = Sequential([\n    Dense(1, activation=\"sigmoid\")\n])\nmodel.compile(\n    optimizer=\"nadam\",\n    loss=\"binary_crossentropy\"\n)\nX = np.random.uniform(size=(100, 100))\ny = np.random.randint(2, size=(100))\nhistory = model.fit(\n    X[:50], y[:50],\n    validation_data=(X[50:], y[50:]),\n    epochs=10,\n    verbose=False\n)\nshow_history(history)\nplot_history(history, path=\"standard.png\")\nplt.close()\n```\n\n### Plotting into separate graphs\n\nBy default, the graphs are all in one big image, but for various reasons, you might need them one by one:\n\n```python\nfrom keras.models import Sequential\nfrom keras.layers import Dense\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom plot_keras_history import plot_history\n\nmodel = Sequential([\n    Dense(1, activation=\"sigmoid\")\n])\nmodel.compile(\n    optimizer=\"nadam\",\n    loss=\"binary_crossentropy\"\n)\nX = np.random.uniform(size=(100, 100))\ny = np.random.randint(2, size=(100))\nhistory = model.fit(\n    X[:50], y[:50],\n    validation_data=(X[50:], y[50:]),\n    epochs=10,\n    verbose=False\n)\nplot_history(history, path=\"singleton\", single_graphs=True)\nplt.close()\n```\n\n### Plotting multiple histories\n\nSuppose you are training your model on multiple holdouts and want to plot all of them, plus an average. Fortunately, we've got you covered!\n\n![Multiple Histories](https://github.com/LucaCappelletti94/plot_keras_history/blob/master/plots/multiple_histories.png?raw=true)\n\n```python\nfrom keras.models import Sequential\nfrom keras.layers import Dense\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom plot_keras_history import plot_history\n\nhistories = []\nfor holdout in range(10):\n    model = Sequential([\n        Dense(1, activation=\"sigmoid\")\n    ])\n    model.compile(\n        optimizer=\"nadam\",\n        loss=\"binary_crossentropy\"\n    )\n    X = np.random.uniform(size=(100, 100))\n    y = np.random.randint(2, size=(100))\n    history = model.fit(\n        X[:50], y[:50],\n        validation_data=(X[50:], y[50:]),\n        epochs=10,\n        verbose=False\n    )\n    histories.append(history)\n\nplot_history(\n    histories,\n    show_standard_deviation=False,\n    show_average=True\n)\nplt.close()\n```\n\n### Reducing the history noise with Savgol Filters\n\nIn some cases, it is necessary to see the progress of the history while interpolating results to reduce noise. A parameter is available to automatically apply a Savgol filter:\n\n![Interpolated](https://github.com/LucaCappelletti94/plot_keras_history/blob/master/plots/interpolated.png?raw=true)\n\n```python\nfrom keras.models import Sequential\nfrom keras.layers import Dense\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom plot_keras_history import plot_history\n\nmodel = Sequential([\n    Dense(1, activation=\"sigmoid\")\n])\nmodel.compile(\n    optimizer=\"nadam\",\n    loss=\"binary_crossentropy\"\n)\nX = np.random.uniform(size=(100, 100))\ny = np.random.randint(2, size=(100))\nhistory = model.fit(\n    X[:50], y[:50],\n    validation_data=(X[50:], y[50:]),\n    epochs=10,\n    verbose=False\n)\nplot_history(history, path=\"interpolated.png\", interpolate=True)\nplt.close()\n```\n\n### Automatic aliases\n\nMetrics such as `\"lr\"` (Learning Rate) or `\"acc\"` (Accuracy) are automatically renamed to more descriptive labels.\n\n### Automatic normalization\n\nThe library normalizes the ranges of metrics known to be in `[-1, 1]` or `[0, 1]` to avoid visual biases.\n\n### All the available options\n\n```python\nfrom keras.models import Sequential\nfrom keras.layers import Dense\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom plot_keras_history import plot_history\n\nmodel = Sequential([\n    Dense(1, activation=\"sigmoid\")\n])\nmodel.compile(\n    optimizer=\"nadam\",\n    loss=\"binary_crossentropy\"\n)\nX = np.random.uniform(size=(100, 100))\ny = np.random.randint(2, size=(100))\nhistory = model.fit(\n    X[:50], y[:50],\n    validation_data=(X[50:], y[50:]),\n    epochs=10,\n    verbose=False\n)\nplot_history(\n    history,\n    style=\"-\", # Line style.\n    interpolate=True, # Whether to interpolate graph datapoints.\n    side=5, # Graph size.\n    graphs_per_row=4, # Number of graphs per row.\n    customization_callback=None, # Callback for customizing graphs.\n    path=\"interpolated.png\", # Save path for the resulting image or images (for single_graphs).\n    single_graphs=False # Whether to save as single or multiple graphs.\n)\nplt.close()\n```\n\n### Chaining histories\n\nIf you stop and restart a model's training, it may break the history into two objects. Use [`chain_histories`](https://github.com/LucaCappelletti94/plot_keras_history/blob/dd590ce7f89b2a52236f231a9a6377b3e1d76489/plot_keras_history/utils.py#L3-L8) to merge them:\n\n```python\nfrom keras.models import Sequential\nfrom keras.layers import Dense\nimport numpy as np\nfrom plot_keras_history import chain_histories\n\nmodel = Sequential([\n    Dense(1, activation=\"sigmoid\")\n])\nmodel.compile(\n    optimizer=\"nadam\",\n    loss=\"binary_crossentropy\"\n)\nX = np.random.uniform(size=(100, 100))\ny = np.random.randint(2, size=(100))\nmodel = Sequential([\n    Dense(1, activation=\"sigmoid\")\n])\nmodel.compile(\n    optimizer=\"nadam\",\n    loss=\"binary_crossentropy\"\n)\nX = np.random.uniform(size=(100, 100))\ny = np.random.randint(2, size=(100))\nhistory1 = model.fit(\n    X[:50], y[:50],\n    validation_data=(X[50:], y[50:]),\n    epochs=10,\n    verbose=False\n)\nhistory2 = model.fit(\n    X[:50], y[:50],\n    validation_data=(X[50:], y[50:]),\n    epochs=10,\n    verbose=False\n)\nhistory = chain_histories(history1, history2)\n```\n\n## Extras\n\nNumerous additional metrics are available in [`extra_keras_metrics`](https://github.com/LucaCappelletti94/extra_keras_metrics).\n\n## Cite this software\n\nIf you need a bib file to cite this work:\n\n```bibtex\n@software{Cappelletti_Plot_Keras_History_2022,\n    author = {Cappelletti, Luca},\n    doi = {10.5072/zenodo.1054923},\n    month = {4},\n    title = {{Plot Keras History}},\n    version = {1.1.36},\n    year = {2022}\n}\n```\n","funding_links":["https://github.com/sponsors/LucaCappelletti94"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucacappelletti94%2Fplot_keras_history","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucacappelletti94%2Fplot_keras_history","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucacappelletti94%2Fplot_keras_history/lists"}