{"id":16560849,"url":"https://github.com/shobrook/sequitur","last_synced_at":"2025-04-04T18:08:44.243Z","repository":{"id":38225391,"uuid":"211413058","full_name":"shobrook/sequitur","owner":"shobrook","description":"Library of autoencoders for sequential data","archived":false,"fork":false,"pushed_at":"2022-11-07T19:10:28.000Z","size":2021,"stargazers_count":370,"open_issues_count":8,"forks_count":57,"subscribers_count":13,"default_branch":"master","last_synced_at":"2023-10-20T23:07:06.232Z","etag":null,"topics":["autoencoder","autoencoder-model","lstm","pytorch","sequence","time-series"],"latest_commit_sha":null,"homepage":"","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/shobrook.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}},"created_at":"2019-09-27T22:51:05.000Z","updated_at":"2023-10-18T12:04:46.000Z","dependencies_parsed_at":"2023-01-21T22:04:16.739Z","dependency_job_id":null,"html_url":"https://github.com/shobrook/sequitur","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shobrook%2Fsequitur","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shobrook%2Fsequitur/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shobrook%2Fsequitur/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shobrook%2Fsequitur/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shobrook","download_url":"https://codeload.github.com/shobrook/sequitur/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247226215,"owners_count":20904465,"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":["autoencoder","autoencoder-model","lstm","pytorch","sequence","time-series"],"created_at":"2024-10-11T20:30:11.867Z","updated_at":"2025-04-04T18:08:44.224Z","avatar_url":"https://github.com/shobrook.png","language":"Python","readme":"# sequitur\n\n`sequitur` is a library that lets you create and train an autoencoder for sequential data in just two lines of code. It implements three different autoencoder architectures in PyTorch, and a predefined training loop. `sequitur` is ideal for working with sequential data ranging from single and multivariate time series to videos, and is geared for those who want to get started _quickly_ with autoencoders.\n\n```python\nimport torch\nfrom sequitur.models import LINEAR_AE\nfrom sequitur import quick_train\n\ntrain_seqs = [torch.randn(4) for _ in range(100)] # 100 sequences of length 4\nencoder, decoder, _, _ = quick_train(LINEAR_AE, train_seqs, encoding_dim=2, denoise=True)\n\nencoder(torch.randn(4)) # =\u003e torch.tensor([0.19, 0.84])\n```\n\nEach autoencoder learns to represent input sequences as lower-dimensional, fixed-size vectors. This can be useful for finding patterns among sequences, clustering sequences, or converting sequences into inputs for other algorithms.\n\n\u003cimg src=\"./img/demo.png\" /\u003e\n\n#### Cited in\n\n[AgriSen-COG, a Multicountry, Multitemporal Large-Scale Sentinel-2 Benchmark Dataset for Crop Mapping Using Deep Learning](https://mdpi-res.com/d_attachment/remotesensing/remotesensing-15-02980/article_deploy/remotesensing-15-02980.pdf)\n\n## Installation\n\n\u003e Requires Python 3.X and PyTorch 1.2.X\n\nYou can install `sequitur` with `pip`:\n\n```bash\n$ pip install sequitur\n```\n\n## Getting Started\n\n### 1. Prepare your data\n\nFirst, you need to prepare a set of example sequences to train an autoencoder on. This training set should be a list of `torch.Tensor` objects, where each tensor has shape `[num_elements, *num_features]`. So, if each example in your training set is a sequence of 10 5x5 matrices, then each example would be a tensor with shape `[10, 5, 5]`.\n\n### 2. Choose an autoencoder\n\nNext, you need to choose an autoencoder model. If you're working with sequences of numbers (e.g. time series) or 1D vectors (e.g. word vectors), then you should use the `LINEAR_AE` or `LSTM_AE` model. For sequences of 2D matrices (e.g. videos) or 3D matrices (e.g. fMRI scans), you'll want to use `CONV_LSTM_AE`. Each model is a PyTorch module, and can be imported like so:\n\n```python\nfrom sequitur.models import CONV_LSTM_AE\n```\n\nMore details about each model are in the \"Models\" section below.\n\n### 3. Train the autoencoder\n\nFrom here, you can either initialize the model yourself and write your own training loop, or import the `quick_train` function and plug in the model, training set, and desired encoding size, like so:\n\n```python\nimport torch\nfrom sequitur.models import CONV_LSTM_AE\nfrom sequitur import quick_train\n\ntrain_set = [torch.randn(10, 5, 5) for _ in range(100)]\nencoder, decoder, _, _ = quick_train(CONV_LSTM_AE, train_set, encoding_dim=4)\n```\n\nAfter training, `quick_train` returns the `encoder` and `decoder` models, which are PyTorch modules that can encode and decode new sequences. These can be used like so:\n\n```python\nx = torch.randn(10, 5, 5)\nz = encoder(x) # Tensor with shape [4]\nx_prime = decoder(z) # Tensor with shape [10, 5, 5]\n```\n\n## API\n\n#### Training your Model\n\n**`quick_train(model, train_set, encoding_dim, verbose=False, lr=1e-3, epochs=50, denoise=False, **kwargs)`**\n\nLets you train an autoencoder with just one line of code. This is useful if you don't want to create your own training loop. Training involves learning a vector encoding of each input sequence, reconstructing the original sequence from the encoding, and calculating the loss (mean-squared error) between the reconstructed input and the original input. The autoencoder weights are updated using the Adam optimizer.\n\n\u003c!--If `denoise=True`, then each input sequence is injected with Gaussian noise before being fed into the autoencoder. The autoencoder is then trained to reconstruct the original undistorted input.--\u003e\n\n**Parameters:**\n\n- `model` _(torch.nn.Module)_: Autoencoder model to train (imported from `sequitur.models`)\n- `train_set` _(list)_: List of sequences (each a `torch.Tensor`) to train the model on; has shape `[num_examples, seq_len, *num_features]`\n- `encoding_dim` _(int)_: Desired size of the vector encoding\n- `verbose` _(bool, optional (default=False))_: Whether or not to print the loss at each epoch\n- `lr` _(float, optional (default=1e-3))_: Learning rate\n- `epochs` _(int, optional (default=50))_: Number of epochs to train for\n\u003c!--- `denoise` _(bool, optional=(default=False))_: If `True`, converts autoencoder into a [Denoising Autoencoder (DAE)](https://en.wikipedia.org/wiki/Autoencoder#Regularized_Autoencoders)--\u003e\n- `**kwargs`: Parameters to pass into `model` when it's instantiated\n\n**Returns:**\n\n- `encoder` _(torch.nn.Module)_: Trained encoder model; takes a sequence (as a tensor) as input and returns an encoding of the sequence as a tensor of shape `[encoding_dim]`\n- `decoder` _(torch.nn.Module)_: Trained decoder model; takes an encoding (as a tensor) and returns a decoded sequence\n- `encodings` _(list)_: List of tensors corresponding to the final vector encodings of each sequence in the training set\n- `losses` _(list)_: List of average MSE values at each epoch\n\n### Models\n\nEvery autoencoder inherits from `torch.nn.Module` and has an `encoder` attribute and a `decoder` attribute, both of which also inherit from `torch.nn.Module`.\n\n#### Sequences of Numbers\n\n**`LINEAR_AE(input_dim, encoding_dim, h_dims=[], h_activ=torch.nn.Sigmoid(), out_activ=torch.nn.Tanh())`**\n\nConsists of fully-connected layers stacked on top of each other. Can only be used if you're dealing with sequences of numbers, not vectors or matrices.\n\n\u003cimg src=\"./img/linear_ae.png\" /\u003e\n\n**Parameters:**\n\n- `input_dim` _(int)_: Size of each input sequence\n- `encoding_dim` _(int)_: Size of the vector encoding\n- `h_dims` _(list, optional (default=[]))_: List of hidden layer sizes for the encoder\n- `h_activ` _(torch.nn.Module or None, optional (default=torch.nn.Sigmoid()))_: Activation function to use for hidden layers; if `None`, no activation function is used\n- `out_activ` _(torch.nn.Module or None, optional (default=torch.nn.Tanh()))_: Activation function to use for the output layer in the encoder; if `None`, no activation function is used\n\n**Example:**\n\nTo create the autoencoder shown in the diagram above, use the following arguments:\n\n```python\nfrom sequitur.models import LINEAR_AE\n\nmodel = LINEAR_AE(\n  input_dim=10,\n  encoding_dim=4,\n  h_dims=[8, 6],\n  h_activ=None,\n  out_activ=None\n)\n\nx = torch.randn(10) # Sequence of 10 numbers\nz = model.encoder(x) # z.shape = [4]\nx_prime = model.decoder(z) # x_prime.shape = [10]\n```\n\n#### Sequences of 1D Vectors\n\n**`LSTM_AE(input_dim, encoding_dim, h_dims=[], h_activ=torch.nn.Sigmoid(), out_activ=torch.nn.Tanh())`**\n\nAutoencoder for sequences of vectors which consists of stacked LSTMs. Can be trained on sequences of varying length.\n\n\u003cimg src=\"./img/lstm_ae.png\" /\u003e\n\n**Parameters:**\n\n- `input_dim` _(int)_: Size of each sequence element (vector)\n- `encoding_dim` _(int)_: Size of the vector encoding\n- `h_dims` _(list, optional (default=[]))_: List of hidden layer sizes for the encoder\n- `h_activ` _(torch.nn.Module or None, optional (default=torch.nn.Sigmoid()))_: Activation function to use for hidden layers; if `None`, no activation function is used\n- `out_activ` _(torch.nn.Module or None, optional (default=torch.nn.Tanh()))_: Activation function to use for the output layer in the encoder; if `None`, no activation function is used\n\n**Example:**\n\nTo create the autoencoder shown in the diagram above, use the following arguments:\n\n```python\nfrom sequitur.models import LSTM_AE\n\nmodel = LSTM_AE(\n  input_dim=3,\n  encoding_dim=7,\n  h_dims=[64],\n  h_activ=None,\n  out_activ=None\n)\n\nx = torch.randn(10, 3) # Sequence of 10 3D vectors\nz = model.encoder(x) # z.shape = [7]\nx_prime = model.decoder(z, seq_len=10) # x_prime.shape = [10, 3]\n```\n\n#### Sequences of 2D/3D Matrices\n\n**`CONV_LSTM_AE(input_dims, encoding_dim, kernel, stride=1, h_conv_channels=[1], h_lstm_channels=[])`**\n\nAutoencoder for sequences of 2D or 3D matrices/images, loosely based on the CNN-LSTM architecture described in _[Beyond Short Snippets: Deep Networks for Video Classification](https://arxiv.org/pdf/1503.08909.pdf)._ Uses a CNN to create vector encodings of each image in an input sequence, and then an LSTM to create encodings of the sequence of vectors.\n\n\u003cimg src=\"./img/conv_lstm_ae.png\" /\u003e\n\n**Parameters:**\n\n- `input_dims` _(tuple)_: Shape of each 2D or 3D image in the input sequences\n- `encoding_dim` _(int)_: Size of the vector encoding\n- `kernel` _(int or tuple)_: Size of the convolving kernel; use tuple to specify a different size for each dimension\n- `stride` _(int or tuple, optional (default=1))_: Stride of the convolution; use tuple to specify a different stride for each dimension\n- `h_conv_channels` _(list, optional (default=[1]))_: List of hidden channel sizes for the convolutional layers\n- `h_lstm_channels` _(list, optional (default=[]))_: List of hidden channel sizes for the LSTM layers\n\n**Example:**\n\n```python\nfrom sequitur.models import CONV_LSTM_AE\n\nmodel = CONV_LSTM_AE(\n  input_dims=(50, 100),\n  encoding_dim=16,\n  kernel=(5, 8),\n  stride=(3, 5),\n  h_conv_channels=[4, 8],\n  h_lstm_channels=[32, 64]\n)\n\nx = torch.randn(22, 50, 100) # Sequence of 22 50x100 images\nz = model.encoder(x) # z.shape = [16]\nx_prime = model.decoder(z, seq_len=22) # x_prime.shape = [22, 50, 100]\n```\n","funding_links":[],"categories":["Python"],"sub_categories":["General-Purpose Machine Learning"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshobrook%2Fsequitur","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshobrook%2Fsequitur","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshobrook%2Fsequitur/lists"}