1. शुरू करने से पहले
इस कोडलैब में, आप REST और gRPC की मदद से TensorFlow सर्विंग का इस्तेमाल करने वाली किसी वेबसाइट से, इमेज की कैटगरी तय करने का तरीका जान सकते हैं.
ज़रूरी बातें
- वेब डेवलपमेंट की बुनियादी जानकारी, जैसे कि एचटीएमएल और JavaScript
- TensorFlow का इस्तेमाल करके, मशीन लर्निंग के बारे में बुनियादी जानकारी, जैसे कि ट्रेनिंग और डिप्लॉयमेंट
- टर्मिनल और डॉकर की बुनियादी जानकारी
आप इन चीज़ों के बारे में जानेंगे
- TensorFlow Hub पर पहले से प्रशिक्षित इमेज की कैटगरी वाले मॉडल ढूंढने का तरीका.
- आसान वेबसाइट बनाने और डाउनलोड किए गए इमेज की कैटगरी तय करने वाले मॉडल को, TensorFlow सर्विंग (REST और gRPC) की मदद से अनुमान लगाने का तरीका.
- यूज़र इंटरफ़ेस (यूआई) में पहचान का नतीजा कैसे रेंडर करें.
आपको इनकी ज़रूरत होगी
- डॉकर
- Google Chrome
- Chrome के लिए वेब सर्वर
- Node.js और NPM
- बैश
- प्रोटोकॉल बफ़र कंपाइलर (सिर्फ़ तभी ज़रूरी है, जब आप खुद gRPC स्टब फिर से जनरेट करना चाहते हों)
- gRPC-वेब कोड जनरेटर प्लग इन (सिर्फ़ तब ज़रूरी है, जब आप gRPC स्टब को खुद से जनरेट करना चाहते हों)
2. सेट अप करें
इस कोडलैब के लिए कोड डाउनलोड करने के लिए:
- इस GitHub रिपॉज़िटरी पर जाएं.
- इस कोडलैब के सभी कोड डाउनलोड करने के लिए, कोड > ज़िप डाउनलोड करें पर क्लिक करें.
codelabs
रूट फ़ोल्डर को अनपैक करने के लिए डाउनलोड किए गए ZIP फ़ाइल को खोलें. इसमें आपको सभी ज़रूरी संसाधन मिलेंगे.
इस कोडलैब के लिए, आपको रिपॉज़िटरी में सिर्फ़ TFServing/ImageClassificationWeb
सबडायरेक्ट्री की फ़ाइलों की ज़रूरत होती है, जिसमें दो फ़ोल्डर होते हैं:
starter
फ़ोल्डर में वह स्टार्टर कोड शामिल है जिसे आपने इस कोडलैब के लिए बनाया है.finished
फ़ोल्डर में, तैयार हो चुके सैंपल ऐप्लिकेशन का पूरा कोड है.
3. डिपेंडेंसी इंस्टॉल करना
डिपेंडेंसी इंस्टॉल करने के लिए:
- अपने टर्मिनल में,
starter
फ़ोल्डर पर जाएं. इसके बाद, ज़रूरी एनपीएम पैकेज इंस्टॉल करें:
npm install
4. स्टार्टर वेबसाइट चलाएं
TFServing/ImageClassificationWeb/starter/dist/index.html
फ़ाइल लोड करने के लिए, Chrome के लिए वेब सर्वर का इस्तेमाल करें:
- Chrome के पता बार में
Chrome://apps/
डालें और फिर ऐप्लिकेशन सूची में Chrome के लिए वेब सर्वर ढूंढें. - Chrome के लिए वेब सर्वर लॉन्च करें और फिर
TFServing/ImageClassificationWeb/starter/dist/
फ़ोल्डर चुनें. - वेब सर्वर टॉगल पर क्लिक करके, इसे चालू करें. इसके बाद, अपने ब्राउज़र में http://localhost:8887/ पर जाएं.
वेबसाइट चलाएं और उसके बारे में ज़्यादा जानें
अब आपको वेबसाइट देखनी चाहिए. यूज़र इंटरफ़ेस (यूआई) बहुत आसान है: यह एक बिल्ली की इमेज है जिसमें आप कैटगरी तय करना चाहते हैं और उपयोगकर्ता, REST या gRPC की मदद से डेटा को बैकएंड में भेज सकता है. बैकएंड, इमेज पर इमेज की कैटगरी तय करता है और नतीजे को दिखाने वाली वेबसाइट के लिए क्लासिफ़िकेशन नतीजे दिखाता है.
श्रेणी तय करें पर क्लिक करने से कुछ नहीं होता, क्योंकि यह अभी बैकएंड के साथ बातचीत नहीं कर सकता.
5. TensorFlow सर्विंग के साथ इमेज क्लासिफ़िकेशन मॉडल को डिप्लॉय करना
इमेज की कैटगरी तय करना एक सामान्य एमएल टास्क है. यह इमेज के मुख्य कॉन्टेंट के आधार पर, पहले से तय की गई कैटगरी में उसे बांटता है. यहां फूलों की कैटगरी तय करने का एक उदाहरण दिया गया है:
TensorFlow हब पर पहले से मौजूद कई इमेज क्लासिफ़िकेशन के मॉडल हैं. इस कोडलैब के लिए, आप लोकप्रिय इंसेप्शन v3 मॉडल का इस्तेमाल करते हैं.
TensorFlow सर्विंग के साथ इमेज की कैटगरी तय करने वाले मॉडल को डिप्लॉय करने के लिए:
- इनसेप्शन v3 मॉडल फ़ाइल डाउनलोड करें.
- डाउनलोड की गई
.tar.gz
फ़ाइल को कंप्रेस करने के लिए, उसे कंप्रेस करने वाले टूल का इस्तेमाल करें, जैसे कि 7-ZIP. inception_v3
फ़ोल्डर बनाएं और फिर उसके अंदर123
सबफ़ोल्डर बनाएं.- निकाले गए
variables
फ़ोल्डर औरsaved_model.pb
फ़ाइल को123
सबफ़ोल्डर में रखें.
आप inception_v3
फ़ोल्डर को SavedModel
फ़ोल्डर के तौर पर देख सकते हैं. 123
, वर्शन नंबर का उदाहरण है. अगर आप चाहें, तो दूसरा नंबर चुन सकते हैं.
फ़ोल्डर का स्ट्रक्चर इस इमेज जैसा दिखना चाहिए:
TensorFlow सर्विंग शुरू करें
- अपने टर्मिनल में, TensorFlow सेवा को डॉक करने वाले व्यक्ति से शुरू करें, लेकिन अपने कंप्यूटर पर
PATH/TO/SAVEDMODEL
कोinception_v3
फ़ोल्डर के पूरे पाथ से बदलें.
docker pull tensorflow/serving docker run -it --rm -p 8500:8500 -p 8501:8501 -v "PATH/TO/SAVEDMODEL:/models/inception" -e MODEL_NAME=inception tensorflow/serving
डॉकर सबसे पहले TensorFlow सर्विंग इमेज को अपने-आप डाउनलोड कर लेता है. इसमें एक मिनट लगता है. इसके बाद, TensorFlow सर्विंग शुरू हो जानी चाहिए. लॉग इस कोड स्निपेट जैसा दिखना चाहिए:
2022-02-25 06:01:12.513231: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle. 2022-02-25 06:01:12.585012: I external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 3000000000 Hz 2022-02-25 06:01:13.395083: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /models/inception/123 2022-02-25 06:01:13.837562: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 1928700 microseconds. 2022-02-25 06:01:13.877848: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/inception/123/assets.extra/tf_serving_warmup_requests 2022-02-25 06:01:13.929844: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: inception version: 123} 2022-02-25 06:01:13.985848: I tensorflow_serving/model_servers/server_core.cc:486] Finished adding/updating models 2022-02-25 06:01:13.985987: I tensorflow_serving/model_servers/server.cc:367] Profiler service is enabled 2022-02-25 06:01:13.988994: I tensorflow_serving/model_servers/server.cc:393] Running gRPC ModelServer at 0.0.0.0:8500 ... [warn] getaddrinfo: address family for nodename not supported 2022-02-25 06:01:14.033872: I tensorflow_serving/model_servers/server.cc:414] Exporting HTTP/REST API at:localhost:8501 ... [evhttp_server.cc : 245] NET_LOG: Entering the event loop ...
6. Envoy प्रॉक्सी को सेट अप करें
फ़िलहाल, TensorFlow सर्विंग Access-Control-Allow-Origin
हेडर सेट नहीं करती, इसलिए ब्राउज़र, सुरक्षा की वजहों से फ़्रंटएंड JavaScript से TensorFlow सर्विंग (उपयोगकर्ता के डिवाइस के हिसाब से पेज दिखाना) को ब्लॉक कर देता है. इस समाधान के लिए, JavaScript से TensorFlow सर्विंग बैकएंड में अनुरोध प्रॉक्सी करने के लिए, आपको Envoy जैसे प्रॉक्सी का इस्तेमाल करना होगा.
शुरू करें
- अपने टर्मिनल में, Envoy इमेज डाउनलोड करें और डॉकर से Envoy शुरू करें. हालांकि,
starter
फ़ोल्डर मेंenvoy-custom.yaml
फ़ाइल के पूरे पाथ के साथPATH/TO/ENVOY-CUSTOM.YAML
प्लेसहोल्डर बदलें.
docker pull envoyproxy/envoy-dev:fd3e8370ddb7a96634c192d1461516e6de1d1797 docker run --add-host host.docker.internal:host-gateway --rm -it -p 9901:9901 -p 8000:8000 -p 8080:8080 -v PATH/TO/ENVOY-CUSTOM.YAML:/envoy-custom.yaml envoyproxy/envoy-dev:fd3e8370ddb7a96634c192d1461516e6de1d1797 -c /envoy-custom.yaml
डॉकर पहले, Envoy इमेज को अपने-आप डाउनलोड कर लेता है. इसके बाद, Envoy शुरू होना चाहिए. लॉग इस कोड स्निपेट जैसा दिखना चाहिए:
[2022-03-02 07:51:48.563][1][info][main] [source/server/server.cc:436] response trailer map: 152 bytes: grpc-message,grpc-status [2022-03-02 07:51:48.681][1][info][main] [source/server/server.cc:772] runtime: {} [2022-03-02 07:51:48.682][1][info][admin] [source/server/admin/admin.cc:134] admin address: 0.0.0.0:9901 [2022-03-02 07:51:48.683][1][info][config] [source/server/configuration_impl.cc:127] loading tracing configuration [2022-03-02 07:51:48.683][1][info][config] [source/server/configuration_impl.cc:87] loading 0 static secret(s) [2022-03-02 07:51:48.683][1][info][config] [source/server/configuration_impl.cc:93] loading 2 cluster(s) [2022-03-02 07:51:48.687][1][info][config] [source/server/configuration_impl.cc:97] loading 2 listener(s) [2022-03-02 07:51:48.694][1][info][config] [source/server/configuration_impl.cc:109] loading stats configuration [2022-03-02 07:51:48.696][1][info][main] [source/server/server.cc:868] starting main dispatch loop [2022-03-02 07:51:48.881][1][info][runtime] [source/common/runtime/runtime_impl.cc:446] RTDS has finished initialization [2022-03-02 07:51:48.881][1][info][upstream] [source/common/upstream/cluster_manager_impl.cc:207] cm init: all clusters initialized [2022-03-02 07:51:48.881][1][info][main] [source/server/server.cc:849] all clusters initialized. initializing init manager [2022-03-02 07:51:48.881][1][info][config] [source/server/listener_manager_impl.cc:784] all dependencies initialized. starting workers [2022-03-02 07:51:48.902][1][warning][main] [source/server/server.cc:747] there is no configured limit to the number of allowed active connections. Set a limit via the runtime key overload.global_downstream_max_connections
7. REST के ज़रिए, TensorFlow की मदद से वेबसाइट को कनेक्ट करें
अब बैकएंड तैयार है, ताकि आप इमेज को अलग-अलग ग्रुप में बांटने के लिए, TensorFlow सर्विंग को क्लाइंट के अनुरोध भेज सकें. TensorFlow सर्विंग को दो तरीकों से अनुरोध भेजे जा सकते हैं:
- आरएसटी
- gRPC
REST के ज़रिए अनुरोध भेजना और जवाब पाना
REST के ज़रिए अनुरोध भेजने और पाने के तीन आसान चरण हैं:
- REST अनुरोध बनाएं.
- TensorFlow सर्विंग को REST का अनुरोध भेजें.
- REST के जवाब से अनुमानित नतीजे निकालें और नतीजा दिखाएं.
आप src/index.js
फ़ाइल में इन चरणों को पूरा करते हैं.
REST अनुरोध बनाएं
फ़िलहाल, classify_img()
फ़ंक्शन'TenorFlow से सर्व करने के लिए REST अनुरोध नहीं भेजता. REST का अनुरोध सबसे पहले बनाने के लिए, आपको इस REST ब्रांच को लागू करना होगा:
if (radioButtons[0].checked) {
console.log('Using REST');
// TODO: Add code to send a REST request to TensorFlow Serving.
}
TensorFlow सर्विंग की मदद से एक ऐसे POST अनुरोध की उम्मीद की जाती है जिसमें आपके इस्तेमाल किए जाने वाले Insations v3 मॉडल के लिए इमेज टेंसर शामिल होता है. इसलिए, आपको इमेज के हर पिक्सल से किसी कैटगरी में आरजीबी वैल्यू निकालना होगी और फिर JSON को एक JSON में रैप करना होगा. यह अनुरोध का पेलोड होता है.
- इस कोड को REST शाखा में जोड़ें:
//Create the REST request.
let imgTensor = new Array();
let pixelArray = new Array();
context.drawImage(img, 0, 0);
for(let i=0; i<inputImgHeight; i++) {
pixelArray[i] = new Array();
for (let j=0; j<inputImgWidth; j++) {
pixelArray[i][j] = new Array();
pixelArray[i][j].push(context.getImageData(i, j, 1, 1).data[0]/255);
pixelArray[i][j].push(context.getImageData(i, j, 1, 1).data[1]/255);
pixelArray[i][j].push(context.getImageData(i, j, 1, 1).data[2]/255);
}
}
imgTensor.push(pixelArray);
const RESTURL = 'http://localhost:8000/v1/models/inception:predict';
let xhr = new XMLHttpRequest();
xhr.open('POST', RESTURL);
xhr.setRequestHeader('Content-Type', 'application/json;charset=utf-8;');
let data = JSON.stringify({
instances: imgTensor
});
xhr.onload = () => {
}
xhr.onerror = () => {
console.log('REST request error');
}
TensorFlow सर्विंग के लिए REST अनुरोध भेजें
अब आप अनुरोध भेज सकते हैं.
- REST की ब्रांच में ऊपर दिए गए कोड के ठीक बाद यह कोड जोड़ें:
// Send the REST request.
xhr.send(data);
TensorFlow सर्विंग से मिलने वाले REST के जवाब को प्रोसेस करें
इंसेप्शन v3 मॉडल संभावना की एक श्रेणी देता है कि इमेज पहले से तय की गई श्रेणियों से संबंधित है. सुझाव सफल होने पर, आपको यूज़र इंटरफ़ेस (यूआई) में सबसे संभावित कैटगरी को आउटपुट करना चाहिए.
रिस्पॉन्स को मैनेज करने के लिए, onload()
लिसनर का इस्तेमाल किया जाता है.
xhr.onload = () => {
}
- इस कोड को
onload()
लिसनर में जोड़ें:
// Process the REST response.
const response = JSON.parse(xhr.responseText);
const maxIndex = argmax(response['predictions'][0])
document.getElementById('category').textContent = 'Predicted category: ' + maxIndex;
अब लिसनर, रिस्पॉन्स से अनुमानित संभावनाओं को निकालता है, ऑब्जेक्ट की सबसे संभावित कैटगरी की पहचान करता है, और नतीजे को यूज़र इंटरफ़ेस (यूआई) में दिखाता है.
इसे चलाएं
- अपने टर्मिनल में,
starter
फ़ोल्डर पर जाएं और सभी JavaScript फ़ाइलों को एक ही फ़ाइल में बंडल करने के लिए वेबपैक का इस्तेमाल करें. आप इस फ़ाइल कोdist/index.html
फ़ाइल में जोड़ सकते हैं:
npm install -g npx npm install --save-dev webpack npx webpack
- अपने ब्राउज़र में http://localhost:8887/ रीफ़्रेश करें और फिर REST > क्लासिफ़ाइड पर क्लिक करें.
वेबसाइट, अनुमानित कैटगरी के तौर पर 286
दिखाती है, जो ImageNet डेटासेट में Egyptian Cat
लेबल के साथ मैप होती है.
8. gRPC की मदद से, TensorFlow सर्विंग के साथ वेबसाइट को कनेक्ट करना
REST के अलावा, TensorFlow सर्व करने की सुविधा gRPC पर भी काम करती है.
gRPC एक आधुनिक, ओपन सोर्स, हाई-परफ़ॉर्मेंस रिमोट प्रोसेस कॉल (आरपीसी) फ़्रेमवर्क है, जो किसी भी एनवायरमेंट में चल सकता है. यह डेटा केंद्रों में, लोड बैलेंसिंग, ट्रेसिंग, स्वास्थ्य जांच, और पुष्टि करने की सुविधा के साथ बेहतर तरीके से सेवाओं को कनेक्ट कर सकती है. यह देखा गया है कि REST की तुलना में gRPC, बेहतर परफ़ॉर्म करता है.
gRPC से अनुरोध भेजें और जवाब पाएं
चार आसान चरण हैं:
- ज़रूरी नहीं: gRPC क्लाइंट स्टब कोड जनरेट करें.
- जीआरपीसी अनुरोध बनाएं.
- TensorFlow सर्विंग के लिए जीआरपीसी अनुरोध भेजें.
- gRPC रिस्पॉन्स से अनुमानित नतीजा निकालें और उसे यूज़र इंटरफ़ेस (यूआई) में दिखाएं.
आप src/index.js
फ़ाइल में, इन चरणों को पूरा करते हैं.
ज़रूरी नहीं: gRPC क्लाइंट स्टब कोड जनरेट करें
TensorFlow सर्विंग के साथ जीआरपीसी का इस्तेमाल करने के लिए, आपको जीआरपीसी वर्कफ़्लो को फ़ॉलो करना होगा. ज़्यादा जानकारी के लिए, gRPC दस्तावेज़ देखें.
TensorFlow सर्विंग और TensorFlow आपके लिए .proto
फ़ाइलें तय करते हैं. TensorFlow और TensorFlow 2.8 वर्शन के लिए, ये .proto
फ़ाइलें ज़रूरी हैं:
tensorflow/core/example/example.proto
tensorflow/core/example/feature.proto
tensorflow/core/protobuf/struct.proto
tensorflow/core/protobuf/saved_object_graph.proto
tensorflow/core/protobuf/saver.proto
tensorflow/core/protobuf/trackable_object_graph.proto
tensorflow/core/protobuf/meta_graph.proto
tensorflow/core/framework/node_def.proto
tensorflow/core/framework/attr_value.proto
tensorflow/core/framework/function.proto
tensorflow/core/framework/types.proto
tensorflow/core/framework/tensor_shape.proto
tensorflow/core/framework/full_type.proto
tensorflow/core/framework/versions.proto
tensorflow/core/framework/op_def.proto
tensorflow/core/framework/graph.proto
tensorflow/core/framework/tensor.proto
tensorflow/core/framework/resource_handle.proto
tensorflow/core/framework/variable.proto
tensorflow_serving/apis/inference.proto
tensorflow_serving/apis/classification.proto
tensorflow_serving/apis/predict.proto
tensorflow_serving/apis/regression.proto
tensorflow_serving/apis/get_model_metadata.proto
tensorflow_serving/apis/input.proto
tensorflow_serving/apis/prediction_service.proto
tensorflow_serving/apis/model.proto
- अपने टर्मिनल में,
starter/src/proto/
फ़ोल्डर पर जाएं और स्टब जनरेट करें:
bash generate_grpc_stub_js.sh
जीआरपीसी अनुरोध बनाएं
REST अनुरोध के समान, आप gRPC ब्रांच में gRPC अनुरोध बनाते हैं.
if (connectionMode[picker.selectedRow(inComponent: 0)] == "REST") {
}
else {
print("Using gRPC")
// TODO: Add code to send a gRPC request to TensorFlow Serving.
}
- यह कोड जीआरपीसी शाखा में जोड़ें:
// Create the gRPC request.
const PredictModule = require('./proto/generated/tensorflow_serving/apis/predict_pb.js');
const PredictionServiceClientModule = require('./proto/generated/tensorflow_serving/apis/prediction_service_grpc_web_pb.js');
const ModelModule = require('./proto/generated/tensorflow_serving/apis/model_pb.js');
const TensorModule = require('./proto/generated/tensorflow/core/framework/tensor_pb.js');
const GPRCURL = 'http://localhost:8080';
const stub = new PredictionServiceClientModule.PredictionServiceClient(GPRCURL);
const modelSpec = new ModelModule.ModelSpec();
modelSpec.setName('inception');
const tensorProto = new TensorModule.TensorProto();
const tensorShapeProto = new TensorModule.TensorShapeProto();
const batchDim = (new TensorModule.TensorShapeProto.Dim()).setSize(1);
const heightDim = (new TensorModule.TensorShapeProto.Dim()).setSize(inputImgHeight);
const widthDim = (new TensorModule.TensorShapeProto.Dim()).setSize(inputImgWidth);
const channelDim = (new TensorModule.TensorShapeProto.Dim()).setSize(3);
tensorShapeProto.setDimList([batchDim, heightDim, widthDim, channelDim]);
tensorProto.setDtype(proto.tensorflow.DataType.DT_FLOAT);
tensorProto.setTensorShape(tensorShapeProto);
context.drawImage(img, 0, 0);
for(let i=0; i<inputImgHeight; i++) {
for (let j=0; j<inputImgWidth; j++) {
tensorProto.addFloatVal(context.getImageData(i, j, 1, 1).data[0]/255);
tensorProto.addFloatVal(context.getImageData(i, j, 1, 1).data[1]/255);
tensorProto.addFloatVal(context.getImageData(i, j, 1, 1).data[2]/255);
}
}
const predictionServiceRequest = new PredictModule.PredictRequest();
predictionServiceRequest.setModelSpec(modelSpec);
predictionServiceRequest.getInputsMap().set('inputs', tensorProto);
TensorFlow सर्व करने के लिए, जीआरपीसी का अनुरोध भेजें
अब आप अनुरोध भेज सकते हैं.
- पिछले कोड स्निपेट में gRPC ब्रांच में कोड के तुरंत बाद यह कोड जोड़ें:
// Send the gRPC request.
stub.predict(predictionServiceRequest, {}, function(err, response) {
// TODO: Add code to process the response.
});
TensorFlow सर्विंग से जीआरपीसी जवाब को प्रोसेस करें
आखिर में, रिस्पॉन्स को मैनेज करने के लिए ऊपर दिए गए कॉलबैक फ़ंक्शन को लागू करें.
- इस कोड को पिछले कोड स्निपेट में फ़ंक्शन बॉडी में जोड़ें:
// Process the gRPC response.
if (err) {
console.log(err.code);
console.log(err.message);
}
else {
const maxIndex = argmax(response.getOutputsMap().get('logits').getFloatValList());
document.getElementById('category').textContent = 'Predicted category: ' + maxIndex;
}
अब लिसनर, रिस्पॉन्स से अनुमानित संभावनाओं को निकालता है, ऑब्जेक्ट की सबसे संभावित कैटगरी की पहचान करता है, और नतीजे को यूज़र इंटरफ़ेस (यूआई) में दिखाता है.
इसे चलाएं
- अपने टर्मिनल में, सभी JavaScript फ़ाइलों को एक ही फ़ाइल में बंडल करने के लिए वेबपैक का इस्तेमाल करें. आप इस फ़ाइल को
index.html
फ़ाइल में जोड़ सकते हैं:
npx webpack
- अपने ब्राउज़र में http://localhost:8887/ रीफ़्रेश करें.
- gRPC > क्लासिफ़िकेशन पर क्लिक करें.
वेबसाइट, 286
की अनुमानित कैटगरी दिखाती है, जो ImageNet डेटासेट में Egyptian Cat
लेबल के साथ मैप होती है.
9. बधाई हो
आपने अपनी वेबसाइट में इमेज को अलग-अलग ग्रुप में बांटने के लिए, TensorFlow सर्विंग का इस्तेमाल किया है!