{"id":13583918,"url":"https://github.com/dvgodoy/deepreplay","last_synced_at":"2025-04-05T06:07:51.146Z","repository":{"id":31865480,"uuid":"129797862","full_name":"dvgodoy/deepreplay","owner":"dvgodoy","description":"Deep Replay - Generate visualizations as in my \"Hyper-parameters in Action!\" series!","archived":false,"fork":false,"pushed_at":"2023-03-24T23:56:19.000Z","size":13640,"stargazers_count":279,"open_issues_count":4,"forks_count":48,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-29T05:08:48.340Z","etag":null,"topics":["callback","deep-learning","keras","visualization-tools"],"latest_commit_sha":null,"homepage":"https://towardsdatascience.com/hyper-parameters-in-action-a524bf5bf1c","language":"Jupyter Notebook","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/dvgodoy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-04-16T19:55:18.000Z","updated_at":"2025-03-24T11:36:05.000Z","dependencies_parsed_at":"2023-12-02T22:40:56.131Z","dependency_job_id":null,"html_url":"https://github.com/dvgodoy/deepreplay","commit_stats":{"total_commits":78,"total_committers":2,"mean_commits":39.0,"dds":"0.012820512820512775","last_synced_commit":"f9feee22efec0ed670d63f0d86f32b5af0b18af9"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvgodoy%2Fdeepreplay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvgodoy%2Fdeepreplay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvgodoy%2Fdeepreplay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvgodoy%2Fdeepreplay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dvgodoy","download_url":"https://codeload.github.com/dvgodoy/deepreplay/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294539,"owners_count":20915340,"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":["callback","deep-learning","keras","visualization-tools"],"created_at":"2024-08-01T15:03:53.871Z","updated_at":"2025-04-05T06:07:51.128Z","avatar_url":"https://github.com/dvgodoy.png","language":"Jupyter Notebook","funding_links":[],"categories":["Jupyter Notebook","Technologies"],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/dvgodoy/deepreplay.svg?branch=master)](https://travis-ci.org/dvgodoy/deepreplay)\n[![Documentation Status](http://readthedocs.org/projects/deepreplay/badge/?version=latest)](http://deepreplay.readthedocs.io/en/latest/?badge=latest)\n\n# Deep Replay\n\n## Generate visualizations as in my \"Hyper-parameters in Action!\" series of posts!\n\n***Deep Replay*** is a package designed to allow you to ***replay*** in a visual fashion the training process of a Deep Learning model in Keras, as I have done in my [Hyper-parameter in Action!](https://towardsdatascience.com/hyper-parameters-in-action-a524bf5bf1c) post on [Towards Data Science](http://towardsdatascience.com).\n\nThis is an example of what you can do using ***Deep Replay***:\n\n![Part 1 Animation](/images/part1.gif)\n\nIt contains:\n - a Keras' callback - ***ReplayData*** - which collects then necessary information, mostly the weights, during the training epochs;\n - a class ***Replay***, which leverages the collected data to build several kinds of visualizations.\n\nThe available visualizations are:\n - ***Feature Space***: plot representing the twisted and turned feature space,  corresponding to the output of a hidden layer (only 2-unit hidden layers supported for now), including grid lines if the input is 2-dimensional;\n - ***Decision Boundary***: plot of a 2-D grid representing the original feature space, together with the decision boundary (only 2-dimensional inputs supported for now);\n - ***Probabilities***: two histograms of the resulting classification probabilities for the inputs, corresponding to the output of the final layer (only binary classification supported for now);\n - ***Loss and Metric***: line plot for the loss and a chosen metric, computed over all the inputs;\n - ***Losses***: histogram of the losses computed over all the inputs (only binary cross-entropy loss suported for now).\n\nFeature Space | Decision Boundary | Class Probability | Loss/Metric | Losses\n:-:|:-:|:-:|:-:|:-:\n![Feature Space](/images/feature_space.png) | ![Decision Boundary](/images/decision_boundary.png) | ![Probability Histogram](/images/prob_histogram.png) | ![Loss and Metric](/images/loss_and_metric.png) | ![Loss Histogram](/images/loss_histogram.png)\n\n### Google Colab\n\nEager to try it out right away? Don't wait any longer!\n\nOpen the notebooks directly on Google Colab and try it yourself:\n\n- [Part 1 - Activation Functions](https://colab.research.google.com/github/dvgodoy/deepreplay/blob/master/notebooks/part1_activation_functions.ipynb)\n- [Moons Dataset](https://colab.research.google.com/github/dvgodoy/deepreplay/blob/master/notebooks/moons_dataset.ipynb)\n- [Circles Dataset](https://colab.research.google.com/github/dvgodoy/deepreplay/blob/master/notebooks/circles_dataset.ipynb)\n- [UCI Spambase Dataset](https://colab.research.google.com/github/dvgodoy/deepreplay/blob/master/notebooks/UCI_spambase_dataset.ipynb)\n\n### Installation\n\nTo install ***Deep Replay*** from [PyPI](https://pypi.org/project/deepreplay/), just type:\n```python\npip install deepreplay\n```\n\n### Documentation\n\nYou can find the full documentations at [Read the Docs](http://deepreplay.readthedocs.io/).\n\n### Quick Start\n\nTo use ***Deep Replay***, you must first create an instance of the Keras' callback, ***ReplayData***, passing as arguments the inputs (X) and outputs (y) you're using to train the model, as well as the filename and group (for more details, see h5py) where you want the collected data to be saved:\n```python\nfrom deepreplay.callbacks import ReplayData\nfrom deepreplay.datasets.parabola import load_data\n\nX, y = load_data()\n\nreplaydata = ReplayData(X, y, filename='hyperparms_in_action.h5', group_name='part1')\n```\n\nThen, create a Keras model of your choice, compile it and fit it, adding the instance of the callback object you just created:\n```python\nfrom keras.models import Sequential\nfrom keras.layers import Dense\nfrom keras.optimizers import SGD\nfrom keras.initializers import glorot_normal, normal\n\nmodel = Sequential()\nmodel.add(Dense(input_dim=2,\n                units=2,\n                activation='sigmoid',\n                kernel_initializer=glorot_normal(seed=42),\n                name='hidden'))\nmodel.add(Dense(units=1,\n                activation='sigmoid',\n                kernel_initializer=normal(seed=42),\n                name='output'))\n\nmodel.compile(loss='binary_crossentropy', optimizer=SGD(lr=0.05), metrics=['acc'])\n\nmodel.fit(X, y, epochs=150, batch_size=16, callbacks=[replaydata])\n```\n\nAfter your model finishes training, you'll end up with a HDF5 file (***hyperparms_in_action.h5***, in the example), containing a new group (***part1***, in the example) that holds all the necessary information. The Keras model itself is also automatically saved as ***\u003cgroup_name\u003e_model.h5***, that is, ***part1_model.h5*** in the example.\n\nNext, it is time to feed the information to a ***Replay*** instance:\n```python\nfrom deepreplay.replay import Replay\n\nreplay = Replay(replay_filename='hyperparms_in_action.h5', group_name='part1')\n```\n\nThen, you can create a regular Matplotlib figure, like:\n```python\nimport matplotlib.pyplot as plt\n\nfig, ax = plt.subplots(1, 1, figsize=(5, 5))\n```\n\nAnd use your ***Replay*** instance to build the visualization of your choice, say, ***Feature Space*** based on the output of the layer named ***hidden***:\n```python\nfs = replay.build_feature_space(ax, layer_name='hidden')\n```\n\nNow, you're ready to make a ***plot*** of your ***Feature Space*** in any given ***epoch***, or to ***animate*** its evolution during the whole training:\n```python\nfs.plot(epoch=60).savefig('feature_space_epoch60.png', dpi=120)\nfs.animate().save('feature_space_animation.mp4', dpi=120, fps=5)\n```\n\nThe results should look like this:\n\n![Feature Space Epoch 60](/images/feature_space_epoch60.png) ![Feature Space Animation](/images/feature_space_animation.gif)\n\n***TIP***: If you get an error message regarding the ```MovieWriter```, try ```conda install -c conda-forge ffmpeg``` to install FFMPEG, the writer used to generate the animations.\n\nAlternatively, you can explicitly specify a different MovieWriter, for instance, `avconv`:\n```python\nfrom matplotlib import animation\n\nWriter = animation.writers['avconv']\nmetadata = dict(title='Sigmoid Activation Function',\n                artist='Hyper-parameters in Action!')\nwriter = Writer(fps=5, metadata=metadata)\n\nfs.animate().save('feature_space_animation.mp4', dpi=120, writer=writer)\n```\n\n## FAQ\n\n### 1. Grid lines are missing!\n\nDoes your input have more than 2 dimensions? If so, this is expected, as grid lines are only plot for 2-dimensional inputs.\n\nIf your input is 2-dimensional and grid lines are missing nonetheless, please open an [issue](https://github.com/dvgodoy/deepreplay/issues).\n\n### 2. My hidden layer has more than 2 units! How can I plot it anyway?\n\nApart from toy datasets, it is likely the (last) hidden layer has more than 2 units. But ***DeepReplay*** only supports ***FeatureSpace*** plots based on 2-unit hidden layers. So, what can you do?\n\nThere are two different ways of handling this: if your inputs are 2-dimensional, you can plot them directly, together with the decision boundary. Otherwise, you can (train and) plot 2-dimensional latent space.\n\n#### 2.1 Using Raw Inputs\n\nInstead of using ***FeatureSpace***, you can use ***DecisionBoundary*** and plot the inputs in their original feature space, with the decision boundary as of any given epoch.\n\nIn this case, there is no need to specify any layer, as it will use the raw inputs.\n\n```python\n## Input layer has 2 units\n## Hidden layer has 10 units\nmodel = Sequential()\nmodel.add(Dense(input_dim=2, units=10, kernel_initializer='he', activation='tanh'))\n\n## Typical output layer for binary classification\nmodel.add(Dense(units=1, kernel_initializer='normal', activation='sigmoid', name='output'))\n\n...\n\nfs = replay.build_decision_boundary(ax_fs)\n```\n\nFor an example, check the [Circles Dataset](https://github.com/dvgodoy/deepreplay/blob/master/notebooks/circles_dataset.ipynb).\n\n#### 2.2 Using a Latent Space\n\nYou can add an extra hidden layer with ***2 units*** and a ***LINEAR*** activation function and tell ***DeepReplay*** to use this layer for plotting the ***FeatureSpace***!\n\n```python\n## Input layer has 57 units\n## Hidden layer has 10 units\nmodel = Sequential()\nmodel.add(Dense(input_dim=57, units=10, kernel_initializer='he', activation='tanh'))\n\n## Added layer with 2 units and LINEAR activation - the layer to plot using FeatureSpace!\nmodel.add(Dense(units=2, kernel_initializer='normal', activation='linear', name='hidden'))\n\n## Typical output layer for binary classification\nmodel.add(Dense(units=1, kernel_initializer='normal', activation='sigmoid', name='output'))\n\n...\n\nfs = replay.build_feature_space(ax_fs, layer_name='hidden')\n```\n\nBy doing so, you will be including a transformation from a highly dimensional space to a 2-dimensional space, which is also going to be learned by the network.\n\nIn fact, the model will be learning a 2-dimensional latent space, which will then feed the last layer. You can think of this as a logistic regression with 2 inputs, in this case, the latent factors.\n\nFor examples, check either the [Moons Dataset](https://github.com/dvgodoy/deepreplay/blob/master/notebooks/moons_dataset.ipynb) or [UCI Spambase Dataset](https://github.com/dvgodoy/deepreplay/blob/master/notebooks/UCI_spambase_dataset.ipynb) notebooks.\n\n\n## Comments, questions, suggestions, bugs\n\n***DISCLAIMER***: this is a project ***under development***, so it is likely you'll run into bugs/problems.\n\nSo, if you find any bugs/problems, please open an [issue](https://github.com/dvgodoy/deepreplay/issues) or submit a [pull request](https://github.com/dvgodoy/deepreplay/pulls).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdvgodoy%2Fdeepreplay","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdvgodoy%2Fdeepreplay","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdvgodoy%2Fdeepreplay/lists"}