<?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 Heet Sankesara on Medium]]></title>
        <description><![CDATA[Stories by Heet Sankesara on Medium]]></description>
        <link>https://medium.com/@heetsankesara3?source=rss-9266f4b8f4c4------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*sLRHOT9IyW1Coo4fRTEtqw.jpeg</url>
            <title>Stories by Heet Sankesara on Medium</title>
            <link>https://medium.com/@heetsankesara3?source=rss-9266f4b8f4c4------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 28 May 2026 00:33:14 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@heetsankesara3/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[U-Net]]></title>
            <link>https://medium.com/data-science/u-net-b229b32b4a71?source=rss-9266f4b8f4c4------2</link>
            <guid isPermaLink="false">https://medium.com/p/b229b32b4a71</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[computer-vision]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[pytorch]]></category>
            <category><![CDATA[image-segmentation]]></category>
            <dc:creator><![CDATA[Heet Sankesara]]></dc:creator>
            <pubDate>Wed, 23 Jan 2019 06:08:44 GMT</pubDate>
            <atom:updated>2019-01-23T15:01:54.031Z</atom:updated>
            <content:encoded><![CDATA[<h3>UNet</h3><h4>Introducing Symmetry in Segmentation</h4><h3>Introduction</h3><p>Vision is one of the most important senses humans possess. But have you ever wondered about the complexity of the task? The ability to capture the reflected light rays and get meaning out of it is a very convoluted task and yet we do it so easily. We developed it due to millions of years of evolution. So how can we give machines the same ability in a very small period of time? For computers, these images are nothing but matrices and understanding the nuances behind these matrices has been an obsession for many mathematicians for years. But after the emergence of artificial intelligence and particularly CNN architectures, the research has made progress like never before. Many problems which are previously considered untouchable are now showing astounding results.</p><p>One such problem is the image segmentation. In Image Segmentation, the machine has to partition the image into different segments, each of them representing a different entity.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*Swzo18J0T70FxFgFklOtjQ.jpeg" /><figcaption>Image Segmentation Example</figcaption></figure><p>As you can see above, how the image turned into two segments, one represents the cat and the other background. Image segmentation is useful in many fields from self-driving cars to satellites. Perhaps the most important of them all is medical imaging. The subtleties in medical images are quite complex and sometimes even challenging for trained physicians. A machine that can understand these nuances and can identify necessary areas can make a profound impact in medical care.</p><p>Convolutional Neural Networks gave decent results in easier image segmentation problems but it hasn&#39;t made any good progress on complex ones. That’s where UNet comes in the picture. UNet was first designed especially for medical image segmentation. It showed such good results that it used in many other fields after. In this article, we’ll talk about why and how UNet works. If you don’t know intuition behind CNN, please read <a href="https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/">this</a> first. You can check out UNet in action <a href="https://www.kaggle.com/hsankesara/unet-image-segmentation">here</a>.</p><h3>The Intuition Behind UNet</h3><p>The main idea behind CNN is to learn the feature mapping of an image and exploit it to make more nuanced feature mapping. This works well in classification problems as the image is converted into a vector which used further for classification. But in image segmentation, we not only need to convert feature map into a vector but also reconstruct an image from this vector. This is a mammoth task because it’s a lot tougher to convert a vector into an image than vice versa. The whole idea of UNet is revolved around this problem.</p><p>While converting an image into a vector, we already learned the feature mapping of the image so why not use the same mapping to convert it again to image. This is the recipe behind UNet. Use the same feature maps that are used for contraction to expand a vector to a segmented image. This would preserve the structural integrity of the image which would reduce distortion enormously. Let’s understand the architecture more briefly.</p><h3>UNet Architecture</h3><h4>How UNet Works</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lvXoKMHoPJMKpKK7keZMEA.png" /><figcaption>UNet Architecture</figcaption></figure><p>The architecture looks like a ‘U’ which justifies its name. This architecture consists of three sections: The contraction, The bottleneck, and the expansion section. The contraction section is made of many contraction blocks. Each block takes an input applies two 3X3 convolution layers followed by a 2X2 max pooling. The number of kernels or feature maps after each block doubles so that architecture can learn the complex structures effectively. The bottommost layer mediates between the contraction layer and the expansion layer. It uses two 3X3 CNN layers followed by 2X2 up convolution layer.</p><p>But the heart of this architecture lies in the expansion section. Similar to contraction layer, it also consists of several expansion blocks. Each block passes the input to two 3X3 CNN layers followed by a 2X2 upsampling layer. Also after each block number of feature maps used by convolutional layer get half to maintain symmetry. However, every time the input is also get appended by feature maps of the corresponding contraction layer. This action would ensure that the features that are learned while contracting the image will be used to reconstruct it. The number of expansion blocks is as same as the number of contraction block. After that, the resultant mapping passes through another 3X3 CNN layer with the number of feature maps equal to the number of segments desired.</p><h4>Loss calculation in UNet</h4><p>What kind of loss one would use in such an intrinsic image segmentation? Well, it is defined simply in the paper itself.</p><blockquote>The energy function is computed by a pixel-wise soft-max over the final feature map combined with the cross-entropy loss function</blockquote><p>UNet uses a rather novel loss weighting scheme for each <strong>pixel </strong>such that there is a higher weight at the border of segmented objects. This loss weighting scheme helped the U-Net model segment cells in biomedical images in a <em>discontinuous fashion</em> such that individual cells may be easily identified within the binary segmentation map.</p><p>First of all pixel-wise softmax applied on the resultant image which is followed by cross-entropy loss function. So we are classifying each pixel into one of the classes. The idea is that even in segmentation every pixel have to lie in some category and we just need to make sure that they do. So we just converted a segmentation problem into a multiclass classification one and it performed very well as compared to the traditional loss functions.</p><h3>UNet Implementation</h3><p>I implemented the UNet model using Pytorch framework. You can check out the UNet module <a href="https://github.com/Hsankesara/DeepResearch"><em>here</em></a>. Images for segmentation of optical coherence tomography images with diabetic macular edema are used. You can checkout UNet in action <a href="https://www.kaggle.com/hsankesara/unet-image-segmentation">here</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c862cc68c602a368ec45012a01baf2ff/href">https://medium.com/media/c862cc68c602a368ec45012a01baf2ff/href</a></iframe><p>The UNet module in the above code represents the whole architecture of UNet. contraction_block and expansive_block are used to create the contraction section and the expansion section respectively. The function crop_and_concat appends the output of contraction layer with the new expansion layer input. The training part can be written as</p><pre>unet = Unet(in_channel=1,out_channel=2)<br>#out_channel represents number of segments desired<br>criterion = torch.nn.CrossEntropyLoss()<br>optimizer = torch.optim.SGD(unet.parameters(), lr = 0.01, momentum=0.99)<br>optimizer.zero_grad()       <br>outputs = unet(inputs)<br># permute such that number of desired segments would be on 4th dimension<br>outputs = outputs.permute(0, 2, 3, 1)<br>m = outputs.shape[0]<br># Resizing the outputs and label to caculate pixel wise softmax loss<br>outputs = outputs.resize(m*width_out*height_out, 2)<br>labels = labels.resize(m*width_out*height_out)<br>loss = criterion(outputs, labels)<br>loss.backward()<br>optimizer.step()</pre><h3>Conclusion</h3><p>Image segmentation is an important problem and every day some new research papers are published. UNet contributed significantly in such research. Many new architectures are inspired by UNet. But still, there is so much to explore. There are so many variants of this architecture in the industry and hence it is necessary to understand the first one to understand them better. So if you have any doubts please comment below or refer to the resources page.</p><h3>Resources</h3><ul><li><a href="https://arxiv.org/pdf/1505.04597.pdf">UNet original paper</a></li><li><a href="https://github.com/Hsankesara/DeepResearch/tree/master/UNet">UNet Pytorch implementation</a></li><li><a href="https://github.com/jakeret/tf_unet">UNet Tensorflow implementation</a></li><li><a href="https://www.jeremyjordan.me/semantic-segmentation/">More about Semantic Segmentation</a></li><li><a href="https://tuatini.me/practical-image-segmentation-with-unet/">Practical Image Segmentation</a></li></ul><h3>Author’s Note</h3><p>This tutorial is the second article in my series of <a href="https://github.com/Hsankesara/DeepResearch">DeepResearch</a> articles. If you like this tutorial please let me know in comments and if you don’t please let me know in comments more briefly. If you have any doubts or any criticism just flood the comments with it. I’ll reply as soon as I can. If you like this tutorial please share it with your peers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b229b32b4a71" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/u-net-b229b32b4a71">U-Net</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[Hierarchical Attention Networks]]></title>
            <link>https://medium.com/analytics-vidhya/hierarchical-attention-networks-d220318cf87e?source=rss-9266f4b8f4c4------2</link>
            <guid isPermaLink="false">https://medium.com/p/d220318cf87e</guid>
            <category><![CDATA[nlp]]></category>
            <category><![CDATA[paper]]></category>
            <category><![CDATA[classification]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[text]]></category>
            <dc:creator><![CDATA[Heet Sankesara]]></dc:creator>
            <pubDate>Fri, 24 Aug 2018 05:34:31 GMT</pubDate>
            <atom:updated>2018-08-24T18:41:04.791Z</atom:updated>
            <content:encoded><![CDATA[<h4>The most human way to classify text</h4><h4>What’s all this hype about text classification?</h4><p>Since the uprising of Artificial Intelligence, text classification has become one of the most staggering tasks to accomplish. In layman terms, We can say Artificial Intelligence is the field which tries to achieve human-like intelligent models to ease the jobs for all of us. We have an astounding proficiency in text classification but even many sophisticated NLP models are failed to achieve proficiency even close to it. So the question arises is that what we humans do differently? How do we classify text?</p><p>First of all, we understand words not each and every word but many of them and we can guess even unknown words just by the structure of a sentence. Then we understand the message that those series of words (sentence) conveys. Then from those series of sentences, we understand the meaning of a paragraph or an article. The similar approach is used in Hierarchical Attention model.</p><h4>So what’s so special about this hierarchical thing?</h4><p>Well to put it in a “too complicated to comprehend even for a techie” way, It uses stacked recurrent neural networks on word level followed by attention model to extract such words that are important to the meaning of the sentence and aggregate the representation of those informative words to form a sentence vector. Then the same procedure applied to the derived sentence vectors which then generate a vector who conceives the meaning of the given document and that vector can be passed further for text classification.</p><h4>Wait….What?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/852/1*28XVtq2lOjOmZhcSgu1NmQ.png" /><figcaption>HAN Structure</figcaption></figure><p>The idea behind the paper is “Words make sentences and sentences make documents”. The intent is to derive sentence meaning from the words and then derive the meaning of the document from those sentences. But not all words are equally important. Some of them characterize a sentence more than others. Therefore we use the attention model so that sentence vector can have more attention on “important” words. Attention model consists of two parts: Bidirectional RNN and Attention networks. While bidirectional RNN learns the meaning behind those sequence of words and returns vector corresponding to each word, Attention network gets weights corresponding to each word vector using its own shallow neural network. Then it aggregates the representation of those words to form a sentence vector i.e it calculates the weighted sum of every vector. This weighted sum embodies the whole sentence. The same procedure applies to sentence vectors so that the final vector embodies the gist of the whole document. Since it has two levels of attention model, therefore, it is called hierarchical attention networks.</p><h4>Enough talking… just show me the code</h4><p>We used <a href="https://www.kaggle.com/rmisra/news-category-dataset">News category Dataset</a> to classify news category. you can see the whole implementation <a href="https://www.kaggle.com/hsankesara/news-classification-using-han/notebook">here</a>. Now the first question comes in mind is what the hell is attention?</p><h4>Attention Model</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ABkaR2glZNP6oh08oY4l-Q.png" /></figure><p>The vectors from Bidirectional RNN pass through shallow neural network to decide weight corresponding to each vector. The weighted sum of each vector embodies the meaning of those vectors combined. To understand it more briefly just go to the <a href="https://github.com/Hsankesara/DeepResearch/blob/master/Hierarchical_Attention_Network/attention_with_context.py">code</a>.</p><p><strong>Data preprocessing</strong></p><p>To process the data we need to convert it into a suitable form.</p><pre>tokenizer = Tokenizer(num_words=max_features, oov_token=True)<br>tokenizer.fit_on_texts(texts)<br>data = np.zeros((len(texts), max_senten_num, max_senten_len), dtype=&#39;int32&#39;)<br>for i, sentences in enumerate(paras):<br>    for j, sent in enumerate(sentences):<br>        if j&lt; max_senten_num:<br>            wordTokens = text_to_word_sequence(sent)<br>            k=0<br>            for _, word in enumerate(wordTokens):<br>                try:<br>                    if k&lt;max_senten_len and tokenizer.word_index[word]&lt;max_features:<br>                        data[i,j,k] = tokenizer.word_index[word]<br>                        k=k+1<br>                except:<br>                    print(word)<br>                    pass</pre><p>We used the above code to convert training dataset to 3 dimension array: the first dimension represents the total number of documents, the second one represents each sentence in a document and the last one represents each word in a sentence. However, We have to set some upper limit in order to create a static graph which in this case are max_senten_len(max number of the sentence in a paragraph), max_senten_num(max number of words in a sentence) and max_features(max number of words Tokenizer can have).</p><p>Now isn’t it unfair to the model if we randomly initialize all the words? Hence we use <a href="https://nlp.stanford.edu/projects/glove/">trained embedded vectors</a> which give the model an extra edge in the terms of performance and yields better results.</p><pre>GLOVE_DIR = &quot;../input/glove6b/glove.6B.100d.txt&quot;<br>embeddings_index = {}<br>f = open(GLOVE_DIR)<br>for line in f:<br>    try:<br>        values = line.split()<br>        word = values[0]<br>        coefs = np.asarray(values[1:], dtype=&#39;float32&#39;)<br>        embeddings_index[word] = coefs<br>    except:<br>        print(word)<br>        pass<br>f.close()<br>embedding_matrix = np.zeros((len(word_index) + 1, embed_size))<br>absent_words = 0<br>for word, i in word_index.items():<br>    embedding_vector = embeddings_index.get(word)<br>    if embedding_vector is not None:<br>        # words not found in embedding index will be all-zeros.<br>        embedding_matrix[i] = embedding_vector<br>    else:<br>        absent_words += 1<br>print(&#39;Total absent words are&#39;, absent_words, &#39;which is&#39;, &quot;%0.2f&quot; % (absent_words * 100 / len(word_index)), &#39;% of total words&#39;)</pre><p>We replaced the known words with their corresponding vector in embedding_matrix. Indeed, some words will be missing but our model has to learn to cope up with that.</p><h4>Now time for HAN model</h4><pre>embedding_layer = Embedding(len(word_index) + 1,embed_size,weights=[embedding_matrix], input_length=max_senten_len, trainable=False)</pre><pre># Words level attention model<br>word_input = Input(shape=(max_senten_len,), dtype=&#39;float32&#39;)<br>word_sequences = embedding_layer(word_input)<br>word_lstm = Bidirectional(LSTM(150, return_sequences=True, kernel_regularizer=l2_reg))(word_sequences)<br>word_dense = TimeDistributed(Dense(200, kernel_regularizer=l2_reg))(word_lstm)<br>word_att = AttentionWithContext()(word_dense)<br>wordEncoder = Model(word_input, word_att)</pre><pre># Sentence level attention model<br>sent_input = Input(shape=(max_senten_num, max_senten_len), dtype=&#39;float32&#39;)<br>sent_encoder = TimeDistributed(wordEncoder)(sent_input)<br>sent_lstm = Bidirectional(LSTM(150, return_sequences=True, kernel_regularizer=l2_reg))(sent_encoder)<br>sent_dense = TimeDistributed(Dense(200, kernel_regularizer=l2_reg))(sent_lstm)<br>sent_att = Dropout(0.5)(AttentionWithContext()(sent_dense))<br>preds = Dense(30, activation=&#39;softmax&#39;)(sent_att)<br>model = Model(sent_input, preds)<br>model.compile(loss=&#39;categorical_crossentropy&#39;,optimizer=&#39;adam&#39;,metrics=[&#39;acc&#39;])</pre><p>For word2vec, we used Keras <a href="https://keras.io/layers/embeddings/">Embedding</a> layer. <a href="https://keras.io/layers/wrappers/">TimeDistributed</a> method is used to apply a Dense layer to each of the time-steps independently. We used Dropout and l2_reg regularizers to reduce overfitting.</p><h4>Conclusion</h4><p>You must be very much impressed or very much confused by now. Sometimes these things can go over the head but text classification is a trending field and despite the many new and prolific researches the scope of improvement is so much. So do not despair only now because you’ll have many more disappointments later 😅 . Just kidding if you have any doubts please comment below or refer to the resources page.</p><h4>Resources</h4><ol><li>Go <a href="https://github.com/Hsankesara/DeepResearch/tree/master/Hierarchical_Attention_Network">here</a> to checkout code.</li><li>Go <a href="https://www.kaggle.com/hsankesara/news-classification-using-han/notebook">here</a> to checkout implementation.</li><li><a href="https://www.ncbi.nlm.nih.gov/pubmed/29155996">Hierarchical attention networks for information extraction from cancer pathology reports.</a></li><li><a href="http://www.cs.cmu.edu/~./hovy/papers/16HLT-hierarchical-attention-networks.pdf">Hierarchical Attention Networks for Document Classification</a></li></ol><h3>Author’s Note</h3><p>This tutorial is the first article in my series of <a href="https://github.com/Hsankesara/DeepResearch">DeepResearch</a> articles. If you like this tutorial please let me know in comments and if you don’t please let me know in comments more briefly. If you have any doubts or any criticism just flood the comments with it. I’ll will reply as soon as I can. If you like this tutorial please share it with your peers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d220318cf87e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/analytics-vidhya/hierarchical-attention-networks-d220318cf87e">Hierarchical Attention Networks</a> was originally published in <a href="https://medium.com/analytics-vidhya">Analytics Vidhya</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>