بررسی تصاویر تولید شده توسط کاربران

تقریبا تمامی کسانی که کسب و کارهایی دارند که بر مبنای تصاویر یا ویدئوهای تولید شده توسط کاربر کار‌میکند، دغدغه این را دارند که این تصاویر حاوی محتوای غیر اخلاقی نباشند. این دغدغه به دلایل مختلفی از جمله فیلترینگ برای صاحبان این کسب و کارها دارای اهمیت است.معمولا کسب و کارهای بزرگ که با تصاویر تولید شده توسط کاربران سروکار دارند، به روش‌های مختلف این مشکل را حل کرده‌اند، چه با کمک اپراتورهای انسانی چه با کمک یادگیری ماشین.امروزه استفاده از یادگیری ماشین در کسب و کارهای مختلف جایگاه ویژه‌ای دارد و اگر شما هم برای حل این مشکل در کسب و کار خودتون تصمیم به استفاده از یادگیری ماشین را دارید موارد زیر را در نظر بگیرید:ساخت یک تیم کوچک از مهندسان یادگیری ماشینجمع آوری دیتای مورد نیازآموزش شبکه‌های مختلف برای رسیدن به نتیجه مطلوبدر نظر گرفتن سرور یا سرورهای مورد نیاز برای بررسی تصاویرخوشبختانه بیشتر فارغ‌التحصیلان رشته هوش‌مصنوعی یا رشته‌های مرتبط بر روی مسایل مرتبط با تصویر کار کرده‌اند و از این جهت برای ساخت این تیم خیلی با مشکل مواجه نخواهید شد.معمولا برای مسايل مختلف مرتبط با تصویر می‌توان از دیتاست‌های عمومی در این زمینه استفاده کرد ولی اینجا و در این مساله کمی اوضاع متفاوت است، چرا که ممکن است تعریفی که شما از محتوای غیراخلاقی دارید با تعریفی که در دیتاست‌های عمومی موجود است متفاوت باشد و شما نیاز به جمع‌ آوری دیتاست دارید. اگر از مدل‌هایی استفاده کنید که دارای فایل‌های پیش‌آموزش داده شده باشند (Pretrained Models) به عنوان مثال مدل GoogLeNet که بر روی دیتاست ImageNet آموزش داده شده باشد، نیاز به جمع آوری دیتای بسیار زیاد ندارید و می‌توانید با استفاده از انتقال آموزش (Transfer Learning) کار خود را تسریع کنید و نتایج بهتری بگیرید.یکی از جاهایی که معمولا با مشکل روبرو می‌شوید تجهیز سرورهایی است که باید عملیات بررسی تصاویر را بر روی مدل‌های آموزش داده شده انجام دهد. معمولا نیاز به کارت‌های گرافیکی گران قیمت به همراه سرورهایی که بتوانند تعداد بالای کارت‌های گرافیکی را پشتیبانی کنند، دارید و این بخشی است که هزینه بسیاری را به شما متحمل می‌کند. در ادامه به راه‌حلی برای این مشکل می‌پردازم.یکی از راه‌ها برای کم کردن پردازش سمت سرور انجام تمامی و یا بخشی از آن سمت کلاینت است. در زمان‌هایی که نرم‌افزار بر روی دسکتاپ و یا موبایل اجرا می‌شود انجام این کار پیچیدگی چندانی ندارد به همین در بخش بعدی به حل این مساله در زمانی که کاربر از طریق وب اپلیکیشن تصویر را ارسال می‌کند می‌پردازم.وب‌اسمبلی و WebDNNبا همه‌گیر شدن وب‌اسمبلی (WebAssembly) و پشتیبانی بر روی بیشتر مرورگرها و امکان اجرای کدهای نوشته شده به زبان‌هایی همچون C/C++ بر روی مرورگر، ابزارهای بسیار زیادی برای مرورگرها توسعه داده شده‌اند از جمله کتابخانه‌های مختلفی برای اجرای مدل‌های یادگیری ماشین بر روی مرورگر. یکی از این‌ها WebDNN است که امکان اجرای مدل‌های آموزش‌داده شده زیر را دارد.Tensorflow (v1.2.0 - v1.4.0)Keras (v2.1.3 - )PyTorch (v0.3.0 - v0.4.1)Chainer (v1.23.0 - v4.0.0)Caffeبرای اینکه با ابزارهای مختلف یادگیری ماشین به خصوص یادگیری عمیق بر روی مرورگر بیشتر آشنا شوید، پیشنهاد می‌کنم این مقاله را مطالعه کنید.Moving Deep Learning into Web Browser: How Far Can We Go?مدل OpenNSFW تصاویر NSFW، تصاویر نامناسب برای محیط کار هستند و در زیر تعبیر ویکی‌پدیا برای آن را می‌بینیدیک اصلاح عامیانه یا تندنویسی است که به رسانه (تصاویر، کلیپ، ویدئو، فیلم) یا وب سایت‌هایی که شامل برهنگی، پورنوگرافی، ناسزا، خشونت، و/یا دیگر موضوعات به‌طور بالقوه آزاردهنده است، که بیننده ممکن است مایل به دیدن در یک محیط عمومی یا رسمی، از جمله محل کار یا مدرسه نباشد، گفته می‌شود.تقریبا ۳ سال پیش یاهو یک مدل برای شناسایی این تصاویر ارائه کرد به نام OpenNSFW که در گیت‌هاب قابل مشاهده است. این مدل به همراه فایل پیش‌آموزش داده شده ارائه شده است. یاهو برای این پروژه از Caffe استفاده کرده است و در اصل یک مدل بر پایه ResNet50 است.ترکیب OpenNSFW و WebDNNهمانطور که در ابتدای این نوشته گفتم، یکی از مسایل پیش روی بررسی تصاویر تولید شده توسط کاربر با استفاده از یادگیری ماشین تجهیز سرورهایی برای این امر بود و راه‌حل این مساله انتقال بخش و یا تمامی پردازش به سمت کاربر است. با ترکیب آنچه در بخش دوم گفته شد ما می‌توانیم تصویری را که کاربر می‌خواهد ارسال کند قبل از ارسال به سرور و بر روی مرورگر کاربر بررسی کنیم.برای این کار می‌توانید از پروژه NSFW-WebDNN که در گیت‌هاب قرار داده‌ام به شکل زیر استفاده کنید.git clone https://github.com/zaghaghi/nsfw-webdnn cd nsfw-webdnn emrun --no_browser --port 8081 .اگر می‌خواهید از مدل‌هایی که خودتان آموزش داده‌اید استفاده کنید، ادامه مطلب را بخوانیدمراحل ساختبرای اینکه بتوانید مدل خود را به معادل WebDNN آن تبدیل کنید نیاز به نصب Emscripten و WebDNN دارید. چنانچه از لینوکس یا مک استفاده نمی‌کنید مراحل نصب را طبق آنچه در مستندات سایت‌های این دو گفته شده است پیش بروید.ابتدا emscripten را نصب کنیدgit clone https://github.com/emscripten-core/emsdk.git cd emsdk export EMSDKPATH=$(pwd) ./emsdk install latest ./emsdk activate latestسپس WebDNN را نصب کنید. من برای نصب نیازمندی‌های پایتون از conda استفاده کردم و شما می‌توانید به روشی دیگر انجام دهید.conda create -p env/ python=3.6 source activate env/ pip install numpy setuptools chainer git clone https://github.com/mil-tokyo/webdnn cd webdnn export WEBDNN=$(pwd) python3 setup.py install wget http://bitbucket.org/eigen/eigen/get/3.3.3.tar.bz2 tar jxf 3.3.3.tar.bz2 ln -s $(pwd)/eigen-eigen-67e894c6cd8f/Eigen $EMSDKPATH/emscripten/*/system/local/includeبرای تبدیل مدل آموزش داده شده از اسکریپتی که به همراه WebDNN آمده است به شکل زیر استفاده کردم. چنانچه شما مدل خود را آموزش داده‌اید می‌توانید به جای مدل یاهو از مدل خود استفاده کنید و اگر مدل آموزش داده شده با Caffe نبوده است می‌توانید با استفاده از مستندات WebDNN مدل خود را تبدیل کنید.git clone https://github.com/yahoo/open_nsfw cd open_nsfw/nsfw_model python $WEBDNN/bin/convert_caffe.py --input_name data --input_shape '(1,3,224,224)' --output_names fc_nsfw --out output resnet_50_1by2_nsfw.caffemodelیکی از مراحلی که نباید فراموش کنید پیش‌پردازش تصویر است. مدل‌های مختلف پیش‌پردازش‌های مختلفی دارند و برای رسیدن به جواب‌های درست حتما باید این پیش‌پردازش‌ها بر روی تصاویر انجام شوند. WebDNN برای این کار متدی دارد که در زیر می‌بینید.پیش پردازش مدل OpenNSFW که با استفاده ابزارهای Caffe انجام شده است.caffe_transformer = caffe.io.Transformer({'data': nsfw_net.blobs['data'].data.shape}) caffe_transformer.set_transpose('data', (2, 0, 1)) # move image channels to outermost caffe_transformer.set_mean('data', np.array([104, 117, 123])) # subtract the dataset-mean value in each channel caffe_transformer.set_raw_scale('data', 255) # rescale from [0, 1] to [0, 255] caffe_transformer.set_channel_swap('data', (2, 1, 0)) # swap channels from RGB to BGRانجام همین پیش‌پردازش با استفاده از WebDNNlet image_array = await WebDNN.Image.getImageArray(img_src, { dstW: 224, dstH: 224, bias: [104, 117, 123], color: WebDNN.Image.Color.BGR, order: WebDNN.Image.Order.CHW, });