जैसा कि हमने नासा स्पेस ऐप चैलेंज हैकाथॉन में एप्लिकेशन लिखा था

20-21 अक्टूबर को मॉस्को में नासा स्पेस एप्स चैलेंज इंटरनेशनल हैकथॉन आयोजित किया गया था। रूस में इसके आयोजक रूसी।हैकर्स समुदाय के लोग थे। घटना के हिस्से के रूप में, प्रतिभागियों को विभिन्न विषयों पर 20 मामलों को हल करने के लिए कहा गया था: हैकथॉन के बारे में फिल्म की शूटिंग से लेकर निगरानी अनुप्रयोगों को विकसित करने और स्वायत्त विमान डिजाइन करने तक। विषयों की पूरी सूची को संदर्भ द्वारा या हैबे पर एक लेख में अध्ययन किया जा सकता है।

हमारी टीम "स्पेस मंकीज़", जिसमें ओलेग बोरोडिन (सिंगुलरिस लैब में फ्रंट-एंड डेवलपर), व्लादिस्लाव प्लोटनिकोव (सिंगुलरिस लैब में क्यूए इंजीनियर), येगोर श्वेत्सोव, दिमित्री पेट्रोव, यूरी बेडरोव और निकोलाई डेनिसेंको ने आकर्षक समस्या के समाधान का फैसला किया "स्पॉट द स्पॉट फायर" शीर्षक से, जिसे निम्नानुसार शब्द दिया गया है: " क्राउडसोर्सिंग लागू करें ताकि लोग जंगल की आग का पता लगाने, पुष्टि करने और ट्रैकिंग में योगदान कर सकें। समाधान मोबाइल या वेब अनुप्रयोग हो सकता है। "

इस तथ्य के कारण कि टीम ने 5 डेवलपर्स को विभिन्न प्लेटफार्मों के लिए विकसित करने में अनुभव के साथ इकट्ठा किया, यह तुरंत निर्णय लिया गया कि हमारे आवेदन का प्रोटोटाइप वेब और मोबाइल प्लेटफार्मों के लिए लागू किया जाएगा।

नासा के डेटा का हमने क्या उपयोग किया?


फिर भी, नेशनल एयरोनॉटिक्स एंड स्पेस एडमिनिस्ट्रेशन के तत्वावधान में हैकाथॉन आयोजित किया गया था, इसलिए नासा के पैंट्री से खुले डेटा का उपयोग नहीं करना गलत होगा। इसके अलावा, हमें तुरंत सक्रिय फायर डेटा डेटासेट मिल गया जिसकी हमें आवश्यकता थी। इस डेटासेट में दुनिया भर की आग के निर्देशांकों की जानकारी होती है (आप किसी विशिष्ट महाद्वीप पर जानकारी डाउनलोड कर सकते हैं)। डेटा हर दिन अपडेट किया जाता है (आप 24 घंटे, 48 घंटे, 7 दिन के लिए डेटा प्राप्त कर सकते हैं)।


फ़ाइल में निम्न क्षेत्रों की जानकारी है: अक्षांश, देशांतर, चमक, स्कैन, ट्रैक, acq_date, acq_time, उपग्रह, आत्मविश्वास, संस्करण, Bright_t31, frp, daynight, जिनमें से हमने केवल फायर पॉइंट (अक्षांश और देशांतर) के निर्देशांक का उपयोग किया था।


आवेदन का सिद्धांत


चूंकि एप्लिकेशन भीड़ है, आदर्श रूप से इसका उपयोग बड़ी संख्या में उपयोगकर्ताओं द्वारा किया जाना चाहिए। आवेदन का सिद्धांत इस प्रकार है:


  1. जब कोई उपयोगकर्ता आग का पता लगाता है, तो वह इसे (जियो टैग के साथ) फोटो और सेवा का उपयोग करके लोड करता है। एप्लिकेशन सर्वर पर जाने के लिए भू-टैग और समन्वय के साथ तस्वीरें। फोटोग्राफी को एप्लीकेशन के वेब या मोबाइल संस्करण से डाउनलोड किया जा सकता है।

  2. परिणामस्वरूप फोटो को एक प्रशिक्षित तंत्रिका नेटवर्क द्वारा सर्वर पर संसाधित किया जाता है ताकि यह पुष्टि हो सके कि तस्वीर वास्तव में आग है। स्क्रिप्ट का परिणाम भविष्यवाणी की सटीकता है, अगर> 0.7, तो तस्वीर वास्तव में आग लगाती है। अन्यथा, हम इस जानकारी को रिकॉर्ड नहीं करते हैं और उपयोगकर्ता को दूसरी तस्वीर अपलोड करने के लिए कहते हैं।

  3. यदि छवि विश्लेषण स्क्रिप्ट ने सकारात्मक परिणाम दिया, तो जियोटैग से निर्देशांक सभी निर्देशांक के साथ डेटासेट में जोड़े जाते हैं। अगला, NASA डेटासेट से i- th बिंदु और उपयोगकर्ता से बिंदु के बीच की दूरी की गणना की जाती है। यदि बिंदुओं के बीच की दूरी 3 किमी है, तो नासा सेट से बिंदु को शब्दकोश में जोड़ा जाता है। तो हम सभी बिंदुओं से गुजरते हैं। उसके बाद, आवेदन के क्लाइंट पक्ष को स्थिति को संतुष्ट करने वाले निर्देशांक के साथ रिटर्न जसन। यदि दी गई स्थिति से कोई निर्देशांक नहीं मिलते हैं, तो हम उपयोगकर्ता से प्राप्त एकमात्र बिंदु वापस कर देते हैं।

  4. यदि सर्वर बिंदुओं की एक सरणी देता है, तो एप्लिकेशन का क्लाइंट हिस्सा मानचित्र पर एक फायर ज़ोन खींचता है। यदि सर्वर एक बिंदु पर लौटा है, तो यह एक विशेष लेबल के साथ मानचित्र पर चिह्नित है।


प्रयुक्त प्रौद्योगिकी ढेर


वेब एप्लिकेशन का फ्रंट-एंड भाग


वेब एप्लिकेशन, एक ब्राउज़र से सुलभ, कंप्यूटर स्क्रीन पर केंद्रित है, और अनुकूली नहीं था, हालांकि, प्रौद्योगिकियों ने आसानी से मोबाइल उपकरणों के लिए इस पहलू को परिष्कृत करना संभव बना दिया। हमने वेब साइड पर निम्नलिखित प्रौद्योगिकी स्टैक का उपयोग किया:


  • Google का कोणीय 6 टाइपस्क्रिप्ट फ़्रेमवर्क
  • सीएसएस और जेएस फ्रेमवर्क सामग्री
  • फ़ाइल ng2-file-upload डाउनलोड करने के लिए मॉड्यूल
  • OpenStreetMap नक्शे, पत्रक पुस्तकालय

कार्य परिदृश्य


उपयोगकर्ता एप्लिकेशन खोलता है और उसका स्थान देखता है:




मानचित्र और उपयोगकर्ता भू का प्रारंभिककरण:


this.map = L.map('map').setView([latitude, longitude], 17); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '& copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' }).addTo(this.map); L.circle([latitude, longitude]).addTo(this.map) .bindPopup('You are here') .openPopup(); 

यदि किलोमीटर की त्रिज्या n (कस्टम चर) में आग लगी है, तो इसे अतिरिक्त जानकारी के सारांश के साथ बहुभुज के रूप में प्रदर्शित किया जाएगा:




उपयोगकर्ता मानचित्र पर एक अग्नि स्थान का चयन करता है:




आग टैग सेटिंग:


 let marker; this.map.on('click', function (e) { if (marker) { self.map.removeLayer(marker); } marker = L.circle([e.latlng.lat, e.latlng.lng], { color: 'red', fillColor: '#f03', fillOpacity: 0.5, radius: 15 }).addTo(self.map) .bindPopup(' ') .openPopup(); self.appService.coordinatesStorage.latitude = e.latlng.lat; self.appService.coordinatesStorage.longitude = e.latlng.lng; console.log('fire', self.appService.coordinatesStorage); }); 

इसके बाद, उपयोगकर्ता ng2-file-upload का उपयोग करके आग की एक तस्वीर अपलोड करता है


इन क्रियाओं के परिणामस्वरूप, निम्न डेटा सर्वर पर स्थानांतरित किया जाता है:


  • उपयोगकर्ता समन्वय करता है
  • निर्दिष्ट आग के निर्देशांक
  • अग्नि फोटो

आवेदन का आउटपुट मान्यता परिणाम है।



मोबाइल एप्लिकेशन अनुप्रयोग


प्रयुक्त प्रौद्योगिकियाँ


  • मूल निवासी - आईओएस और एंड्रॉइड के लिए क्रॉस-प्लेटफॉर्म एप्लिकेशन विकसित करने के लिए एक रूपरेखा
  • Redux - अनुप्रयोग डेटा प्रवाह नियंत्रण
  • Redux-saga - Redux में साइड इफेक्ट्स का उपयोग करते हुए पुस्तकालय

कार्य परिदृश्य


आग फोटो चयन


उपयोगकर्ता से टिप्पणी


आग का निशान



एप्लिकेशन का बैक-एंड भाग


  • प्रोग्रामिंग भाषा - JAVA 8

  • क्लाउड प्लेटफ़ॉर्म - Microsoft Azure

  • वेब एप्लीकेशन फ्रेमवर्क - प्ले फ्रेमवर्क

  • ऑब्जेक्ट-रिलेशनल मैपिंग - ईबिन फ्रेमवर्क


सर्वर में पायथन में लिखी गई 2 स्क्रिप्ट्स हैं: भविष्यवाणी और getZone.py, निम्नलिखित पायथन पुस्तकालयों को उनके काम के लिए स्थापित किया गया था:


  • पांडा - डाटा प्रोसेसिंग और विश्लेषण के लिए
  • जियोपैन्डस - जियोडेटा के साथ काम करने के लिए
  • सुन्न - बहुआयामी सरणियों के साथ काम करने के लिए
  • matplotlib - डेटा के विज़ुअलाइज़ेशन के लिए द्वि-आयामी (2D) ग्राफ़िक्स (3D ग्राफ़िक्स भी समर्थित हैं)
  • सुडौल - फ्लैट ज्यामितीय वस्तुओं के हेरफेर और विश्लेषण के लिए।

सर्वर API: fire.iconx.app/api


  • निर्देशांक लोड हो रहा है

 post /pictures {} return { id } 

  • चित्र अपलोड करें

 post /pictures/:id 

स्क्रिप्ट की भविष्यवाणी


एक इनपुट स्क्रिप्ट को एक चित्र प्राप्त हुआ, चित्र का एक सरल प्रीप्रोसेसिंग हुआ ("मॉडल प्रशिक्षण" अनुभाग में इसके बारे में अधिक) और वेट के साथ सहेजी गई फ़ाइल के आधार पर, जो सर्वर पर भी स्थित है, एक भविष्यवाणी जारी की गई थी। यदि मॉडल एक सटीकता> 0.7 का उत्पादन करता है, तो आग ठीक हो जाती है, अन्यथा - नहीं।


स्क्रिप्ट को क्लासिक तरीके से चलाया जाता है।

 $ python predict.py image.jpg 

कोड लिस्टिंग:
 import keras import sys from keras.layers import Dense from keras.models import model_from_json from sklearn.externals import joblib from PIL import Image import numpy as np from keras import models, layers, optimizers from keras.applications import MobileNet from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten from keras.layers import Conv2D, MaxPooling2D def crop_resize(img_path, img_size_square): # Get dimensions mysize = img_size_square image = Image.open(img_path) width, height = image.size # resize if (width and height) >= img_size_square: if width > height: wpercent = (mysize/float(image.size[1])) vsize = int((float(image.size[0])*float(wpercent))) image = image.resize((vsize, mysize), Image.ANTIALIAS) else: wpercent = (mysize/float(image.size[0])) hsize = int((float(image.size[1])*float(wpercent))) image = image.resize((mysize, hsize), Image.ANTIALIAS) # crop width, height = image.size left = (width - mysize)/2 top = (height - mysize)/2 right = (width + mysize)/2 bottom = (height + mysize)/2 image=image.crop((left, top, right, bottom)) return image conv_base = MobileNet(weights='imagenet', include_top=False, input_shape=(224, 224, 3)) def build_model(): model = models.Sequential() model.add(conv_base) model.add(layers.Flatten()) model.add(layers.Dense(256, activation='relu')) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=2e-5), metrics=['acc']) return model image=crop_resize(sys.argv[1],224) image = np.reshape(image,[1,224,224,3]) #Loading models and text processing model = build_model() print('building a model') model.load_weights('./models/mobile_weights.h5') print('model loaded') pred_cat=model.predict(image) if pred_cat > 0.7: print('fire {}'.format(pred_cat)) else: print('no fire {}'.format(pred_cat)) 



स्क्रिप्ट getZone.py


स्क्रिप्ट का इनपुट उस बिंदु का निर्देशांक है जो अनुप्रयोग के क्लाइंट पक्ष से आया है। स्क्रिप्ट नासा से सभी निर्देशांक को कसती है, इस फ़ाइल में एक नया अक्षांश और देशांतर जोड़ता है, मूल फ़ाइल को ओवरराइट करता है और निकटतम बिंदुओं की तलाश शुरू करता है। अंकों के बीच की दूरी की गणना हैवरसाइन सूत्र का उपयोग करके की जाती है


ऐसा करने के लिए, बिंदुओं का अक्षांश और देशांतर रेडियन में परिवर्तित हो जाता है:


 pt1_lon, pt1_lat, pt2_lon, pt2_lat = map(radians, [pt1_lon, pt1_lat, pt2_lon, pt2_lat]) 

प्रत्येक बिंदु के लिए अक्षांश और देशांतर के बीच अंतर हैं:


 d_lon = pt2_lon - pt1_lon d_lat = pt2_lat - pt1_lat 

यह सब हैवरसाइन सूत्र में प्रतिस्थापित है:


 a = sin(d_lat/2)**2 + cos(pt1_lat) * cos(pt2_lat) * sin(d_lon/2)**2 

हम गणना परिणाम की जड़ लेते हैं, आर्सेन की गणना करते हैं और परिणाम को 2 से गुणा करते हैं।


 c = 2 * asin(sqrt(a)) 

दूरी पृथ्वी की त्रिज्या (6371 किमी) का उत्पाद और पिछली गणना का परिणाम होगा।


मॉडल प्रशिक्षण


आग के लिए तस्वीर का विश्लेषण करने के लिए, हमें आग के साथ तस्वीरों के प्रशिक्षण सेट की आवश्यकता थी। तस्वीरें https://www.flickr.com/ साइट से एक स्क्रिप्ट द्वारा एकत्र की गईं और मैन्युअल रूप से टैग की गईं।


FlikerAPI का उपयोग करके डाउनलोडिंग हुई। स्क्रिप्ट ने चित्रों के साथ मानक प्रीप्रोसेसिंग ऑपरेशन किए: क्रॉपिंग - सेंटरिंग के साथ वर्ग (अनुपात 1: 1), और 256 × 256 प्रारूप का आकार।


कोड लिस्टिंग:
 import flickrapi import urllib.request from PIL import Image import pathlib import os from tqdm import tqdm # Flickr api access key flickr=flickrapi.FlickrAPI('your API key', 'your secret key', cache=True) def get_links(): search_term = input("Input keywords for images: ") keyword = search_term max_pics=2000 photos = flickr.walk(text=keyword, tag_mode='all', tags=keyword, extras='url_c', per_page=500, # mb you can try different numbers.. sort='relevance') urls = [] for i, photo in enumerate(photos): url = photo.get('url_c') if url is not None: urls.append(url) if i > max_pics: break num_of_pics=len(urls) print('total urls:',len(urls)) # print number of images available for a keywords return urls, keyword, num_of_pics #resizing and cropping output images will be besquare def crop_resize(img_path, img_size_square): # Get dimensions mysize = img_size_square image = Image.open(img_path) width, height = image.size # resize if (width and height) >= img_size_square: if width > height: wpercent = (mysize/float(image.size[1])) vsize = int((float(image.size[0])*float(wpercent))) image = image.resize((vsize, mysize), Image.ANTIALIAS) else: wpercent = (mysize/float(image.size[0])) hsize = int((float(image.size[1])*float(wpercent))) image = image.resize((mysize, hsize), Image.ANTIALIAS) # crop width, height = image.size left = (width - mysize)/2 top = (height - mysize)/2 right = (width + mysize)/2 bottom = (height + mysize)/2 image=image.crop((left, top, right, bottom)) return image def download_images(urls_,keyword_, num_of_pics_): num_of_pics=num_of_pics_ keyword=keyword_ urls=urls_ i=0 base_path='./flickr_data/' # your base folder to save pics for item in tqdm(urls): name=''.join([keyword,'_',str(i),'.jpg']) i+=1 keyword_=''.join([keyword,'_',str(num_of_pics)]) dir_path= os.path.join(base_path,keyword_) file_path=os.path.join(dir_path,name) pathlib.Path(dir_path).mkdir(parents=True, exist_ok=True) urllib.request.urlretrieve(item, file_path) resized_img=crop_resize(file_path, 256) #set output image size try: resized_img.save(file_path) except: pass urls, keyword, num_of_pics =get_links() continue = input("continue or try other keywords (y,n): ") if continue =='y': download_images(urls, keyword, num_of_pics) elif continue =='n': get_links() else: pass 


स्वाभाविक रूप से, तंत्रिका नेटवर्क की दृढ़ वास्तुकला, जिसमें पूर्व-प्रशिक्षित मॉडल का उपयोग किया गया था, चित्रों के साथ काम करने के लिए उपयोग किया गया था। पसंद MobileNet पर (अपेक्षित) पर गिर गया, क्योंकि:


  • लाइटवेट - यह महत्वपूर्ण है कि आवेदन प्रतिक्रिया समय कम से कम हो।
  • फास्ट - यह महत्वपूर्ण है कि आवेदन प्रतिक्रिया समय कम से कम हो।
  • वास्तव में - मोबाइलनेट आवश्यक सटीकता के साथ भविष्यवाणी करता है।

प्रशिक्षण के बाद, नेटवर्क ने ~ 0.85 की सटीकता का उत्पादन किया।


मॉडल, प्रशिक्षण और भविष्यवाणी का निर्माण करने के लिए, केर + टेंसोरफ्लो का एक गुच्छा इस्तेमाल किया गया थापंडों के माध्यम से डेटा के साथ काम किया गया था।


चूंकि NASA DataSet भौगोलिक डेटा है, इसलिए हम GeoPandas लाइब्रेरी का उपयोग करना चाहते थे। यह पुस्तकालय ज्यामितीय प्रकारों पर स्थानिक तरीके और संचालन प्रदान करने के लिए पंडों की क्षमताओं का विस्तार है। ज्यामितीय संचालन को आकार-प्रकार की लाइब्रेरी के माध्यम से कार्यान्वित किया जाता है, फाइलों के साथ काम किया जाता है - फियोना, ग्राफिंग - मेटप्लोटिब


इस लाइब्रेरी को जानने के लिए लगभग डेढ़ दिन का समय लगा, हमने इसे छोड़ दिया क्योंकि हम यह नहीं खोज पाए कि यह हमें इसके साथ काम करने से वास्तविक लाभ कैसे दिला सकती है। निर्देशांक की गणना करने का हमारा काम बहुत छोटा था, इसलिए अंत में, सब कुछ मूल रूप से लागू किया गया था।


आगे क्या है?


स्वाभाविक रूप से, हम सभी को एक परिणाम के रूप में मिला एक बहुत अस्थिर और क्रूड एप्लिकेशन है, जिसे अंतिम रूप देने का अधिकार है।


हम सफल हुए हैं:


  1. मोबाइल और वेब एप्लिकेशन के प्रोटोटाइप को लागू करें जो फोटो (केवल मोबाइल संस्करण) लेने में सक्षम थे, उन्हें सर्वर पर अपलोड करें और भेजें। साथ ही, भेजने के निर्देशांक सफलतापूर्वक सर्वर पर आते हैं।
  2. सर्वर पर, 2 लिपियों को तैनात करना संभव था जो आवेदन के मुख्य तर्क को लागू करते हैं। इन लिपियों में इनपुट डेटा के प्रवाह और बाद में ग्राहक के हिस्से को भेजने के साथ आउटपुट डेटा की प्राप्ति की व्यवस्था की गई थी।
  3. हमारे आवेदन के वास्तविक "प्रोटोटाइप" को लागू करें।

हमने इसे लागू करने का प्रबंधन नहीं किया है, लेकिन मैं निम्नलिखित समस्याओं को हल करना और सुविधाओं को जोड़ना चाहूंगा (आइटम कार्य की प्राथमिकता के अनुसार चलते हैं:


  1. डेटाबेस से सीधे संपर्क करने के लिए डेटासेट से डेटाबेस तक सभी निर्देशांक की रिकॉर्डिंग व्यवस्थित करें।
  2. NASA वेबसाइट से एक नई फ़ाइल का स्वचालित अपलोड व्यवस्थित करें, अर्थात स्वचालित दैनिक समन्वय अपडेट व्यवस्थित करें।
  3. आग के करीब क्षेत्र में स्थित उपयोगकर्ताओं के लिए अधिसूचना जोड़ें।
  4. पंजीकरण जोड़ें (पहले पैराग्राफ को लागू करने के लिए आवश्यक)।
  5. फायर ज़ोन गणना एल्गोरिथ्म को फिर से लिखें।
  6. डिजाइन कार्यों को हल करें - एप्लिकेशन के मोबाइल और वेब संस्करणों में सुंदरता लाएं।

Source: https://habr.com/ru/post/hi430480/


All Articles