<?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 David Lourenço Mestre on Medium]]></title>
        <description><![CDATA[Stories by David Lourenço Mestre on Medium]]></description>
        <link>https://medium.com/@davidlourenomestre?source=rss-c05b7f87e9ec------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*isdcN6q5PklJMFo4.</url>
            <title>Stories by David Lourenço Mestre on Medium</title>
            <link>https://medium.com/@davidlourenomestre?source=rss-c05b7f87e9ec------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 21 May 2026 11:39:59 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@davidlourenomestre/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[The Trials and Tribulations of Automating Colour Classification]]></title>
            <link>https://medium.com/empathyco/the-trials-and-tribulations-of-automating-colour-classification-ed3d3a750740?source=rss-c05b7f87e9ec------2</link>
            <guid isPermaLink="false">https://medium.com/p/ed3d3a750740</guid>
            <category><![CDATA[rgb]]></category>
            <category><![CDATA[k-means]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[David Lourenço Mestre]]></dc:creator>
            <pubDate>Wed, 29 May 2019 09:39:52 GMT</pubDate>
            <atom:updated>2019-05-29T09:39:52.086Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xLLxmzyfM3rguaojMHRnKg.png" /></figure><h3>Introduction</h3><p>One of the growing trends in the search industry is the use of machine learning techniques to fill gaps in manually curated merchant catalogues by incorporating information using, for example, computer vision or natural language processing algorithms.</p><p>Within the search space, fashion catalogues are often large, with thousands or even tens of thousands of products. These catalogues have the natural gaps and inconsistencies that result from the manual curation of such a large number of items. At the same time fashion is in essence something deeply visual, so it is an excellent playground for computer vision algorithms.</p><p>One of the limitations often encountered is colour classification: catalogue labels for colours can often be inconsistent or lacking due to the different copy systems and responsibilities employed when building the catalogue. Here at empathy.co, to overcome this issue, we have devised an automatic process to assign consistent colour labels that can be used to complement merchant catalogues.</p><p>In this article, we’ll consider the different challenges when building an automatic colour extraction tool: the options available to build such a tool, how to keep the time it takes to process each image within an acceptable time frame, how subjective and nebulous colour naming might be, and so on.</p><h3>Where to start</h3><p>Our first attempt to automate colour extraction was to design a full-fledged neural network. While it was successful with single colour clothing articles, we quickly found out that articles with multiple colours were leading to ambiguous results. Improving the neural network would mean going down the rabbit hole of creating and curating a new training dataset to improve the results. Easily months of work!</p><p>We decided instead to opt for what initially looked like a less fancy strategy, but one that was informed by the different steps involved in deriving the desired colour classification: We’re not interested in the whole image, just in the foreground and the pixels that compose the main object (1). We’re not interested in the complete list of colours in the image, just a broad range of palettes (2). And, we wanted a name for each one of those broad RGB sections (3).</p><p>Finally, we were looking for a method that would work out-of-the-box for a variety of different circumstances; a fairly complex background or a neutral background, a white foreground on a darker background, or a foreground composed by black and white segments over different types of backgrounds.</p><p><strong>Background rejection: Grab Cut</strong></p><p>Initially we started working with lighter methods: threshold, otsu, gradients. And since we’re pretty nerdy when it comes to deep learning, we also tried mask rcnn. Some of the methods didn’t fare well when some conditions involving the relation between the background and the foreground weren’t met, while others such as mask rcnn were too slow. We ended up working with a method based on graph cut: grab cut.</p><p>Why grab cut? Isn’t it an interactive algorithm? Yes, but we made the assumption that the targeted object would be in the middle of the image, and by running a first pass we can identify the most likely position where the object might stand, and get a rectangle that contains the object.</p><p>Once having that box we can classify all the pixels outside of it as background, just like a user of grab cut would set certain hard constraints for segmentation by indicating some pixels as part of the background. That way we give the seeds for what will be background and foreground to the algorithm.</p><p>Once we have completed this step, the grab cut algorithm does an initial prediction for the labels of the other pixels in the image: it basically goes through each pixel without a label and estimates if they belong into the foreground or background.</p><p>The idea behind grab cuts is that image segmentation is akin to energy minimisation, and the minimum of that energy function should correspond to a good segmentation.</p><p>The image segmentation is defined as a cost function that sums up two terms. The first term is the cost of assigning each pixel as foreground or background based on how well each pixel fits on the gaussian mixture models for each label. The second enforces similar and neighbouring pixels to share the same region.</p><p>The process of minimisation works iteratively, and the process runs until it reaches convergence by running new estimations on the gaussian mixture models every cycle, being that new estimations should reflect the new refined background and foreground distributions.</p><p>Once the process stops, we have a binary mask with the same shape as the image parsed with grab cut.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*nT8nsjigvtYiR1lf" /></figure><p><strong>Clustering</strong></p><p>At this point our image is represented as an array with shape (N, 3), with N the number of foreground pixels, and each pixel having a 3-channel RGB vector. Since we might have thousands of colours we need to run a method to reduce and find the dominant RGBs. For example, let’s consider a red and green shirt, for a human eye it will look like two clear and unambiguous colours. However, at the pixel level we do not have just two RGBs, but two clouds with a high level of variance, large sets of shades of red and green. Since we do not have any ground truth classes, we cluster pixels together based on how similar they are.</p><p>We opted to work with k-means, being one of the most popular and efficient clustering algorithms. For k-means, a cluster is characterised by a centre that is the arithmetic mean of all the points on the cluster. Each point in the cluster is closer to its own centre than to other clusters’ centres. K-means requires a notion of distance between data points, for that we have used the Euclidean distance between RGBs.</p><p>The main limitation of k-means clustering is that it provides a fixed number of clusters. There are some methods to determine the ideal number of clusters in the data, but none of those can in the end guarantee that the number of clusters will match the number of distinct colours in the image.</p><p>In the end, we decided to use a fixed number of clusters and remove the possible extra clusters by running a later stage algorithm to identify similar RGBs. If we find that the difference between two RGBs is below a specific threshold, we assume both values to be the same colour with an RGB value as the weighted arithmetic mean.</p><p>To do this latter processing, we needed to know how to parse RGB information. More on that in the next section…</p><p><strong>Colour Naming</strong></p><p>This is perhaps the trickiest step in the process, not necessarily technically speaking, but for its implicit subjective nature. Colour naming is not a trivial subject as it’s a matter of human perception, and not a physical property like temperature or pressure. When classifying RGB values we frequently found ourselves scratching our heads and asking if a value that we were analysing was red or orange, blue or navy, pink or beige.</p><p>Our plan was to create a list of pre-classified RGBs, and find the closest colour for the RGB under consideration.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*gqFSmfxyZezLWY1R57BFFg.png" /></figure><p>Our first approach was to employ Euclidean distance. Quickly we found out that we were on shaky grounds: the RGB colour space doesn’t represent how we humans perceive the colour, since <a href="https://en.wikipedia.org/wiki/RGB_color_space">it isn’t perceptually uniform</a>. A change in the same amount in a colour value doesn’t necessarily imply a change of the same magnitude on the visual perception (Figure 1).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XLa8mpj_mOOZ-m_kDe5VFw.png" /><figcaption><em>Figure 1. Euclidean distance for the RGBs [245, 0, 0], [160, 40, 0], and [90, 100, 10]. Some shades of red are closer to green than to other reds, making the Euclidean distance inadequate to properly identify colour.</em></figcaption></figure><p>We needed a way to identify similar colours, and for that having a perceptually uniform colour space was crucial. In this colour space, equal steps in delta between RGBs should be perceived as equal steps in a colour map. We opted to work with the <a href="https://en.wikipedia.org/wiki/CIELAB_color_space">CIELAB</a> (<a href="https://zschuessler.github.io/DeltaE/learn/#toc-delta-e-2000">CIE2000</a>) colour space. The CIELAB colour space provides a mathematical interpretation of the visible spectrum strongly correlated with the human visual system, and a revised version of the Euclidean distance: Delta E (Figure 2).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gd_Ti3CrG6cT2RT3kxrQcQ.png" /><figcaption><em>Figure 2. CIELAB 2000 Delta E Distance for the RGBs [245, 0, 0], [160, 40, 0], and [90, 100, 10]. Now the shades of red are closer and distance to green is larger.</em></figcaption></figure><p>Having a robust method for quantitative colour comparison provides the foundations for naming the colour of a RGB value. Our strategy is to translate the RGBs into LAB values, and apply the Delta E against a pre-classified list of colours, the closest one resulting in the desired colour label.</p><p>The same CIELAB Delta E can be applied in the previous step to remove extra clustering data, since it also involves comparing RGB values and quantifying the difference to remove clusters that will result in the same or a very similar perceived colour.</p><p><strong>Results</strong></p><p>Here are a few examples of fashion images that have been run through our classification pipeline, together with the final results — an RGB average value, a colour label and the relative weight for each dominant colour cluster that has been identified.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*L-PhUT-2JAS3l22Ee7XAOQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qfW6hA3DIJOTzEvk_8EK-g.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LAiwLysDy3GNP_dSikDgIQ.png" /></figure><h3>Conclusion</h3><p>By splitting the colour classification problem into a few basic steps, leveraging machine learning methods and complementing it with basic colour perception theory, we’ve been able to devise a process that can be used to quickly, and robustly, attach colour labels to fashion images.</p><p>In our internal testing, this piecemeal approach fares much better than more straight-forward deep learning classifiers. Which goes to show how, in many cases, applying domain model expertise allows us to maximise the benefit of machine learning algorithms.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ed3d3a750740" width="1" height="1" alt=""><hr><p><a href="https://medium.com/empathyco/the-trials-and-tribulations-of-automating-colour-classification-ed3d3a750740">The Trials and Tribulations of Automating Colour Classification</a> was originally published in <a href="https://medium.com/empathyco">Empathy.co</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Machine Learning Model Evaluation and Hyper-Parameter Tuning: Looking Beyond Accuracy]]></title>
            <link>https://medium.com/empathyco/machine-learning-model-evaluation-and-hyper-parameter-tuning-looking-beyond-accuracy-e50ff1852250?source=rss-c05b7f87e9ec------2</link>
            <guid isPermaLink="false">https://medium.com/p/e50ff1852250</guid>
            <category><![CDATA[hyperparameter-tuning]]></category>
            <category><![CDATA[model-evaluation]]></category>
            <category><![CDATA[bias-variance-tradeoff]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[k-fold]]></category>
            <dc:creator><![CDATA[David Lourenço Mestre]]></dc:creator>
            <pubDate>Fri, 22 Mar 2019 10:56:45 GMT</pubDate>
            <atom:updated>2019-03-22T10:56:45.669Z</atom:updated>
            <content:encoded><![CDATA[<p>Last month, we discussed the impact of <a href="https://medium.com/empathybroker/gradient-descent-an-algorithm-for-deep-learning-optimisation-74aa8ebf8de2">gradient descent on deep learning optimisation</a> and reviewed the importance of optimising the cost function. In this post, we will be exploring in detail how to evaluate model results, as well as best practice for optimising hyper-parameters.</p><p>To do this, we will be building a model for image recognition. We will show how to compute metrics to assess the quality of the model and some optimisation techniques for hyper-parameters.</p><h3><strong>Model Evaluation</strong></h3><p>Just like a student revising for an exam, your machine learning model will have to go through a process of learning and training before being ready to complete its intended task. This training will enable it to generalise and derive patterns from actual data, but how can we assess whether or not our model provides a good representation of our data? How can we validate the model and predict how it will perform with data it hasn’t seen before?</p><p>When assessing a data model, accuracy is the most frequently used metric. It gives a general understanding of how many data samples are misclassified, however this information can be deceptive and can give us a false sense of security.</p><p>Normally, you’d split your data into a training set and a test set. You’d train the model on the training set, and would measure accuracy while testing the model on the test set. This is the fastest way to evaluate the model’s performance, but it’s not the best one.</p><p><strong>Bias-variance tradeoff</strong></p><p>Although there are many different metrics that can be used to measure a model’s performance, keeping bias and variance low is always essential. We define bias as any systematic difference between the output of our model and the ‘true’ value. Variance refers to the model’s statistical limit (see figure for illustration).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/732/1*qwQVirKWFcG7OaiV_eAFcA.png" /><figcaption><em>Mastering Machine Learning with scikit-learn, pg. 14</em></figcaption></figure><p>So, in which situations will we have to combat high bias or high variance?</p><p>If the model is overtrained, or too complex for a given training dataset, it will memorise patterns and even the input noise. In such situations, we will have high variance (overfitting) and the model will perform poorly with unseen data.</p><p>In the opposite scenario, the model will perform poorly and produce similar errors on both training and testing data. In this situation, we will see high bias (underfitting). The model will be too inflexible and won’t have enough features to fully represent the data.</p><p>We ideally want to achieve both low bias and low variance. We are aiming for model predictions that are very close or identical to the values seen in the training data. Unfortunately, the efforts to reduce one often increases the other. We have to find a compromise. This balance between bias and variance is called the bias-variance tradeoff.</p><p>While it might not always be possible to find enough data to prevent overfitting, or to know exactly how complex a model should be, plotting the training and testing accuracies as functions of the number of training samples might help.</p><p><strong>K-fold cross-validation</strong></p><p>In this section, we will use Keras to wrap a neural network, and leverage on sklearn to run a K-fold cross validation. For the neural network, we will use LeNet architecture. It was one of the first prominent deep <a href="http://deeplearning.stanford.edu/tutorial/supervised/ConvolutionalNeuralNetwork/">convolutional architectures</a>, it’s fairly easy to code, and it’s not too computationally expensive. The architecture consists of two sets of convolutional and subsampling (also known as Pooling) layers, followed by a flattening convolutional layer, then two dense (fully connected) layers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EB8HBpeU_By0pYWXQsgsKQ.png" /><figcaption><em>Deep Learning with Keras, pg. 78</em></figcaption></figure><p>Before going through the code in detail, it may be useful to define what k-fold cross-validation is and why you should use it.</p><p>K-fold cross-validation is one of the most common methods for confirming an estimated hypothesis on data, and for assessing how accurately a model performs and its ability to generalise. In k-fold cross-validation, you randomly split the training data into ‘k’ equal-sized folds. In each iteration, one of the folds is used for performance evaluation, while the rest is used for training. This process is executed ‘k’ times so that we obtain ‘k’ models and performance estimates.</p><p>Statistically, the average performance measured over k-fold cross-validation gives a proper estimate of how well a model does its task in general.</p><p><strong>Cross-Validation Code</strong></p><p>First, we’ll import the data from Keras. As a training set, we will be using the <a href="https://research.zalando.com/welcome/mission/research-projects/fashion-mnist/">Fashion-MNIST dataset</a>. Fashion-MNIST is a dataset consisting of Zalando’s product images. It has a training set of 60,000 samples and a test set of 10,000 samples. Each image within these sets is 28 pixels by 28 pixels.</p><p>Before passing the data to our model, we must declare the number of channels (also known as the depth of the image) and reshape the samples to 60,000 x [1, 28, 28] to suit the convolutional requirements. Note that the dataset is composed of black and white images. For that reason, we have just one channel.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/36384c8ac4e536ceb6921b04021a94ea/href">https://medium.com/media/36384c8ac4e536ceb6921b04021a94ea/href</a></iframe><p>On the following step we define a class for the convolutional neural network (LeNet):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e2a653b1555cf2dc58bf10ac1eed3931/href">https://medium.com/media/e2a653b1555cf2dc58bf10ac1eed3931/href</a></iframe><p>To perform cross-validation, we will import the function ‘cross_val_score’ from Sklearn. This function takes the classifier, the samples (X), the labels (y), and the number of folds (cv) as inputs:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/33772f4514c65f1374a653ea211a771c/href">https://medium.com/media/33772f4514c65f1374a653ea211a771c/href</a></iframe><p>After running cross-validation, the function returns a list of accuracies for the five folds. In order to know how it performs on average, we look at the mean and the standard deviation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UCLBds6zAGGzF9fZWCWk9Q.png" /></figure><p>As a side note, this metric measures the percentage of data samples properly classified, or being more precise, a proportion of correct predictions with respect to the samples. In the background, Keras classifies each sample, yields a vector with the probability for each class, and selects the highest value as the model prediction. Finally Keras compares the prediction against the true value</p><p>After running cross-validation for 5 folds, and extracting the mean accuracy and the standard deviation, we have a more accurate assessment of the model’s performance and of how robust it is on average. We can see that the classifier achieves on average 90% accuracy. This value fluctuates from iteration to iteration with a standard deviation of roughly 0.4%. We can conclude that we have a low variance and a relatively low bias. Still, we encourage you to benchmark different CNN architectures with the Fashion-MNIST dataset: <a href="https://github.com/zalandoresearch/fashion-mnist#benchmark">https://github.com/zalandoresearch/fashion-mnist#benchmark</a></p><h3><strong>Hyper-Parameters Optimisation</strong></h3><p>When creating a neural network we have two types of parameters. There are the parameters that are learned during training, such as weights, and the parameters that will be hard-coded and optimised separately. This second class of parameters are called hyper-parameters. Examples being the dropout rate, learning rate, number of epochs, batch size, optimiser, number of layers, number of nodes, etc.</p><p>Fine-tuning the hyper-parameters might improve predictions, but there isn’t a rule that will tell you how many layers, the number of epochs, or the batch size to use on your neural network.</p><p>Finding an optimal solution (or even a sub-optimal solution) often involves repeatedly training different versions of a model to different sets of hyper-parameters. However, there are still a few techniques for hyper-parameter optimisation. One of the simplest is grid-search.</p><p><strong>Grid-Search</strong></p><p>Grid-Search is a popular method for identifying the best hyper-parameter set for a model. It’s a brute force search method that takes a set of possible values for each hyper-parameter we want to tune. The machine evaluates the performance for each combination. In the end, it will return the selection with the best performance.</p><p>It’s a time-consuming method, but since we can have multiple local minima and acceptable solutions for hyper-parameters, (and it’s easy to end working with a suboptimal set of combinations), a grid-search might improve your model’s performance. In a real scenario, we start with a broad and wide-ranging set of values for each hyper-parameter. After identifying which values and region to explore, we can reduce the range on the grid-search.</p><p><strong>Grid-Search Example</strong></p><p>We will carry on working with the sample code we were using before, but modified so we can pass a set of values for the learning rate, the epochs, and the batch size.</p><p>Even though we are using a low number of folds for the cross validation (the cv parameter) and a modest number of values for the 3 hyper-parameters to reduce waiting times, it will still take over an hour to run the following configuration. We recommend to set n_jobs to -1 to run the grid search in parallel on all processors:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fa3ff3c10d2872c5702cac1738dee3dd/href">https://medium.com/media/fa3ff3c10d2872c5702cac1738dee3dd/href</a></iframe><p>After running the grid-search we can get the best combination of parameters, the best score, and a dictionary with each combination’s results:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BkrDlp7MKsZX-VMyoyG4hw.png" /></figure><p>In the end, the best combination turned out to be the one we had previously used to run the cross-validation.</p><h3><strong>Conclusion</strong></h3><p>In this article, we went through some basic ideas on how to evaluate a machine learning model and how to fine-tune its hyper-parameters.</p><p>We explored a very common strategy for model evaluation, k-fold cross-validation, which, by averaging individual model performance, will identify whether a model suffers from high bias or high variance.</p><p>We also explored how to search for the right set of hyper-parameters, by applying grid-search. Exhausting all possible hard-coded combinations that will help you to find the optimal combination of hyper-parameters.</p><p>If you have any thoughts or questions about model evaluation or hyper-parameter optimisation please feel free to get in touch.</p><h3>Key Takeaways</h3><ul><li>Accuracy measured across a training and a testing dataset is the fastest most frequently used metric for assessing a model, but it’s not the best.</li><li>Whatever metric you use to measure performance, you need to ensure you keep bias and variance as low as possible.</li><li>If a model is overtrained or too complex, you will see high variance. If a model is too inflexible and produces similar errors in both training and testing data, you will see high bias.</li><li>Attempts to reduce one often increases the other. A compromise is needed, known as a bias-variance tradeoff.</li><li>Average performance measured over k-fold cross-validation gives a proper estimate of how well a model does its task in general.</li><li>Neural networks have two types of parameters; those learned during training, and those that are hard-coded and optimised separately. The latter are hyper-parameters.</li><li>Optimising hyper-parameters often requires repeatedly training different versions of a model to different sets of hyper-parameters.</li><li>Grid-search is one of the simplest techniques for hyper-parameter optimisation.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e50ff1852250" width="1" height="1" alt=""><hr><p><a href="https://medium.com/empathyco/machine-learning-model-evaluation-and-hyper-parameter-tuning-looking-beyond-accuracy-e50ff1852250">Machine Learning Model Evaluation and Hyper-Parameter Tuning: Looking Beyond Accuracy</a> was originally published in <a href="https://medium.com/empathyco">Empathy.co</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Gradient Descent: An Algorithm for Deep Learning Optimisation]]></title>
            <link>https://medium.com/empathyco/gradient-descent-an-algorithm-for-deep-learning-optimisation-74aa8ebf8de2?source=rss-c05b7f87e9ec------2</link>
            <guid isPermaLink="false">https://medium.com/p/74aa8ebf8de2</guid>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[David Lourenço Mestre]]></dc:creator>
            <pubDate>Tue, 05 Feb 2019 08:46:36 GMT</pubDate>
            <atom:updated>2019-02-05T08:46:36.251Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>Optimisation algorithms, used to minimise a cost function against training data, are the cornerstone of many mathematical methods, from simple curve fitting to deep machine learning.</blockquote><p>Within the realm of machine learning, <em>gradient descent</em> and its variants are undoubtedly between the most popular optimisation algorithms. In this article we want to explore the mathematical foundations of gradient descent alongside the practicalities of its implementation — using sampling code running in TensorFlow. Stay tuned.</p><h3><strong>Cost Function</strong></h3><p>Let’s start with a typical classification problem like training a model to assign labels to data. For this we’ll use a neural network that will be trained with a set of pre-labelled data. One of the key ingredients during the supervised learning process is the cost function that has to be optimised.</p><p>The cost function for a neural network depends on the weights and biases that we want to shape, and it measures how well the model performs with respect to the training dataset. The most common cost function can be expressed as a sum of the squared differences:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HZ7gfJdgrTWgGp4E1UucnQ.png" /></figure><p>where ŷ, or ‘y hat’, represents the prediction of the neural network, y^i the value from the data point i and the sum runs over <em>m </em>data points in the training set.</p><p>We now have to identify the weights and biases that minimise the cost function. At the beginning of the training we would have set random values for our parameters and, through a process of back propagation and iteration, we can adjust the weights and biases to reduce the value of the cost function. This is where gradient descent enters.</p><p>But before going any further, why gradient descent? Why do we need to optimise the cost function in the first place? Why not run lots of possible and random weights?</p><p>We could try out thousands of values for the weights on the cost function and see which ones work best. While this could work for one weight, once we increase the number of layers and synapses we can’t escape the problems that arise within a high-dimensional space. It becomes computationally infeasible to get the minimum value of the cost function in an acceptable amount of time.</p><p>Let’s assume that we’re working with the following neural network that has 16 weights:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*skJQnsjPOPFwWY9Z9JP0TQ.png" /></figure><p>To try 10,000 values for each weight would imply to run 10⁶⁴ combinations (10,000¹⁶). In a real case scenario, we would have hundreds or thousands of weights. Not very efficient right.</p><h3><strong>Gradient Descent</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/883/1*asnDYc-FoM815CJKSul0Bw.png" /><figcaption>Raschka, Sebastian. Python Machine Learning, Packt Publishing, p. 36</figcaption></figure><p>So, what is the gradient descent? At a theoretical level, gradient descent is a first order iterative method for finding the minimum of a function, and thus is very well suited to use with continuous and convex cost functions.</p><p>In each iteration the weights of the neural network are modified by a value proportional to the negative gradient of the cost function at the current point, to get closer to the function minima:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lqQK4VgdhWwRNqgVpBgfjA.png" /></figure><p>Where the w’ on the left side is the vector of neural network weights after a learning step and <em>∇J(w) </em>is the first-order derivative, the gradient. The proportionality constant 𝜼 is normally referred to as the learning rate.</p><p>The equivalent expression for the weight of a single neuron w_j is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZuFUYf2YNMDaixCFkU-Upg.png" /></figure><p>Where we now have the partial derivative of the cost function.</p><p>For our simple cost function, we can perform the calculation explicitly in the simplest case of a linear transformation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JG27FKnif46zjVHjTNDvaA.png" /></figure><p>However, in most situations the gradient will be calculated numerically.</p><p><strong>The learning rate</strong></p><p>The learning rate will determine how many iterations will be needed to adjust the parameters with respect to the cost function, because it controls how fast the weights are updated at each interval. Smaller rates will take longer to converge to a minima. Too large a rate may lead to high fluctuations around a minima, or diverge from the optimal solution.</p><p><strong>Non-convex error functions</strong></p><p>A word of advice — the gradient descent works well for a convex function, but if the surface of the cost function that we’re trying to minimise is not convex, the gradient descent may be stuck in a local minima without ever reaching the global minima (this is the optimal solution for the relationship between cost function and weights and biases).</p><p>We can visualise it as a mountain range with different valleys. Independently of the number of iterations, the gradient might end up moving around the same valley, without necessarily reaching the lowest point. Or, the gradient may converge to another stationary point that we’re not interested in, a saddle point, which can be visualised as a plateau in our mountain example.</p><h3><strong>Code Implementation</strong></h3><p>Now the fun part, let’s see how to run the gradient descent inside a neural network. For simplicity, we’ll import from scikit-learn the <a href="https://en.wikipedia.org/wiki/Iris_flower_data_set">Iris dataset</a>, which is perfect for testing purposes, and will split the dataset into two sets; one for training, and another for testing:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/aa3fe1c1a6fd9bc3ddf08193178dfdfb/href">https://medium.com/media/aa3fe1c1a6fd9bc3ddf08193178dfdfb/href</a></iframe><p>Since we’re implementing a neural network we should normalise the data so let’s transform the data with MinMaxScaler:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c5da4ec3b7428f8924c57228447f1fb5/href">https://medium.com/media/c5da4ec3b7428f8924c57228447f1fb5/href</a></iframe><p>As good practice, we should vectorise each label (if we don’t do this the model might conclude that the labels have some kind of hierarchy):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5d00c4e16e0ff4a489d64a6d478d765f/href">https://medium.com/media/5d00c4e16e0ff4a489d64a6d478d765f/href</a></iframe><p>In the following step we initialise two variables, one for the number of data points, the other for the number of labelling classes, and at this point we pre-define the two tensors as placeholders (upon execution, those placeholders will be fed with data):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/683869b7671750d3e0f41a03ebccff23/href">https://medium.com/media/683869b7671750d3e0f41a03ebccff23/href</a></iframe><p>We now need to pass some key parameters. These are the learning rate that we mentioned before, the number of epochs to iterate the gradient descent (the back-propagation process), a regularisation factor to avoid overfitting, and the number of nodes for each network layer.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8a4231be43fdbd856b5640f94e9c1a08/href">https://medium.com/media/8a4231be43fdbd856b5640f94e9c1a08/href</a></iframe><p>In a real case-scenario we would have to find the optimal values of the parameters for our neural network.</p><p>After we’ve defined the tensors for the weights and the biases:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bf30d15db3292c957cd3f68cbf1e3643/href">https://medium.com/media/bf30d15db3292c957cd3f68cbf1e3643/href</a></iframe><p>We can now build the neural network and define the cost function. The prediction (y_hat) will be computed as the output of the last fully connected layer.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d95dfae0dcaa31267a4282204f445604/href">https://medium.com/media/d95dfae0dcaa31267a4282204f445604/href</a></iframe><p>As the cost function we have used the mean squared error, as described before, but in a real application of a classification problem like this one other functions like the cross entropy/softmax would be more appropriate.</p><p>The real action, and the most time-consuming element lies in the training loop:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e88ecbb6466cc719237d131b7f8762a8/href">https://medium.com/media/e88ecbb6466cc719237d131b7f8762a8/href</a></iframe><h3><strong>Beyond Gradient Descent</strong></h3><p>To avoid being stuck in undesirable stationary points or dealing with computationally expensive matrixes, there are more advanced methods to run or optimise the gradient. To run the gradient let’s look at Stochastic GD and Mini Batch GD, while to see how to optimise the gradient we can use Adam (Adaptive Moment Estimation).</p><p><strong>Stochastic Gradient Descent</strong></p><p>SGD may be considered an approximation of the GD, where each iteration is evaluated on a single data sample instead of on the whole training set. Obviously, finding the best fit parameters based on a single sample reduces the overhead costs significantly for large datasets, and it tends to reach convergence faster. The main disadvantage is that the journey to find a global minima tends to be more erratic and noisy.</p><p><strong>Mini-Batch</strong></p><p>We can see mini-batch as a compromise between the simple gradient descent and the stochastic version. Instead of running just a training sample or the full dataset to minimise the error function, it uses a small subset of the data, chosen randomly. Thus taking the best of both methods.</p><p><strong>Adam</strong></p><p>Adam, which is not an acronym, derives its name from adaptive moment estimation. As with the above methods, it’s a first order gradient but in contrast to them it allows the learning rates of each of the network weights to be adapted following the learning process itself. It can be seen as a fusion between two other popular methods: AdaGrad (Adaptive Gradient Algorithm), well suited for sparse data, and RMSProp (Root Mean Square Propagation), which works well for online and non-stationary problems.</p><h3><strong>Conclusion</strong></h3><p>In this article we’ve introduced some of the key concepts of gradient descent:</p><ul><li>We saw how the gradient descent method minimises the cost function to ensure the convergence to a global minima,</li><li>We worked through a mathematical example of a simple linear transformation to show how to go from a cost function to the gradient descent,</li><li>We’ve seen that the learning rate defines how fast or slow the algorithm moves towards the optimal weights values,</li><li>We’ve gone through a code sample that illustrates how to integrate gradient descent with a neural network.</li></ul><p>For anyone planning to explore machine learning, having a grasp on how to minimise a cost function will be essential, and we hope that this article has helped to explain and explore some of the core ideas behind gradient descent.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=74aa8ebf8de2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/empathyco/gradient-descent-an-algorithm-for-deep-learning-optimisation-74aa8ebf8de2">Gradient Descent: An Algorithm for Deep Learning Optimisation</a> was originally published in <a href="https://medium.com/empathyco">Empathy.co</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Solve the Common Problems in Image Recognition]]></title>
            <link>https://medium.com/empathyco/how-to-solve-the-common-problems-in-image-recognition-d519af322bea?source=rss-c05b7f87e9ec------2</link>
            <guid isPermaLink="false">https://medium.com/p/d519af322bea</guid>
            <category><![CDATA[image-recognition]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[ecommerce]]></category>
            <dc:creator><![CDATA[David Lourenço Mestre]]></dc:creator>
            <pubDate>Fri, 14 Sep 2018 07:57:15 GMT</pubDate>
            <atom:updated>2018-09-14T08:52:39.681Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>How to Solve the Common Problems in Image Recognition</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*waku0dB3IHNeOClC3pzTYA.jpeg" /></figure><p><strong>Introduction</strong></p><p>Most classification problems related to image recognition are plagued with well-known and established problems. For example, frequently there won’t be enough data to properly train a classification system, the data might have some underrepresented classes, and most commonly, working with unscrutinised data will imply working with poorly labelled data.</p><p>Data is the key that determines whether your efforts will fail or succeed. These systems don’t just need <em>more</em> data than humans to learn and distinguish different classes, they need <em>thousands of times more</em> to do the job.</p><p>Deep learning relies on enormous amounts of high-quality data to predict future trends and behaviour patterns. The data sets need to be representative of the classes that we intend to predict, otherwise, the system will generalise the skewed classes distribution, and the bias will ruin your model.</p><p>These problems normally will share a common cause; the ability to find, extract, and store large quantities of data, and on a second level, cleanse, curate, and process that data.</p><p>While we can increase computing power and data storage capacity, one machine will not stand a chance when running a complex and large convolutional neural network against a large data set. It might not have enough space and, most likely, will not have enough computing power to run the classification system. It will also require access to parallel/distributed computing through cloud resources, and to understand how to run, organise and set complex clusters.</p><p>Yet, having enough data and the power to process is not enough to prevent these problems.</p><p>In this post, we’ll explore and discuss different techniques that can address the problems that arise when working with small data sets, how to mitigate class imbalance, and how to prevent over-fitting.</p><p><strong>Transfer Learning</strong></p><p>Data might be the new coal, quoting Neil Lawrence, and we know that deep learning algorithms need large sets of labelled data to train a fully-fledged network from scratch, but we often fail to fully comprehend how much data that means. Just finding the amount of data that meets your needs might be an endless source of frustration, but there are some techniques, such as a data augmentation or transfer learning, that will save you a lot of energy and time to find data for your model.</p><p>Transfer learning is a popular and very powerful approach which in short can be summed up as the process of learning from a pre-trained model that was instructed by a larger data set. That means leveraging an existing model and changing it to suit your own goals. This method involves cutting off the last few layers of a pre-trained model and retraining them with your small data set. It has the following advantages:</p><ul><li>It creates a new model over an older one with verified efficiency for image classification tasks. For example, a model can be built upon a CNN architecture such as Inception-v3 (a CNN developed by Google) and pre-trained with ImageNet;</li><li>It reduces the training time as it allows the reuse of parameters to achieve a performance that could take weeks to reach.</li></ul><p><strong>Unbalanced Data</strong></p><p>Often the proportion of a group of labels inside a data set versus the others can be unbalanced and it’s often that this minority group of labels is the set of categories that we are interested in precisely for its rarity. For example, suppose we have a binary classification problem, class X represents 95% of the data and class Y the other 5%. Thus, the model is more sensitive to class X and less sensitive to class Y. As the classifier reaches an accuracy of 95% it will basically predict class X every time.</p><p>Clearly accuracy here is not an appropriate scoring. In this situation, we should consider the cost of the errors, the precision, and the recall. A sensible starting point is a 2-D representation of the different types of errors, in other words, a confusion matrix. In the context of the outcome of our classification, it can be described as method to illustrate the actual labels versus the label prediction, as illustrated in the below diagram.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*RB5TDRHJZgOPWmQlom7iQQ.png" /></figure><p>By storing the number for each label of true positives, false positives, true negatives and false negatives acquired from the model’s predictions, we can estimate the performance for each label using recall and precision. Precision is defined as the ratio:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/806/1*EJBzm83xp1z7SKThBU02Ig.png" /></figure><p>Recall is defined as the ratio:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/674/1*MRsRmbt7mtfc-qEsMiZLHw.png" /></figure><p>Recall and/or precision will disclose an underlying problem, but not solve it. However, there are different methods to mitigate the problems associated with a marked imbalance in the distribution of classes:</p><ul><li>By assigning distinct coefficients to each label;</li><li>By resampling the original dataset, either by oversampling the minority class and/or under-sampling the majority class. That said, oversampling can be prone to over-fitting as classification boundaries will be more strict and small data sets will introduce bias;</li><li>By applying the SMOTE method (Synthetic Minority Oversampling Technique) which alleviates this problem replicating the data of less frequent classes. This method applies the same ideas behind data augmentation and makes it possible to create new synthetic samples by interpolating between neighbouring instances from the minority class.</li></ul><p><strong>Over-fitting</strong></p><p>As we know our model learns/generalises key features on a data set through backpropagation and by minimising a cost function. Each step back and forth is called an epoch, and with each epoch the model is trained and the weights are adjusted to minimise the cost of the errors. In order to test the accuracy of the model, a common rule is to split the data set into the training set and the validation set.</p><p>The training set is used to tune and create the model that embodies a proposition based on the patterns underlying in the training set, the validation set tests the efficiency and validation of the model based on unseen samples.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/848/1*OQiDWppm-cyCj53bHNPlgg.png" /></figure><p>Albeit the change on the validation error for a real case tends to show more jumps and downs:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/752/1*XDlv4mUL3v0xIYpa5ODR4w.png" /></figure><p>At the end of each epoch we test the model with the validation set, and at some point the model starts memorising the features in the training set, while the cost error and the accuracy for the samples on the validation set gets worst. When we reach this stage, the model is overfitting.</p><p>Selecting how large and complex the network should be will be a determinant cause for overfitting. Complex architectures are more prone to overfitting but, there are some strategies to prevent it:</p><ul><li>Raising the number of samples on the training set; if the network is trained with more real cases it will generalise better;</li><li>Stopping the backpropagation when overfitting happens is another option, which implies checking the cost function and the accuracy on the validation set for each epoch;</li><li>Applying a regularisation method is another popular choice to avoid overfitting.</li></ul><p><strong>L2 Regularisation</strong></p><p>L2 regularisation is a method that can be used to reduce the complexity of a model by assigning a constraint to larger individual weights. By setting a penalty constraint we decrease the dependence of our model on the training data.</p><p><strong>Dropout</strong></p><p>Dropout is a common option too for regularisation, it’s used on the hidden units of higher layers, so that we end up with different architectures for each epoch. Basically, the system randomly selects Neurons to be removed during the training. As a consequence, by constantly rescaling the weights the network is forced to learn more general patterns from the data.</p><p><strong>Conclusion</strong></p><p>As we’ve seen there are various different methods and techniques to solve the most common classification problems in image recognition, each with their benefits and potential drawbacks. There are problems such as Unbalanced Data, Over-fitting, and quite frequently there will not be enough data available but, as we’ve explained their effect can be mitigated with transfer learning, sampling methods, and regularization techniques.</p><p>This is an area that we continue to explore as we develop our own Imaginize image recognition technology. This new product feature has been designed to help our <a href="https://www.empathybroker.com/resources/">eCommerce</a> customers improve the classification, tagging and findability of their products through being able to automatically identify and recognise colours and categories.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d519af322bea" width="1" height="1" alt=""><hr><p><a href="https://medium.com/empathyco/how-to-solve-the-common-problems-in-image-recognition-d519af322bea">How to Solve the Common Problems in Image Recognition</a> was originally published in <a href="https://medium.com/empathyco">Empathy.co</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Challenging Dimensions of Image Recognition (2º part)]]></title>
            <link>https://medium.com/empathyco/the-challenging-dimensions-of-image-recognition-2%C2%BA-part-d8bddb85fc00?source=rss-c05b7f87e9ec------2</link>
            <guid isPermaLink="false">https://medium.com/p/d8bddb85fc00</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[future]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <dc:creator><![CDATA[David Lourenço Mestre]]></dc:creator>
            <pubDate>Mon, 28 May 2018 07:49:56 GMT</pubDate>
            <atom:updated>2018-05-28T07:49:56.432Z</atom:updated>
            <content:encoded><![CDATA[<p>Machine Learning and Artificial Intelligence have been gaining traction and popularity over the last few years, and beyond Google’s tech scene. As eCommerce continues to grow at such an electric pace, we see more and more features, from recommendations and search ranking to alert systems, that are driven by deep learning and artificial intelligence technologies.</p><p>One of the most interesting and challenging features is within object detection and recognition and, in particular in regards to the well-known problems associated with Deep Learning/Machine Learning problems such as data curation, data pre-processing, data collection, model performance, memory errors and so on.</p><p>In my last post, we started to look at some of the complexities around image recognition, and we´ll continue to explore this area here by examining how we can tackle some of these issues, as well as some of the principles behind Deep Learning.</p><p><strong>Neural Networks</strong></p><p>So, what are neural networks, and what is this deep learning all about? How can they recognize these features and patterns? Let´s use an illustrative example.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/259/1*iNWEXXmqAmgF5a-FsmVFWw.png" /></figure><p>The above image is a famous perceptual illusion. Depending on the features your brain opts to select, the features it processes, you’ll see either a vase, or two faces looking at each other. Your brain will classify the image as either one or the other. <strong>A trained convolutional neural network works along these identical principles</strong>; it will slice the image and look for certain features and patterns that it was trained to identify.</p><p>To a certain extent classic Artificial Neural Networks mimic how the brain works. More specifically, they mimic the concept behind the inter-neuron connections. A neuron receives signals from many adjacent neurons upstream, if the input signals surpasses its activation threshold, it transmits the signal. These are some of the building blocks behind an Artificial Neural Network. We have highly interconnected processing layers composed of artificial neurons, where each one receives input values from different “synapses”. Each connection has a weight assigned, and if the sum of all the weighted values/connections surpasses the activation function then the neuron fires its output to the next connected neuron.</p><p>Unlike the brain, the weights are assigned randomly when the process starts. During the learning stage the <strong>weights are updated and optimised through backpropagation</strong> to minimise the error, and while doing so, the predictions converge to the sample labels that have been used to train the model. This process goes back and forth until the ANN (or CNN) reaches the expected output and the model captures the relations within the data. That’s how an artificial neural network learns and identifies common patterns and attributes within each class.</p><p><strong>Data Augmentation</strong></p><p>After an extensive AI winter, <strong>Deep Learning erupted once more due to a massive increase in computing power and a huge amount of data</strong>. However, despite our era of pervasive big data, there are large limiting factors in accessing reliable data. For example, how to find the right type of data to suit a well-defined tree of classes, and importantly, how to have a symmetrical number of images per class. While some classes might have enough data, some will not meet the criteria and will be underrepresented.</p><p>And a crucial point, the images may not abstract/outline all of the elements that should represent each class. The data available has to characterize the diversity and general features, patterns and attributes, that we might find in real cases.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*nsDSMqSVspDiMcsPXkBnPA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*sDOK8uW-jeBvw9P-j8VrLA.jpeg" /></figure><p>For example, let’s imagine that we have a small corpus of structured data with two classes: “Jackets” and “Sweatshirts.” Now, let’s assume that each Jacket is large enough to occupy almost the full image allocation, while the Sweatshirts compose just a tiny fraction of each image. After dividing the original dataset into a training set and a testing set we apply our fancy deep-learning tricks and reach an accuracy of 97%, hurrah!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*c7uBJdYqkNRuiRrwStpBhg.jpeg" /></figure><p>What if we then, however, feed the recently trained model with a Sweatshirt that nearly occupies the whole picture, and the model says it’s a Jacket. But wait, didn’t we get an accuracy of 97%. So why we would get such a result?</p><p>Deep-learning, at its core, is really just looking for the set of features and patterns that best represent each class, and, in this case, the area occupied by the item of clothing is one of the main features. In the end, any model is as good as the data used to feed it. A high-quality data set is crucial, and as we know, the more (and diverse) data a DL algorithm has access to, the more effective it can be.</p><p>To guarantee that we have good general properties, and that the model ignores the noise and irrelevant features, we may choose to augment the data using the existing data set. There are different techniques to do this, such as rotating, scaling, flipping, changing the lighting conditions, or cropping. For our two labels dataset, applying different scales would certainly improve the model’s general properties. While data augmentation consistently leads to improved generalisation, it will not replace a good dataset from the beginning.</p><p><strong>Parallelism</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/246/1*f5ySeQqn5E8SpRBZXKcvCQ.jpeg" /></figure><p>While working with Deep Learning there are different libraries and frameworks available: Deep Learning Pipelines, Keras, and <a href="https://www.tensorflow.org/">TensorFlow</a>, are examples. We decided to look at TensorFlow (TF), being one of the most mature options available. TF is a low-level API with a steep learning curve, it was developed by the researchers and engineers at the Google Brain, and open-sourced in 2015.</p><p>One of the first problems we came across, and we already knew to expect it, was that we would not be able to fit our training tasks into the memory, so it would require days or weeks, to finish a simple training task on a regular CPU. We would have to distribute TF and assign the graph across different machines. Albeit TF offers a native solution, making it work can be as fun as a toothache! It requires manually managing a cluster of machines, enabling gRPC protocol, configuring manually the devices, and so on.</p><p>In 2017 Yahoo open-sourced <strong>TensorFlowOnSpark</strong> significantly reducing the pain with the many pros that Spark brings; data integration through RDDs, S3 and HDFS incorporated within the pipelines, an almost effortless integration with GPU and CPU clusters on-premise or on the cloud. Nevertheless, to make it work still requires a slow process of trial and error, and there are still some hurdles to overcome.</p><p>For example, it doesn’t come with a cluster manager or a distributed I/O layer out of the box so users have to manually set up a distributed TF cluster and feed data into it. This also means it comes with all the problems of having 300 error messages on Yarn logs when you just missed a typo on the code! It’s also not easy to identify the correct configuration on the command line, and there are some slightly obscure steps such as having to install libhdfs.so on all machines. Still any TF program can be modified to work with TensorFlowOnSpark.</p><p>TensorFlowOnSpark will launch distributed model training as a single Spark job, and automatically feeds data from Spark RDDs or DataFrames into the TensorFlow job. The cluster architecture can be divided into three kinds of nodes:</p><ul><li>A PS (Parameter Server) node that hosts the models</li><li>A master worker that coordinates the training operations</li><li>Workers responsible for managing the training steps</li></ul><p>We initially worked with clusters using CPU machines but, in the end, we decided to work exclusively with GPUs instances as even a single GPU machine offers impressive results. GPUs can be seen as a cluster of multiple computational units, and its specific capabilities can be exploited to further speed up calculations.</p><p><strong>Conclusions</strong></p><p>It’s not a trivial process to tune neural network settings, there are many hyperparameters, for example, activation functions, learning rate, batch size, momentum, number of epochs, different types of regularization, and furthermore, the layers of the networks can vary in number, type, and width. The fine-tuning therefore <strong>requires extensive bookkeeping</strong> and, even if there are different methods to find out the optimal configuration, the large scope of potential combinations, especially when working with a low number of machines, makes the operation not for the faint of heart.</p><p><strong>There’s a high computational time and memory usage</strong>. Even a fairly small dataset will require expensive machines, cloud or on-premise, and some cloud GPU machines might fail when working with large widths and heights.</p><p>The data used to train a model has to be nearly perfect, meet exceptionally comprehensive and high quality standards, and finding, or creating, an acceptable dataset is often the biggest hurdle. Working with an incomplete or poor dataset will be an endless source of frustration.</p><p>In the next post, we’ll continue this exploration by looking at Faster R-CNN, and how we can use it to detect fashion items.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d8bddb85fc00" width="1" height="1" alt=""><hr><p><a href="https://medium.com/empathyco/the-challenging-dimensions-of-image-recognition-2%C2%BA-part-d8bddb85fc00">The Challenging Dimensions of Image Recognition (2º part)</a> was originally published in <a href="https://medium.com/empathyco">Empathy.co</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Challenging Dimensions of Image Recognition (part 1)]]></title>
            <link>https://medium.com/empathyco/the-challenging-dimensions-of-image-recognition-part-1-726e8269aa2f?source=rss-c05b7f87e9ec------2</link>
            <guid isPermaLink="false">https://medium.com/p/726e8269aa2f</guid>
            <category><![CDATA[image-recognition]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[David Lourenço Mestre]]></dc:creator>
            <pubDate>Fri, 02 Mar 2018 09:06:20 GMT</pubDate>
            <atom:updated>2018-03-02T10:49:10.754Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*axbVIpSDg1dTPDhQZXXWfw.png" /></figure><p>As consistent product data greases the wheels of eCommerce, the inconsistency that emerges from dealing with a large number of fashion items raises different challenges. How to organise and standardise the product data received from different retailers? Or, how to supply the missing information and ensure accuracy across distinctive catalogues?</p><p>For example, the colour for the same jacket may be classified by Retailer A as “salmon”, “light-red” by Retailer B, and Retailer C might use an abbreviation such as “RD”. Also the descriptive category/name for the same jacket might vary across the suppliers.</p><p>To save us from the human effort required to curate and clean data, one method is to use automated solutions that standardise information through robust tools to clean up the data received from different sources and extract attributes and categories from fashion items.</p><p>There are however problems to overcome by using this method, for example if a random image contains clothing, how do you predict the clothing type through multi-class classification, how to you predict the colours, and find attributes such as strips, types of sleeves and collars?</p><p>For a human eye, it might be an easy task to identify a huge range of objects and detect features such as colour or to distinguish a coat from a shirt. To recognise patterns and similarities comes naturally to us but for a computer, image recognition is still a significant challenge.</p><p>And while working with convolutional neural networks, it´s also important to cover classical architectures to know where this takes us.</p><p><strong>Image Segmentation</strong></p><p>Optimising a solution for fashion classification is a fundamental vision problem. There are multiple techniques, first it´s important to work with image segmentation, and use this approach to analyse an image based on the abrupt changes in the homogeneity attributes of pixels. Image segmentation should be used as a first step in image analysis and recognition.</p><p>It´s also essential to note that when processing images, it´s key to focus on the features that represent the dominant object. However, this is not always as simple as it sounds as each image may well have a background of some sort; a plain white backdrop, or a complex setting such as a street scenario.</p><p>To address this problem, there are many different methods available for image segmentation, one option is to look for a light solution. Watershed is a good background removal solution, and one of the most common algorithms used for image segmentation. It uses the process of extracting information from an image using groups of pixels with regions of similarity.</p><p>Starting from user defined markers, the Watershed algorithm treats the grayscale image as if it was composed of “high” and “low” areas. The algorithm floods the “low” areas using the values set on the markers. The values above the threshold markers are then used to extract the dominant object from the image, by creating an alpha channel that reflects the proportion of foreground and background.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/162/1*pqHas06M3VI2rxvxZ_9ubA.png" /><figcaption>Original Image</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/161/1*bw9dP17X03BXLz84G1eG9Q.png" /><figcaption>Alpha Channel</figcaption></figure><p>However, Watershed doesn´t always work well for images with fairly complex backgrounds.</p><p>Another solution is to work with GrabCut. Albeit slower than Watershed, it performs well on complex backgrounds. GrabCut tends to be used as an interactive foreground extraction tool, but it can be tweaked to work on an autonomous fashion. When applying it, it´s fair to make the assumption that the product would be centred within the image.</p><p>By setting a box over an image, the algorithm defines everything outside of the box as a known background, and the data inside it is classified as unknown. The machine does an initial classification based on the entry values and tries to estimate as to which class the unknown pixels belong. Through an iteration process, GrabCut applies a probabilistic function to identify the probable foreground and the probable background. The process is repeated until the classification converges.</p><p><strong>Clustering</strong></p><p>An image can be viewed as a large array of discrete pixels. For an image encoded with three channels (Red, Green and Blue), each pixel represents a colour. Therefore, clustering is a good method to extract the colours from a fashion article and to divide and group similar pixels.</p><p>After all, when we as persons define something as Red or Blue, we are also clustering specific wave lengths into similar groups, and categorising those groups with a symbolic name.</p><p>To cluster image data, one technique is to work with an unsupervised machine learning algorithm such as k-means. K-means relocates centroids to minimise the sum of squared distances between the centroids and the points that form each pixel.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/546/1*-GZL8vX8ldcf7qBLBcg3-A.png" /></figure><p>The process runs k-means with a number of centroids equal to the number of colours, where each centroid is assigned to a k-cluster. K-means´ algorithm is then executed for each pixel on the image. K-means clustering finds the Euclidean distance for each pixel to the cluster mean.</p><p>After some iterations, the centroid moves from a random position to a local optimum (the centre of the cluster), in a process that recalculates the centre for all clusters on each iteration. The outcome of the centroids positions as a proxy can be used for the colours that will define the palette.</p><p>The challenge with k-means is that it´s necessary to specify the number of clusters before running the algorithm, and estimating the number of clusters from an array of RGB values can be computationally expensive and a slow procedure. And even though there are some methods to assess the number of clusters, such as Elbow or Silhouette, none offer a wholly accurate estimation for the ideal number of clusters.</p><p><strong>Conclusions</strong></p><p>While attaining respectable results, GrabCut and clustering have a slow performance, due to the iterative refinement stage on GrabCut, as well as having to determine the ideal number of clusters beforehand, which is a problem on its own. This makes both methods problematic when used to process large catalogues. In the next post, we´ll continue this exploration by looking at deep learning, and how we can use this method to automatise some of our tools.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=726e8269aa2f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/empathyco/the-challenging-dimensions-of-image-recognition-part-1-726e8269aa2f">The Challenging Dimensions of Image Recognition (part 1)</a> was originally published in <a href="https://medium.com/empathyco">Empathy.co</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>