از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
شبکههای عصبی در جاوا اسکریپت با Brain.js در چند سال اخیر، بهویژه، شبکههای عصبی (NN) واقعاً بهعنوان یک روش عملی و کارآمد برای حل مشکلاتی مطرح شدهاند که نمیتوانند به راحتی با یک الگوریتم حل شوند، مانند تشخیص چهره، تشخیص صدا، و تشخیص پزشکی این تا حد زیادی به لطف اکتشافات اخیر است روی چگونه بهتر تمرین کنیم…
سرفصلهای مطلب
معرفی
به ویژه در چند سال اخیر، شبکههای عصبی (NN) واقعاً به عنوان یک راه عملی و کارآمد برای حل مشکلاتی مطرح شدهاند که نمیتوان آنها را به راحتی با یک الگوریتم حل کرد، مانند تشخیص چهره، تشخیص صدا و تشخیص پزشکی. این تا حد زیادی به لطف اکتشافات اخیر است روی روش آموزش بهتر و تنظیم شبکه و همچنین افزایش سرعت کامپیوترها.
اخیراً، دانشجویی در امپریال کالج لندن یک NN به نام ایجاد کرده است زرافه که می توانست تنها در 72 ساعت برای بازی شطرنج در سطح یک استاد بین المللی فیده آموزش ببیند. رایانههایی که در این سطح شطرنج بازی میکنند، واقعاً جدید نیست، اما روشی که در آن این برنامه ایجاد شده است است جدید. این برنامه ها معمولاً سال ها طول می کشد تا ساخته شوند و با کمک یک استاد بزرگ واقعی تنظیم می شوند، در حالی که زرافه، روی از سوی دیگر، به سادگی با استفاده از یک شبکه عصبی عمیق، مقداری خلاقیت و مجموعه داده عظیمی از بازیهای شطرنج ساخته شد. این نمونه دیگری از شبکههای عصبی وعدهای است که اخیراً نشان دادهاند و فقط در حال بهبود هستند.
Brain.js
نقطه ضعف NN ها و به طور کلی هوش مصنوعی این است که این رشته بسیار سنگین است که باعث می شود مردم قبل از شروع کار از آن دور شوند. ماهیت بسیار فنی NN ها و تمام اصطلاحات واژگانی که با آن همراه است، استفاده از آن را برای افراد ناآشنا دشوار می کند. اینجاست که Brain.js وارد بازی می شود. Brain.js در ساده سازی کار بسیار خوبی انجام می دهد process ایجاد و آموزش یک NN با استفاده از سهولت استفاده از جاوا اسکریپت و با محدود کردن API فقط به چند فراخوانی روش و گزینه.
اشتباه نکنید، شما هنوز باید برخی از مفاهیم پشت NN ها را بدانید، اما این ساده سازی آن را بسیار کمتر دلهره آور می کند.
به عنوان مثال، برای آموزش یک شبکه برای تقریب XOR تابع (که یکی از نمونه های استاندارد NN است)، تنها چیزی که نیاز دارید این است:
var brain = require('brain');
var net = new brain.NeuralNetwork();
net.train(({input: (0, 0), output: (0)},
{input: (0, 1), output: (1)},
{input: (1, 0), output: (1)},
{input: (1, 1), output: (0)}));
var output = net.run((1, 0)); // (0.933)
این کد فقط یک شبکه جدید ایجاد می کند (net
) train
شبکه با استفاده از آرایه ای از مثال ها و سپس run
s شبکه با ورودی از (1, 0)
، که به درستی نتیجه می دهد (0.933)
(موسوم به 1
).
در حالی که Brain.js گزینه های زیادی برای سفارشی کردن شبکه های خود ندارد، API پارامترهای کافی را می پذیرد تا برای برنامه های کاربردی ساده مفید باشد. می توانید تعداد و اندازه لایه های مخفی، آستانه خطا، نرخ یادگیری و موارد دیگر را تنظیم کنید:
var net = new brain.NeuralNetwork({
hiddenLayers: (128,64)
});
net.train({
errorThresh: 0.005, // error threshold to reach before completion
iterations: 20000, // maximum training iterations
log: true, // console.log() progress periodically
logPeriod: 10, // number of iterations between logging
learningRate: 0.3 // learning rate
});
برای لیست کامل گزینه ها به مستندات مراجعه کنید.
در حالی که شما در انواع شبکه هایی که می توانید بسازید محدود هستید، این بدان معنا نیست که نمی توانید چیزی را معنادار کنید. بگیرید این پروژه مثلا. نویسنده مجموعه ای از تصاویر CAPTCHA را برای مجموعه داده خود جمع آوری کرد، از برخی پردازش های ساده تصویر برای پیش پردازش تصاویر استفاده کرد، و سپس از Brain.js برای ایجاد یک شبکه عصبی که هر شخصیت فردی را شناسایی می کند، استفاده کرد.
مزایای
همانطور که قبلاً اشاره کردم، Brain.js برای ایجاد سریع یک NN ساده در یک زبان سطح بالا عالی است که در آن می توانید از تعداد زیادی کتابخانه منبع باز استفاده کنید. با یک مجموعه داده خوب و چند خط کد می توانید عملکردهای واقعا جالبی ایجاد کنید.
کتابخانههای بسیار علمی/محاسباتی که در جاوا اسکریپت نوشته شدهاند، تمایل به دریافت دارند به شدت انتقاد کرد، اما شخصاً فکر می کنم Brain.js جای خود را در JS دارد تا زمانی که شما انتظارات و برنامه درستی داشته باشید. به عنوان مثال، JS زبان غالب (فقط؟) است که در سمت کلاینت در مرورگر اجرا میشود، پس چرا از این کتابخانه برای مواردی مانند بازیهای درون مرورگر، قرار دادن تبلیغات (خستهکننده، میدانم) یا تشخیص کاراکتر استفاده نکنید؟
معایب
در حالی که قطعاً میتوانیم از کتابخانهای مانند این مقداری ارزش به دست آوریم، اما بینقص نیست. همانطور که اشاره کردم، کتابخانه معماری شبکه شما را به نقطه ای محدود می کند که فقط می توانید برنامه های کاربردی ساده را انجام دهید. امکان زیادی برای لایه های softmax یا ساختارهای دیگر وجود ندارد. خوب است که حداقل گزینه ای برای سفارشی سازی بیشتر معماری به جای پنهان کردن همه چیز از شما داشته باشید.
شاید بزرگترین شکایت من این است که کتابخانه در آن نوشته شده است خالص جاوا اسکریپت. آموزش یک NN کند است process که می تواند هزاران تکرار (به معنای میلیون ها یا میلیاردها عملیات) برای آموزش نیاز داشته باشد روی میلیون ها نقطه داده جاوا اسکریپت به هیچ وجه زبان سریعی نیست و واقعاً باید افزونه هایی برای مواردی مانند این داشته باشد تا محاسبات را در حین آموزش سرعت بخشد. کرکر CAPTCHA از بالا یک زمان آموزشی بسیار کم 20 دقیقه طول کشید، اما تنها چیزی که لازم است چند ورودی بیشتر و مقداری داده بیشتر است تا زمان آموزش را چند ساعت یا حتی چند روز افزایش دهد، همانطور که در مثال من در زیر خواهید دید.
متأسفانه، این کتابخانه قبلاً توسط نویسنده آن رها شده است (توضیحات GitHub با “(UNMAINTAINED)” اضافه شده است). در حالی که من دریافتم که حفظ خواسته های یک کتابخانه منبع باز محبوب می تواند سخت باشد، اما دیدن آن هنوز ناامید کننده است، و ما فقط می توانیم امیدوار باشیم که کسی واجد شرایط می تواند جای خالی را پر کند من مطمئن هستم که یک چنگال خوب در حال حاضر در حال کار است، اما ممکن است کمی جستجو برای یافتن آن لازم باشد.
مثال
در اینجا من به شما یک مثال درگیرتر از روش استفاده از Brain را نشان خواهم داد. در این مثال، من یک NN ایجاد کردم که می تواند یک رقم دست نویس (0-9) را تشخیص دهد. مجموعه داده ای که من استفاده می کنم محبوب است MNIST مجموعه داده، که شامل بیش از 50000 نمونه از ارقام دستنویس است. این نوع مشکل به عنوان تشخیص کاراکتر نوری (OCR) که یک برنامه محبوب NN ها است.
تشخیص با گرفتن یک تصویر 28×28 در مقیاس خاکستری از یک رقم دستنویس، و خروجی رقمی که شبکه فکر میکند «دیده» کار میکند. این بدان معناست که ما 784 ورودی (یکی برای هر پیکسل) با مقادیر بین 0-255 خواهیم داشت و 10 خروجی (یکی برای هر رقم) خواهیم داشت. هر خروجی دارای مقدار 0-1 خواهد بود که اساساً به عنوان سطح اطمینان از اینکه آن رقم خاص پاسخ صحیح است عمل می کند. بالاترین ارزش اطمینان پاسخ ما است.
روی کد:
var brain = require('brain');
var fs = require('fs');
var getMnistData = function(content) {
var lines = content.toString().split('\n');
var data = ();
for (var i = 0; i < lines.length; i++) {
var input = lines(i).split(',').map(Number);
var output = Array.apply(null, Array(10)).map(Number.prototype.valueOf, 0);
output(input.shift()) = 1;
data.push({
input: input,
output: output
});
}
return data;
};
fs.readFile(__dirname + '/train.csv', function (err, trainContent) {
if (err) {
console.log('Error:', err);
}
var trainData = getMnistData(trainContent);
console.log('Got ' + trainData.length + ' samples');
var net = new brain.NeuralNetwork({hiddenLayers: (784, 392, 196)});
net.train(trainData, {
errorThresh: 0.025,
log: true,
logPeriod: 1,
learningRate: 0.1
});
});
را train.csv
فایل فقط یک CSV با یک تصویر در هر خط است. اولین مقدار رقم نشان داده شده در تصویر است و 784 مقدار بعدی داده پیکسل است.
تعداد لایهها و گرههایی که من انتخاب کردم برای این برنامه OCR کمی دلخواه و احتمالاً غیرضروری زیاد بود. با این حال، زمانی که نمی توانید از مواردی مانند softmaxes یا pooling استفاده کنید، ممکن است شانس بیشتری برای افزایش تعداد لایه ها داشته باشید. node شمردن.
تمرین به راحتی بیش از یک ساعت طول کشید تا نتایج مناسبی بدست آورید. در حالی که این انتظار می رفت، من هنوز کمی ناامید بودم که باید برای آزمایش ساختار شبکه جدید یا پارامترهای یادگیری جدید اینقدر صبر کنم. یک برنامه ساده مانند این نباید آنقدر طول بکشد، اما این بهایی است که برای اجرای تمام جاوا اسکریپت می پردازید.
برای تست شبکه، فایل دیگری را بارگذاری کردم، test.csv
، و از آن به عنوان پایه ای برای مقایسه شبکه ها استفاده کرد. به این ترتیب، از آنجایی که در حال آزمایش ورودی هایی هستیم که شبکه قبلاً آموزش ندیده است، ایده بهتری از عملکرد به دست می آوریم. روی.
در اینجا روش آزمایش شبکه (فقط قسمت های مربوطه را نشان می دهم):
// Require packages...
fs.readFile(__dirname + '/test.csv', function (err, testContent) {
if (err) {
console.log('Error:', err);
}
// Load training data...
// Train network...
// Test it out
var testData = getMnistData(testContent);
var numRight = 0;
console.log('Neural Network tests:');
for (i = 0; i < testData.length; i++) {
var resultArr = net.run(testData(i).input);
var result = resultArr.indexOf(Math.max.apply(Math, resultArr));
var actual = testData(i).output.indexOf(Math.max.apply(Math, testData(i).output));
var str = '(' + i + ') GOT: ' + result + ', ACTUAL: ' + actual;
str += result === actual ? '' : ' -- WRONG!';
numRight += result === actual ? 1 : 0;
console.log(str);
}
console.log('Got', numRight, 'out of 350, or ' + String(100*(numRight/350)) + '%');
});
نتیجه
در حالی که کاستی هایی وجود دارد، به طور کلی فکر می کنم Brain.js می تواند بسیار مفید باشد و ارزش زیادی به برنامه های JavaScript/Node اضافه کند. سهولت استفاده آن باید به هر کسی اجازه دهد تا با شبکه های عصبی شروع کند.
اگر چیزی با انعطاف پذیری بیشتری می خواهید یا عدم پشتیبانی از Brain.js شما را آزار می دهد، نگاهی به سیناپسی، که امکان سفارشی سازی بسیار بیشتری را در معماری شبکه شما فراهم می کند. محبوبیت/توجهی که Brain دارد را ندارد، اما به نظر میرسد بهترین انتخاب بعدی برای شبکههای عصبی در جاوا اسکریپت باشد.
تجربه شما از Brain.js چیست؟ آیا بسته های هوش مصنوعی دیگری پیشنهاد می کنید؟ در نظرات به ما اطلاع دهید!
منتشر شده در 1403-01-30 03:28:04