<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Max Ehrlich on Medium]]></title>
        <description><![CDATA[Stories by Max Ehrlich on Medium]]></description>
        <link>https://medium.com/@max.ehr?source=rss-cf880ddfcaf1------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*Kij1bxC987XHvpAmcusqrQ.jpeg</url>
            <title>Stories by Max Ehrlich on Medium</title>
            <link>https://medium.com/@max.ehr?source=rss-cf880ddfcaf1------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 07 Jun 2026 01:26:32 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@max.ehr/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Compression in the ImageNet Dataset]]></title>
            <link>https://medium.com/data-science/compression-in-the-imagenet-dataset-34c56d14d463?source=rss-cf880ddfcaf1------2</link>
            <guid isPermaLink="false">https://medium.com/p/34c56d14d463</guid>
            <category><![CDATA[computer-vision]]></category>
            <category><![CDATA[compressio]]></category>
            <category><![CDATA[editors-pick]]></category>
            <category><![CDATA[making-sense-of-big-data]]></category>
            <category><![CDATA[deep-learning]]></category>
            <dc:creator><![CDATA[Max Ehrlich]]></dc:creator>
            <pubDate>Fri, 14 May 2021 18:08:29 GMT</pubDate>
            <atom:updated>2021-05-19T21:35:17.196Z</atom:updated>
            <content:encoded><![CDATA[<h4><a href="https://towardsdatascience.com/tagged/making-sense-of-big-data">Making Sense of Big Data</a></h4><h4>A deep dive into the compression settings of deep learning’s most popular benchmark</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*vmI31dFr2vCBlK8_LOIJTA.png" /><figcaption>Frankenstein’s Monster of datasets? Read on to find out. Image by author.</figcaption></figure><p>I’ve been on a mission lately to get more people thinking about how lossy compression affects their deep learning models [1]. In the process I spent a lot of time with ImageNet [2], which consists entirely of JPEG files, and I started noticing some peculiar compression settings. To see how systemic these odd settings are, I decided to survey the compression settings over the entire dataset. In this post, I report what I saw, including why I think some of these settings are weird, and show the statistics I computed for each of the relevant compression settings. At the end I show that by plotting a 2D projection of these compression settings, it’s actually possible to see graphically that there were several different sources involved in the creation of ImageNet.</p><h3>Methodology</h3><p>To examine the images, I used the read_coefficients function from <a href="https://queuecumber.gitlab.io/torchjpeg/api/torchjpeg.codec.html#torchjpeg.codec.read_coefficients">torchjpeg</a>. This function reads DCT coefficients directly from a JPEG file without decoding them, allowing me to examine low level details like chroma subsampling and quantization. This process revealed that one image in the training set is actually not a JPEG at all. It’s a PNG that someone renamed to have a .JPEG extension. In all it took around 4.5 hours to process the training set and around 10 minutes for the validation set. After processing I plotted the results. I’ve made all the data collection and plotting code available in <a href="https://gitlab.com/-/snippets/2118212">this gist </a>along with full size PDF plots.</p><p>Note that the Y axis on all charts uses a log scale.</p><h3>Overview</h3><p>Overall most of the images in ImageNet are compressed “lightly” and are quite small. The most common image size appears to be around 500 by 500 though there are some outlier sizes that are very large or oddly proportioned. For example, a 2592 by 3888 (very large) image, or a 500 by 33 image (oddly proportioned). This is important because most people resize images to 224 by 224 during preprocessing, and weird aspect ratios or much larger/smaller images will create artifacts from resampling.</p><p>The vast majority of the images are color images, are not chroma subsampled and were quantized at quality 96. This indicates very light compression which would not have a noticeable effect on the images. Of course there are exceptions here, such as 4:1:1 subsampling (which is VERY bad) and some quality &lt; 10 images (also VERY bad). There also appears to be some disparity between the training and test sets for all of these parameters.</p><p>If you’re unfamiliar with any of the terms I used above, don’t worry I’ll be explaining everything as we dive into the results in detail.</p><h3>What About That PNG?</h3><p>Before we go any further: yes, “n02105855/n02105855_2933.JPEG” is actually a PNG that someone renamed to .JPEG. Here it is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/213/1*_rLjHguDgfGm6prZ3L_VJg.jpeg" /><figcaption>“n02105855/n02105855_2933.JPEG” Image credit: ImageNet [2].</figcaption></figure><p>Opening it in a hex editor gives it away pretty clearly:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/424/1*sdP5U4q-2mnGpGUP706OYg.png" /><figcaption>Big oof. Image by author.</figcaption></figure><p>Not much else to say about it, except to note that it’s about an order of magnitude larger than the other images of comparable size.</p><h3>Color</h3><p>Lets start simple, how many images are color and how many are grayscale.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*31mSxDjP9PCsQnjV_REJ_Q.png" /><figcaption>Color results. Image by author.</figcaption></figure><p>Fairly straightforward, almost all the images are color. One thing to note about this though is that JPEG makes a distinction between a grayscale image stored with three color channels exactly the same and an actual grayscale image stored in one channel, what we’re counting here is the later: images which when loaded returned only one channel.</p><h3>Image Sizes</h3><p>Next, let’s look at the image sizes, this section has some of the most interesting results. Image sizes are tricky to visualize, and plotting them graphically is very hard to interpret (I do have these graphs along with the plotting code in the gist), so instead I plotted the width and height on heatmaps. Because these are quite large, I cropped them to 1000x1000 for clarity (full size heatmaps are in the gist). Here’s the training set:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*ioM-GwNaatWBy_izgp-prw.png" /><figcaption>Training set heatmap. Image by author.</figcaption></figure><p>Each pixel in this map represents a size, for example the pixel at position (10, 70) shows the count of images that have a width of 10 and a height of 70. Brighter colors indicate more images.</p><p>We can see some interesting behavior. There’s a clear preference for width and height of 500, as well as some other intervals. and there are some interesting diagonal lines going from the top left to the bottom right of the map. Here’s the same image with some things labeled:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*qEEM3nYc7sFzH03Bw7t1Dg.png" /><figcaption>Training heatmap annotated. Image by author.</figcaption></figure><p>To make the interpretation of the diagonal lines easier, I overlayed a set of lines indicating aspect ratios 1:1 (red), 4:3 (green), and 3:2 (blue).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*iC6V835fm7UPH3ks01HBFw.png" /><figcaption>Training heatmap with aspect ratios. Image by author.</figcaption></figure><p>So we can see the lines correspond to these aspect ratios. 1:1 and 4:3 make sense, but 3:2 I only know of from 35mm film so frankly I’m sure how it ended up in here in such quantity.</p><p>Let’s briefly look at the same heatmap for the validation set:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*xsNd2A_5ndgFcww_scrAig.png" /><figcaption>Validation set heatmap. Image by author.</figcaption></figure><p>Not only is it significantly more sparse (in fact almost all the images are in that 500 width or height area), but the aspect ratios are much more sensible. This is concerning because the size distribution in the validation set doesn’t reflect the training set.</p><p>Time for some pathological examples. Here’s an example of a small image from the training set, its size is only 20 by 17:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/20/1*PEqV2dDsge2cSVg_MZDE1Q.jpeg" /><figcaption>“n07760859/n07760859_5275.JPEG” Image credit: ImageNet [2]</figcaption></figure><p>I have no idea what this is supposed to be, zooming doesn’t help, and I doubt your neural network could figure this out either.</p><p>Here’s one with a crazy aspect ratio, it’s 500 by 32:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*LOzI7kpV-9pRWdIyCwH89w.jpeg" /><figcaption>“n04228054/n04228054_11471.JPEG” Image credit: ImageNet [2]</figcaption></figure><p>I think it’s a ski? It’s sure to look weird after resizing to 224x224 with or without center cropping:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/460/1*-koV2M9r3hiF3VWmjmzrIA.png" /><figcaption>“n04228054/n04228054_11471.JPEG” after center crop and resize (left) and only resize (right). Image credit: ImageNet [2]</figcaption></figure><h3>Chroma Subsampling</h3><p>Next we can look at the chroma subsampling settings. I’ll first explain what chroma subsampling is, feel free to skip this section if you’re familiar, then I’ll go into the results.</p><p><strong>What is chroma subsampling? <br></strong>Human vision is less sensitive to small changes in color than it is to small changes in brightness. JPEG compression leverages this to save additional space by subsampling color information, in other words, it stores less color information than brightness information. The algorithm does this by converting the standard RGB image that it is given into the YCbCr color space. This color space separates the brightness or <em>luma</em> of a pixel from the color or <em>chroma. </em>The Y channel stores brightness, and is saved at full resolution. The Cb and Cr channels store color information (roughly blueness and redness respectively) and are often downsampled.</p><p>When we talk about how the downsampling is done, we use the following notation: “4:a:b”. This scheme refers to a 4 column, 2 row block of pixels. “a” indicates the number of color samples in the first row, and “b” indicates the number of these samples which change in the second row. So if we have 4:2:2 subsampling, we are saying that for every 4 luma samples, the first row only has 2 chroma samples, and both of them change in the second row. We interpret this as the chroma channels being half the width, but the same height as the luma channel.</p><p>The notation is strange at first but makes sense when you’re used to looking at it and I’ll fully explain the interpretation of the schemes when discussing results in the next section.</p><p><strong>Results</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*7PG30i2DQ2jat6XQe0ByYQ.png" /><figcaption>Chroma subsampling results. Image by author.</figcaption></figure><p>Above you can see the chroma subsampling results. There are a couple of interesting things to note here, the first is that the vast majority of images are using “4:4:4” which means there is <em>no </em>subsampling. Around 10% use “4:2:0” meaning that the chroma channels are half the width and height. This is the most common setting in practice because it’s the default in many JPEG implementations, so if you’re deploying a system that’s going to work on real images, ImageNet might not be representative enough for you.</p><p>One thing that really stands out is the number of “4:1:1” images. This is a weird one (uncommon in practice), and it indicates that the chroma channels have only 1/4th the width of the luma channel (but the height is the same). This is going to incur a very large and noticeable degradation to the image. Also note that there are around an order of magnitude more of these in the validation set than there are in the training set, although they still make up a small fraction of the total images.</p><p>Here’s an example of a 4:1:1 image from the training set</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/473/1*hKao3OzQWsdsi7oqM0WDJQ.jpeg" /><figcaption>“n02445715/n02445715_2673.JPEG”. Image credit ImageNet [2].</figcaption></figure><p>Note how it looks terrible and the colors largely don’t make sense.</p><h3>Quality</h3><p>The setting that has the largest effect on the size and fidelity of a JPEG is its quality setting. This is actually non-standard but fairly common, anyone who has exported a JPEG file may be familiar with the slider that comes up asking for a quality from 0 to 100. Lower quality images look worse but are considerably smaller than high quality images. As in the last section I’ll first explain what this quality actually is, then we’ll look at the results.</p><p><strong>What is JPEG Quality?<br></strong>When a JPEG file is saved, it isn’t actually storing pixels, it’s storing coefficients of the Discrete Cosine Transform (DCT). The DCT is applied to the pixels to produce transform coefficients, these coefficients are then <em>quantized </em>by rounding them to save space. This rounding is the primary source of information loss in JPEG compression and is also responsible for the majority of its space saving. Essentially, the quality is used to control the amount of rounding, so high quality means less rounding resulting in a larger file. JPEG controls the rounding by computing a matrix from the quality factor which is used to element-wise divide the coefficients. Larger entries in this matrix means smaller coefficients after dividing and therefore more rounding. The rounding allows the coefficients to be represented as integers and creates runs of zeros and repeated elements (lower entropy representations).</p><p>Since quality is non-standard it is not stored in the JPEG file, and estimating quality is not always straightforward. I used the <a href="https://queuecumber.gitlab.io/torchjpeg/api/torchjpeg.quantization.html#module-torchjpeg.quantization.ijg">torchjpeg.quantization.ijg</a> library to compute quantization matrices for every quality from 0 to 100 for each image until I found one that matched exactly the quantization matrix stored in the file. This is time consuming and it only works if the images were compressed using libjpeg, which luckily they all were.</p><p><strong>Results</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*-kRpH9gx2dqB9egLk55fQQ.png" /><figcaption>Quality results. Image by author.</figcaption></figure><p>Above are the quality results. We can see a large spike at quality 96 indicating that the vast majority of images were compressed at this quality. 96 is very high, and wouldn’t noticeably effect the images. Interesting things to note here are the small proportion of very low quality (generally less than 10) images in the training set, these images would be almost completely destroyed by compression. Also note the sparsity of the validation set, where the training set covers a wide range of diverse qualities (albeit in small proportion), these are not generally represented in the validation set.</p><p>Here’s an example of a quality 3 image from the training set.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*u0YPXQo7nNfda1zT3GczbQ.jpeg" /><figcaption>“n02441942/n02441942_6428.JPEG” Image credit ImageNet [2]</figcaption></figure><p>Note how it’s only somewhat recognizable and the colors are largely missing.</p><h3>Exploring the Space of Images</h3><p>One thing that immediately stands out to me is that ImageNet seems to have been assembled from several very different sources, kind of like the Frankenstein’s monster of datasets. There was clearly a source that was assembled with great care for the compression settings, changing the defaults to quality 96 and 4:4:4 subsampling and using 500 by 500 images. Then there are some others which seem to lack that kind of intentional design but which are present in enough numbers that they appear to be related in someway. This may have been supplemented with single images from various sources which would explain some of the outliers. This can likely be corroborated by someone who knows the history of the dataset.</p><p>We can actually visualize this graphically. To do this, I stored the compression settings as 4D vectors (chroma subsampling type, width, height, quality) and projected them into 2D using UMAP [8]. I computed this on the training set and I used only 10% of the images with a width <strong>or </strong>height of 500 since those tend to dominate the signal otherwise. Here’s what that looks like, after I colored in some very clear clusters:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*L4EF5XOAKDAth1pJz4qfIQ.png" /><figcaption>Image space with prominent clusters highlighted. Image by author.</figcaption></figure><p>Examining these clusters gives us an idea of why they are grouped together. The orange cluster contains only size 500 by 375 images compressed at quality 96 and with 4:4:4 chroma subsampling. The green cluster contains 375 by 500 images (transposed of the orange cluster), with otherwise the same settings. The red cluster is again the same, but with 333 by 500 images.</p><p>Next let’s color the points by chroma subsampling scheme</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*vmI31dFr2vCBlK8_LOIJTA.png" /><figcaption>Image space colored by chroma subsampling scheme. Image by author.</figcaption></figure><p>We get a nice, clear, separation on this one. Yellow points are 4:2:0 and purple points are 4:4:4, the rest are in between. A cluster of 4:2:2 (blue) shows up on the left hand side, looking back at the original plot above, this cluster sticks out a little more now that we’ve identified it.</p><p>Coloring the points by quality gives another interesting result</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*JbEx4opDNLOMc3vMkA_dTA.png" /><figcaption>Image space colored by quality. Image by author.</figcaption></figure><p>We can see lower qualities heavily represented on the lower right. This is the same region that 4:2:0 chroma subsampling was featured prominently.</p><p>If I had to guess based on these plots, I would say that the smaller clusters on the left hand side represent some initial sources of data. They have similar parameters, differ only in their dimensions, and are small in number. Around them on the left hand side are images which were gathered from other sources but with similar parameters. The right hand side represents a large departure in the method of data collection, with very different parameters represented. Take this with a grain of salt, because projection techniques like UMAP are not guaranteed to perfectly model the space, and this is just my speculation.</p><h3>Conclusion</h3><p>Although ImageNet remains the most popular computer vision dataset, it is generally becoming known that it has some major issues with its labels [3, 4], its widespread use [5], and its potential for societal impact [6, 7]. I’d like to echo those concerns while raising one of my own: data quality. In my most recent paper [1] I showed that compression settings can have a large and sometimes unexpected effect on deep networks. While most of the compression is light, there are enough outliers to cause concern and there are disparities between the training and validation sets. Also the image sizes are quite varied and contain extreme aspect ratios that could cause problems when resizing images for input to the network. Based on this analysis I definitely recommend thinking about these issues and whether they will affect your performance the next time you consider using ImageNet. It’s not that ImageNet is objectively a bad dataset, it has served the community quite well over the years, and it may even help to have this kind of variation in some cases. But as deep learning advances into a more precise science it’s good to take a proactive approach to these issues and figure out early whether they’re important for your particular application.</p><h3>Acknowledgement</h3><p>This post was inspired by my research [1] that was graciously supported by independent grants from DARPA MediFor, DARPA SemaFor, and Facebook AI. I want to also thank my co-authors, Professors Abhinav Shrivastava and Larry Davis of UMD and Dr. Ser-Nam Lim of Facebook AI for their contributions.</p><h3>References</h3><ol><li>Ehrlich, Max, et al. “Analyzing and Mitigating Compression Defects in Deep Learning.” arXiv preprint arXiv:2011.08932 (2020).</li><li>Deng, Jia, et al. “Imagenet: A large-scale hierarchical image database.” 2009 IEEE conference on computer vision and pattern recognition. Ieee, 2009.</li><li>Beyer, Lucas, et al. “Are we done with ImageNet?.” arXiv preprint arXiv:2006.07159 (2020).</li><li>Yun, Sangdoo, et al. “Re-labeling ImageNet: from Single to Multi-Labels, from Global to Localized Labels.” arXiv preprint arXiv:2101.05022 (2021).</li><li>Tuggener, Lukas, Jürgen Schmidhuber, and Thilo Stadelmann. “Is it enough to optimize cnn architectures on imagenet?.” arXiv preprint arXiv:2103.09108 (2021).</li><li>Birhane, Abeba, and Vinay Uday Prabhu. “Large Image Datasets: A Pyrrhic Win for Computer Vision?.” Proceedings of the IEEE/CVF Winter Conference on Applications of Computer Vision. 2021.</li><li>Yang, Kaiyu, et al. “A Study of Face Obfuscation in ImageNet.” arXiv preprint arXiv:2103.06191 (2021).</li><li>McInnes, Leland, John Healy, and James Melville. “Umap: Uniform manifold approximation and projection for dimension reduction.” arXiv preprint arXiv:1802.03426 (2018).</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=34c56d14d463" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/compression-in-the-imagenet-dataset-34c56d14d463">Compression in the ImageNet Dataset</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Revisiting DCT Domain Deep Learning]]></title>
            <link>https://medium.com/data-science/revisiting-dct-domain-deep-learning-51458fe2e6e4?source=rss-cf880ddfcaf1------2</link>
            <guid isPermaLink="false">https://medium.com/p/51458fe2e6e4</guid>
            <category><![CDATA[compression]]></category>
            <category><![CDATA[editors-pick]]></category>
            <category><![CDATA[jpeg]]></category>
            <category><![CDATA[opinion]]></category>
            <category><![CDATA[computer-vision]]></category>
            <dc:creator><![CDATA[Max Ehrlich]]></dc:creator>
            <pubDate>Wed, 27 Jan 2021 00:41:24 GMT</pubDate>
            <atom:updated>2021-02-01T18:53:00.701Z</atom:updated>
            <content:encoded><![CDATA[<h4><a href="https://towardsdatascience.com/tagged/opinion">Opinion</a></h4><h4>Deep learning on JPEG and DCT domain data represents a promising new direction for research.</h4><p>While working on my dissertation proposal, I had the opportunity to revisit my ICCV 2019 paper “Deep Residual Learning in the JPEG Transform Domain”. It was an interesting experience to look back on it after about a year and see how the field has evolved since then. In this article, I will give some details about the method we presented in the paper, then talk a little about the latest advances in DCT domain deep learning.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MyN3zrmDjk9q0m9iFU_tvQ.png" /><figcaption>JPEG vs spatial throughput, more on this later. Image by author.</figcaption></figure><h3>Overview</h3><p>I expect many readers will be familiar with deep learning, the ubiquitous technique for modern machine learning. Fewer people, however, will be familiar with DCT domain techniques and how they apply here. These ideas were extremely popular in the late 1980s and early 1990s when decompressing a JPEG was a time-consuming process for a computer. The idea is simple: redefine the operations you want to perform so that they can be done on the compressed data rather than on the pixels themselves. This is possible because the JPEG transform is (mostly) linear. We usually refer to these techniques as JPEG, DCT, or compressed domain operations.</p><p>While these ideas fell out of style as compute power increased, in my opinion, they are still highly applicable to computer vision where saving a few milliseconds per image can add up to massive time savings over the long run (for example: training a convolutional neural network), and this is exactly what I wanted to show in the ICCV paper [1]. 2019 was an extremely active area of research for this field and it’s been exciting to look back at the progress, with four orthogonal techniques eventually emerging as the foundation.</p><p>Up front, here are some additional resources:</p><ol><li>The paper itself is freely available on <a href="https://arxiv.org/abs/1812.11690">arxiv</a></li><li>I took extensive notes while developing the technique and you can read them <a href="http://maxehr.umiacs.io/jpeg_domain_resnet/jpeg_domain_resnet_html.html">here</a> these notes are also available as <a href="https://colab.research.google.com/drive/1UHho38IkrF4QqQiIm5rX8RWw-8V3D0h3#scrollTo=2YdUQrum0onC">runnable Jupyter notebooks</a></li><li>The code used in the paper is public, you can get it from my <a href="https://gitlab.com/Queuecumber/jpeg-domain-resnet">gitlab</a></li></ol><h3>JPEG and the DCT</h3><p>There’s a lot written on how JPEG works and on the discrete cosine transform (DCT) so I’m going to only cover them briefly. JPEG encoding consists of roughly the following steps, starting from an RGB image:</p><ol><li>Convert the image YCbCr color space, which separates the brightness (grayscale or Y) data from the color data (Cb and Cr).</li><li>Pad and center the image. Most encoders will do chroma subsampling (4:2:0 is the most common) which means that the color channels are halved in each dimension. Since the DCT will be taken in 8 by 8 blocks, this means that the image needs to be padded to a multiple of 16 so that after subsampling the color channels the size is divisible by 8. The pixels are then centered by subtracting 128 from each pixel.</li><li>Compute the 2D type II discrete cosine transform (often just called the DCT) of each of the blocks. This is the real meat of the JPEG algorithm, and most of the work in compressed domain operations deals the DCT vs the other steps of the algorithm which are often trivial to derive operations for.</li><li>The results of the above transform are called DCT coefficients, they are then quantized using a precomputed quantization table. The is just an element-wise divide of each of the 8 by 8 blocks, with rounding applied to the result. This is the main lossy step in JPEG, all the complex JPEG artifacts are caused by this relatively simple operation on the DCT coefficients.</li><li>The coefficients are vectorized in a zig-zag order which places low frequencies in the beginning and high frequencies at the end. This is because the quantization tends to zero out high frequencies which our brain doesn’t perceive clearly anyway. By concentrating the zeroes at the end of the vector, they can be efficiently run-length encoded.</li><li>The RLE vectors are then entropy coded</li></ol><p>JPEG decoding is essentially the reverse process. Note that we say that step 4 is lossy because it can’t really be undone. We know what the quantization matrix used to divide the coefficients was, but because the coefficients were rounded, when we multiply we only get an approximation of the original coefficients.</p><p>For reference the DCT is given by the following equation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/879/0*cYeYP0zMxGBdYJh-" /></figure><p>For blocks of pixels <em>P,</em> block offsets <em>m,n</em> and spatial frequencies <em>α, β</em>. The function <em>V()</em> computes a scale factor which makes the transform orthonormal. There are two important results to note here. The first is that each coefficient is a function of <strong>all</strong><em> </em>the pixels in the block, the second is that the first frequency (<em>α = β = </em>0) :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/575/0*--AAB6q78qYhU79X" /></figure><p>In other words, it is an unweighted sum of the pixels and is proportional to the mean of the block.</p><h3>Linearity of JPEG</h3><p>As I mentioned above, one way to model JPEG compression is as a linear map. We can do this for JPEG encoding as long as we ignore the rounding in step 4 in the previous section, and it works exactly for JPEG decoding. This is useful because any other linear map can be multiplied through the JPEG linear map to create a new map which operates on JPEG data. For a simple illustration of this, consider the following two linear functions of real numbers:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/129/0*9xpfmQTgWkHjdrtU" /></figure><p>If I wanted to apply <em>f </em>then<em> g </em>to the same input, I could simply compute <em>f(x) </em>then <em>g(x) </em>, which would take two multiplies, or I could compute</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/319/0*RcbE0Fxg-PCg5qDY" /></figure><p>which only takes a single multiply. This is the idea behind compressed domain techniques: if <em>f </em>is JPEG and <em>g </em>is some operations on pixels, then you can multiply them out to make an operation on JPEG data.</p><p>So what exactly does this look like? Brian Smith figured this out in 1993 [2] and I attempted to formalize it a little using ideas from multi-linear algebra. If you don’t know what multi-linear algebra is, it’s just an extension of linear algebra to arbitrarily shaped tensors (note: the proper mathematical term for a tensors shape is its <strong>type</strong>). Fair warning this gets a little mathy.</p><p>First, let&#39;s go over some notation. All equations in this section are going to be in what&#39;s called “Einstein notation” (which he developed while working on general relativity). This is essentially a short-form way of writing summations and it makes tensor products much more readable. In Einstein notation, there are upper and lower indices and it’s important to remember that if you see a superscript, it is an <strong>upper index </strong>not a power. Unsurprisingly, a subscript is called a <strong>lower index</strong>. Any time an index appears as an upper index for one tensor in an expression, and a lower index for another tensor, the elements are multiplied and summed. Any time an index appears in the same (upper or lower) position in two tensors, the elements are multiplied but not summed. Any indices that were not summed out carry over to the result. Here’s an example of what a matrix-vector product looks like for a matrix <em>Q </em>and a vector <em>x:</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/123/0*uZCkoHkGzWA5MMPQ" /></figure><p>So we multiply over the index <em>i </em>since it appears in the top of <em>Q</em> and the bottom of <em>x </em>and sum, and we leave <em>j </em>alone yielding a vector <em>q </em>indexed by <em>j</em>.</p><p>Next we need to define what an image looks like under this model. We’ll say that a <strong>single plane</strong> image (e.g., a grayscale image) is a type (0, 2) tensor meaning that it has no upper indices and two lower indices (essentially it’s a matrix). We denote this as:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/176/0*68qbcFOR7EpXOz6C" /></figure><p>The circled times there is a tensor product (sometimes called the outer product), the <em>H</em> and <em>W </em>are vector spaces, and the * denotes a <strong>dual space</strong>, which for our purposes just means that the result of the tensor product has lower indices.</p><p>Finally, we can derive the JPEG compression and decompression tensors. For brevity, I won’t put the derivation in here (it is quite long), but you can find it in Section 3.2 of the paper. The result of the derivation is two linear maps, the first is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/408/0*LQ05zTn18j3BL_WK" /></figure><p><em>J</em> performs JPEG compression, note that <em>H, W</em> here are without the *, this means they are upper indices so they get multiplied out when we apply this to <em>I</em>. Also note that the X and Y index a block in the image and the K indexes the stored coefficient (there are 64 per block). The second map is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/410/0*-t-tDIlJtxyu9vgJ" /></figure><p>which performs JPEG decompression. With these two maps, we can take a new linear map which computes a linear function of pixels, this looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/343/0*BTJ9xgpqNSD3BrJP" /></figure><p>and compute the corresponding JPEG domain map as:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/300/0*MG_OahkMcxTRzRlm" /></figure><p>Reading the right hand side of this last equation we can see what the new map does. It decompresses the image, applies <em>C</em>, and then compresses the result. But since we multiplied all this out beforehand, it does all three of these in a single step.</p><p>Before continuing, I’ll show another important tensor derived in the paper that we will make use of in the next section: the DCT tensor. This can be used to perform both the forward and inverse DCT:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/772/0*UWAQgkvcsBXE3oAs" /></figure><p>As in the DCT equation in the previous section <em>m,n</em> index a block of pixels and α, β index the spatial frequency. <em>V </em>is a constant used to make the transform orthonormal. Note the missing summation: this is taken care of by the tensor product.</p><h3>JPEG Domain Deep Learning</h3><p>It turns out that this gets us most of the way to JPEG domain deep learning. For the ICCV paper we had a simple goal: use the analysis in the previous section to make a ResNet [3] which operates on JPEG domain data but gets as close as possible to the same result as if it was operating on pixels. ResNet has several operations and we need to define each of them.</p><p><strong>Convolutions </strong>This one is pretty straightforward and follows directly from the previous section. Convolutions are linear maps on pixels, so they are essentially the <em>C</em> we discussed prior. So using the same technique we can define Ξ as our compressed domain convolution. There are still some tricks we can do here, see Section 4.1 if you’re interested.</p><p><strong>Batch Normalization </strong>This one is also straightforward. Batch norm defines learnable affine parameters γ and β and measures the running mean and variance of the batches. These values are then applied using the following formula:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/305/0*6OxUFRJMpVJ9YeTC" /></figure><p>As we discussed previously, the 0,0 coefficient is proportional to the mean of the block, which makes it easy to extract and significantly faster than computing the pixel mean (an unconditional read vs 64 sums). Computing the variance is also easy, it turns out that if the pixels have a zero mean, then the mean of the DCT coefficients is equal to the variance of the pixels. Similarly, applying β is as simple as adding it to the 0,0 coefficient and applying γ is a simple as multiplying each coefficient by it. See Section 4.3 for more details on this procedure.</p><p><strong>Global Average Pooling </strong>This one carries over a lot from batch normalization. The idea is to take only the average of each channel for each feature map. This is as simple as reading off the 0,0 coefficient for each block which already contains the mean. See the figure below and Section 4.5 of the paper. Note that from this point, ResNet uses fully connected layers, and the GAP output is exactly what these fully connected layers expect as input so there are no further compressed domain operations that need to be derived.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/521/1*Iib62OE_mNFbGkT1CA-SoA.png" /><figcaption>DCT domain global average pooling. Image by author.</figcaption></figure><p><strong>Model Conversion </strong>One last thing to mention in this section is that nothing in our formulation depends on starting from random weights, it is just as valid to start from a pre-trained model and derive a JPEG domain model from it. We call this model conversion and it basically means that you can get a model that operates on JPEG domain data without having to retrain anything.</p><p>While this gets us most of the way to a JPEG domain ResNet, there is still one big piece missing: ReLU [4].</p><h3>The ReLU Problem</h3><p>CNNs are inherently non-linear which is what allows them to learn such complex mappings. In modern architectures, ReLU is almost exclusively used to introduce non-linearity. The previous analysis only works for linear functions, so we need to rely on an approximation technique.</p><p>Recall that ReLU is defined as</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/299/0*8VJvSBD-g5rMUd5F" /></figure><p>setting all negative values to zero. This can instead be accomplished with a binary mask defined as</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/279/0*bqFDhapmoxeYJrtH" /></figure><p>which is then multiplied with the original feature map. The advantage of this is that it’s a lot easier to approximate the mask than it is to approximate the ReLU itself (see figure below).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/483/1*R-a7SUUqx0oqs4F9r-auZA.png" /><figcaption>Example blocks from our approximation technique. Green indicates negative values, red indicates positive values, blue indicates zero values. Image by author.</figcaption></figure><p>We compute the approximate mask using a subset of the DCT coefficients from each JPEG block. By only using a subset of the coefficients, we still have higher throughput than doing a full decompression.</p><p>The most interesting part of this by far is the method we came up with for applying the mask, which is a pixel mask, to DCT coefficients, and this is a direct result of the JPEG linearity we discussed in the previous section. For this part, we can use the DCT tensor <em>D </em>since we don’t have to worry about cross-block interactions. We will operate with a DCT block <em>F </em>its pixel domain block <em>I, </em>and the mask <em>G.</em></p><p>If we were to do this naively, we would:</p><ol><li>Decompress the image</li><li>Pixelwise multiply the mask</li><li>Recompress the image</li></ol><p>All of which are either linear or bilinear maps:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/192/0*xvgbStoRPxlmk7L7" /></figure><p>so we can multiply these steps out to get a single bilinear map which does all three steps:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/347/0*IJUpDZftdQ66zQB7" /></figure><p>We can then make the following definition:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/483/0*F8Fqe2YG5gPC2DeE" /></figure><p>and <em>H </em>is a bilinear map which applies the pixel mask to DCT coefficients. This operation is a little more involved than the previous ones, and the full details are in Section 4.2 of the paper.</p><h3>Results</h3><p>So how does all of this work? Fairly well actually. We tested this technique on MNIST [5] and CIFAR [6]. Here’s the toy network we used:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/513/1*n9ciKCJU1ztJCDGOXIBbrw.png" /><figcaption>Toy network structure. Image by author.</figcaption></figure><p>which is basically a tiny ResNet [3].</p><p>The first interesting thing to talk about is the accuracy of the approximation. We can start by noting that if you do no approximation at all (e.g., by using all spatial frequencies to compute the mask something which is quite slow) we match the pixel domain network to within a floating point error. When we start approximating the ReLU, we get the following accuracy, comparing the naive method (APX) with our method (ASM):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ORJ-gWKHFFE_B4GBhj1VVQ.png" /><figcaption><strong>Left:</strong> RMSE for individual 8 by 8 blocks. <strong>Middle:</strong> network accuracy after model conversion. <strong>Right:</strong> network accuracy with retraining. Image by author.</figcaption></figure><p>Even with fewer frequencies used for the reconstruction, our method does quite well especially when retraining.</p><p>The next thing to look at is throughput. Our goal was to make a network that runs faster because it doesn’t need to decompress anything, did we succeed? Sort of:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MyN3zrmDjk9q0m9iFU_tvQ.png" /><figcaption>Throughput results. Image by author.</figcaption></figure><p>We can see that JPEG training is a tiny bit faster, while JPEG inference is almost 4 times faster, a great improvement. So why is training slower? Not only does inference allow us to precompute some of the maps we need offline, but the backward pass of the JPEG training is significantly more complex because it needs gradients of the JPEG compression and decompression tensors.</p><h3>Further Advances</h3><p>While my paper was neat, there were some other great advances in 2019 for this kind of work. First, we should talk about the major drawback of my method: the weights are significantly larger than in a traditional CNN. So much so, that it is essentially impossible to apply this to a “real” architecture or to a dataset like ImageNet for example. Weights for the method presented here have size in O(HW) vs the nice O(1) weights in a traditional CNN. I did come up with an extension of this work that has O(1) weights but this hasn’t been published and there is significant memory overhead still. One of the goals of this method was to get as close as possible to the pixel domain operations, which is why we only used one approximation. If you relax this constraint, there are some really interesting things you can do. There are now three other foundational techniques in this area which have been developed.</p><p><strong>Do Nothing </strong>Probably the most well known is by <a href="https://papers.nips.cc/paper/7649-faster-neural-networks-straight-from-jpeg">Gueguen et al.</a> [7] and which basically says “hand the ResNet DCT coefficients with no modification to the network structure”. It turns out that this works with only a mild accuracy penalty and you can remove initial layers from the ResNet to get high throughput, but it doesn’t seem to work outside of whole-image classification (e.g., detection, segmentation, etc don’t work well with this).</p><p><strong>Block Representation </strong>The next technique exploits the DCT block structure by defining a <a href="https://arxiv.org/abs/1904.08408">“block representation”</a> [8] for each of the DCT blocks. They do this by using an 8 by 8 stride-8 convolution. This gives an image which is one eighth the size in each dimension. They used this idea for object detection.</p><p><strong>Frequency Coefficient Rearrangement</strong> The final technique exploits the frequency <a href="https://dl.acm.org/doi/abs/10.1145/3338533.3366557?casa_token=ituStLLbGcwAAAAA:wWLarXh94TGd7iFPabG-yaAMe1-MBN-xGI0Z7XHSaYFIywOcya-t3UwflZQY3ST5nS7RyLiHxeciX58">structure of the coefficients</a> [9]. They do this by rearranging the frequencies to be channel-wise. So again, you end up with an image which is one eighth the size in each dimension, this time with 64 channels. They used this idea for semantic segmentation.</p><p>Overall it’s been exciting to watch this field develop. I think this is really important and really interesting, so I’m always encouraging people to get involved. JPEG files are everywhere, so there is no shortage of applications for this kind of math. As another example at ECCV 2020, I used both of the last two techniques to achieve state-of-the-art in JPEG artifact correction [10].</p><h4>References</h4><ol><li>M. Ehrlich and L. Davis, <a href="https://arxiv.org/abs/1812.11690">Deep Residual Learning in the JPEG Transform Domain</a> (2019), In: Proceedings of the International Conference on Computer Vision.</li><li>B. Smith, <a href="https://dl.acm.org/doi/10.1145/192593.192628">Fast software processing of motion JPEG video</a> (1994), In: Proceedings of the Second ACM International Conference on Multimedia.</li><li>K. He et al., <a href="https://arxiv.org/abs/1512.03385">Deep residual learning for image recognition</a> (2016), In: Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition.</li><li>V. Nair and G. Hinton, <a href="https://www.cs.toronto.edu/~hinton/absps/reluICML.pdf">Rectified linear units improve restricted boltzmann machines</a> (2010), International Conference on Machine Learning.</li><li>Y. LeCun, <a href="http://yann.lecun.com/exdb/mnist/">The MNIST database of handwritten digits</a></li><li>A. Krizhevsky and G. Hinton, <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.222.9220&amp;rep=rep1&amp;type=pdf">Learning multiple layers of features from tiny images</a> (2009)</li><li>L. Gueguen et al., <a href="https://papers.nips.cc/paper/2018/hash/7af6266cc52234b5aa339b16695f7fc4-Abstract.html">Faster neural networks straight from jpeg</a> (2018) Advances in Neural Information Processing Systems.</li><li>B. Deguerre et al., <a href="https://arxiv.org/abs/1904.08408">Fast object detection in compressed jpeg images</a> (2019),<em> </em>IEEE Intelligent Transportation Systems Conference.</li><li>SY. Lo and H. Hsueh-Ming, <a href="https://arxiv.org/abs/1907.10015">Exploring semantic segmentation on the DCT representation</a> (2019) Proceedings of the ACM Multimedia Asia.</li><li>M. Ehrlich et al., <a href="https://arxiv.org/abs/2004.09320">Quantization Guided JPEG Artifact Correction</a> (2020) Proceedings of the European Conference on Computer Vision.</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=51458fe2e6e4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/revisiting-dct-domain-deep-learning-51458fe2e6e4">Revisiting DCT Domain Deep Learning</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>