<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Sieci neuronowe - Inero Software - Rozwiązania IT i Konsulting</title>
	<atom:link href="https://inero-software.com/pl/tag/sieci-neuronowe/feed/" rel="self" type="application/rss+xml" />
	<link>https://inero-software.com/pl/tag/sieci-neuronowe/</link>
	<description>Tworzymy cyfrowe innowacje</description>
	<lastBuildDate>Wed, 20 Nov 2024 14:47:40 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://inero-software.com/wp-content/uploads/2018/11/inero-logo-favicon.png</url>
	<title>Sieci neuronowe - Inero Software - Rozwiązania IT i Konsulting</title>
	<link>https://inero-software.com/pl/tag/sieci-neuronowe/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">153509928</site>	<item>
		<title>Sieci neuronowe w przeglądarce: Przewodnik na przykładzie customowej sieci YOLO do wykrywania twarzy</title>
		<link>https://inero-software.com/pl/sieci-neuronowe-w-przegladarce-przewodnik-na-przykladzie-customowej-sieci-yolo-do-wykrywania-twarzy/</link>
		
		<dc:creator><![CDATA[Martyna Mul]]></dc:creator>
		<pubDate>Thu, 10 Oct 2024 11:20:57 +0000</pubDate>
				<category><![CDATA[Firma]]></category>
		<category><![CDATA[ML]]></category>
		<category><![CDATA[NLP]]></category>
		<category><![CDATA[oprogramowanie]]></category>
		<category><![CDATA[optymalizacja procesów biznesowych]]></category>
		<category><![CDATA[repozytorium]]></category>
		<category><![CDATA[sieci neuronowe]]></category>
		<category><![CDATA[yolo]]></category>
		<category><![CDATA[zarządzanie danymi]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=6230</guid>

					<description><![CDATA[<p>Wraz z rosnącym zapotrzebowaniem na aplikacje działające w czasie rzeczywistym, uruchamianie modeli głębokiego uczenia w przeglądarce staje się coraz bardziej dostępne i wydajne. W tym artykule pokażemy, jak zaimplementować wykrywanie obiektów bezpośrednio w przeglądarce, wykorzystując YOLO (You Only Look Once) oraz TensorFlow.js. Skoncentrujemy się na zastosowaniu wytrenowanego przez nas niestandardowego&#8230;</p>
<p>Artykuł <a href="https://inero-software.com/pl/sieci-neuronowe-w-przegladarce-przewodnik-na-przykladzie-customowej-sieci-yolo-do-wykrywania-twarzy/">Sieci neuronowe w przeglądarce: Przewodnik na przykładzie customowej sieci YOLO do wykrywania twarzy</a> pochodzi z serwisu <a href="https://inero-software.com/pl">Inero Software - Rozwiązania IT i Konsulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="6230" class="elementor elementor-6230" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-d225397 e-flex e-con-boxed e-con e-parent" data-id="d225397" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-4df78db elementor-widget elementor-widget-html" data-id="4df78db" data-element_type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
					</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-0827b19 e-flex e-con-boxed e-con e-parent" data-id="0827b19" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-afa200d e-con-full e-flex e-con e-child" data-id="afa200d" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-3302212 e-con-full e-flex e-con e-child" data-id="3302212" data-element_type="container">
				<div class="elementor-element elementor-element-640ca1b elementor-widget elementor-widget-text-editor" data-id="640ca1b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><strong>Wraz z rosnącym zapotrzebowaniem na aplikacje działające w czasie rzeczywistym, uruchamianie modeli głębokiego uczenia w przeglądarce staje się coraz bardziej dostępne i wydajne. W tym artykule pokażemy, jak zaimplementować wykrywanie obiektów bezpośrednio w przeglądarce, wykorzystując YOLO (You Only Look Once) oraz TensorFlow.js. Skoncentrujemy się na zastosowaniu wytrenowanego przez nas niestandardowego modelu YOLOv8 do wykrywania ludzkich twarzy. Na końcu tego przewodnika dowiesz się, jak skonfigurować i uruchomić model YOLO do wykrywania twarzy za pomocą TensorFlow.js, przetworzyć wyniki i zoptymalizować wydajność – wszystko to bez potrzeby korzystania z serwera czy przetwarzania po stronie backendu.</strong></p>						</div>
				</div>
				<div class="elementor-element elementor-element-aed25a2 elementor-widget elementor-widget-heading" data-id="aed25a2" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Dlaczego warto korzystać z sieci neuronowych w przeglądarce?</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-344fad5 elementor-widget elementor-widget-text-editor" data-id="344fad5" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Uruchamianie sieci neuronowych w przeglądarce ma wiele zalet. Najważniejsze z nich to:</p><ol><li><strong>Niskie opóźnienia</strong>: Wszystko odbywa się po stronie klienta, co eliminuje opóźnienia wynikające z przesyłania danych na serwer i oczekiwania na odpowiedź.</li><li><strong>Większa prywatność</strong>: Wrażliwe dane pozostają na urządzeniu użytkownika, co minimalizuje ryzyko ich naruszenia lub ujawnienia.</li><li><strong> Możliwość użycia offline</strong>: Użytkownicy mogą korzystać z funkcji uczenia maszynowego nawet bez stałego połączenia z internetem.</li><li><strong>Kompatybilność między platformami</strong>: Aplikacja działa na każdym urządzeniu z przeglądarką – niezależnie czy to komputer, tablet, czy smartfon.</li></ol>						</div>
				</div>
				<div class="elementor-element elementor-element-9e13d20 elementor-widget elementor-widget-heading" data-id="9e13d20" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Wybór i przygotowanie sieci neuronowej</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-769829b elementor-widget elementor-widget-text-editor" data-id="769829b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Przy wyborze sieci neuronowej do implementacji w przeglądarce warto uwzględnić takie czynniki jak rozmiar modelu, szybkość działania, zużycie pamięci oraz kompatybilność z technologiami przeglądarkowymi, np. WebGL. Dla optymalnej wydajności na urządzeniach o ograniczonych zasobach zaleca się stosowanie modeli o rozmiarze poniżej 30 MB. Do odpowiednich modeli należą MobileNetV2, SqueezeNet, EfficientNet oraz wybrane warianty YOLO. My zdecydowaliśmy się na wytrenowany przez nas model YOLOv8 do wykrywania ludzkich twarzy na obrazach.</p><p>Jeśli Twój model przekracza zalecany rozmiar, warto rozważyć techniki optymalizacji, takie jak kwantyzacja (quantization) i przycinanie (pruning). Kwantyzacja zmniejsza precyzję wag modelu, zazwyczaj konwertując wartości zmiennoprzecinkowe 32-bitowe na liczby zmiennoprzecinkowe 16-bitowe lub całkowite 8-bitowe. Przycinanie usuwa zbędne połączenia w sieci neuronowej. Obie metody zmniejszają rozmiar modelu i redukują złożoność obliczeniową, co poprawia szybkość inferencji – szczególnie na urządzeniach takich jak smartfony – choć mogą one nieznacznie wpłynąć na dokładność.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-76a71b3 elementor-widget elementor-widget-heading" data-id="76a71b3" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Optymalizacja YOLOv8 do wykrywania twarzy: wyniki naszego niestandardowego modelu
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-9111e72 elementor-widget elementor-widget-text-editor" data-id="9111e72" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Nasz model YOLOv8 został wytrenowany na niestandardowym zbiorze danych w celu automatycznego sprawdzania, czy załącznik zawiera wyraźne zdjęcie ludzkiej twarzy, skierowanej na wprost i niezasłoniętej, np. przez maskę. Taka funkcjonalność jest szczególnie przydatna w systemach obiegu dokumentów, gdzie weryfikacja tożsamości wymaga widoczności twarzy. Zbiór danych składał się z 1500 obrazów, z czego 1200 wykorzystano do treningu, a 300 do walidacji. Dataset zawierał zdjęcia twarzy fotografowanych z różnych kątów, twarzy częściowo zasłoniętych oraz zdjęcia innych obiektów. Dzięki treningowi model nauczył się skutecznie wykrywać twarze spełniające wymagane kryteria. Poniższe przykłady ilustrują, jak model działa w praktyce. Dwie twarze po lewej stronie zostały poprawnie wykryte, podczas gdy dwie po prawej nie zostały rozpoznane, ponieważ były częściowo zasłonięte:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-fd798a3 elementor-widget elementor-widget-image" data-id="fd798a3" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img fetchpriority="high" decoding="async" width="934" height="258" src="https://inero-software.com/wp-content/uploads/2024/10/9102024gr1.jpg" class="attachment-large size-large wp-image-6206" alt="" srcset="https://inero-software.com/wp-content/uploads/2024/10/9102024gr1.jpg 934w, https://inero-software.com/wp-content/uploads/2024/10/9102024gr1-300x83.jpg 300w, https://inero-software.com/wp-content/uploads/2024/10/9102024gr1-768x212.jpg 768w" sizes="(max-width: 934px) 100vw, 934px" data-attachment-id="6206" data-permalink="https://inero-software.com/running-ai-in-client-side-real-time-face-detection-in-the-browser-using-yolo-and-tensorflow-js-use-case-study/9102024gr1/" data-orig-file="https://inero-software.com/wp-content/uploads/2024/10/9102024gr1.jpg" data-orig-size="934,258" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="9102024gr1" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2024/10/9102024gr1-300x83.jpg" data-large-file="https://inero-software.com/wp-content/uploads/2024/10/9102024gr1.jpg" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-34bbb24 elementor-widget elementor-widget-heading" data-id="34bbb24" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<p class="elementor-heading-title elementor-size-default">(source of images: https://www.kaggle.com/datasets/ashwingupta3012/human-faces, https://www.kaggle.com/datasets/andrewmvd/face-mask-detection) </p>		</div>
				</div>
				<div class="elementor-element elementor-element-12bfcb4 elementor-widget elementor-widget-text-editor" data-id="12bfcb4" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Wyniki wnioskowania na czterech przykładach – dwie twarze po lewej stronie zostały poprawnie wykryte, natomiast dwie po prawej nie, ponieważ były częściowo zasłonięte.</p><p>Jako bazowy model dla naszego projektu wybraliśmy YOLOv8s (small), co dało model o rozmiarze 44 MB, osiągający 99,9% precyzji (ang. precision) oraz 99,1% czułości (ang. recall) na naszym niestandardowym zbiorze danych walidacyjnych. W celu optymalizacji przetestowaliśmy również mniejszy model bazowy, YOLOv8n (nano), oraz przeanalizowaliśmy efekty kwantyzacji. Trening z modelem YOLOv8n dał model o rozmiarze zaledwie 12 MB, przy niemal identycznych wynikach – 99,7% precyzji i 99,1% czułości. Następnie przeprowadziliśmy kwantyzację obu modeli, a ich rozmiary oraz dokładność po kwantyzacji zostały zaprezentowane w poniższej tabeli:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-859298c elementor-widget elementor-widget-text-editor" data-id="859298c" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<table class=" aligncenter" style="font-weight: 400;" data-tablestyle="MsoNormalTable" data-tablelook="1568" aria-rowcount="4"><tbody><tr aria-rowindex="1"><td colspan="1" rowspan="2" data-celllook="69905"><p><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td colspan="3" data-celllook="69905"><p><strong>Model bazowy</strong></p><p> </p></td><td colspan="3" data-celllook="69905"><p><strong>Model kwantyzowany 16-bitowy</strong></p><p> </p></td></tr><tr aria-rowindex="2"><td data-celllook="69905"><p><b><span data-contrast="auto">Rozmiar</span></b><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><b>Precyzja</b></p></td><td data-celllook="69905"><p><b><span data-contrast="auto">Recall</span></b><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><b><span data-contrast="auto">Rozmiar</span></b><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><b>Precyzja</b></p></td><td data-celllook="69905"><p><b><span data-contrast="auto">Recall</span></b><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td></tr><tr aria-rowindex="3"><td data-celllook="69905"><p><b><span data-contrast="auto">YOLOv8 small</span></b><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><b><span data-contrast="auto">44 MB</span></b><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><span data-contrast="auto">0.999</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><span data-contrast="auto">0.991</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><span data-contrast="auto">22 MB</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><span data-contrast="auto">0.997</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><span data-contrast="auto">0.991</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td></tr><tr aria-rowindex="4"><td data-celllook="69905"><p><b><span data-contrast="auto">YOLOv8 nano</span></b><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><span data-contrast="auto">12 MB</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><span data-contrast="auto">0.997</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><span data-contrast="auto">0.991</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><b><span data-contrast="auto">6 MB</span></b><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><span data-contrast="auto">0.989</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td><td data-celllook="69905"><p><span data-contrast="auto">0.991</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335551550&quot;:6,&quot;335551620&quot;:6,&quot;335559740&quot;:360}"> </span></p></td></tr></tbody></table>						</div>
				</div>
				<div class="elementor-element elementor-element-a7be2ba elementor-widget elementor-widget-text-editor" data-id="a7be2ba" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><strong>Uwaga: </strong>Czułość mierzy, ile rzeczywistych pozytywnych próbek zostało poprawnie zidentyfikowanych (tutaj: ile twarzy zostało poprawnie wykrytych), natomiast precyzja wskazuje, ile próbek zidentyfikowanych przez model jako pozytywne było faktycznie pozytywnych (tutaj: ile obiektów wykrytych przez model to faktycznie ludzkie twarze). W idealnym przypadku oba wskaźniki wynoszą 1.</p><p>W naszym przykładzie, zastosowanie mniejszego modelu bazowego wraz z kwantyzacją zmniejszyło dokładność o mniej niż 1%, jednocześnie redukując rozmiar modelu z 44 MB do zaledwie 6 MB.</p><p>Poniżej przedstawiamy kilka przykładowych zdjęć, które pokazują, jak działają dwa modele: YOLOv8s i YOLOv8n z kwantyzacją.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-ba300a9 elementor-widget elementor-widget-image" data-id="ba300a9" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img decoding="async" width="934" height="307" src="https://inero-software.com/wp-content/uploads/2024/10/9102024gr2.jpg" class="attachment-large size-large wp-image-6208" alt="" srcset="https://inero-software.com/wp-content/uploads/2024/10/9102024gr2.jpg 934w, https://inero-software.com/wp-content/uploads/2024/10/9102024gr2-300x99.jpg 300w, https://inero-software.com/wp-content/uploads/2024/10/9102024gr2-768x252.jpg 768w, https://inero-software.com/wp-content/uploads/2024/10/9102024gr2-913x300.jpg 913w" sizes="(max-width: 934px) 100vw, 934px" data-attachment-id="6208" data-permalink="https://inero-software.com/running-ai-in-client-side-real-time-face-detection-in-the-browser-using-yolo-and-tensorflow-js-use-case-study/9102024gr2/" data-orig-file="https://inero-software.com/wp-content/uploads/2024/10/9102024gr2.jpg" data-orig-size="934,307" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="9102024gr2" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2024/10/9102024gr2-300x99.jpg" data-large-file="https://inero-software.com/wp-content/uploads/2024/10/9102024gr2.jpg" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-3d14285 elementor-widget elementor-widget-text-editor" data-id="3d14285" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Wyniki inferencji z modelem YOLOv8s, bez kwantyzacji (o rozmiarze 44 MB):</p><p><span class="TextRun SCXW46079478 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW46079478 BCX0">(source of images: </span><span class="NormalTextRun SCXW46079478 BCX0">https://www.kaggle.com/datasets/ashwingupta3012/human-faces</span><span class="NormalTextRun SCXW46079478 BCX0">).</span></span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-e4f1955 elementor-widget elementor-widget-image" data-id="e4f1955" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img decoding="async" width="934" height="313" src="https://inero-software.com/wp-content/uploads/2024/10/9102024gr3.jpg" class="attachment-large size-large wp-image-6207" alt="" srcset="https://inero-software.com/wp-content/uploads/2024/10/9102024gr3.jpg 934w, https://inero-software.com/wp-content/uploads/2024/10/9102024gr3-300x101.jpg 300w, https://inero-software.com/wp-content/uploads/2024/10/9102024gr3-768x257.jpg 768w, https://inero-software.com/wp-content/uploads/2024/10/9102024gr3-895x300.jpg 895w" sizes="(max-width: 934px) 100vw, 934px" data-attachment-id="6207" data-permalink="https://inero-software.com/running-ai-in-client-side-real-time-face-detection-in-the-browser-using-yolo-and-tensorflow-js-use-case-study/9102024gr3/" data-orig-file="https://inero-software.com/wp-content/uploads/2024/10/9102024gr3.jpg" data-orig-size="934,313" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="9102024gr3" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2024/10/9102024gr3-300x101.jpg" data-large-file="https://inero-software.com/wp-content/uploads/2024/10/9102024gr3.jpg" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-8185505 elementor-widget elementor-widget-text-editor" data-id="8185505" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Wyniki inferencji z modelem YOLOv8n po kwantyzacji 16-bitowej (o rozmiarze 6 MB). Różnica w poziomie ufności jest minimalna, natomiast położenie wykrytych obiektów pozostało takie samo.</p><p>Przetestowaliśmy wydajność dwóch modeli — YOLOv8s (44 MB) i YOLOv8n po kwantyzacji 16-bitowej (6 MB) — na trzech różnych procesorach. Mniejszy model, YOLOv8n, konsekwentnie przewyższał swój większy odpowiednik pod względem czasu wczytania modelu oraz szybkości pojedynczej inferencji. Szczegółowe dane dotyczące wydajności zostały podsumowane w tabeli poniżej.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-bba7a47 elementor-widget elementor-widget-text-editor" data-id="bba7a47" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<table style="font-weight: 400;" data-tablestyle="MsoTableGrid" data-tablelook="1696" aria-rowcount="5"><tbody><tr aria-rowindex="1"><td colspan="1" rowspan="2" data-celllook="0"><p><span data-ccp-props="{}"> </span></p></td><td colspan="3" data-celllook="0"><p><strong>Ładowanie modelu</strong></p></td><td colspan="3" data-celllook="0"><p><strong>Pojedyncze wnioskowanie</strong></p></td></tr><tr aria-rowindex="2"><td data-celllook="0"><p><b><span data-contrast="auto">CPU 1</span></b><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><b><span data-contrast="auto">CPU 2</span></b><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><b><span data-contrast="auto">CPU 3</span></b><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><b><span data-contrast="auto">CPU 1</span></b><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><b><span data-contrast="auto">CPU 2</span></b><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><b><span data-contrast="auto">CPU 3</span></b><span data-ccp-props="{}"> </span></p></td></tr><tr aria-rowindex="3"><td data-celllook="0"><p><b><span data-contrast="auto">YOLOv8 small</span></b><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">1050 ms</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">3700 ms</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">4200 ms</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">21 ms</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">117.5 ms</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">196.5 ms</span><span data-ccp-props="{}"> </span></p></td></tr><tr aria-rowindex="4"><td data-celllook="0"><p><b><span data-contrast="auto">YOLOv8 nano 16-bit</span></b><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">980 ms</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">3200 ms</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">3700 ms</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">16 ms</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">112.5 ms</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">189 ms</span><span data-ccp-props="{}"> </span></p></td></tr><tr aria-rowindex="5"><td data-celllook="0"><p>Przyspieszenie</p></td><td data-celllook="0"><p><span data-contrast="auto">6.7 %</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">13.5 %</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">11.9 %</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">23.8 %</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">4.2 %</span><span data-ccp-props="{}"> </span></p></td><td data-celllook="0"><p><span data-contrast="auto">3.8 %</span><span data-ccp-props="{}"> </span></p></td></tr></tbody></table>						</div>
				</div>
				<div class="elementor-element elementor-element-cc12989 elementor-widget elementor-widget-text-editor" data-id="cc12989" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Oprócz czasu wczytania modelu i inferencji, istotnym czynnikiem do rozważenia jest również czas pobrania modelu, który nie został uwzględniony w tabeli. Czas ten jest bezpośrednio proporcjonalny do rozmiaru modelu i w znacznym stopniu zależy od prędkości połączenia internetowego użytkownika.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d6f4734 elementor-widget elementor-widget-heading" data-id="d6f4734" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Praktyczna implementacja krok po kroku</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-e00fb33 elementor-widget elementor-widget-text-editor" data-id="e00fb33" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Aby wdrożyć model uczenia maszynowego w przeglądarce, skorzystamy z TensorFlow.js — popularnej biblioteki, która umożliwia uruchamianie wytrenowanych modeli lub całkowite trenowanie nowych modeli bezpośrednio w przeglądarce. W tym przewodniku skupimy się na wdrożeniu wytrenowanego modelu YOLOv8 do wykrywania twarzy. Poniżej znajdziesz instrukcję, jak krok po kroku skonfigurować środowisko i uruchomić model z TensorFlow.js.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d18e614 elementor-widget elementor-widget-heading" data-id="d18e614" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h4 class="elementor-heading-title elementor-size-default">1. Instalacja TensorFlow.js </h4>		</div>
				</div>
				<div class="elementor-element elementor-element-cb9241f elementor-widget elementor-widget-text-editor" data-id="cb9241f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Najłatwiejszą metodą instalacji Tensorflow.js jest użycie npm:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-c5deef0 elementor-widget elementor-widget-text-editor" data-id="c5deef0" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre>npm install @tensorflow/tfjs </pre>						</div>
				</div>
				<div class="elementor-element elementor-element-cd338d1 elementor-widget elementor-widget-heading" data-id="cd338d1" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h4 class="elementor-heading-title elementor-size-default">2. Wczytanie modelu</h4>		</div>
				</div>
				<div class="elementor-element elementor-element-d54d572 elementor-widget elementor-widget-text-editor" data-id="d54d572" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Ponieważ używamy biblioteki TensorFlow.js, musisz przekonwertować swój model na format TensorFlow.js (Tf.js). W przypadku modeli YOLO, twórcy Ultralytics udostępnili łatwy sposób na dokonanie tego za pomocą prostego polecenia:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-8acf4f8 elementor-widget elementor-widget-text-editor" data-id="8acf4f8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span class="TextRun Highlight SCXW164933469 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW164933469 BCX0">yolo </span></span><span class="TextRun Highlight SCXW164933469 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW164933469 BCX0">export</span></span><span class="TextRun Highlight SCXW164933469 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW164933469 BCX0"> model=path/to/best.pt format=tfjs</span></span><span class="EOP SCXW164933469 BCX0" data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-a9c3625 elementor-widget elementor-widget-text-editor" data-id="a9c3625" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Po konwersji Twój model zostanie zapisany jako pliki binarne wraz z plikiem JSON o nazwie <strong>model.json</strong>. Wówczas możesz wczytać model korzystając z funkcji <strong>tf.loadGraphModel()</strong>. Poniżej znajdziesz przykład implementacji. Zwróć uwagę na dodatkowy etap &#8222;rozgrzewki&#8221; modelu, poprzez wykonanie jednokrotnej inferencji na losowych danych wejściowych. Ten krok poprawi wydajność modelu przy kolejnej inferencji.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-8ae265d elementor-widget elementor-widget-text-editor" data-id="8ae265d" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">export</span></span> <span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">async</span></span> <span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">function</span></span> <span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">loadModel</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">(modelPath) {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">  </span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">try</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0"> {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">    </span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">// Load the model using a URL</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">    </span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">const</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0"> model = </span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">await</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0"> tf.loadGraphModel(</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">`${modelPath}/model.json`</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">    </span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">// Warm up the model</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">    </span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">const</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0"> dummyInput = tf.ones(model.inputs[</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">0</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">].shape);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">    </span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">await</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0"> model.execute(dummyInput);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">    </span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">return</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0"> model;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">  } </span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">catch</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0"> (error) {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">    </span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">throw</span></span> <span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">new</span></span> <span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">Error</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">(</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">`Failed to load model: ${error.message}`</span></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">  }</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW28304209 BCX0"><span class="SCXW28304209 BCX0"> </span><br class="SCXW28304209 BCX0" /></span><span class="TextRun Highlight SCXW28304209 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW28304209 BCX0">}</span></span><span class="EOP SCXW28304209 BCX0" data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-4fb7ba0 elementor-widget elementor-widget-heading" data-id="4fb7ba0" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h4 class="elementor-heading-title elementor-size-default">3. Przygotowanie danych wejściowych</h4>		</div>
				</div>
				<div class="elementor-element elementor-element-bcd536f elementor-widget elementor-widget-text-editor" data-id="bcd536f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Przed uruchomieniem modelu musimy odpowiednio przygotować obraz wejściowy. Modele YOLO oczekują obrazów o określonym rozmiarze, takim samym jaki został użyty podczas treningu sieci. Zamiast jednak zmieniać rozmiar obrazu (np. funkcją resize()), zalecamy bardziej zaawansowaną metodę przetwarzania obrazu, która zachowuje proporcje i stosuje wypełnienie (letterbox padding). Takie podejście jest zgodne z przetwarzaniem stosowanym przez Ultralytics podczas trenowania modelu YOLO i zapewni najlepszą skuteczność.</p><p>Poniższa funkcja skaluje obraz tak, aby największy jego wymiar zgadzał się z tym oczekiwanym przez model, dodaje wypełnienie aby dopasować drugi wymiar obrazu (jeżeli trzeba) i normalizuje obraz wejściowy:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-dd83945 elementor-widget elementor-widget-text-editor" data-id="dd83945" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">function</span></span> <span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">preprocessImage</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">(base64Image, imgSize) {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> image = </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">new</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> Image();</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  image.src = base64Image;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> canvas = </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">document</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">.createElement(</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">'canvas'</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  canvas.width = image.width;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  canvas.height = image.height;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> ctx = canvas.getContext(</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">'2d'</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  ctx.drawImage(image, </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">0</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">, </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">0</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">, image.width, image.height);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">// Convert canvas image to a tensor</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">let</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> imgTensor = tf.browser.fromPixels(canvas);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">// Determine rescale factor</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> xFactor = image.width / imgSize;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> yFactor = image.height / imgSize;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> factor = </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">Math</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">.max(xFactor, yFactor);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> newWidth = </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">Math</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">.round(image.width / factor);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> newHeight = </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">Math</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">.round(image.height / factor);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">// Resize to expected input shape </span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  imgTensor = tf.image.resizeBilinear(imgTensor, [newHeight, newWidth]);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">// Add padding</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> xPad = (imgSize - newWidth) / </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">2</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> yPad = (imgSize - newHeight) / </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">2</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> top = </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">Math</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">.floor(yPad);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">co</span><span class="NormalTextRun SCXW147374849 BCX0">nst</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> bottom = </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">Math</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">.ceil(yPad);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> left = </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">Math</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">.floor(xPad);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">const</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> right = </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">Math</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">.ceil(xPad);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  imgTensor = tf.pad(imgTensor, [[top, bottom], [left, right], [</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">0</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">, </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">0</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">]], </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">114</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">// Normalize pixel values</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  imgTensor = imgTensor.div(</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">255.0</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">).expandDims(</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">0</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">); </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">// Add batch dimension</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">  </span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">return</span></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0"> { imgTensor, left, top, factor };</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW147374849 BCX0"><span class="SCXW147374849 BCX0"> </span><br class="SCXW147374849 BCX0" /></span><span class="TextRun Highlight SCXW147374849 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW147374849 BCX0">}</span></span><span class="EOP SCXW147374849 BCX0" data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-183b6cf elementor-widget elementor-widget-heading" data-id="183b6cf" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h4 class="elementor-heading-title elementor-size-default">4. Uruchom inferencję modelu</h4>		</div>
				</div>
				<div class="elementor-element elementor-element-639b754 elementor-widget elementor-widget-text-editor" data-id="639b754" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Po załadowaniu modelu i przetworzeniu danych wejściowych, wykonanie inferencji odbywa się za pomocą tej linii kodu:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-25f3c6b elementor-widget elementor-widget-text-editor" data-id="25f3c6b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span class="TextRun Highlight SCXW75192197 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW75192197 BCX0">const</span></span><span class="TextRun Highlight SCXW75192197 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW75192197 BCX0"> prediction = </span></span><span class="TextRun Highlight SCXW75192197 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW75192197 BCX0">await</span></span><span class="TextRun Highlight SCXW75192197 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW75192197 BCX0"> model.execute(inputTensor);</span></span><span class="EOP SCXW75192197 BCX0" data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-0830169 elementor-widget elementor-widget-heading" data-id="0830169" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h4 class="elementor-heading-title elementor-size-default">5. Przetwarzanie wyników modelu</h4>		</div>
				</div>
				<div class="elementor-element elementor-element-aeca953 elementor-widget elementor-widget-text-editor" data-id="aeca953" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Wynik sieci YOLO to tensor, który należy odpowiednio zinterpretować. Poniżej znajdują się kroki w naszej funkcji <span style="color: #008000;">postprocessInferenceResults()</span>, które pozwalają na wyodrębnienie współrzędnych wszystkich wykrytych obiektów:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-04c9010 elementor-widget elementor-widget-text-editor" data-id="04c9010" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre data-ccp-border-bottom="0px none #000000" data-ccp-padding-bottom="0px" data-ccp-border-between="0px none #000000" data-ccp-padding-between="0px"><span data-contrast="none">const</span><span data-contrast="none"> results = prediction.transpose([</span><span data-contrast="none">0</span><span data-contrast="none">, </span><span data-contrast="none">2</span><span data-contrast="none">, </span><span data-contrast="none">1</span><span data-contrast="none">]); </span> <br /><span data-contrast="none">const</span><span data-contrast="none"> numClass = </span><span data-contrast="none">1</span><span data-contrast="none">; </span><span data-contrast="none">// Only one class in our case</span> <br /><span data-contrast="none">const</span><span data-contrast="none"> boxes = tf.tidy(() =&gt; {</span> <br /><span data-contrast="none">const</span><span data-contrast="none"> w = results.slice([</span><span data-contrast="none">0</span><span data-contrast="none">, </span><span data-contrast="none">0</span><span data-contrast="none">, </span><span data-contrast="none">2</span><span data-contrast="none">], [</span><span data-contrast="none">-1</span><span data-contrast="none">, </span><span data-contrast="none">-1</span><span data-contrast="none">, </span><span data-contrast="none">1</span><span data-contrast="none">]); </span><span data-contrast="none">// Get width</span> <br /><span data-contrast="none">const</span><span data-contrast="none"> h = results.slice([</span><span data-contrast="none">0</span><span data-contrast="none">, </span><span data-contrast="none">0</span><span data-contrast="none">, </span><span data-contrast="none">3</span><span data-contrast="none">], [</span><span data-contrast="none">-1</span><span data-contrast="none">, </span><span data-contrast="none">-1</span><span data-contrast="none">, </span><span data-contrast="none">1</span><span data-contrast="none">]); </span><span data-contrast="none">// Get height</span> <br /><span data-contrast="none">const</span><span data-contrast="none"> x1 = tf.sub(results.slice([</span><span data-contrast="none">0</span><span data-contrast="none">, </span><span data-contrast="none">0</span><span data-contrast="none">, </span><span data-contrast="none">0</span><span data-contrast="none">], [</span><span data-contrast="none">-1</span><span data-contrast="none">, </span><span data-contrast="none">-1</span><span data-contrast="none">, </span><span data-contrast="none">1</span><span data-contrast="none">]), tf.div(w, </span><span data-contrast="none">2</span><span data-contrast="none">)); </span><span data-contrast="none">// Get x1</span><span data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span><br /><br /><span data-contrast="none">const</span><span data-contrast="none"> y1 = tf.sub(results.slice([</span><span data-contrast="none">0</span><span data-contrast="none">, </span><span data-contrast="none">0</span><span data-contrast="none">, </span><span data-contrast="none">1</span><span data-contrast="none">], [</span><span data-contrast="none">-1</span><span data-contrast="none">, </span><span data-contrast="none">-1</span><span data-contrast="none">, </span><span data-contrast="none">1</span><span data-contrast="none">]), tf.div(h, </span><span data-contrast="none">2</span><span data-contrast="none">)); </span><span data-contrast="none">// Get y1</span> <br /><span data-contrast="none">return</span><span data-contrast="none"> tf.concat([y1, x1, y1.add(h), x1.add(w)], </span><span data-contrast="none">2</span><span data-contrast="none">).squeeze();</span> <br /><span data-contrast="none">});</span><span data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-70bdd06 elementor-widget elementor-widget-text-editor" data-id="70bdd06" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Aby wyodrębnić klasy i poziomy ufności dla każdego obiektu:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-4e859a7 elementor-widget elementor-widget-text-editor" data-id="4e859a7" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">const</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0"> numClass = labels.length;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW92870568 BCX0"><span class="SCXW92870568 BCX0"> </span><br class="SCXW92870568 BCX0" /></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">const</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0"> [scores, classes] = tf.tidy(() =&gt; {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW92870568 BCX0"><span class="SCXW92870568 BCX0"> </span><br class="SCXW92870568 BCX0" /></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">const</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0"> rawData = results.slice([</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">0</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">, </span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">0</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">, </span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">4</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">], [</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">-1</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">, </span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">-1</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">, numClass]).squeeze(</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">0</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW92870568 BCX0"><span class="SCXW92870568 BCX0"> </span><br class="SCXW92870568 BCX0" /></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">  </span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">return</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0"> [rawData.max(</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">1</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">), rawData.argMax(</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">1</span></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">)];</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW92870568 BCX0"><span class="SCXW92870568 BCX0"> </span><br class="SCXW92870568 BCX0" /></span><span class="TextRun Highlight SCXW92870568 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW92870568 BCX0">});</span></span><span class="EOP SCXW92870568 BCX0" data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-c29f2bf elementor-widget elementor-widget-text-editor" data-id="c29f2bf" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Następnie należy pozbyć się wyników z poziomem ufności poniżej ustalonego progu (u nas był to 0.4):</p>						</div>
				</div>
				<div class="elementor-element elementor-element-2bbe314 elementor-widget elementor-widget-text-editor" data-id="2bbe314" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">const</span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0"> array = </span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">await</span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0"> scores.array();</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW227521811 BCX0"><span class="SCXW227521811 BCX0"> </span><br class="SCXW227521811 BCX0" /></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">const</span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0"> highConfidenceIndices = array.reduce((acc, value, index) =&gt; {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW227521811 BCX0"><span class="SCXW227521811 BCX0"> </span><br class="SCXW227521811 BCX0" /></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">  </span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">if</span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0"> (value &gt; </span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">0.4</span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">) acc.push(index);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW227521811 BCX0"><span class="SCXW227521811 BCX0"> </span><br class="SCXW227521811 BCX0" /></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">  </span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">return</span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0"> acc;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW227521811 BCX0"><span class="SCXW227521811 BCX0"> </span><br class="SCXW227521811 BCX0" /></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">}, []);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW227521811 BCX0"><span class="SCXW227521811 BCX0"> </span><br class="SCXW227521811 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW227521811 BCX0"><span class="SCXW227521811 BCX0"> </span><br class="SCXW227521811 BCX0" /></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">const</span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0"> highConfidenceBoxes = boxes.gather(highConfidenceIndices);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW227521811 BCX0"><span class="SCXW227521811 BCX0"> </span><br class="SCXW227521811 BCX0" /></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">const</span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0"> highConfidenceScores = scores.gather(highConfidenceIndices);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW227521811 BCX0"><span class="SCXW227521811 BCX0"> </span><br class="SCXW227521811 BCX0" /></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0">const</span></span><span class="TextRun Highlight SCXW227521811 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW227521811 BCX0"> highConfidenceClasses = classes.gather(highConfidenceIndices);</span></span><span class="EOP SCXW227521811 BCX0" data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-6d455b0 elementor-widget elementor-widget-text-editor" data-id="6d455b0" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Na koniec zastosuj Non-Max Suppression (NMS), aby odfiltrować duplikaty, tzn. wykryte obiekty, które się na siebie nakładają:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-a51ed9c elementor-widget elementor-widget-text-editor" data-id="a51ed9c" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">const</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0"> nms = </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">await</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0"> tf.image.nonMaxSuppressionAsync(highConfidenceBoxes, highConfidenceScores, </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">40</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">, </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">0.45</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">, </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">0.4</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">); </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">// NMS to filter boxes</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW150352841 BCX0"><span class="SCXW150352841 BCX0"> </span><br class="SCXW150352841 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW150352841 BCX0"><span class="SCXW150352841 BCX0"> </span><br class="SCXW150352841 BCX0" /></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">const</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0"> boxesData = highConfidenceBoxes.gather(nms, </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">0</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">); </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">// Indexing boxes by NMS index</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW150352841 BCX0"><span class="SCXW150352841 BCX0"> </span><br class="SCXW150352841 BCX0" /></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">const</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0"> scoresData = highConfidenceScores.gather(nms, </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">0</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">).dataSync(); </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">// Indexing scores by</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW150352841 BCX0"><span class="SCXW150352841 BCX0"> </span><br class="SCXW150352841 BCX0" /></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">const</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0"> classesData = highConfidenceClasses.gather(nms, </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">0</span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">).dataSync(); </span></span><span class="TextRun Highlight SCXW150352841 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW150352841 BCX0">// Indexing classes by NMS index</span></span><span class="EOP SCXW150352841 BCX0" data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-a61bead elementor-widget elementor-widget-text-editor" data-id="a61bead" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Ostatnim krokiem jest przeskalowanie współrzędnych, aby dopasować je do kształtu oryginalnego obrazu:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-84b07f0 elementor-widget elementor-widget-text-editor" data-id="84b07f0" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">// Precompute the margins and factors outside the stack</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">const</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0"> yMarginTensor = tf.scalar(yMargin);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">const</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0"> xMarginTensor = tf.scalar(xMargin);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">const</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0"> resizeFactorTensor = tf.scalar(resizeFactor);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">// Slice the boxesData and apply transformations in one step</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">const</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0"> [yCoordinates, xCoordinates, height, width] = </span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">  [</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">'0'</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">, </span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">'1'</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">, </span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">'2'</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">, </span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">'3'</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">].map((index) =&gt; </span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">    boxesData.slice([</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">0</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">, </span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">parseInt</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">(index)], [</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">-1</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">, </span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">1</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">]).sub(index % </span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">2</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0"> === </span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">0</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0"> ? yMarginTensor : xMarginTensor).mul(resizeFactorTensor)</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">// Stack the tensors without converting to arrays (unless needed)</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">const</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0"> bbox = tf.stack([yCoordinates, xCoordinates, height, width], </span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">1</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">// Convert to an array only if absolutely necessary</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW260954935 BCX0"><span class="SCXW260954935 BCX0"> </span><br class="SCXW260954935 BCX0" /></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0">const</span></span><span class="TextRun Highlight SCXW260954935 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW260954935 BCX0"> bboxArray = bbox.arraySync();</span></span><span class="EOP SCXW260954935 BCX0" data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-b542632 elementor-widget elementor-widget-text-editor" data-id="b542632" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Na końcu możemy zdefiniować funkcję <strong>runInference()</strong>, która zawiera cały opisany powyżej proces wykrywania obiektów. Ta funkcja zawiera przygotowanie obrazu, uruchomienie inferencji modelu oraz przetworzenie wyników. Oto jak wygląda:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d6642ff elementor-widget elementor-widget-text-editor" data-id="d6642ff" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">export</span></span> <span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">async</span></span> <span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">function</span></span> <span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">runInference</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">(model, labels, image, confidenceThreshold = </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">0.4</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">) {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">  </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">try</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0"> {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">    </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">// Preprocess the image</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">    </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">const</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0"> imgSize = model.inputs[</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">0</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">].shape[</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">1</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">];</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">    </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">const</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0"> { imgTensor: inputTensor, left: xMargin, top: yMargin, factor: resizeFactor } = preprocessImage(image, imgSize);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">    </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">// Run inference</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">    </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">const</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0"> prediction = </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">await</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0"> model.execute(inputTensor);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">    </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">// Post-process the model output</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">    </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">const</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0"> [boxes, scores, classes] = </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">await</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0"> postprocessInferenceResults(prediction, labels, xMargin, yMargin, resizeFactor, confidenceThreshold);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">    </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">return</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0"> [boxes, scores, classes];</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">  } </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">catch</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0"> (error) {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">    </span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">throw</span></span> <span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">new</span></span> <span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">Error</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">(</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">`Inference failed: ${error.message}`</span></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">  }</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW217269171 BCX0"><span class="SCXW217269171 BCX0"> </span><br class="SCXW217269171 BCX0" /></span><span class="TextRun Highlight SCXW217269171 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW217269171 BCX0">}</span></span><span class="EOP SCXW217269171 BCX0" data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-d087385 elementor-widget elementor-widget-heading" data-id="d087385" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h4 class="elementor-heading-title elementor-size-default">6. Wizualizacja wyników </h4>		</div>
				</div>
				<div class="elementor-element elementor-element-84689b0 elementor-widget elementor-widget-text-editor" data-id="84689b0" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Na samym końcu, gdy mamy już gotowe wyniki detekcji, możemy narysować wykryte obiekty na obrazie:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d769790 elementor-widget elementor-widget-text-editor" data-id="d769790" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">function</span></span> <span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">drawBoxesOnCanvas</span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">(ctx, boxes, classes, scores, colors) {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW6384134 BCX0"><span class="SCXW6384134 BCX0"> </span><br class="SCXW6384134 BCX0" /></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">  boxes.forEach((box, i) =&gt; {</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW6384134 BCX0"><span class="SCXW6384134 BCX0"> </span><br class="SCXW6384134 BCX0" /></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">    </span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">const</span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0"> [x1, y1, x2, y2] = box;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW6384134 BCX0"><span class="SCXW6384134 BCX0"> </span><br class="SCXW6384134 BCX0" /></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">    ctx.strokeStyle = colors[classes[i]];</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW6384134 BCX0"><span class="SCXW6384134 BCX0"> </span><br class="SCXW6384134 BCX0" /></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">    ctx.lineWidth = </span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">2</span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">;</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW6384134 BCX0"><span class="SCXW6384134 BCX0"> </span><br class="SCXW6384134 BCX0" /></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">    ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW6384134 BCX0"><span class="SCXW6384134 BCX0"> </span><br class="SCXW6384134 BCX0" /></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">    ctx.fillStyle = colors[classes[i]];</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW6384134 BCX0"><span class="SCXW6384134 BCX0"> </span><br class="SCXW6384134 BCX0" /></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">    ctx.fillText(</span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">`${labels[classes[i]]} (${</span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">Math</span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">.round(scores[i] * </span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">100</span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">)}%)`</span></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">, x1, y1);</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW6384134 BCX0"><span class="SCXW6384134 BCX0"> </span><br class="SCXW6384134 BCX0" /></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">  });</span></span><span class="LineBreakBlob BlobObject DragDrop SCXW6384134 BCX0"><span class="SCXW6384134 BCX0"> </span><br class="SCXW6384134 BCX0" /></span><span class="TextRun Highlight SCXW6384134 BCX0" lang="PL" xml:lang="PL" data-contrast="none"><span class="NormalTextRun SCXW6384134 BCX0">}</span></span><span class="EOP SCXW6384134 BCX0" data-ccp-props="{&quot;134245417&quot;:false,&quot;201341983&quot;:0,&quot;335559740&quot;:360,&quot;335572071&quot;:0,&quot;335572072&quot;:0,&quot;335572073&quot;:0,&quot;335572075&quot;:0,&quot;335572076&quot;:0,&quot;335572077&quot;:0,&quot;335572079&quot;:0,&quot;335572080&quot;:0,&quot;335572081&quot;:0,&quot;335572083&quot;:0,&quot;335572084&quot;:0,&quot;335572085&quot;:0,&quot;335572087&quot;:0,&quot;335572088&quot;:0,&quot;335572089&quot;:0,&quot;469789798&quot;:&quot;nil&quot;,&quot;469789802&quot;:&quot;nil&quot;,&quot;469789806&quot;:&quot;nil&quot;,&quot;469789810&quot;:&quot;nil&quot;,&quot;469789814&quot;:&quot;nil&quot;}"> </span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-0a7536b elementor-widget elementor-widget-text-editor" data-id="0a7536b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Podsumowując, uruchamianie modelu YOLO do wykrywania obiektów bezpośrednio w przeglądarce przy użyciu TensorFlow.js otwiera nowe możliwości dla aplikacji real-time. W tym wpisie przedstawiliśmy wszystkie kroki, od konfiguracji TensorFlow.js, przez ładowanie modeli, przetwarzanie obrazów, uruchamianie wnioskowania, aż po wizualizację wyników, wraz ze wskazówkami jak zrobić to efektywnie. W miarę dalszego zgłębiania tej ciekawej technologii, warto eksperymentować z różnymi modelami, technikami optymalizacji oraz przypadkami użycia, aby w pełni wykorzystać potencjał uczenia maszynowego w aplikacjach internetowych.</p>						</div>
				</div>
		<div class="elementor-element elementor-element-b23a8f8 e-grid e-con-full e-con e-child" data-id="b23a8f8" data-element_type="container">
				<div class="elementor-element elementor-element-2e189c2 elementor-widget elementor-widget-heading" data-id="2e189c2" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h4 class="elementor-heading-title elementor-size-default">Zapraszam do kontaktu, jeśli masz pytania lub chciałbyś podzielić się swoimi implementacjami!</h4>		</div>
				</div>
				<div class="elementor-element elementor-element-a749555 elementor-button-success elementor-align-center elementor-widget elementor-widget-button" data-id="a749555" data-element_type="widget" data-widget_type="button.default">
				<div class="elementor-widget-container">
							<div class="elementor-button-wrapper">
					<a class="elementor-button elementor-button-link elementor-size-sm" href="https://inero-software.com/pl/kontakt/">
						<span class="elementor-button-content-wrapper">
						<span class="elementor-button-icon">
				<svg aria-hidden="true" class="e-font-icon-svg e-fas-envelope" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"></path></svg>			</span>
									<span class="elementor-button-text">KONTAKT</span>
					</span>
					</a>
				</div>
						</div>
				</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-38cdd54 e-con-full e-flex e-con e-child" data-id="38cdd54" data-element_type="container">
				</div>
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/pl/sieci-neuronowe-w-przegladarce-przewodnik-na-przykladzie-customowej-sieci-yolo-do-wykrywania-twarzy/">Sieci neuronowe w przeglądarce: Przewodnik na przykładzie customowej sieci YOLO do wykrywania twarzy</a> pochodzi z serwisu <a href="https://inero-software.com/pl">Inero Software - Rozwiązania IT i Konsulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6230</post-id>	</item>
		<item>
		<title>Budowa systemu rozpoznawania komend głosowych w języku polskim</title>
		<link>https://inero-software.com/pl/budowa-systemu-rozpoznawania-komend-glosowych/</link>
		
		<dc:creator><![CDATA[Andrzej Chybicki]]></dc:creator>
		<pubDate>Mon, 04 Apr 2022 10:08:58 +0000</pubDate>
				<category><![CDATA[Blog_pl]]></category>
		<category><![CDATA[Firma]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[deepspeech]]></category>
		<category><![CDATA[model językowy]]></category>
		<category><![CDATA[modele ASR]]></category>
		<category><![CDATA[rozpoznawanie komend głosowych]]></category>
		<category><![CDATA[sieci neuronowe]]></category>
		<category><![CDATA[system rozpoznawania głosu]]></category>
		<category><![CDATA[zbiory danych]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=4748</guid>

					<description><![CDATA[<p>System rozpoznawania głosu pełni rolę pomocnika, który wyszuka dla nas odpowiednie informacje, ułatwi zakupy w Internecie czy umożliwi obsługę różnych urządzeń bez wykorzystywania zewnętrznych przycisków czy regulacji.</p>
<p>Artykuł <a href="https://inero-software.com/pl/budowa-systemu-rozpoznawania-komend-glosowych/">Budowa systemu rozpoznawania komend głosowych w języku polskim</a> pochodzi z serwisu <a href="https://inero-software.com/pl">Inero Software - Rozwiązania IT i Konsulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>&nbsp;</p>
<div class="row">
<p><div class="col-sm-1"></div></p>
<p><div class="col-sm-10">
<p><img loading="lazy" decoding="async" class=" wp-image-2770 aligncenter" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png" alt="" width="75" height="75" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-50x50.png 50w" sizes="(max-width: 75px) 100vw, 75px" /></p>
<p>&nbsp;</p>
<h2><span style="color: #800080;">Budowa systemu rozpoznawania komend głosowych w języku polskim</span></h2>
<p>&nbsp;</p>
<p><span data-contrast="auto"><span class="TextRun SCXW189727610 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW189727610 BCX0"><span class="TextRun SCXW21457896 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW21457896 BCX0"><img loading="lazy" decoding="async" class=" wp-image-2768 alignleft" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png" alt="" width="71" height="71" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-50x50.png 50w" sizes="(max-width: 71px) 100vw, 71px" /></span></span></span></span></span>System rozpoznawania komend głosowych został stworzony po to, aby usprawnić życie człowieka. Pełni on rolę pomocnika, który wyszuka dla nas odpowiednie informacje, ułatwi zakupy w Internecie czy umożliwi obsługę różnych urządzeń bez wykorzystywania zewnętrznych przycisków czy regulacji. Jednak stworzenie takiego systemu od podstaw może być trudnym wyzwaniem. W szczególności, jeśli chcemy zbudować go w języku polskim.</p>
<p>Istnieją ogólne modele sieci neuronowych, które dedykowane są rozpoznawaniu języka mówionego, czyli transkrypcji nagrania audio do tekstu. Wszystko jednak uwarunkowane jest od tego, ile danych posiadamy. Obecnie istnieje wiele zbiorów nagrań z języka angielskiego, które są odpowiednio przygotowane. Same dane jednak nie wystarczą. Muszą być do nich dołączone transkrypcje. Niestety w języku polskim nie mamy dużej ilości próbek głosowych razem z transkrypcjami. Na dzień dzisiejszy nie jesteśmy więc w stanie tak dobrze wyuczyć modeli, jak to jest robione w języku angielskim.</p>
<p>Jak na razie nie możemy wyuczyć asystentów wykorzystując modele open source’owe z zadowalającą skutecznością, jednak możemy sprawdzić co jesteśmy w stanie zbudować z ogólnie dostępnych danych. Celem naszej pracy jest stworzenie systemu rozpoznawania mowy, który działa w ograniczonym zbiorze komend.</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" class=" wp-image-2770 aligncenter" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png" alt="" width="75" height="75" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-50x50.png 50w" sizes="(max-width: 75px) 100vw, 75px" /></p>
<p>&nbsp;</p>
<h2><span style="color: #800080;">Główne źródła zbierania danych dla systemu rozpoznawania komend głosowych</span></h2>
<p>&nbsp;</p>
<p><span data-contrast="auto"><span class="TextRun SCXW189727610 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW189727610 BCX0"><span class="TextRun SCXW21457896 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW21457896 BCX0"><img loading="lazy" decoding="async" class=" wp-image-2768 alignleft" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png" alt="" width="71" height="71" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-50x50.png 50w" sizes="(max-width: 71px) 100vw, 71px" /></span></span></span></span></span>W ostatnich miesiącach pojawiły się zbiory danych: <strong><a href="https://commonvoice.mozilla.org/pl">Common Voice</a> i <a href="https://zasobynauki.pl/zasoby/korpus-nagran-probek-mowy-do-celow-budowy-modeli-akustycznych-dla-automatycznego-rozpoznawania-mowy,56411/">Zasoby Nauki</a></strong>, które są odpowiednio przygotowane pod modele ASR (Automatic Speech Recognition). Oznacza to, że nagrania dźwiękowe zawierają również transkrypcje. Są to tak naprawdę dwa największe zbiory danych, które można użyć. Do zbudowania własnego systemu wykorzystaliśmy więc je i złączyliśmy w jedno.</p>
<p><a href="https://commonvoice.mozilla.org/pl">Common Voice</a> jest ciekawym zbiorem danych. Jeżeli chcemy aby ich ilość była jeszcze większa, możemy kontrybuować w tym działaniu. Każdy z nas może wejść na stronę i nagrać swój głos, który zostanie zapisany, a następnie sprawdzony przez innych użytkowników. W ten sposób będziemy mogli przyczynić się do powiększenia ilości danych z języka polskiego, dzięki czemu budowanie systemów rozpoznawania komend głosowych będzie łatwiejsze.</p>
<p>W przyszłości istnieje możliwość, że YouTube udostępni do wykorzystania swoje nagrania audio razem z automatycznie generowanymi transkrypcjami. Jest to jednak rozwiązanie, które (być może) powstanie dopiero później. Dodatkowym źródłem danych mogą również być audiobooki, które zawierają transkrypcję książek i nagrania audio. W takim przypadku musimy jednak wykonać pracę przygotowania danych polegającą na pofragmentowaniu danych na krótsze nagrania. Dodatkowo zmienna intonacja lektora może wpływać na dokładność wyuczonych przez nas modeli.</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" class=" wp-image-2770 aligncenter" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png" alt="" width="75" height="75" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-50x50.png 50w" sizes="(max-width: 75px) 100vw, 75px" /></p>
<p>&nbsp;</p>
<h2><span style="color: #800080;">Przygotowanie i ujednolicenie danych</span></h2>
<p>&nbsp;</p>
<p><span data-contrast="auto"><span class="TextRun SCXW189727610 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW189727610 BCX0"><span class="TextRun SCXW21457896 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW21457896 BCX0"><img loading="lazy" decoding="async" class=" wp-image-2768 alignleft" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png" alt="" width="87" height="87" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-50x50.png 50w" sizes="(max-width: 87px) 100vw, 87px" /></span></span></span></span></span>Przede wszystkim musimy zapewnić minimalną i maksymalną długość nagrania. Muszą one znajdować się w określonych ramach czasowych. Zbyt długie nagrania mogą być problemem podczas uczenia modelu, natomiast krótkie nagrania mogą nie nieść ze sobą żadnej istotnej informacji. Musimy także zapewnić jednakową częstotliwość próbkowania sygnału. Jest to bardzo ważna kwestia przy uczeniu modeli opartych na dźwięk.</p>
<p>Fala dźwiękowa czystego tonu, rozchodząca się w przestrzeni, ma charakter sinusoidalny. Zmiana częstotliwości takiego dźwięku oznacza zmianę okresu sinusoidy, więc zmieniają się odległości między jej grzbietami. Jednak dźwięk w komputerze również musi być w jakiś sposób zaprezentowany. Sinusoida jest przebiegiem ciągłym, natomiast komputer zapisuje pojedyncze wartości. Częstotliwość próbkowania mówi nam o tym, ile razy na sekundę została zapisana wartość rejestrowanej fali dźwiękowej. Bardzo ważne jest to, żeby każdy dźwięk, który wchodzi do naszego modelu miał taką samą częstotliwość próbkowania.</p>
<p>Poprzez nieprawidłowe próbkowanie rekonstruowany dźwięk może być zniekształcony lub całkowicie niesłyszalny. Trzeba więc pamiętać o odpowiednim dobraniu częstotliwości próbkowania, aby zminimalizować rozmiar zapisywanych danych przy jednoczesnym braku utraty informacji. Zbyt rzadkie próbkowanie może spowodować pojawienie się zjawiska aliasingu, czyli nakładania się wyższych częstotliwości na niższe.</p>
<p><img loading="lazy" decoding="async" data-attachment-id="4749" data-permalink="https://inero-software.com/pl/budowa-systemu-rozpoznawania-komend-glosowych/picture1/" data-orig-file="https://inero-software.com/wp-content/uploads/2022/03/Picture1.png" data-orig-size="605,454" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Picture1" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2022/03/Picture1-300x225.png" data-large-file="https://inero-software.com/wp-content/uploads/2022/03/Picture1.png" tabindex="0" role="button" class="aligncenter wp-image-4749 size-full" src="https://inero-software.com/wp-content/uploads/2022/03/Picture1.png" alt="częstotliwość próbkowania dźwięku" width="605" height="454" srcset="https://inero-software.com/wp-content/uploads/2022/03/Picture1.png 605w, https://inero-software.com/wp-content/uploads/2022/03/Picture1-300x225.png 300w, https://inero-software.com/wp-content/uploads/2022/03/Picture1-400x300.png 400w" sizes="(max-width: 605px) 100vw, 605px" /></p>
<p style="text-align: center;"><em>Źródło: <a href="https://pbc.gda.pl/dlibra/publication/109835/edition/98484/content">Reprezentacje danych dźwiękowych w kontekście metod uczenia maszynowego</a>, s. 134, Tymoteusz Cejrowski</em></p>
<p>Zapobieganie takiemu zjawisku polega na próbkowaniu sygnału z częstotliwością co najmniej dwa razy większą od najwyższej częstotliwości występującej w sygnale. Częstotliwość ta nazywana jest częstotliwością Nyqiusta. Dla przykładu, nagrania na płytach CD są zapisywane z częstotliwością próbkowania 44100 Hz. Natomiast maksymalna poprawnie zrekonstruowana częstotliwość będzie wynosiła 22050 Hz, co odpowiada górnemu zakresowi dźwięków słyszalnych przez człowieka.</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" class=" wp-image-2770 aligncenter" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png" alt="" width="75" height="75" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-50x50.png 50w" sizes="(max-width: 75px) 100vw, 75px" /></p>
<p>&nbsp;</p>
<h2><span style="color: #800080;">Opis i uczenie modelu deepspeech w systemie rozpoznawania komend głosowych</span></h2>
<p>&nbsp;</p>
<p><span data-contrast="auto"><span class="TextRun SCXW189727610 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW189727610 BCX0"><span class="TextRun SCXW21457896 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW21457896 BCX0"><img loading="lazy" decoding="async" class=" wp-image-2768 alignleft" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png" alt="" width="48" height="48" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-50x50.png 50w" sizes="(max-width: 48px) 100vw, 48px" /></span></span></span></span></span>Sieci neuronowe w pewien sposób przypominają układ nerwowy. Podstawowymi jednostkami w takich sieciach są neurony, które rozmieszczone są w warstwach. Jest to uproszczony model procesu przetwarzania informacji przez ludzki umysł.</p>
<p>Zazwyczaj sieć neuronowa składa się z trzech części. Pierwsza to warstwa wejściowa, która posiada jednostki reprezentujące zmienne wejściowe. Następna część to warstwy ukryte, które zawierają jednostki nieobserwowane i są ukrytym stanem sieci neuronowej. To właśnie od tych warstw w dużej mierze zależy efektywność modelu. Natomiast ostatnią częścią jest oczywiście warstwa wyjściowa, która posiada jednostki reprezentujące zmienne przewidywane. Wszystkie jednostki złączone są konkretnymi połączeniami o różnej wadze. Dane wejściowe znajdują się na pierwszej warstwie, przechodzą one przez kolejne, a ostatecznie z warstwy wyjściowej otrzymujemy wynik.</p>
<p>Sieć neuronowa uczy się przez porównywanie rekordów. Generuje ona predykcje dla konkretnych danych (nagrań audio) i wprowadza korekty wag, jeśli generują one niepoprawną predykcję (złą transkrypcję). Cały proces powtarzany jest wiele razy do uzyskania satysfakcjonującej dokładności. Wszystkie wagi na początku mają charakter losowy, a odpowiedzi wychodzące nie mają dużo sensu, z czasem natomiast sieć poprawia swoje predykcje. Dzieje się tak, ponieważ sieć dopasowuje się do danych w procesie uczenia wykorzystując algorytm wstecznej propagacji błędu.</p>
<p>Jednym z najprostszych modeli Sieci Neuronowych jest <strong>Perceptron wielowarstwowy</strong>. Składa się on z wielu warstw neuronowych. Neurony poprzedniej warstwy tworzą konkretny wektor, który jest podawany na wejście neuronów do warstwy następnej. Pojedynczy neuron w warstwie następnej ma liczbę wejść równej liczbie neuronów z warstwy poprzedniej +1. Jednak w ramach jednej warstwy, neurony między sobą nie mają żadnych połączeń. Taki typ modelu nazywany jest również modelem „Feed-Forward” i jest jedną z podstawowych architektur sieci neuronowych.</p>
<p><img loading="lazy" decoding="async" data-attachment-id="4750" data-permalink="https://inero-software.com/pl/budowa-systemu-rozpoznawania-komend-glosowych/picture2/" data-orig-file="https://inero-software.com/wp-content/uploads/2022/03/Picture2.png" data-orig-size="361,461" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Picture2" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2022/03/Picture2-235x300.png" data-large-file="https://inero-software.com/wp-content/uploads/2022/03/Picture2.png" tabindex="0" role="button" class="wp-image-4750 size-full aligncenter" src="https://inero-software.com/wp-content/uploads/2022/03/Picture2.png" alt="model sieci feed-forward" width="361" height="461" srcset="https://inero-software.com/wp-content/uploads/2022/03/Picture2.png 361w, https://inero-software.com/wp-content/uploads/2022/03/Picture2-235x300.png 235w" sizes="(max-width: 361px) 100vw, 361px" /></p>
<p style="text-align: center;"><em>Rysunek przedstawiający model „Feed-Forward”</em></p>
<p><strong>Sieci rekurencyjne</strong> różnią się od sieci typu „Feed-Forward” w wielu aspektach. Jedną z głównych różnic jest sposób propagacji danych wejściowych na wyjście sieci. W najprostszym modelu wyjście sieci jest niczym innym kombinacją wag i wejścia modelu (pojedynczego rekordu). W przypadku sieci rekurencyjnych wyjście modelu zależy również od poprzedniego wyjścia. Wynik działania modelu dla rekordu X jest brany pod uwagę przy wyliczaniu wyjścia dla kolejnego rekordu Y.</p>
<p><strong>Konwolucyjna sieć neuronowa</strong> jest typem sieci najczęściej stosowanej do analizy obrazów wizualnych z uwagi na swój charakter procesowania wejścia. Podobnie jak człowiek, sieć ta nie analizuje obrazu piksel po pikselu ale wyłapuje wzorce obecne w danych wejściowych dzięki zastosowaniu tzw. Kerneli czyli filtrów. Każda warstwa w sieci neuronowej uczy się cech obrazu takich jak kontury czy nasycenie światłem. Złożenie tych informacji poprawia efektywność modelu.</p>
<p>Poza neuronowymi modelami rozpoznawania mowy, warto pochylić się nad open source’owymi systemami, które umożliwiają zbudowanie systemu rozpoznawania komend głosowych. Jednym z nich jest <a href="http://kaldi-asr.org"><strong>Kaldi</strong></a>, który został napisany w C++. Powstał on w 2009 roku, a jego głównymi cechami jest to, że system ten jest rozszerzalny i cały czas rozwijany. Udostępnia on m.in. narzędzia do pre-procesowania nagrań audio czy modeli opartych o Ukryte Modele Markowa (HMM). Sama społeczność udostępnia wiele innych modułów, które można wykorzystać do własnych zadań. Kaldi, poza modelami statystycznymi, obsługuje także głębokie sieci neuronowe. Pomimo tego, że jest napisany głównie w C++, to posiada on skrypty w jezyku Bash czy Python.</p>
<p>W naszej pracy skupiliśmy się jednak na konkretnym modelu ASR: <a href="https://github.com/SeanNaren/deepspeech.pytorch"><strong>deepspeech</strong></a><strong> 2</strong>. Jest to model, który wykorzystuje głębokie uczenie (ang. Deep Learning), składa się on z 3 warstw konwolucyjnych, 8 rekurencyjnych i jednej Fully-Connected. Deepspeech 2 można z powodzeniem wyuczyć na dowolnym języku, trzeba jednak pamiętać, że takie uczenie wymaga wydajnego systemu komputerowego/serwerowego wyposażonego w odpowiednią ilość kart graficznych lub akceleratorów obliczeń.</p>
<p>W przypadku popularnych języków takich jak angielski czy mandaryński można znaleźć przetrenowane modele gotowe do użycia. W naszym zadaniu wybraliśmy deepspeech 2 z implementacją w <a href="https://github.com/SeanNaren/deepspeech.pytorch">PyTorchu</a>, ponieważ jest on lekki, ma stosunkowo mało parametrów (wag do wyuczenia) i wybrana przez nas implementacja jest aktywnie utrzymywana. W tym modelu oprócz przygotowania odpowiednich częstotliwości próbkowania o których pisaliśmy wyżej, musieliśmy również przygotować odpowiednio dane pod sam model deepspeech. Wiązało się to z zapewnieniem odpowiedniej struktury katalogów.</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" class=" wp-image-2770 aligncenter" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png" alt="" width="75" height="75" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-50x50.png 50w" sizes="(max-width: 75px) 100vw, 75px" /></p>
<p>&nbsp;</p>
<h2><span style="color: #800080;">Wnioskowanie z użyciem modeli ASR i dodatkowego modelu językowego</span></h2>
<p>&nbsp;</p>
<p><span data-contrast="auto"><span class="TextRun SCXW189727610 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW189727610 BCX0"><span class="TextRun SCXW21457896 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW21457896 BCX0"><img loading="lazy" decoding="async" class=" wp-image-2768 alignleft" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png" alt="" width="101" height="101" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-50x50.png 50w" sizes="(max-width: 101px) 100vw, 101px" /></span></span></span></span></span>Wykorzystując deepspeech jesteśmy w stanie zastosować dodatkowy model językowy (model n-gramowy). Opiera się on na statystykach i pomaga w przewidywaniu kolejnego elementu sekwencji w wynikowej transkrypcji. Trzeba pamiętać, że zastosowanie takiego modelu wymaga zgromadzenia dużego zasobu danych statystycznych. N-gramy pomagają maszynom w zrozumieniu słowa w konkretnym kontekście. Dzięki temu mogą one lepiej zrozumieć jego przeznaczenie.</p>
<p>Jeśli chcemy utworzyć taki model, zaczynamy od zliczania wystąpień sekwencji o ustalonej długości <em>n</em> w istniejących już zasobach językowych. Analizuje się więc całe teksty i zlicza się pojedyncze wystąpienia (1-gram), dwójki (2-gramy) i trójki (3-gramy). Możemy również uzyskać model 4-gramowy, jednak tutaj potrzebne są już ogromne zbiory danych, przez co dla języka polskiego jest to niezwykle trudne do zrealizowania. W kolejnym kroku zamienia się liczbę wystąpień na prawdopodobieństwo poprzez normalizację. W ten sposób zyskujemy predykcję kolejnego elementu na podstawie dotychczasowych sekwencji. Warto zaznaczyć, że im więcej przeanalizowanego tekstu, tym wyższa jakość modelu. Dane te są głównie wykorzystywane w aplikacjach przetwarzania języka naturalnego (NLP). Model n-gramowy dla języka polskiego można znaleźć <a href="https://zasobynauki.pl/zasoby/model-jezykowy-dla-jezyka-polskiego,55644/">tutaj</a>.</p>
<p>Użycie modelu n-gramowego na etapie wnioskowania pozwala na skorygowanie wyjścia sieci neuronowej (transkrypcji modelu deepspeech 2) zgodnie z regułami zawartymi w modelu n-gramowym.</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" class=" wp-image-2770 aligncenter" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png" alt="" width="75" height="75" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-50x50.png 50w" sizes="(max-width: 75px) 100vw, 75px" /></p>
<p>&nbsp;</p>
<h2><span style="color: #800080;">Działanie w ograniczonym zbiorze komend</span></h2>
<p>&nbsp;</p>
<p><span data-contrast="auto"><span class="TextRun SCXW189727610 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW189727610 BCX0"><span class="TextRun SCXW21457896 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW21457896 BCX0"><img loading="lazy" decoding="async" class=" wp-image-2768 alignleft" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png" alt="" width="101" height="101" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-50x50.png 50w" sizes="(max-width: 101px) 100vw, 101px" /></span></span></span></span></span>Niestety budowane modele nie mogą być wystarczająco dokładne ze względu na małą ilość danych w języku polskim. W naszym przypadku możemy jednak działać w ograniczonym zbiorze komend. Oznacza to, że rozpoznawaniu podlega konkretna ilość komend głosowych. Nasze zadanie polegało na tym, żeby dopasować odpowiednią komendę ze zbioru z tym co dostarczył nam model. Ważne jest tutaj określenie najwyższego podobieństwa pomiędzy komendą, a tym co zwrócił nam model.</p>
<p>Do tego zadania wykorzystaliśmy miarę zwaną <strong>odległością Levenshteina</strong>, która wskazuje na podobieństwo pomiędzy transkrypcją, a daną komendą. Polega ona na zliczaniu pozycji lub liter, które się nie zgadzają. Przykładowo, odległość Levenshteina pomiędzy wyrazami:</p>
<ul>
<li>drzwi</li>
<li>drzwi</li>
</ul>
<p>Jest zerowa. Są to wyrazy identyczne, więc nie potrzeba tutaj żadnych działań.</p>
<p>Natomiast odległość Levenshteina pomiędzy wyrazami:</p>
<ul>
<li>kołacz</li>
<li>połać</li>
</ul>
<p>wynosi 3, ponieważ potrzeba co najmniej 3 działań: zamiany <strong>k</strong> na <strong>p</strong>, zamiany <strong>c</strong> na <strong>ć</strong> i usunięcia litery <strong>z</strong>.</p>
<p>Tam, gdzie jest najmniej podstawień, posiadamy największe prawdopodobieństwo, że komendy są takie same.</p>
<p>&nbsp;</p>
<p><img loading="lazy" decoding="async" class=" wp-image-2770 aligncenter" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png" alt="" width="75" height="75" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-10-50x50.png 50w" sizes="(max-width: 75px) 100vw, 75px" /></p>
<p>&nbsp;</p>
<h2><span style="color: #800080;">Podsumowanie</span></h2>
<p>&nbsp;</p>
<p><span data-contrast="auto"><span class="TextRun SCXW189727610 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW189727610 BCX0"><span class="TextRun SCXW21457896 BCX0" lang="EN-US" xml:lang="EN-US" data-contrast="auto"><span class="NormalTextRun SCXW21457896 BCX0"><img loading="lazy" decoding="async" class=" wp-image-2768 alignleft" src="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png" alt="" width="101" height="101" srcset="https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08.png 208w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-80x80.png 80w, https://inero-software.com/wp-content/uploads/2019/05/inero-glify-08-50x50.png 50w" sizes="(max-width: 101px) 100vw, 101px" /></span></span></span></span></span>Celem systemów rozpoznawania głosu jest zapewnienie łatwości w komunikacji między urządzeniem a człowiekiem. Podejście wykorzystujące narzędzia Open-Source w zadaniu uczenia modeli ASR na razie ogranicza się do rozpoznawania ograniczonego zbioru komend. Budowanie takiego sytemu w oparciu o dane w języku polskim jest trudnym zadaniem, ze względu na małą ilość danych dźwiękowych połączonych z transkrypcjami. Zastosowanie miary podobieństwa pomiędzy transkrypcją a zbiorem komend pozwala na zbudowanie użytecznego systemu ASR działającego w trybie offline. Biorąc pod uwagę aktualne trendy w wykorzystaniu inteligentnych urządzeń oraz możliwości techniczne, warto obserwować dalszy rozwój tych systemów i pojawiające się nowe zbiory danych.</p>
<p><a href="https://inero-software.com/pl/"><span style="color: #800080;"><strong>Inero Software</strong></span></a> oferuje wiedzę i doświadczenie w zakresie skutecznego wykorzystywania najnowocześniejszych technologii i danych do kształtowania korporacyjnych produktów cyfrowych przyszłości.</p>
<p>W sekcji <a href="https://inero-software.com/pl/category/firma/"><span style="color: #800080;"><strong>BLOG</strong></span></a> można znaleźć inne artykuły dotyczące nowoczesnych rozwiązań dla przedsiębiorstw.</p>
<p><strong><span style="color: #000000;">Redakcja: Tymoteusz Cejrowski, Software Developer.</span></strong></p>
<p></p></div><br />
</p></div>
<p>Artykuł <a href="https://inero-software.com/pl/budowa-systemu-rozpoznawania-komend-glosowych/">Budowa systemu rozpoznawania komend głosowych w języku polskim</a> pochodzi z serwisu <a href="https://inero-software.com/pl">Inero Software - Rozwiązania IT i Konsulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4748</post-id>	</item>
	</channel>
</rss>
