{"id":427,"date":"2021-05-31T19:46:16","date_gmt":"2021-05-31T15:16:16","guid":{"rendered":"https:\/\/m-shaeri.ir\/blog\/?p=427"},"modified":"2024-12-20T09:59:02","modified_gmt":"2024-12-20T06:29:02","slug":"tensorflow-keras-train-in-python-predict-use-in-c-plus","status":"publish","type":"post","link":"https:\/\/mshaeri.com\/blog\/tensorflow-keras-train-in-python-predict-use-in-c-plus\/","title":{"rendered":"TensorFlow-Keras Model, Train in Python, Use in C++"},"content":{"rendered":"\n<p>Despite many advantages of <strong>Python <\/strong>such as simple syntax, easy-to-read code and large number of available 3rd-party packages, when it comes to embedded systems and real-time applications, <strong>C++<\/strong> is undoubtedly one of the most efficient and powerful programming languages that dominates the realm of these systems. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/05\/EmbeddedProgrammingLanguages.png\"><img loading=\"lazy\" decoding=\"async\" width=\"615\" height=\"452\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/05\/EmbeddedProgrammingLanguages.png\" alt=\"Embedding System\" class=\"wp-image-434\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/05\/EmbeddedProgrammingLanguages.png 615w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/05\/EmbeddedProgrammingLanguages-300x220.png 300w\" sizes=\"(max-width: 615px) 100vw, 615px\" \/><\/a><figcaption class=\"wp-element-caption\">Top 10 languages that used in embedded projects (<a rel=\"noreferrer noopener\" href=\"http:\/\/images.content.ubmtechelectronics.com\/Web\/UBMTechElectronics\/%7Ba7a91f0e-87c0-4a6d-b861-d4147707f831%7D_2013EmbeddedMarketStudyb.pdf\" data-type=\"URL\" data-id=\"http:\/\/images.content.ubmtechelectronics.com\/Web\/UBMTechElectronics\/%7Ba7a91f0e-87c0-4a6d-b861-d4147707f831%7D_2013EmbeddedMarketStudyb.pdf\" target=\"_blank\">Reference<\/a>)<\/figcaption><\/figure>\n\n\n\n<p>However, complex syntax of<strong> C++<\/strong> makes it difficult to implement high level algorithm such as <strong>Machine Learning<\/strong> algorithms. For example building a small <strong>CNN network <\/strong>and it&#8217;s training pipeline can go so complex that no developer prefers doing such task the in <strong>C++<\/strong> from the scratch.<\/p>\n\n\n\n<p>In this post, we&#8217;ll learn how to transfer and use<strong> CNN models<\/strong> that is trained in <strong>Python <\/strong>with <strong>Keras <\/strong>to <strong>C++<\/strong> using a light weight header-only library named <strong>frugally-deep<\/strong>. I found no good tutorial on the web teaching this library and its usage in details. So, here we are going to explore it step by step.<\/p>\n\n\n\n<p>First we train a simple CNN network in Python on a 2000 Cat &amp; Dog image dataset. No matter how much accuracy we achieve, we just save the model to use it in the c++ code : <\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler\"><div class=\"wp-block-embed__wrapper\">\n<div id=\"gist109816281\" class=\"gist\">\n    <div class=\"gist-file\" translate=\"no\" data-color-mode=\"light\" data-light-theme=\"light\">\n      <div class=\"gist-data\">\n        \n<div class=\"js-gist-file-update-container js-task-list-container\">\n      <div id=\"file-catdogcnn-py\" class=\"file my-2\">\n    \n    <div itemprop=\"text\" class=\"Box-body p-0 blob-wrapper data type-python  \" style=\"overflow: auto\" tabindex=\"0\" role=\"region\" aria-label=\"CatDogCNN.py content, created by birddevelper on 07:41PM on May 31, 2021.\">\n\n        \n<div class=\"js-check-hidden-unicode js-blob-code-container blob-code-content\">\n\n  <template class=\"js-file-alert-template\">\n  <div data-view-component=\"true\" class=\"flash flash-warn flash-full d-flex flex-items-center\">\n  <svg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewbox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n    <span>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\"Link--inTextBlock\" href=\"https:\/\/github.co\/hiddenchars\" target=\"_blank\">Learn more about bidirectional Unicode characters<\/a>\n    <\/span>\n\n\n  <div data-view-component=\"true\" class=\"flash-action\">        <a href=\"%7B%7B%20revealButtonHref%20%7D%7D\" data-view-component=\"true\" class=\"btn-sm btn\">    Show hidden characters\n<\/a>\n<\/div>\n<\/div><\/template>\n<template class=\"js-line-alert-template\">\n  <span aria-label=\"This line has hidden Unicode characters\" data-view-component=\"true\" class=\"line-alert tooltipped tooltipped-e\">\n    <svg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewbox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n<\/span><\/template>\n\n  <table data-hpc class=\"highlight tab-size js-file-line-container\" data-tab-size=\"4\" data-paste-markdown-skip data-tagsearch-path=\"CatDogCNN.py\">\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L1\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"1\"><\/td>\n          <td id=\"file-catdogcnn-py-LC1\" class=\"blob-code blob-code-inner js-file-line\">import cv2<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L2\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"2\"><\/td>\n          <td id=\"file-catdogcnn-py-LC2\" class=\"blob-code blob-code-inner js-file-line\">import glob<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L3\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"3\"><\/td>\n          <td id=\"file-catdogcnn-py-LC3\" class=\"blob-code blob-code-inner js-file-line\">from sklearn.neighbors import KNeighborsClassifier<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L4\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"4\"><\/td>\n          <td id=\"file-catdogcnn-py-LC4\" class=\"blob-code blob-code-inner js-file-line\">import numpy as np<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L5\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"5\"><\/td>\n          <td id=\"file-catdogcnn-py-LC5\" class=\"blob-code blob-code-inner js-file-line\">from sklearn.preprocessing import LabelEncoder<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L6\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"6\"><\/td>\n          <td id=\"file-catdogcnn-py-LC6\" class=\"blob-code blob-code-inner js-file-line\">from tensorflow.keras.utils import to_categorical<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L7\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"7\"><\/td>\n          <td id=\"file-catdogcnn-py-LC7\" class=\"blob-code blob-code-inner js-file-line\">from joblib import dump, load<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L8\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"8\"><\/td>\n          <td id=\"file-catdogcnn-py-LC8\" class=\"blob-code blob-code-inner js-file-line\">from sklearn.model_selection import train_test_split<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L9\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"9\"><\/td>\n          <td id=\"file-catdogcnn-py-LC9\" class=\"blob-code blob-code-inner js-file-line\">import tensorflow as tf<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L10\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"10\"><\/td>\n          <td id=\"file-catdogcnn-py-LC10\" class=\"blob-code blob-code-inner js-file-line\">from tensorflow.keras import models<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L11\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"11\"><\/td>\n          <td id=\"file-catdogcnn-py-LC11\" class=\"blob-code blob-code-inner js-file-line\">from tensorflow.keras import layers<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L12\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"12\"><\/td>\n          <td id=\"file-catdogcnn-py-LC12\" class=\"blob-code blob-code-inner js-file-line\">import os<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L13\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"13\"><\/td>\n          <td id=\"file-catdogcnn-py-LC13\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L14\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"14\"><\/td>\n          <td id=\"file-catdogcnn-py-LC14\" class=\"blob-code blob-code-inner js-file-line\">data=[]<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L15\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"15\"><\/td>\n          <td id=\"file-catdogcnn-py-LC15\" class=\"blob-code blob-code-inner js-file-line\">labels=[]<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L16\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"16\"><\/td>\n          <td id=\"file-catdogcnn-py-LC16\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L17\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"17\"><\/td>\n          <td id=\"file-catdogcnn-py-LC17\" class=\"blob-code blob-code-inner js-file-line\">for item in glob.glob(\"Dataset\/*\/*\"):<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L18\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"18\"><\/td>\n          <td id=\"file-catdogcnn-py-LC18\" class=\"blob-code blob-code-inner js-file-line\">    img = cv2.imread(item,cv2.IMREAD_GRAYSCALE) # read images with one channel grayscale<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L19\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"19\"><\/td>\n          <td id=\"file-catdogcnn-py-LC19\" class=\"blob-code blob-code-inner js-file-line\">    r_img= cv2.resize(img,(128,128)) # resize to 128x128<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L20\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"20\"><\/td>\n          <td id=\"file-catdogcnn-py-LC20\" class=\"blob-code blob-code-inner js-file-line\">    r_img = np.expand_dims(r_img, axis = -1)<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L21\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"21\"><\/td>\n          <td id=\"file-catdogcnn-py-LC21\" class=\"blob-code blob-code-inner js-file-line\">    data.append(r_img) # add resized image to dataset list<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L22\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"22\"><\/td>\n          <td id=\"file-catdogcnn-py-LC22\" class=\"blob-code blob-code-inner js-file-line\">    label = item.split(\"\\\\\")[1]<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L23\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"23\"><\/td>\n          <td id=\"file-catdogcnn-py-LC23\" class=\"blob-code blob-code-inner js-file-line\">    labels.append(label) #add image label to dataset list<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L24\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"24\"><\/td>\n          <td id=\"file-catdogcnn-py-LC24\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L25\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"25\"><\/td>\n          <td id=\"file-catdogcnn-py-LC25\" class=\"blob-code blob-code-inner js-file-line\">#preprocess<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L26\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"26\"><\/td>\n          <td id=\"file-catdogcnn-py-LC26\" class=\"blob-code blob-code-inner js-file-line\">le = LabelEncoder()<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L27\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"27\"><\/td>\n          <td id=\"file-catdogcnn-py-LC27\" class=\"blob-code blob-code-inner js-file-line\">labels = le.fit_transform(labels)<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L28\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"28\"><\/td>\n          <td id=\"file-catdogcnn-py-LC28\" class=\"blob-code blob-code-inner js-file-line\">labels = to_categorical(labels)<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L29\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"29\"><\/td>\n          <td id=\"file-catdogcnn-py-LC29\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L30\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"30\"><\/td>\n          <td id=\"file-catdogcnn-py-LC30\" class=\"blob-code blob-code-inner js-file-line\">data = np.array(data)\/255 # Normalize channel between 0 to 1<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L31\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"31\"><\/td>\n          <td id=\"file-catdogcnn-py-LC31\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L32\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"32\"><\/td>\n          <td id=\"file-catdogcnn-py-LC32\" class=\"blob-code blob-code-inner js-file-line\">#split test and train randomly<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L33\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"33\"><\/td>\n          <td id=\"file-catdogcnn-py-LC33\" class=\"blob-code blob-code-inner js-file-line\">x_train, x_test, y_train, y_test = train_test_split(data,labels,test_size=0.2)<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L34\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"34\"><\/td>\n          <td id=\"file-catdogcnn-py-LC34\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L35\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"35\"><\/td>\n          <td id=\"file-catdogcnn-py-LC35\" class=\"blob-code blob-code-inner js-file-line\">#train<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L36\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"36\"><\/td>\n          <td id=\"file-catdogcnn-py-LC36\" class=\"blob-code blob-code-inner js-file-line\">net= models.Sequential(<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L37\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"37\"><\/td>\n          <td id=\"file-catdogcnn-py-LC37\" class=\"blob-code blob-code-inner js-file-line\">                        [<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L38\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"38\"><\/td>\n          <td id=\"file-catdogcnn-py-LC38\" class=\"blob-code blob-code-inner js-file-line\">                            layers.Conv2D(32,(3,3),strides=(1,1),activation=\"relu\",input_shape=(128,128,1)),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L39\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"39\"><\/td>\n          <td id=\"file-catdogcnn-py-LC39\" class=\"blob-code blob-code-inner js-file-line\">                            layers.Conv2D(32,(3,3),strides=(1,1),activation=\"relu\"),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L40\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"40\"><\/td>\n          <td id=\"file-catdogcnn-py-LC40\" class=\"blob-code blob-code-inner js-file-line\">                            layers.BatchNormalization(),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L41\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"41\"><\/td>\n          <td id=\"file-catdogcnn-py-LC41\" class=\"blob-code blob-code-inner js-file-line\">                            layers.MaxPool2D((3,3)),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L42\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"42\"><\/td>\n          <td id=\"file-catdogcnn-py-LC42\" class=\"blob-code blob-code-inner js-file-line\">                            layers.Conv2D(64,(5,5),strides=(1,1),activation=\"relu\"),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L43\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"43\"><\/td>\n          <td id=\"file-catdogcnn-py-LC43\" class=\"blob-code blob-code-inner js-file-line\">                            layers.Conv2D(64,(5,5),strides=(1,1),activation=\"relu\"),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L44\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"44\"><\/td>\n          <td id=\"file-catdogcnn-py-LC44\" class=\"blob-code blob-code-inner js-file-line\">                            layers.BatchNormalization(),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L45\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"45\"><\/td>\n          <td id=\"file-catdogcnn-py-LC45\" class=\"blob-code blob-code-inner js-file-line\">                            layers.AvgPool2D((3,3)),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L46\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"46\"><\/td>\n          <td id=\"file-catdogcnn-py-LC46\" class=\"blob-code blob-code-inner js-file-line\">                            layers.Dropout(0.75),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L47\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"47\"><\/td>\n          <td id=\"file-catdogcnn-py-LC47\" class=\"blob-code blob-code-inner js-file-line\">                            layers.Flatten(),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L48\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"48\"><\/td>\n          <td id=\"file-catdogcnn-py-LC48\" class=\"blob-code blob-code-inner js-file-line\">                            layers.Dense(64,activation=\"relu\"),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L49\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"49\"><\/td>\n          <td id=\"file-catdogcnn-py-LC49\" class=\"blob-code blob-code-inner js-file-line\">                            layers.Dense(16,activation=\"relu\"),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L50\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"50\"><\/td>\n          <td id=\"file-catdogcnn-py-LC50\" class=\"blob-code blob-code-inner js-file-line\">                            layers.Dense(2,activation=\"softmax\")<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L51\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"51\"><\/td>\n          <td id=\"file-catdogcnn-py-LC51\" class=\"blob-code blob-code-inner js-file-line\">                        ]<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L52\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"52\"><\/td>\n          <td id=\"file-catdogcnn-py-LC52\" class=\"blob-code blob-code-inner js-file-line\">                    )<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L53\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"53\"><\/td>\n          <td id=\"file-catdogcnn-py-LC53\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L54\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"54\"><\/td>\n          <td id=\"file-catdogcnn-py-LC54\" class=\"blob-code blob-code-inner js-file-line\">print(net.summary())<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L55\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"55\"><\/td>\n          <td id=\"file-catdogcnn-py-LC55\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L56\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"56\"><\/td>\n          <td id=\"file-catdogcnn-py-LC56\" class=\"blob-code blob-code-inner js-file-line\">net.compile(optimizer=\"SGD\", loss=\"binary_crossentropy\",metrics=[\"accuracy\"])<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L57\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"57\"><\/td>\n          <td id=\"file-catdogcnn-py-LC57\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L58\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"58\"><\/td>\n          <td id=\"file-catdogcnn-py-LC58\" class=\"blob-code blob-code-inner js-file-line\">H = net.fit(x_train,y_train,batch_size=32, epochs=24, validation_data=(x_test,y_test))<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L59\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"59\"><\/td>\n          <td id=\"file-catdogcnn-py-LC59\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L60\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"60\"><\/td>\n          <td id=\"file-catdogcnn-py-LC60\" class=\"blob-code blob-code-inner js-file-line\">net.save(\"CatDogNew.h5\")  # Save the model<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-catdogcnn-py-L61\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"61\"><\/td>\n          <td id=\"file-catdogcnn-py-LC61\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n  <\/table>\n<\/div>\n\n\n    <\/div>\n\n  <\/div>\n\n<\/div>\n\n      <\/div>\n      <div class=\"gist-meta\">\n        <a href=\"https:\/\/gist.github.com\/birddevelper\/4778bdb74094ebaf52a70cf9441da6c0\/raw\/7d161198b6369ab622103930e135730e29af324d\/CatDogCNN.py\" style=\"float:right\" class=\"Link--inTextBlock\">view raw<\/a>\n        <a href=\"https:\/\/gist.github.com\/birddevelper\/4778bdb74094ebaf52a70cf9441da6c0#file-catdogcnn-py\" class=\"Link--inTextBlock\">\n          CatDogCNN.py\n        <\/a>\n        hosted with &#10084; by <a class=\"Link--inTextBlock\" href=\"https:\/\/github.com\">GitHub<\/a>\n      <\/div>\n    <\/div>\n<\/div>\n\n<\/div><\/figure>\n\n\n\n<p>After running the above code , we will have our model &#8220;CatDogNew.h5&#8221; file saved in project folder. <\/p>\n\n\n\n<p>Before we start the next step we need to download the library from its repository on <a href=\"https:\/\/github.com\/Dobiasd\/frugally-deep\" data-type=\"URL\" data-id=\"https:\/\/github.com\/Dobiasd\/frugally-deep\" target=\"_blank\" rel=\"noreferrer noopener\"><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-bright-blue-color\"><strong>gihub<\/strong><\/span><\/a>. After download , find &#8220;keras_export&#8221; directory in the main folder of the library, and open command prompt from this directory :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/05\/keras_export.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"635\" height=\"415\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/05\/keras_export.jpg\" alt=\"keras model export to json\" class=\"wp-image-451\" style=\"width:476px;height:311px\" title=\"keras export to cpp\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/05\/keras_export.jpg 635w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/05\/keras_export-300x196.jpg 300w\" sizes=\"(max-width: 635px) 100vw, 635px\" \/><\/a><figcaption class=\"wp-element-caption\">open command prompt in keras_export folder<\/figcaption><\/figure>\n\n\n\n<p>Now, we should convert the model to <strong>json <\/strong>file using <strong>convert_model.py<\/strong> . Run the following command in the command line to build model in <strong>json <\/strong>format :<\/p>\n\n\n\n<pre title=\"\" class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">python convert_model.py path\/to\/your\/model\/CatDogNew.h5 CatDogNew.json<\/code><\/pre>\n\n\n\n<p> Running the above command will yield &#8220;<span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-medium-pink-color\">CatDogNew.json<\/span>&#8221; in the <span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-medium-pink-color\">keras_export <\/span>folder.<\/p>\n\n\n\n<p>In this step which is so important, we should prepare our Visual Studio project to use the <strong>frugally-deep<\/strong> library. I use Visual Studio 2019, however there is no big difference between this version and its old ones.  First, Create new <span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-medium-pink-color\">Console App<\/span> and choose a name for it.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/05\/keras_export_to_cpp_1.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"703\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/05\/keras_export_to_cpp_1-1024x703.jpg\" alt=\"keras model to cpp json\" class=\"wp-image-471\" title=\"create new project to import keras model\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/05\/keras_export_to_cpp_1-1024x703.jpg 1024w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/05\/keras_export_to_cpp_1-300x206.jpg 300w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/05\/keras_export_to_cpp_1-768x527.jpg 768w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/05\/keras_export_to_cpp_1.jpg 1300w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Create new Console App project <\/figcaption><\/figure>\n\n\n\n<p>After creating the Project, you should have one cpp file opened with a main function containing &#8220;hello world&#8221; output. Now, It&#8217;s time to include library header file in project. Frugally-deep depends on 3 other libraries which they are also header-only and can be included without any pain. The libraries are :<\/p>\n\n\n\n<ul style=\"font-size:14px\" class=\"has-dark-purple-color has-text-color\">\n<li><code><strong>Eigen<\/strong><\/code><\/li>\n\n\n\n<li><code><strong>fplus<\/strong><\/code><\/li>\n\n\n\n<li><code><strong>nlohmann<\/strong><\/code><\/li>\n<\/ul>\n\n\n\n<p>I gathered all of them in a zip file that you can download it with just a click <a href=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/includesLibrary.zip\" data-type=\"URL\" data-id=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/includesLibrary.zip\"><span class=\"has-inline-color has-bright-blue-color\">here<\/span><\/a>. I added the frugally-deep header files to the zip file so you don&#8217;t need to get it from source code downloaded from github.<\/p>\n\n\n\n<p>Extract zip file and move the <span class=\"has-inline-color has-medium-pink-color\">include <\/span>folder to a place that is easy to address later. The include folder must contains all libraries like below : <\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_2.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"807\" height=\"203\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_2.jpg\" alt=\"tensorflow keras c plus c++\" class=\"wp-image-544\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_2.jpg 807w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_2-300x75.jpg 300w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_2-768x193.jpg 768w\" sizes=\"(max-width: 807px) 100vw, 807px\" \/><\/a><figcaption class=\"wp-element-caption\">the extracted folder should contain 4 libraries<\/figcaption><\/figure>\n\n\n\n<p>Open <span class=\"has-inline-color has-medium-pink-color\">project properties<\/span> from Project menu, in the left side panel click on <span class=\"has-inline-color has-medium-pink-color\">VC++ Directories<\/span>, then in right side edit the <span class=\"has-inline-color has-medium-pink-color\"><strong>Include Directories<\/strong><\/span> row and insert the path to the already extracted include folder containing 4 libraries in the field :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_3.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"664\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_3-1024x664.jpg\" alt=\"keras model to cpp\" class=\"wp-image-548\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_3-1024x664.jpg 1024w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_3-300x194.jpg 300w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_3-768x498.jpg 768w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_3.jpg 1245w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Add extracted include folder address to project<\/figcaption><\/figure>\n\n\n\n<p>As the the frugally-deep is a header-only library, it need no more configuration in project properties. So, we can go to the project&#8217;s main file and past following codes in it :<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler\"><div class=\"wp-block-embed__wrapper\">\n<div id=\"gist109840598\" class=\"gist\">\n    <div class=\"gist-file\" translate=\"no\" data-color-mode=\"light\" data-light-theme=\"light\">\n      <div class=\"gist-data\">\n        \n<div class=\"js-gist-file-update-container js-task-list-container\">\n      <div id=\"file-kerasmodelincpp-cpp\" class=\"file my-2\">\n    \n    <div itemprop=\"text\" class=\"Box-body p-0 blob-wrapper data type-c  \" style=\"overflow: auto\" tabindex=\"0\" role=\"region\" aria-label=\"kerasModelInCpp.cpp content, created by birddevelper on 02:36PM on June 01, 2021.\">\n\n        \n<div class=\"js-check-hidden-unicode js-blob-code-container blob-code-content\">\n\n  <template class=\"js-file-alert-template\">\n  <div data-view-component=\"true\" class=\"flash flash-warn flash-full d-flex flex-items-center\">\n  <svg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewbox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n    <span>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\"Link--inTextBlock\" href=\"https:\/\/github.co\/hiddenchars\" target=\"_blank\">Learn more about bidirectional Unicode characters<\/a>\n    <\/span>\n\n\n  <div data-view-component=\"true\" class=\"flash-action\">        <a href=\"%7B%7B%20revealButtonHref%20%7D%7D\" data-view-component=\"true\" class=\"btn-sm btn\">    Show hidden characters\n<\/a>\n<\/div>\n<\/div><\/template>\n<template class=\"js-line-alert-template\">\n  <span aria-label=\"This line has hidden Unicode characters\" data-view-component=\"true\" class=\"line-alert tooltipped tooltipped-e\">\n    <svg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewbox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n<\/span><\/template>\n\n  <table data-hpc class=\"highlight tab-size js-file-line-container\" data-tab-size=\"4\" data-paste-markdown-skip data-tagsearch-path=\"kerasModelInCpp.cpp\">\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L1\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"1\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC1\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L2\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"2\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC2\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;iostream&gt;<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L3\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"3\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC3\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;fdeep\/fdeep.hpp&gt;<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L4\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"4\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC4\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;opencv2\/core\/core.hpp&gt;<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L5\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"5\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC5\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;opencv2\/highgui\/highgui.hpp&gt;<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L6\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"6\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC6\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;opencv2\/imgproc.hpp&gt;<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L7\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"7\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC7\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;filesystem&gt;<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L8\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"8\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC8\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;exception&gt;<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L9\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"9\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC9\" class=\"blob-code blob-code-inner js-file-line\">using namespace stdext;<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L10\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"10\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC10\" class=\"blob-code blob-code-inner js-file-line\">namespace fs = std::filesystem;<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L11\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"11\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC11\" class=\"blob-code blob-code-inner js-file-line\">int main()<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L12\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"12\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC12\" class=\"blob-code blob-code-inner js-file-line\">{<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L13\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"13\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC13\" class=\"blob-code blob-code-inner js-file-line\">    <\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L14\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"14\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC14\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L15\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"15\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC15\" class=\"blob-code blob-code-inner js-file-line\">        std::string test_image_folder_path = \"d:\/catdog\/\"; \/\/ path to folder containing test images<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L16\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"16\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC16\" class=\"blob-code blob-code-inner js-file-line\">        const auto mymodel = fdeep::load_model(\"D:\/CatDogNew.json\"); \/\/ load the converted model<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L17\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"17\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC17\" class=\"blob-code blob-code-inner js-file-line\">        for (const auto&amp; entry : fs::directory_iterator(test_image_folder_path)) {<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L18\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"18\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC18\" class=\"blob-code blob-code-inner js-file-line\">           try<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L19\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"19\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC19\" class=\"blob-code blob-code-inner js-file-line\">             { <\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L20\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"20\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC20\" class=\"blob-code blob-code-inner js-file-line\">                    std::string image_path = entry.path().string(); \/\/ get images path one by one<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L21\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"21\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC21\" class=\"blob-code blob-code-inner js-file-line\">                    const cv::Mat image = cv::imread(image_path, cv::IMREAD_GRAYSCALE);  \/\/ read the image in single channel grayscale mode <\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L22\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"22\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC22\" class=\"blob-code blob-code-inner js-file-line\">                   <\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L23\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"23\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC23\" class=\"blob-code blob-code-inner js-file-line\">                    cv::Mat resizedImg;<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L24\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"24\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC24\" class=\"blob-code blob-code-inner js-file-line\">                    cv::resize(image, resizedImg, cv::Size(128, 128)); \/\/ resize image to the 128x128 (Model input dimension)<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L25\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"25\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC25\" class=\"blob-code blob-code-inner js-file-line\">                    imshow(\"Display Window\", resizedImg); \/\/ just show the image<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L26\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"26\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC26\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L27\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"27\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC27\" class=\"blob-code blob-code-inner js-file-line\">                    \/\/ convert cv::MAT to fdeep::tensor<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L28\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"28\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC28\" class=\"blob-code blob-code-inner js-file-line\">                    const auto input = fdeep::tensor_from_bytes(resizedImg.ptr(),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L29\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"29\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC29\" class=\"blob-code blob-code-inner js-file-line\">                        static_cast&lt;std::size_t&gt;(resizedImg.rows),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L30\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"30\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC30\" class=\"blob-code blob-code-inner js-file-line\">                        static_cast&lt;std::size_t&gt;(resizedImg.cols),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L31\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"31\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC31\" class=\"blob-code blob-code-inner js-file-line\">                        static_cast&lt;std::size_t&gt;(resizedImg.channels()),<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L32\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"32\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC32\" class=\"blob-code blob-code-inner js-file-line\">                        0.0f, 1.0f); <\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L33\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"33\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC33\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L34\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"34\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC34\" class=\"blob-code blob-code-inner js-file-line\">                    auto result = mymodel.predict({ input }); \/\/ predict the image's label and ouput a 1x2 tensor containing each class probability<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L35\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"35\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC35\" class=\"blob-code blob-code-inner js-file-line\">                    std::cout &lt;&lt; fdeep::show_tensors(result) &lt;&lt; std::endl; \/\/ print the tensor<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L36\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"36\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC36\" class=\"blob-code blob-code-inner js-file-line\">                    cv::waitKey();<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L37\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"37\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC37\" class=\"blob-code blob-code-inner js-file-line\">        }<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L38\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"38\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC38\" class=\"blob-code blob-code-inner js-file-line\">        catch (const std::exception&amp; e)<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L39\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"39\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC39\" class=\"blob-code blob-code-inner js-file-line\">        {<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L40\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"40\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC40\" class=\"blob-code blob-code-inner js-file-line\">            std::cout &lt;&lt; e.what() &lt;&lt; '\\n';<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L41\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"41\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC41\" class=\"blob-code blob-code-inner js-file-line\">        }<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L42\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"42\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC42\" class=\"blob-code blob-code-inner js-file-line\">    }<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L43\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"43\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC43\" class=\"blob-code blob-code-inner js-file-line\">    <\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L44\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"44\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC44\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr class=\"line\">\n          <td id=\"file-kerasmodelincpp-cpp-L45\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"45\"><\/td>\n          <td id=\"file-kerasmodelincpp-cpp-LC45\" class=\"blob-code blob-code-inner js-file-line\">}<\/td>\n        <\/tr>\n  <\/table>\n<\/div>\n\n\n    <\/div>\n\n  <\/div>\n\n<\/div>\n\n      <\/div>\n      <div class=\"gist-meta\">\n        <a href=\"https:\/\/gist.github.com\/birddevelper\/ce3b6edcd71f3e7bf3d579e81c247777\/raw\/9bb05c3497bba9602565de11aebdc9091279bf27\/kerasModelInCpp.cpp\" style=\"float:right\" class=\"Link--inTextBlock\">view raw<\/a>\n        <a href=\"https:\/\/gist.github.com\/birddevelper\/ce3b6edcd71f3e7bf3d579e81c247777#file-kerasmodelincpp-cpp\" class=\"Link--inTextBlock\">\n          kerasModelInCpp.cpp\n        <\/a>\n        hosted with &#10084; by <a class=\"Link--inTextBlock\" href=\"https:\/\/github.com\">GitHub<\/a>\n      <\/div>\n    <\/div>\n<\/div>\n\n<\/div><\/figure>\n\n\n\n<p>let&#8217;s see what happens in important parts of the code, line by line:<\/p>\n\n\n\n<p> <span style=\"background-color:rgba(0, 0, 0, 0);color:#061589\" class=\"has-inline-color\">Line 1 to 8<\/span> is doing include jobs. First of all, we need to have <strong>OpenCV <\/strong>installed, to install and use  <strong>OpenCV <\/strong>in <strong>c++<\/strong> please see this<span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-bright-blue-color\"> <\/span><a href=\"https:\/\/towardsdatascience.com\/install-and-configure-opencv-4-2-0-in-windows-10-vc-d132c52063a1\" data-type=\"URL\" data-id=\"https:\/\/towardsdatascience.com\/install-and-configure-opencv-4-2-0-in-windows-10-vc-d132c52063a1\" target=\"_blank\" rel=\"noreferrer noopener\"><span style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-bright-blue-color\">post<\/span><\/a>.  Then we load the JSON model in <span style=\"background-color:rgba(0, 0, 0, 0);color:#061589\" class=\"has-inline-color\">line 16<\/span>. We have accomplished half of the job, but the important part of the code is still remained, reading image and applying preprocess. We must feed the model with (128,128) single channel image that is normalized to [0-1] for each pixel. In <span style=\"background-color:rgba(0, 0, 0, 0);color:#061589\" class=\"has-inline-color\">line 21<\/span> we read the image in grayscale mode, then resize it in <span style=\"background-color:rgba(0, 0, 0, 0);color:#061589\" class=\"has-inline-color\">line 24<\/span>. The normalization part still remained. We will do it when we are converting the image matrix to tensor. The <span style=\"background-color:rgba(0, 0, 0, 0);color:#061589\" class=\"has-inline-color\"><strong>tensor_from_bytes<\/strong> <\/span>function in frugally-deep library does it for us in <span style=\"background-color:rgba(0, 0, 0, 0);color:#061589\" class=\"has-inline-color\">line 28<\/span>. It takes 6 input parameters, first one is the image matrix pointer, the second and third parameters are the image height and image width. Fourth parameter is the number of channels. And very important last parameters are intended to re-scale the channel values from range [0, 255] to [low, high] in which the low and high must be specified with fifth and sixth parameters.<\/p>\n\n\n\n<p>Finally we pass the input tensor to predict function, maybe you ask why we give it within {}, the answer is : <strong>frugally-deep<\/strong> supports models with multiple inputs , so we give each input in {}, separated by comma. The predict function output a tensor array that each element shows the corresponding class probability.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_4.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"594\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_4-1024x594.jpg\" alt=\"tensorflow keras c plus c++\" class=\"wp-image-571\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_4-1024x594.jpg 1024w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_4-300x174.jpg 300w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_4-768x445.jpg 768w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2021\/06\/keras_export_to_cpp_4.jpg 1133w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Final Output that predicted the Cat with 58% of confidence<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Congratulations! You have made your way to the end of this short journey. Our CNN model was trained in python, converted, and then used in C++. <\/p>\n\n\n\n<p>Although using <strong>frugally-deep<\/strong> in your c++ project can be funny, you should know its pros and cons :<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pros<\/h3>\n\n\n\n<ul>\n<li><strong>Performance<\/strong>: Since it\u2019s a C++ library, it can offer better performance compared to running the same model in Python.<\/li>\n\n\n\n<li><strong>Deployment<\/strong>: Useful for deploying models in environments where Python is not an option (e.g., embedded systems).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Cons<\/h3>\n\n\n\n<ul>\n<li><strong>Complex Models<\/strong>: There might be limitations in terms of the types of models and layers supported compared to running directly in Keras with TensorFlow.<\/li>\n\n\n\n<li><strong>Updates<\/strong>: Keeping up with the latest changes and features in Keras and TensorFlow might require updates to <code>frugally-deep<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>Thank you so much for reading this post!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Despite many advantages of Python such as simple syntax, easy-to-read code and large number of available 3rd-party packages, when it comes to embedded systems and &hellip; <\/p>\n","protected":false},"author":1,"featured_media":616,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[200,1,148,149,198,28,147,41],"tags":[61,8,57,52,199,62,29,58,39,268,270],"_links":{"self":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts\/427"}],"collection":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/comments?post=427"}],"version-history":[{"count":5,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts\/427\/revisions"}],"predecessor-version":[{"id":1950,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts\/427\/revisions\/1950"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/media\/616"}],"wp:attachment":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/media?parent=427"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/categories?post=427"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/tags?post=427"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}