<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ American Sign Language - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ American Sign Language - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 15:49:15 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/american-sign-language/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to use transfer learning for sign language recognition ]]>
                </title>
                <description>
                    <![CDATA[ By Vagdevi Kommineni As a continuation of my previous post on ASL Recognition using AlexNet — training from scratch, let us now consider how to solve this problem using the transfer learning technique. Transfer learning has become so handy for compu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/asl-recognition-using-transfer-learning-918ba054c004/</link>
                <guid isPermaLink="false">66c344fa9972b7c5c7624e03</guid>
                
                    <category>
                        <![CDATA[ American Sign Language ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Deep Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 10 Mar 2019 18:13:51 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*tmh4aAYfP-1SGqpqAaim3w.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Vagdevi Kommineni</p>
<p>As a continuation of my previous post on <a target="_blank" href="https://medium.com/@vagdevi.k15/asl-using-alexnet-training-from-scratch-cfec9a8acf84">ASL Recognition using AlexNet — training from scratch</a>, let us now consider how to solve this problem using the transfer learning technique.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/nhxsEn9S-VwNdFKCClwfeKhKmTd1buwzF3pR" alt="Image" width="750" height="500" loading="lazy"></p>
<p>Transfer learning has become so handy for computer vision geeks.</p>
<p>It’s basically a mechanism where the knowledge acquired by training a model for achieving a task is efficiently modified or optimized in order to accomplish the second related task.</p>
<blockquote>
<p>One of the powerful tasks of deep learning is that, sometimes we can take the knowlewdge the neural network has learnt from one task (task A) and apply that knowledge in another task (task B). This is called transfer learning.<br> — Andrew Ng</p>
</blockquote>
<p><img src="https://cdn-media-1.freecodecamp.org/images/2BSIEF-cvwEyUbDX-CPAqKmhs8Fg1VZ1jj0t" alt="Image" width="259" height="194" loading="lazy"></p>
<p>For example, a neural network trained on object recognition can be used to read x-ray scans. This is achieved by freezing the weights until the initial or mid-layers are learned on the data for task A, removing the last layer or a few of the last layers, and adding new layers and training those parameters using the data for task B.</p>
<p>Transfer learning makes sense when the data in training for task A is quite large and that of task B is relatively smaller. By getting trained on such vast amounts of data and showing excellent performance on its test data, this implies that the neural network has a good knowledge of extracting useful features from the input images. This is essential and powerful for achieving a task.</p>
<p>Now that we have such powerful features from these layers (whose weights from task A are frozen), we just need to make use of these extracted features to achieve task B. So, these features from frozen layers are fed to the new layers and the parameters for these layers are trained on the data of task B.</p>
<p>So basically, we store the knowledge from the previous task in the form of the weights of the frozen layers (called pre-training). Then we make the neural network task B-specific by training (called fine-tuning) the latter layers on the new data. For more information about transfer learning, please visit <a target="_blank" href="https://www.youtube.com/watch?v=yofjFQddwHE">here</a>.</p>
<p>This technique is really useful because:</p>
<ul>
<li>we can bring up a model which performs elegantly for task B, though we have less data available for task B,</li>
<li>there are fewer parameters to be trained (only last layer/layers) and thus less training time,</li>
<li>there is less demand for heavy computational resources like GPU, TPU (but still depends on the data available for task B).</li>
</ul>
<p>Since this post is the continuation of the previous post about <a target="_blank" href="https://medium.com/@vagdevi.k15/asl-using-alexnet-training-from-scratch-cfec9a8acf84">ASL Recognition using AlexNet — training from scratch</a>, please refer to that post for preprocessing details and the code (preprocess.py).</p>
<p>The data used for both the posts is this <a target="_blank" href="https://www.kaggle.com/grassknoted/asl-alphabet">Kaggle data for ASL</a>. The dataset consists of images of hand gestures for each letter in the English alphabet. The images of a single class are of different variants, as in zoomed versions, dim and bright light conditions, etc. For each class, there are as many as 3000 images. Here are links for the full code of <a target="_blank" href="https://github.com/vagdevik/American-Sign-Language-Recognition-System/blob/master/4_VGG16_BCVWL/asl_full.py">preprocessing &amp; training</a> and <a target="_blank" href="https://github.com/vagdevik/American-Sign-Language-Recognition-System/blob/master/4_VGG16_BCVWL/predict.py">testing</a>.</p>
<p>For transfer learning, I have used the VGG16 pre-trained model trained on the ImageNet Dataset. The weights are readily available in keras. We shall first import all the necessary modules as follows:</p>
<pre><code><span class="hljs-keyword">import</span> kerasfrom keras.optimizers <span class="hljs-keyword">import</span> SGD       <span class="hljs-keyword">from</span> keras.models <span class="hljs-keyword">import</span> Sequential <span class="hljs-keyword">from</span> keras.applications <span class="hljs-keyword">import</span> VGG16   #VGG16 pretrained weights    <span class="hljs-keyword">from</span> keras.preprocessing <span class="hljs-keyword">import</span> imagefrom keras.layers.normalization <span class="hljs-keyword">import</span> BatchNormalizationfrom keras.layers <span class="hljs-keyword">import</span> Dense, Activation, Dropout, Flatten,Conv2D, MaxPooling2D
</code></pre><pre><code>print(<span class="hljs-string">"Imported Network Essentials"</span>)
</code></pre><p>Let us now initiate the model to be a sequential one and first add the pre-trained VGG16 network to our model. Note that we need to remove the last layers (called top layers) and freeze the weights of all the previous layers. That’s done by <code>include_top=False</code> . <code>weights='imagenet’</code> takes the weights of the VGG16 network trained on the ImageNet Dataset.</p>
<pre><code># to fix the input image sizeimage_size=<span class="hljs-number">224</span>
</code></pre><pre><code># Load the VGG modelvgg_base = VGG16(weights=<span class="hljs-string">'imagenet'</span>,include_top=False,                 input_shape=(image_size,image_size,<span class="hljs-number">3</span>))
</code></pre><p>Now, the part of VGG16 we want is stored in <code>vgg_base</code>. We shall also add the other layers like dense layers and dropout layers on top of <code>vgg_base</code>. Thus the full architecture of the neural network we use shall be:</p>
<pre><code>#initiate a modelmodel = Sequential() #Add the VGG base modelmodel.add(vgg_base) #Add <span class="hljs-keyword">new</span> layersmodel.add(Flatten()) model.add(Dense(<span class="hljs-number">8192</span>,activation=<span class="hljs-string">'relu'</span>))model.add(Dropout(<span class="hljs-number">0.8</span>))model.add(Dense(<span class="hljs-number">4096</span>,activation=<span class="hljs-string">'relu'</span>))model.add(Dropout(<span class="hljs-number">0.5</span>))model.add(Dense(<span class="hljs-number">5</span>, activation=<span class="hljs-string">'softmax'</span>))
</code></pre><p>We shall next define our optimizer as SGD and set the learning rate <code>lr</code> value. Since this is a categorical classification, we use categorical_crossentropy as the loss function in <code>model.compile</code>. Using checkpoints is the best way to store the weights we got until the point of interruption, so that we may use them later. The first parameter is to set the place to store: save it as <code>weights.{epoch:02d}-{val_loss:.2f}.hdf5</code> in the Checkpoints folder. We then go for training by using <code>model.fit</code>.</p>
<pre><code># Compile sgd = SGD(lr=<span class="hljs-number">0.001</span>)model.compile(loss=<span class="hljs-string">'categorical_crossentropy'</span>, optimizer=sgd,    metrics=[<span class="hljs-string">'accuracy'</span>])checkpoint = keras.callbacks.ModelCheckpoint(<span class="hljs-string">"Weights/weights.{epoch:02d}-{val_loss:.2f}.hdf5"</span>, monitor=<span class="hljs-string">'val_loss'</span>, verbose=<span class="hljs-number">0</span>, save_best_only=False, save_weights_only=False, mode=<span class="hljs-string">'auto'</span>, period=<span class="hljs-number">1</span>)
</code></pre><pre><code># Trainmodel.fit(X_train/<span class="hljs-number">255.0</span>, Y_train, batch_size=<span class="hljs-number">32</span>, epochs=<span class="hljs-number">15</span>, verbose=<span class="hljs-number">1</span>,validation_data=(X_test/<span class="hljs-number">255.0</span>,Y_test/<span class="hljs-number">255.0</span>), shuffle=True,callbacks=[checkpoint])
</code></pre><p>We can save the model and weights as follows:</p>
<pre><code># serialize model to JSONmodel_json = model.to_json()<span class="hljs-keyword">with</span> open(<span class="hljs-string">"Model/model.json"</span>, <span class="hljs-string">"w"</span>) <span class="hljs-keyword">as</span> json_file:    json_file.write(model_json)
</code></pre><pre><code># serialize weights to HDF5model.save_weights(<span class="hljs-string">"Model/model_weights.h5"</span>)print(<span class="hljs-string">"Saved model to disk"</span>)
</code></pre><p>Let’s have a look at the whole code for training here:</p>
<pre><code># train.py
</code></pre><pre><code><span class="hljs-keyword">import</span> kerasfrom keras.optimizers <span class="hljs-keyword">import</span> SGD       <span class="hljs-keyword">from</span> keras.models <span class="hljs-keyword">import</span> Sequential <span class="hljs-keyword">from</span> keras.applications <span class="hljs-keyword">import</span> VGG16   #VGG16 pretrained weights    <span class="hljs-keyword">from</span> keras.preprocessing <span class="hljs-keyword">import</span> imagefrom keras.layers.normalization <span class="hljs-keyword">import</span> BatchNormalizationfrom keras.layers <span class="hljs-keyword">import</span> Dense, Activation, Dropout, Flatten,Conv2D, MaxPooling2Dprint(<span class="hljs-string">"Imported Network Essentials"</span>)
</code></pre><pre><code># to fix the input image sizeimage_size=<span class="hljs-number">224</span>
</code></pre><pre><code># Load the VGG modelvgg_base = VGG16(weights=<span class="hljs-string">'imagenet'</span>,include_top=False,                 input_shape=(image_size,image_size,<span class="hljs-number">3</span>))
</code></pre><pre><code>#initiate a modelmodel = Sequential() #Add the VGG base modelmodel.add(vgg_base) #Add <span class="hljs-keyword">new</span> layersmodel.add(Flatten()) model.add(Dense(<span class="hljs-number">8192</span>,activation=<span class="hljs-string">'relu'</span>))model.add(Dropout(<span class="hljs-number">0.8</span>))model.add(Dense(<span class="hljs-number">4096</span>,activation=<span class="hljs-string">'relu'</span>))model.add(Dropout(<span class="hljs-number">0.5</span>))model.add(Dense(<span class="hljs-number">5</span>, activation=<span class="hljs-string">'softmax'</span>))
</code></pre><pre><code># Compile sgd = SGD(lr=<span class="hljs-number">0.001</span>)model.compile(loss=<span class="hljs-string">'categorical_crossentropy'</span>, optimizer=sgd,    metrics=[<span class="hljs-string">'accuracy'</span>])checkpoint = keras.callbacks.ModelCheckpoint(<span class="hljs-string">"Weights/weights.{epoch:02d}-{val_loss:.2f}.hdf5"</span>, monitor=<span class="hljs-string">'val_loss'</span>, verbose=<span class="hljs-number">0</span>, save_best_only=False, save_weights_only=False, mode=<span class="hljs-string">'auto'</span>, period=<span class="hljs-number">1</span>)
</code></pre><pre><code># Trainmodel.fit(X_train/<span class="hljs-number">255.0</span>, Y_train, batch_size=<span class="hljs-number">32</span>, epochs=<span class="hljs-number">15</span>, verbose=<span class="hljs-number">1</span>,validation_data=(X_test/<span class="hljs-number">255.0</span>,Y_test/<span class="hljs-number">255.0</span>), shuffle=True,callbacks=[checkpoint])
</code></pre><pre><code># serialize model to JSONmodel_json = model.to_json()<span class="hljs-keyword">with</span> open(<span class="hljs-string">"Model/model.json"</span>, <span class="hljs-string">"w"</span>) <span class="hljs-keyword">as</span> json_file:    json_file.write(model_json)
</code></pre><pre><code># serialize weights to HDF5model.save_weights(<span class="hljs-string">"Model/model_weights.h5"</span>)print(<span class="hljs-string">"Saved model to disk"</span>)
</code></pre><p>Now it’s time for testing! Here’s the way to load the model and trained weights from the stored JSON files and use the evaluation metric <code>accuracy_score</code> from <code>sklearn.metrics</code> .</p>
<pre><code># test.py
</code></pre><pre><code><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> npfrom keras.models <span class="hljs-keyword">import</span> model_from_jsonfrom sklearn.metrics <span class="hljs-keyword">import</span> accuracy_score
</code></pre><pre><code># dimensions <span class="hljs-keyword">of</span> our imagesimage_size = <span class="hljs-number">224</span> <span class="hljs-keyword">with</span> open(<span class="hljs-string">'Model/model.json'</span>, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> f:    model = model_from_json(f.read())      model.summary()model.load_weights(<span class="hljs-string">'Model/model_weights.h5'</span>)
</code></pre><pre><code># loading the numpy test images (feel free to look at preprocessing)X_test=np.load(<span class="hljs-string">"Numpy/test_set.npy"</span>)Y_test=np.load(<span class="hljs-string">"Numpy/test_classes.npy"</span>)
</code></pre><pre><code># getting predictions and getting the maximum <span class="hljs-keyword">of</span> predictions# since predictions are <span class="hljs-keyword">of</span> form [<span class="hljs-number">0.01</span>, <span class="hljs-number">0.99</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> Y_predict and # are <span class="hljs-keyword">of</span> the form [<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> Y_testY_predict = model.predict(X_test) Y_predict = [np.argmax(r) <span class="hljs-keyword">for</span> r <span class="hljs-keyword">in</span> Y_predict]Y_test = [np.argmax(r) <span class="hljs-keyword">for</span> r <span class="hljs-keyword">in</span> Y_test]
</code></pre><pre><code>print(<span class="hljs-string">"##################"</span>)acc_score = accuracy_score(Y_test, Y_predict)print(<span class="hljs-string">"Accuracy: "</span>+str(acc_score))print(<span class="hljs-string">"##################"</span>)
</code></pre><p>I got an accuracy of 97%. You may follow certain steps to improve accuracy like:</p>
<ul>
<li>hyperparameter tuning.</li>
<li>using a different pretrained model like ResNet, VGG19, etc instead of VGG16.</li>
</ul>
<p>The full code can be found <a target="_blank" href="https://github.com/vagdevik/American-Sign-Language-Recognition-System/tree/master/3_VGG16_newData">here</a>. I would love to hear your results in the comments section below.</p>
<p>Happy learning!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to build a convolutional neural network that recognizes sign language gestures ]]>
                </title>
                <description>
                    <![CDATA[ By Vagdevi Kommineni Sign language has been a major boon for people who are hearing- and speech-impaired. But it can serve its purpose only when the other person can understand sign language. Thus it would be really nice to have a system which could ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/asl-using-alexnet-training-from-scratch-cfec9a8acf84/</link>
                <guid isPermaLink="false">66c344fd790a62b5fbf7b886</guid>
                
                    <category>
                        <![CDATA[ Alexnet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ American Sign Language ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Data Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Deep Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 31 Jan 2019 14:45:22 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*vrcZTOV9qoL_pmjAXC-WsQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Vagdevi Kommineni</p>
<p>Sign language has been a major boon for people who are hearing- and speech-impaired. But it can serve its purpose only when the other person can understand sign language. Thus it would be really nice to have a system which could convert the hand gesture image to the corresponding English letter. And so the aim of this post is to build such an American Sign Language Recognition System.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/SkR0qk59Nc-jKggp41TAHT8TQFairUfB5oKH" alt="Image" width="800" height="270" loading="lazy"></p>
<p>Wikipedia has defined ASL as the following:</p>
<blockquote>
<p><strong>American Sign Language</strong> (<strong>ASL</strong>) is a <a target="_blank" href="https://en.wikipedia.org/wiki/Natural_language">natural language</a> that serves as the predominant <a target="_blank" href="https://en.wikipedia.org/wiki/Sign_language">sign language</a> of <a target="_blank" href="https://en.wikipedia.org/wiki/Deaf_communities">Deaf communities</a> in the United States and most of Anglophone Canada.</p>
</blockquote>
<p>First, the data: it is really important to remember the diversity of image classes with respect to influential factors like lighting conditions, zooming conditions etc. <a target="_blank" href="https://www.kaggle.com/grassknoted/asl-alphabet">Kaggle data on ASL</a> has all such different variants. Training on such data makes sure our model has pretty good knowledge of each class. So, let's work on the K<a target="_blank" href="https://www.kaggle.com/grassknoted/asl-alphabet">aggle data</a>.</p>
<p>The dataset consists of the images of hand gestures for each letter in the English alphabet. The images of a single class are of different variants — that is, zoomed versions, dim and bright light conditions, etc. For each class, there are as many as 3000 images. Let us consider classifying “A”, “B” and “C” images in our work for simplicity. Here are links for the full code for <a target="_blank" href="https://github.com/vagdevik/American-Sign-Language-Recognition-System/blob/master/2_AlexNet/asl_full.py">training</a> and <a target="_blank" href="https://github.com/vagdevik/American-Sign-Language-Recognition-System/blob/master/2_AlexNet/predict_full.py">testing</a>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/2Ja-bVTS-nR0ToERP8duawXQ2fFxG8RsH7GS" alt="Image" width="265" height="265" loading="lazy">
<em>An image for the letter ‘A’ from the dataset</em></p>
<p>We are going to build an <a target="_blank" href="https://www.learnopencv.com/understanding-alexnet/">AlexNet</a> to achieve this classification task. Since we are training the CNN, make sure that there is the support of computational resources like GPU.</p>
<p>We start by importing the necessary modules.</p>
<pre><code><span class="hljs-keyword">import</span> warningswarnings.filterwarnings(<span class="hljs-string">"ignore"</span>, category=DeprecationWarning)
</code></pre><pre><code><span class="hljs-keyword">import</span> osimport cv2import randomimport numpy <span class="hljs-keyword">as</span> npimport kerasfrom random <span class="hljs-keyword">import</span> shufflefrom keras.utils <span class="hljs-keyword">import</span> np_utilsfrom shutil <span class="hljs-keyword">import</span> unpack_archive
</code></pre><pre><code>print(<span class="hljs-string">"Imported Modules..."</span>)
</code></pre><p>Download the data zip file from K<a target="_blank" href="https://www.kaggle.com/grassknoted/asl-alphabet">aggle data</a>. Now, let us select the gesture images for A, B, and C and split the obtained data into training data, validation data, and test data.</p>
<pre><code># data folder pathdata_folder_path = <span class="hljs-string">"asl_data/new"</span> files = os.listdir(data_folder_path)
</code></pre><pre><code># shuffling the images <span class="hljs-keyword">in</span> the folderfor i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>):   shuffle(files)
</code></pre><pre><code>print(<span class="hljs-string">"Shuffled Data Files"</span>)
</code></pre><pre><code># dictionary to maintain numerical labelsclass_dic = {<span class="hljs-string">"A"</span>:<span class="hljs-number">0</span>,<span class="hljs-string">"B"</span>:<span class="hljs-number">1</span>,<span class="hljs-string">"C"</span>:<span class="hljs-number">2</span>}
</code></pre><pre><code># dictionary to maintain countsclass_count = {<span class="hljs-string">'A'</span>:<span class="hljs-number">0</span>,<span class="hljs-string">'B'</span>:<span class="hljs-number">0</span>,<span class="hljs-string">'C'</span>:<span class="hljs-number">0</span>}
</code></pre><pre><code># training listsX = []Y = []
</code></pre><pre><code># validation listsX_val = []Y_val = []
</code></pre><pre><code># testing listsX_test = []Y_test = []
</code></pre><pre><code><span class="hljs-keyword">for</span> file_name <span class="hljs-keyword">in</span> files:  label = file_name[<span class="hljs-number">0</span>]  <span class="hljs-keyword">if</span> label <span class="hljs-keyword">in</span> class_dict:    path = data_folder_path+<span class="hljs-string">'/'</span>+file_name    image = cv2.imread(path)    resized_image = cv2.resize(image,(<span class="hljs-number">224</span>,<span class="hljs-number">224</span>))    <span class="hljs-keyword">if</span> class_count[label]&lt;<span class="hljs-number">2000</span>:      class_count[label]+=<span class="hljs-number">1</span>      X.append(resized_image)      Y.append(class_dic[label])    elif class_count[label]&gt;=<span class="hljs-number">2000</span> and class_count[label]&lt;<span class="hljs-number">2750</span>:      class_count[label]+=<span class="hljs-number">1</span>      X_val.append(resized_image)      Y_val.append(class_dic[label])    <span class="hljs-keyword">else</span>:      X_test.append(resized_image)      Y_test.append(class_dic[label])
</code></pre><p>Each image in the dataset is named according to a naming convention. The 34th image of class A is named as “A_34.jpg”. Hence, we consider only the first element of the name of the file string and check if it is of the desired class.</p>
<p>Also, we are splitting the images based on counts and storing those images in the X and Y lists — X for image, and Y for the corresponding classes. Here, counts refer to the number of images we wish to put in the training, validation, and test sets respectively. So here, out of 3000 images for each class, I have put 2000 images in the training set, 750 images in the validation set, and the remaining in the test set.</p>
<p>Some people also prefer to split based on the total dataset (not for each class as we did here), but this doesn’t promise that all classes are learned properly. The images are read and are stored in the form of Numpy arrays in the lists.</p>
<p>Now the label lists (the Y’s) are encoded to form numerical one-hot vectors. This is done by the np_utils.to_categorical.</p>
<pre><code># one-hot encodings <span class="hljs-keyword">of</span> the classesY = np_utils.to_categorical(Y)Y_val = np_utils.to_categorical(Y_val)Y_test = np_utils.to_categorical(Y_test)
</code></pre><p>Now, let us store these images in the form of .npy files. Basically, we create separate .npy files to store the images belonging to each set.</p>
<pre><code><span class="hljs-keyword">if</span> not os.path.exists(<span class="hljs-string">'Numpy_folder'</span>):    os.makedirs(<span class="hljs-string">'Numpy_folder'</span>)
</code></pre><pre><code>np.save(npy_data_path+<span class="hljs-string">'/train_set.npy'</span>,X)np.save(npy_data_path+<span class="hljs-string">'/train_classes.npy'</span>,Y)
</code></pre><pre><code>np.save(npy_data_path+<span class="hljs-string">'/validation_set.npy'</span>,X_val)np.save(npy_data_path+<span class="hljs-string">'/validation_classes.npy'</span>,Y_val)
</code></pre><pre><code>np.save(npy_data_path+<span class="hljs-string">'/test_set.npy'</span>,X_test)np.save(npy_data_path+<span class="hljs-string">'/test_classes.npy'</span>,Y_test)
</code></pre><pre><code>print(<span class="hljs-string">"Data pre-processing Success!"</span>)
</code></pre><p>Now that we have completed the data preprocessing part, let us take a look at the full data preprocessing code here:</p>
<pre><code># preprocess.py
</code></pre><pre><code><span class="hljs-keyword">import</span> warningswarnings.filterwarnings(<span class="hljs-string">"ignore"</span>, category=DeprecationWarning)
</code></pre><pre><code><span class="hljs-keyword">import</span> osimport cv2import randomimport numpy <span class="hljs-keyword">as</span> npimport kerasfrom random <span class="hljs-keyword">import</span> shufflefrom keras.utils <span class="hljs-keyword">import</span> np_utilsfrom shutil <span class="hljs-keyword">import</span> unpack_archive
</code></pre><pre><code>print(<span class="hljs-string">"Imported Modules..."</span>)
</code></pre><pre><code># data folder pathdata_folder_path = <span class="hljs-string">"asl_data/new"</span> files = os.listdir(data_folder_path)
</code></pre><pre><code># shuffling the images <span class="hljs-keyword">in</span> the folderfor i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>):   shuffle(files)
</code></pre><pre><code>print(<span class="hljs-string">"Shuffled Data Files"</span>)
</code></pre><pre><code># dictionary to maintain numerical labelsclass_dic = {<span class="hljs-string">"A"</span>:<span class="hljs-number">0</span>,<span class="hljs-string">"B"</span>:<span class="hljs-number">1</span>,<span class="hljs-string">"C"</span>:<span class="hljs-number">2</span>}
</code></pre><pre><code># dictionary to maintain countsclass_count = {<span class="hljs-string">'A'</span>:<span class="hljs-number">0</span>,<span class="hljs-string">'B'</span>:<span class="hljs-number">0</span>,<span class="hljs-string">'C'</span>:<span class="hljs-number">0</span>}
</code></pre><pre><code># training listsX = []Y = []
</code></pre><pre><code># validation listsX_val = []Y_val = []
</code></pre><pre><code># testing listsX_test = []Y_test = []
</code></pre><pre><code><span class="hljs-keyword">for</span> file_name <span class="hljs-keyword">in</span> files:  label = file_name[<span class="hljs-number">0</span>]  <span class="hljs-keyword">if</span> label <span class="hljs-keyword">in</span> class_dict:    path = data_folder_path+<span class="hljs-string">'/'</span>+file_name    image = cv2.imread(path)    resized_image = cv2.resize(image,(<span class="hljs-number">224</span>,<span class="hljs-number">224</span>))    <span class="hljs-keyword">if</span> class_count[label]&lt;<span class="hljs-number">2000</span>:      class_count[label]+=<span class="hljs-number">1</span>      X.append(resized_image)      Y.append(class_dic[label])    elif class_count[label]&gt;=<span class="hljs-number">2000</span> and class_count[label]&lt;<span class="hljs-number">2750</span>:      class_count[label]+=<span class="hljs-number">1</span>      X_val.append(resized_image)      Y_val.append(class_dic[label])    <span class="hljs-keyword">else</span>:      X_test.append(resized_image)      Y_test.append(class_dic[label])
</code></pre><pre><code># one-hot encodings <span class="hljs-keyword">of</span> the classesY = np_utils.to_categorical(Y)Y_val = np_utils.to_categorical(Y_val)Y_test = np_utils.to_categorical(Y_test)
</code></pre><pre><code><span class="hljs-keyword">if</span> not os.path.exists(<span class="hljs-string">'Numpy_folder'</span>):    os.makedirs(<span class="hljs-string">'Numpy_folder'</span>)
</code></pre><pre><code>np.save(npy_data_path+<span class="hljs-string">'/train_set.npy'</span>,X)np.save(npy_data_path+<span class="hljs-string">'/train_classes.npy'</span>,Y)
</code></pre><pre><code>np.save(npy_data_path+<span class="hljs-string">'/validation_set.npy'</span>,X_val)np.save(npy_data_path+<span class="hljs-string">'/validation_classes.npy'</span>,Y_val)
</code></pre><pre><code>np.save(npy_data_path+<span class="hljs-string">'/test_set.npy'</span>,X_test)np.save(npy_data_path+<span class="hljs-string">'/test_classes.npy'</span>,Y_test)
</code></pre><pre><code>print(<span class="hljs-string">"Data pre-processing Success!"</span>)
</code></pre><p>Now comes the training part! Let us start by importing the essential modules so we can construct and train the CNN AlexNet. Here it is primarily done using Keras.</p>
<pre><code># importing <span class="hljs-keyword">from</span> keras.optimizers <span class="hljs-keyword">import</span> SGDfrom keras.models <span class="hljs-keyword">import</span> Sequentialfrom keras.preprocessing <span class="hljs-keyword">import</span> imagefrom keras.layers.normalization <span class="hljs-keyword">import</span> BatchNormalizationfrom keras.layers <span class="hljs-keyword">import</span> Dense, Activation, Dropout, Flatten,Conv2D, MaxPooling2D
</code></pre><pre><code>print(<span class="hljs-string">"Imported Network Essentials"</span>)
</code></pre><p>We next go for loading the images stored in the form of .npy:</p>
<pre><code>X_train=np.load(npy_data_path+<span class="hljs-string">"/train_set.npy"</span>)Y_train=np.load(npy_data_path+<span class="hljs-string">"/train_classes.npy"</span>)
</code></pre><pre><code>X_valid=np.load(npy_data_path+<span class="hljs-string">"/validation_set.npy"</span>)Y_valid=np.load(npy_data_path+<span class="hljs-string">"/validation_classes.npy"</span>)
</code></pre><pre><code>X_test=np.load(npy_data_path+<span class="hljs-string">"/test_set.npy"</span>)Y_test=np.load(npy_data_path+<span class="hljs-string">"/test_classes.npy"</span>)
</code></pre><p>We then head towards defining the structure of our CNN. Assuming prior knowledge of the <a target="_blank" href="https://www.learnopencv.com/understanding-alexnet/">AlexNet</a> architecture, here is the Keras code for that.</p>
<pre><code>model = Sequential()
</code></pre><pre><code># <span class="hljs-number">1</span>st Convolutional Layermodel.add(Conv2D(filters=<span class="hljs-number">96</span>, input_shape=(<span class="hljs-number">224</span>,<span class="hljs-number">224</span>,<span class="hljs-number">3</span>), kernel_size=(<span class="hljs-number">11</span>,<span class="hljs-number">11</span>),strides=(<span class="hljs-number">4</span>,<span class="hljs-number">4</span>), padding=<span class="hljs-string">'valid'</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))
</code></pre><pre><code># Max Pooling model.add(MaxPooling2D(pool_size=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), strides=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), padding=<span class="hljs-string">'valid'</span>))
</code></pre><pre><code># Batch Normalisation before passing it to the next layermodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">2n</span>d Convolutional Layermodel.add(Conv2D(filters=<span class="hljs-number">256</span>, kernel_size=(<span class="hljs-number">11</span>,<span class="hljs-number">11</span>), strides=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>), padding=<span class="hljs-string">'valid'</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))
</code></pre><pre><code># Max Poolingmodel.add(MaxPooling2D(pool_size=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), strides=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), padding=<span class="hljs-string">'valid'</span>))
</code></pre><pre><code># Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">3</span>rd Convolutional Layermodel.add(Conv2D(filters=<span class="hljs-number">384</span>, kernel_size=(<span class="hljs-number">3</span>,<span class="hljs-number">3</span>), strides=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>), padding=<span class="hljs-string">'valid'</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))
</code></pre><pre><code># Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">4</span>th Convolutional Layermodel.add(Conv2D(filters=<span class="hljs-number">384</span>, kernel_size=(<span class="hljs-number">3</span>,<span class="hljs-number">3</span>), strides=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>), padding=<span class="hljs-string">'valid'</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))
</code></pre><pre><code># Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">5</span>th Convolutional Layermodel.add(Conv2D(filters=<span class="hljs-number">256</span>, kernel_size=(<span class="hljs-number">3</span>,<span class="hljs-number">3</span>), strides=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>), padding=<span class="hljs-string">'valid'</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))
</code></pre><pre><code># Max Poolingmodel.add(MaxPooling2D(pool_size=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), strides=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), padding=<span class="hljs-string">'valid'</span>))
</code></pre><pre><code># Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># Passing it to a dense layermodel.add(Flatten())
</code></pre><pre><code># <span class="hljs-number">1</span>st Dense Layermodel.add(Dense(<span class="hljs-number">4096</span>, input_shape=(<span class="hljs-number">224</span>*<span class="hljs-number">224</span>*<span class="hljs-number">3</span>,)))model.add(Activation(<span class="hljs-string">'relu'</span>))
</code></pre><pre><code># Add Dropout to prevent overfittingmodel.add(Dropout(<span class="hljs-number">0.4</span>))
</code></pre><pre><code># Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">2n</span>d Dense Layermodel.add(Dense(<span class="hljs-number">4096</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))
</code></pre><pre><code># Add Dropoutmodel.add(Dropout(<span class="hljs-number">0.6</span>))
</code></pre><pre><code># Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">3</span>rd Dense Layermodel.add(Dense(<span class="hljs-number">1000</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))
</code></pre><pre><code># Add Dropoutmodel.add(Dropout(<span class="hljs-number">0.5</span>))
</code></pre><pre><code># Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># Output Layermodel.add(Dense(<span class="hljs-number">24</span>))model.add(Activation(<span class="hljs-string">'softmax'</span>))
</code></pre><pre><code>model.summary()
</code></pre><p>The <code>Sequential</code> model is a linear stack of layers. We add the convolutional layers (applying filters), activation layers (for non-linearity), max-pooling layers (for computational efficiency) and batch normalization layers (to standardize the input values from the previous layer to the next layer) and the pattern is repeated five times.</p>
<p>The Batch Normalization layer was introduced in 2014 by Ioffe and Szegedy. It addresses the vanishing gradient problem by standardizing the output of the previous layer, it speeds up the training by reducing the number of required iterations, and it enables the training of deeper neural networks.</p>
<p>At last, 3 fully-connected dense layers along with dropouts (to avoid over-fitting) are added.</p>
<p>To get the summarized description of the model, use model.summary().</p>
<p>The following is the code for the compilation part of the model. We define the optimization method to follow as SGD and set the parameters.</p>
<pre><code># Compile sgd = SGD(lr=<span class="hljs-number">0.001</span>)
</code></pre><pre><code>model.compile(loss=<span class="hljs-string">'categorical_crossentropy'</span>, optimizer=sgd, metrics=[<span class="hljs-string">'accuracy'</span>])
</code></pre><pre><code>checkpoint = keras.callbacks.ModelCheckpoint(<span class="hljs-string">"Checkpoint/weights.{epoch:02d}-{val_loss:.2f}.hdf5"</span>, monitor=<span class="hljs-string">'val_loss'</span>, verbose=<span class="hljs-number">0</span>,
</code></pre><pre><code>save_best_only=False, save_weights_only=False, mode=<span class="hljs-string">'auto'</span>, period=<span class="hljs-number">1</span>)
</code></pre><p><code>lr</code> in SGD is the learning rate. Since this is a categorical classification, we use categorical<em>crossentropy as the loss function in <code>model.compile</code>. We set the optimizer to be <code>sgd</code></em>,_ the SGD object we have defined and set the evaluation metric to be accuracy.</p>
<p>While using GPU, sometimes it may happen to interrupt its running. Using checkpoints is the best way to store the weights we had gotten up to the point of interruption, so that we may use them later. The first parameter is to set the place to store: save it as <code>weights.{epoch:02d}-{val_loss:.2f}.hdf5</code> in the Checkpoints folder.</p>
<p>Finally, we save the model in the json format and weights in .h5 format. These are thus saved locally in the specified folders.</p>
<pre><code># serialize model to JSONmodel_json = model.to_json()<span class="hljs-keyword">with</span> open(<span class="hljs-string">"Weights_Full/model.json"</span>, <span class="hljs-string">"w"</span>) <span class="hljs-keyword">as</span> json_file:    json_file.write(model_json)
</code></pre><pre><code># serialize weights to HDF5model.save_weights(<span class="hljs-string">"Weights_Full/model_weights.h5"</span>)print(<span class="hljs-string">"Saved model to disk"</span>)
</code></pre><p>Let’s look at the whole code of defining and training the network. Consider this as a separate file ‘training.py’.</p>
<pre><code># training.py
</code></pre><pre><code><span class="hljs-keyword">from</span> keras.optimizers <span class="hljs-keyword">import</span> SGDfrom keras.models <span class="hljs-keyword">import</span> Sequentialfrom keras.preprocessing <span class="hljs-keyword">import</span> imagefrom keras.layers.normalization <span class="hljs-keyword">import</span> BatchNormalizationfrom keras.layers <span class="hljs-keyword">import</span> Dense, Activation, Dropout, Flatten,Conv2D, MaxPooling2D
</code></pre><pre><code>print(<span class="hljs-string">"Imported Network Essentials"</span>)
</code></pre><pre><code># loading .npy datasetX_train=np.load(npy_data_path+<span class="hljs-string">"/train_set.npy"</span>)Y_train=np.load(npy_data_path+<span class="hljs-string">"/train_classes.npy"</span>)
</code></pre><pre><code>X_valid=np.load(npy_data_path+<span class="hljs-string">"/validation_set.npy"</span>)Y_valid=np.load(npy_data_path+<span class="hljs-string">"/validation_classes.npy"</span>)
</code></pre><pre><code>X_test=np.load(npy_data_path+<span class="hljs-string">"/test_set.npy"</span>)Y_test=np.load(npy_data_path+<span class="hljs-string">"/test_classes.npy"</span>)
</code></pre><pre><code>X_test.shape
</code></pre><pre><code>model = Sequential()# <span class="hljs-number">1</span>st Convolutional Layermodel.add(Conv2D(filters=<span class="hljs-number">96</span>, input_shape=(<span class="hljs-number">224</span>,<span class="hljs-number">224</span>,<span class="hljs-number">3</span>), kernel_size=(<span class="hljs-number">11</span>,<span class="hljs-number">11</span>),strides=(<span class="hljs-number">4</span>,<span class="hljs-number">4</span>), padding=<span class="hljs-string">'valid'</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))# Pooling model.add(MaxPooling2D(pool_size=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), strides=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), padding=<span class="hljs-string">'valid'</span>))# Batch Normalisation before passing it to the next layermodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">2n</span>d Convolutional Layermodel.add(Conv2D(filters=<span class="hljs-number">256</span>, kernel_size=(<span class="hljs-number">11</span>,<span class="hljs-number">11</span>), strides=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>), padding=<span class="hljs-string">'valid'</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))# Poolingmodel.add(MaxPooling2D(pool_size=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), strides=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), padding=<span class="hljs-string">'valid'</span>))# Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">3</span>rd Convolutional Layermodel.add(Conv2D(filters=<span class="hljs-number">384</span>, kernel_size=(<span class="hljs-number">3</span>,<span class="hljs-number">3</span>), strides=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>), padding=<span class="hljs-string">'valid'</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))# Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">4</span>th Convolutional Layermodel.add(Conv2D(filters=<span class="hljs-number">384</span>, kernel_size=(<span class="hljs-number">3</span>,<span class="hljs-number">3</span>), strides=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>), padding=<span class="hljs-string">'valid'</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))# Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">5</span>th Convolutional Layermodel.add(Conv2D(filters=<span class="hljs-number">256</span>, kernel_size=(<span class="hljs-number">3</span>,<span class="hljs-number">3</span>), strides=(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>), padding=<span class="hljs-string">'valid'</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))# Poolingmodel.add(MaxPooling2D(pool_size=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), strides=(<span class="hljs-number">2</span>,<span class="hljs-number">2</span>), padding=<span class="hljs-string">'valid'</span>))# Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># Passing it to a dense layermodel.add(Flatten())# <span class="hljs-number">1</span>st Dense Layermodel.add(Dense(<span class="hljs-number">4096</span>, input_shape=(<span class="hljs-number">224</span>*<span class="hljs-number">224</span>*<span class="hljs-number">3</span>,)))model.add(Activation(<span class="hljs-string">'relu'</span>))# Add Dropout to prevent overfittingmodel.add(Dropout(<span class="hljs-number">0.4</span>))# Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">2n</span>d Dense Layermodel.add(Dense(<span class="hljs-number">4096</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))# Add Dropoutmodel.add(Dropout(<span class="hljs-number">0.6</span>))# Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># <span class="hljs-number">3</span>rd Dense Layermodel.add(Dense(<span class="hljs-number">1000</span>))model.add(Activation(<span class="hljs-string">'relu'</span>))# Add Dropoutmodel.add(Dropout(<span class="hljs-number">0.5</span>))# Batch Normalisationmodel.add(BatchNormalization())
</code></pre><pre><code># Output Layermodel.add(Dense(<span class="hljs-number">24</span>))model.add(Activation(<span class="hljs-string">'softmax'</span>))
</code></pre><pre><code>model.summary()
</code></pre><pre><code># (<span class="hljs-number">4</span>) Compile sgd = SGD(lr=<span class="hljs-number">0.001</span>)model.compile(loss=<span class="hljs-string">'categorical_crossentropy'</span>, optimizer=sgd, metrics=[<span class="hljs-string">'accuracy'</span>])checkpoint = keras.callbacks.ModelCheckpoint(<span class="hljs-string">"Checkpoint/weights.{epoch:02d}-{val_loss:.2f}.hdf5"</span>, monitor=<span class="hljs-string">'val_loss'</span>, verbose=<span class="hljs-number">0</span>, save_best_only=False, save_weights_only=False, mode=<span class="hljs-string">'auto'</span>, period=<span class="hljs-number">1</span>)# (<span class="hljs-number">5</span>) Trainmodel.fit(X_train/<span class="hljs-number">255.0</span>, Y_train, batch_size=<span class="hljs-number">32</span>, epochs=<span class="hljs-number">50</span>, verbose=<span class="hljs-number">1</span>,validation_data=(X_valid/<span class="hljs-number">255.0</span>,Y_valid/<span class="hljs-number">255.0</span>), shuffle=True,callbacks=[checkpoint])
</code></pre><pre><code># serialize model to JSONmodel_json = model.to_json()<span class="hljs-keyword">with</span> open(<span class="hljs-string">"Weights_Full/model.json"</span>, <span class="hljs-string">"w"</span>) <span class="hljs-keyword">as</span> json_file:    json_file.write(model_json)# serialize weights to HDF5model.save_weights(<span class="hljs-string">"Weights_Full/model_weights.h5"</span>)print(<span class="hljs-string">"Saved model to disk"</span>)
</code></pre><p>When we run the training.py file, we get to see something as follows:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/QPaPyUKNcBciGmQDLii7chrt-EMmvZ3lDs7T" alt="Image" width="800" height="412" loading="lazy"></p>
<p>For example, considering the first epoch of 12(Epoch 1/12):</p>
<ul>
<li>it took 1852s to complete that epoch</li>
<li>the training loss was 0.2441</li>
<li>accuracy was 0.9098 on the validation data</li>
<li>0.0069 was the validation loss, and</li>
<li>0.9969 was the validation accuracy.</li>
</ul>
<p>So based on these values, we know the parameters of which epochs are performing better, where to stop training, and how to tune the hyperparameter values.</p>
<p>Now it’s time for testing!</p>
<pre><code># test.py
</code></pre><pre><code><span class="hljs-keyword">import</span> warningswarnings.filterwarnings(<span class="hljs-string">"ignore"</span>, category=DeprecationWarning) <span class="hljs-keyword">from</span> keras.preprocessing <span class="hljs-keyword">import</span> imageimport numpy <span class="hljs-keyword">as</span> npfrom keras.models <span class="hljs-keyword">import</span> model_from_jsonfrom sklearn.metrics <span class="hljs-keyword">import</span> accuracy_score
</code></pre><pre><code># dimensions <span class="hljs-keyword">of</span> our imagesimage_size = <span class="hljs-number">224</span>
</code></pre><pre><code># load the model <span class="hljs-keyword">in</span> json formatwith open(<span class="hljs-string">'Model/model.json'</span>, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> f:    model = model_from_json(f.read())    model.summary()model.load_weights(<span class="hljs-string">'Model/model_weights.h5'</span>)model.load_weights(<span class="hljs-string">'Weights/weights.250-0.00.hdf5'</span>)
</code></pre><pre><code>X_test=np.load(<span class="hljs-string">"Numpy/test_set.npy"</span>)Y_test=np.load(<span class="hljs-string">"Numpy/test_classes.npy"</span>)
</code></pre><pre><code>Y_predict = model.predict(X_test)Y_predict = [np.argmax(r) <span class="hljs-keyword">for</span> r <span class="hljs-keyword">in</span> Y_predict]
</code></pre><pre><code>Y_test = [np.argmax(r) <span class="hljs-keyword">for</span> r <span class="hljs-keyword">in</span> Y_test]
</code></pre><pre><code>print(<span class="hljs-string">"##################"</span>)acc_score = accuracy_score(Y_test, Y_predict)print(<span class="hljs-string">"Accuracy: "</span> + str(acc_score))print(<span class="hljs-string">"##################"</span>)
</code></pre><p>From the above code, we load the saved model architecture and the best weights. Also, we load the .npy files (the Numpy form of the test set) and go for the prediction of these test set of images. In short, we just load the saved model architecture and assign it the learned weights.</p>
<p>Now the approximator function along with the learned coefficients (weights) is ready. We just need to test it by feeding the model with the test set images and evaluating its performance on this test set. One of the famous evaluation metrics is accuracy. The accuracy is given by <code>_accuracy_score_</code> of <code>sklearn.metrics</code>.</p>
<p>Thank you for reading! Happy learning! :)</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
