{'fraction_non_alphanumeric': 0.030267062314540058, 'fraction_numerical': 0.008358061325420376, 'mean_word_length': 4.829057365234938, 'pattern_counts': {'":': 0, '<': 0, '<?xml version=': 0, '>': 0, 'https://': 3, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
DeepZip: Lossless Data Compression using Recurrent Neural Networks

Sequential data is being generated at an unprecedented pace in various forms, including text and genomic data. This creates the need for efficient compression mechanisms to enable better storage, transmission and processing of such data. To solve this problem, many of the existing compressors attempt to learn models for the data and perform prediction-based compression. Since neural networks are known as universal function approximators with the capability to learn arbitrarily complex mappings, and in practice show excellent performance in prediction tasks, we explore and devise methods to compress sequential data using neural network predictors. We combine recurrent neural network predictors with an arithmetic coder and losslessly compress a variety of synthetic, text and genomic datasets. The proposed compressor outperforms Gzip on the real datasets and achieves near-optimal compression for the synthetic datasets. The results also help understand why and where neural networks are good alternatives for traditional finite context models


Introduction
There has been a tremendous surge in the amount of data generated in the past years. Along with image and textual data, new types of data such as genomic, 3D VR, and point cloud data are being generated at a rapid pace. A lot of human effort is spent in analyzing the statistics of these new data formats for designing good compressors. From information theory, we understand that a good predictor naturally leads to good compression. In the recent past, recurrent neural network (RNN) based models have proved extremely effective in natural language processing tasks such as language translation, semantic parsing and more specifically, in the task of language modeling, which includes predicting the next symbol/character in a sequence [1]. This raises a natural question: Can RNN-based models be utilized for effective lossless compression? In this work, we propose a neural network based lossless compressor for sequential data, named DeepZip. DeepZip consists of two major blocks: an RNN based probability estimator and an arithmetic coding based encoder [2].
Before describing the compression framework in detail, we take a look at the existing literature on lossless sequence compression. We then assess the performance of DeepZip on synthetic data as well as real textual and genomic datasets. We conclude by discussing some observations and future extensions.

Related Work
Ever since Shannon introduced information theory [3] and showed that the entropy rate is the fundamental limit on the compression rate for any stationary process, there have been multiple works attempting to achieve this optimum. Perhaps the most common compression tool is Gzip (https://www.gzip.org/). Gzip is based on LZ77 [4] and Huffman coding [5]. LZ77 is a universal compressor, i.e., it asymptotically achieves the optimal compression rate for any stationary source, without the knowledge of the source statistics. LZ77 works by searching for matching substrings in the text appearing before the current position and storing pointers to the matches. Gzip achieves further improvements by using Huffman coding to compress the pointers and other streams generated by LZ77.
LZMA (https://www.7-zip.org/) is another popular compressor which combines LZ77 with atithmetic coding (described later in detail). More generally, arithmetic coding is a technique for compressing data streams given a probability model for the sequence. A large class of compressors model the data using a conditional probability distribution and then use arithmetic coding as the entropy coding technique. This class includes context-tree weighting (CTW) [6] and PPM [7], which efficiently use a mixture of multiple models to generate their predictions.
There has been some related work in the past on lossless compression using neural networks. [8] discussed the application of character-level RNN model for text, and observed that it gives competitive compression performance as compared with the existing compressors. However, as vanilla RNNs were used, the performance was not very competitive for complex sources with longer memory. Recently, [9] introduced a different framework for using neural networks for text compression. An RNN was used as a context mixer for mixing the opinions of multiple compressors, to obtain improved compression performance. This was later improved upon by the CMIX compressor [10], which is based on a similar approach that mixes together more than 2000 models using an LSTM context mixer. However, unlike DeepZip it still requires designing of the individual context based compressors, which can heavily depend on the kind of source being analyzed. More recently there has also been some work on word-based and semantically aware models for text compression [11].

Methods
Consider a data stream S N = {S 1 , S 2 , . . . , S N } over an alphabet S which we want to compress losslessly. We next describe in detail the DeepZip compression framework for such a stream, and the specific models used in the experiments.

Framework Overview
The compressor framework can be broken down into two blocks: Probability predictor: For a sequence S N = {S 1 , S 2 , . . . , S N }, the probability predictor block estimates the conditional probability distribution of S r based on the previously K observed symbols, where K is a hyperparameter. This probability estimateP (S r |S r−1 , . . . , S r−K ) is then fed into the the arithmetic encoding block. The probability predictor block is modeled as a neural network based predictor.
Arithmetic coder block: This block can be thought of as a reversible Finite-State-Machine (FSM) which takes in the probability distribution estimate for the next symbol S r ,P (S r |S r−1 , . . . , S r−K ), and encodes it into a state. The final state is encoded using bits which form the compressed representation of the sequence.

Encoding-Decoding Mechanism
The encoding-decoding operations proceed as follows (see Figure 1): 1) The neural network model in the probability predictor block is trained on the sequence to be compressed for multiple epochs. Once the training is complete, the model weights are stored, to allow its usage during decompression.
2) The probability predictor block uses the trained model weights to output a probability distribution over each symbol, which is then used by the arithmetic encoder to perform compression. For the initial K symbols, any prior can be chosen by the arithmetic encoding block. In our framework, we choose a uniform prior, known also to the decoder. Figure 1a depicts this process for the special case of K = 1.
3) The operations of the decoder are exactly symmetrical to the encoder, as shown in Figure 1b. The arithmetic decoder decodes the initial K symbols using a uniform prior distribution, whereas the subsequent symbols are decoded by using the probability distribution provided by the NN-based predictor block. The predictor block utilizes the stored model weights to produce exactly the same probability estimates as the compressor.
There are a couple of things which are of utmost important for the correct functionality of DeepZip: Firstly, the probability predictor block needs to be causal, and can have input features based only on the past symbols to ensure all the necessary information is available to the decoder. Secondly, the probability prediction block needs to be perfectly symmetric so as to get back the same probability distribution at the decoder, guaranteeing successful reconstruction of the encoded sequence.

Probability Predictor Block
We explored several models for the probability predictor block, ranging from fully connected networks to recurrent neural networks such as LSTMs, GRUs, and other variants. This section describes some specific models and motivation for their use.
Fully connected/dense models (FC): A dense or fully connected neural network is a combination of multiple fully connected layers. Mathematically, a dense layer with input X of shape (batchsize, n) with n features can be defined as : where σ(x) is the activation function, W is the weight matrix, and B is the bias term. In the context of sequence compression, the input for the model would be the previous K symbols and the output would be a multinomial distribution for the next character, (p 1 , p 2 , . . . , p |S| ), where |S| is the alphabet size of the sequence. This is obtained by adding a softmax layer at the end, defined as: LSTM/GRU single output framework: LSTM/GRU (Gated Recurrent Units) belong to the class of gated RNNs, and have been used very effectively in the past few years for various natural language processing applications. For every symbol S r , the input consists of the past K symbols S r−K , . . . , S r−1 . Each of the symbols is an input to a bi-directional GRU cell. Finally, a softmax layer is applied on the final hidden state obtained from the LSTM/GRU cell. The model architecture is illustrated in Figure 2a. For our experiments, we use a bi-directional variant of the GRU, denoted biGRU. LSTM multi output (concat.) framework: The LSTM/GRU single output framework suffers from the vanishing gradients issue, making the dependence on far-ther symbols weak. To alleviate the issue, we consider an LSTM based framework, which includes explicit dependence on all the past K symbols via a fully connected layer on top of LSTM embedding. The architecture is depicted in Figure 2b. The input consists of past K symbols, which are fed to K LSTM cells. The LSTM cell outputs are concatenated, followed by a dense layer and a subsequent softmax layer which gives the final probability distribution to be used for arithmetic encoding.

Training
To train the NN predictor based on K previous encountered symbols, with K chosen to be 64, the sequence is divided into overlapping segments of length K + 1 (shifted by one), where the first K symbols in each segment form the input and the last symbol acts as the output. In all of the models described above, the optimizer Adam [12] is used to minimize categorical cross entropy (default parameters and a batch size fixed at 1024 are used). The model is optimized for a maximum of 10 epochs, where the training is terminated early, if significant improvement is not observed. For every epoch the training data is shuffled, which helps in achieving convergence. We update the model every epoch if there is a decrease in average loss from the previous minima (initially ∞). In the LSTM and GRU based models, a cuDNN accelerated implementation [13] is used which reduces the training time by approximately 7×.
Note that we do not use cross-validation during the training and in fact attempt to overfit on the training data. This is because the proposed framework stores the model weights as part of the compressed representation and the trained model is used only for prediction on the training data.

Arithmetic coder block
Arithmetic coding [2] is an entropy coding technique to compress a stream of data given a probability estimate for every symbol, conditioned on the past. Arithmetic coding maintains a range in the interval [0, 1]. Every stream of symbols uniquely determines a range. This range can be computed sequentially and is directly based on the conditional probability distribution for the next symbol. At the end, the range is encoded into bits, forming the compressed data. The decoder performs the inverse operations, given the probability estimates. We refer the reader to [2] for a detailed description and practical implementation.
To understand how the compressed size for arithmetic coding relates to the categorical cross entropy loss used for training of the prediction models, consider Equation 3 below which shows the loss function C(Y,Ŷ ), where Y is the one-hot encoded ground truth,Ŷ is the predicted probability, |S| is the alphabet size and N is the sequence length.
Using the chain rule for probabilities, this expression can be rewritten as shown in Equation 4 where S N is the sequence andp is the joint probability distribution obtained from the predictor block.
Finally, Equation 5 shows thatL AE , the average number of bits used per symbol for arithmetic coding is very close to the loss function from Equation 4. Thus, categorical cross entropy loss is in fact the optimal loss function to consider while training the models in the DeepZip framework.
The arithmetic coder in DeepZip is based on an open source Python implementation [14]. We achieved significant speedups by parallelizing the encoding and decoding operations. While the computation of predicted probabilities can be easily parallelized during the encoding process, parallelizing the decoding is slightly non-trivial because the computation of probabilities itself depends on the previously decompressed symbols. Thus, we divide the original sequence into B non-overlapping segments during encoding (by default B = 1000). At each step, the probabilities for these segments are computed independently and in parallel by creating a batch of size B. This is followed by separate arithmetic coding steps for each segment. The decompression process is symmetric to the compression process, and the segments are decoded independently in parallel and concatenated at the end to produce the decoded file.

Experiments
We benchmark the performance of our neural network-based compressor DeepZip against Gzip, BSC [15], and some dataset specific compressors like GeCo [16] (for genomic data) and ZPAQ [17] (for text). For DeepZip we considered the three introduced probability predictor blocks FC, biGRU and LSTM-multi. BSC is a BWTbased compressor which improves over Gzip while being computationally efficient. Several synthetic and real datasets are considered to evaluate the compression that can be achieved with our method and also highlight the advantage which this work provides.
-Real datasets: We consider a wide variety of data types including genomic and text data. These datasets were chosen as they benefit in practice from lossless compression.
Human chr1 dataset: We consider the chromosome 1 DNA refence sequence of the Human Genome Project [18]. The alphabet of a DNA sequence typically consists of {A, C, G, T, N }, where {A, C, G, T } represent the possible nucleotides (bases), and the symbol N represents an unknown nucleotide. Although it is well known that genome sequences have significant repeated regions, state-of-the-art compressors have been unable to capture these repeats, making it a difficult source to compress.
C. Elegans whole genome: We also consider the C. Elegans whole genome sequence for compression, obtained by concatenating its six chromosomes.
PhiX virus quality value data: Along with sequenced nucleotides, raw genomic sequencing data also consists of quality values that represent the probability of error of the obtained nucleotides. We consider 100MB of quality value data for a PhiX virus data, where each symbol takes 4 possible values. Unlike the nucleotide sequences, the quality value sequences are highly compressible since most quality values are the same and correspond to the best quality.
text8 dataset: Along with genomic datasets, we also consider the text8 dataset, which is an ASCII text dataset of size 100MB. The text8 dataset has been widely studied and experimented on in the literature. It can be accessed at http://mattmahoney. net/dc/text8.zip.
-Synthetic datasets: We generate data from synthetic sources of known entropy rate. Since entropy rate provides a lower bound on the compression ratio, it allows us to gauge the performance of a compression algorithm against this ideal bound. The following sources are considered: Independent and identically distributed (IID): IID binary data distributed as Bern(0.1) is considered since existing compressors perform fairly good on IID sequences.
k-order Markov (XOR): The Markov-k sources are generated as follows: where M is the alphabet size (2 by default). This source is closely related to the lagged Fibonacci pseudorandom generator [19] and hence is difficult to compress for most traditional compressors, even though the entropy rate for Markov-k sources is in fact 0. We consider k = {20, 30, 40, 50} for our experiments. Hidden Markov Model (HMM): HMM is a statistical Markov model where the system being modeled is assumed to be a Markov process with unobserved hidden state [20]. We simulate a HMM source where the hidden state follows the Markov-k sequence described earlier. Specifically, the HMM process is generated as follows: Here, the hidden process H = X n−1 + X n−k−1 (mod M ) is Markov-k, and Z n is the added IID noise. We consider Z n ∼ Bern(0.1) and k = {20, 30, 40} for our experiments. For all our experiments we used a NVIDIA TITAN X GPU (12GB). All the training and encoding-decoding scripts are available at: https://github.com/mohit1997/ DeepZip Results and discussion  DeepZip. We observe that the proposed compressor outperforms Gzip by about 20% on text and genomic data. As compared to BSC, DeepZip usually achieves comparable results, with slightly better compression on the C. Elegans genome. We also observe that for DeepZip, biGRU exhibits in general the best performance. We also tested some specialized compressors for these datasets. For the human and C. Elegans genomes, we used GeCo, which achieves 5-10 % smaller size as compared to DeepZip. Similarly, for text compression, ZPAQ achieves a compressed size of 17.5MB on the text8 dataset [21], which is 25% lower than that for DeepZip. These results are to be expected, since the specialized compressors typically involve handcrafted contexts and mechanisms which are highly optimized for the dataset statistics. Also, they can improve the compression performance by taking into account that the datasets can in fact be non-stationary. In contrast, the proposed compressor achieves reasonably good results on a wide variety of datasets. Table 2 shows the breakdown of size between the model weights and the arithmetic coded stream for the proposed compressor. We observe that the model size contributes significantly to the overall size, especially when the sequence length is small. Currently the model weights are represented as 32 bit floats without further compression. We attempted to use 16 bit floats and TensorFlow Lite [22], but faced stability and compatibility issues. We believe that the model size can be reduced significantly without losing compression performance by using techniques similar to those outlined in [23]. Furthermore, in some cases, the model can be shared between different sequences, for example when compressing genomes of different individuals which are very similar.  To better understand the ability of the proposed framework, we also experimented with some synthetic data of low Kolmogorov complexity, but which are not compressed well by traditional compressors. Table 3 shows the results for these datasets (IID, XOR and HMM). We see that as we go towards sequences with long-term dependencies, the traditional compressors fail to achieve good compression, only achieving 1 bit per binary symbol. The proposed compressor DeepZip, on the other hand, is able to exploit the structure in these sequences to achieve much better compression. There is still some gap from the entropy of the sequences because of the space needed to store the model and some overhead associated with arithmetic coding. Note that, we observe that in some cases, XOR40 dataset for e.g., the DeepZip performance is significantly dependent upon the training parameters. This can be understood by the fact that the source is pseudo-random, making it difficult for the optimization process to find the appropriate minima.
Regarding the running time of DeepZip, we observe that for typical datasets of size 10MB, every training epoch requires 1-2 hrs (with a 12GB NVIDIA TITAN X GPU and a batch size of 1024). We typically train every dataset for 3-4 epochs. The encoding/decoding requires performing a single forward pass through the NN-model, and takes approximately 5-10 mins, depending upon the model.