Accord.NET #3
نویسنده: محسن نجف زاده
تاریخ: ۱۳۹۴/۰۶/۱۰ ۲۲:۵۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
*روش "یک در مقابل یک" یا One-against-one اساس کار دسته بندی MulticlassSupportVectorMachine در فضای نام Accord.MachineLearning است.
یک مثال کاربردی : هدف در این مثال دسته بندی اعداد فارسی به کمک MulticlassSupportVectorMachine است.
به معرفی ابزار کار مورد نیاز میپردازیم.
1.مجموعه ارقام دستنویس هدی: مجموعه ارقام دستنویس هدی که اولین مجموعهی بزرگ ارقام دستنویس فارسی است، مشتمل بر ۱۰۲۳۵۳ نمونه دستنوشته سیاه سفید است. این مجموعه طی انجام یک پروژهی کارشناسی ارشد درباره بازشناسی فرمهای دستنویس تهیه شده است. دادههای این مجموعه از حدود ۱۲۰۰۰ فرم ثبت نام آزمون سراسری کارشناسی ارشد سال ۱۳۸۴ و آزمون کاردانی پیوستهی دانشگاه جامع علمی کاربردی سال ۱۳۸۳ استخراج شده است. (اطلاعات بیشتر درباره مجموعه ارقام دستنویس هدی) .
تعداد 1000 نمونه (از هر عدد 100 نمونه) از این مجموعه داده، با فرمت bmp در این پروژه مورد استفاده قرار گرفته که به همراه پروژه در انتهای این مطلب قابل دریافت است.
2.استخراج ویژگی (Feature extraction ) : در بازشناسی الگو و مفاهیم کلاس بندی، یکی از مهمترین گامها، استخراج ویژگی است. ما موظف هستیم تا اطلاعات مناسبی را به عنوان ورودی برای دسته بندیمان معرفی نماییم. روشهای مختلفی برای استخراج ویژگی وجود دارند. ویژگیها به دو دستهی کلی ویژگیهای ظاهری (Appearance) و ویژگیهای توصیف کننده ( Descriptive) قابل تقسیم هستند. در تشخیص حروف و اعداد، ویژگیهایی مانند شدت نور نقاط (Intensity)، تعداد حلقه بسته، تعداد خطوط راست، تعداد دندانه، تعداد نقطه (برای حروف) و ... در دستهی اول و ویژگیهایی مانند شیب خطوط، گرادیان، میزان افت یا شدت نور یک ناحیه، HOG و ... در دسته دوم قرار میگیرند. در این مطلب ما تنها از روش شدت نور نقاط برای استخراج ویژگیهایمان استفاده کردهایم.
کد زیر با دریافت یک فایل Bitmap، ابتدا ابعاد را به اندازه 32*32 تغییر میدهد و سپس آنرا به صورت یک بردار 1*1024 را بر میگرداند:
//تابع استخراج ویژگی
private static double[] FeatureExtractor(Bitmap bitmap)
{
bitmap = BitmapResizer(bitmap, 32, 32);
double[] features = new double[32 * 32];
for (int i = 0; i < 32; i++)
for (int j = 0; j < 32; j++)
features[i * 32 + j] = (bitmap.GetPixel(j, i).R == 255) ? 0 : 1;
return features;
}
//تابع تغییر دهنده ابعاد عکس
private static Bitmap BitmapResizer(Bitmap bitmap, int width, int height)
{
var newbitmap = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage((Image)newbitmap))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(bitmap, 0, 0, width, height);
}
return newbitmap;
}
var path = new DirectoryInfo(Directory.GetCurrentDirectory()).Parent.Parent.FullName + @"\dataset\";
// ایجاد ورودی و برچسب
int trainingCount = 50;
double[][] inputs = new double[trainingCount * 10][];
int[] labels = new int[trainingCount * 10];
var index = 0;
var filename = "";
Bitmap bitmap;
double[] feature;
for (int number = 0; number < 10; number++)
{
for (int j = 0; j < trainingCount; j++)
{
index = (number * trainingCount) + j;
filename = string.Format(@"{0}\{0} ({1}).bmp", number, j + 1);
bitmap = new Bitmap(path + filename);
feature = FeatureExtractor(bitmap);
inputs[index] = feature;
labels[index] = number;
Console.WriteLine(string.Format("{0}.Create input and label for number {1}", index, number));
}
} private static double MachineLearning(IKernel kernel, double[][] inputs, int[] labels)
{
machine_svm = new MulticlassSupportVectorMachine(1024, kernel, 10);
// معرفی دسته بندمان به الگوریتم یادگیری SMO
MulticlassSupportVectorLearning ml = new MulticlassSupportVectorLearning(machine_svm, inputs, labels)
{
Algorithm = (svm, classInputs, classOutputs, i, j) =>
new SequentialMinimalOptimization(svm, classInputs, classOutputs)
};
var error = ml.Run();
return error;
} // بررسی یک دسته از ورودیها
index = 51;
for (int number = 0; number < 10; number++)
{
filename = string.Format(@"{0}\{0} ({1}).bmp", number, index);
bitmap = new Bitmap(path + filename);
feature = FeatureExtractor(bitmap);
double[] responses;
int recognizednumber = machine_svm.Compute(feature, out responses);
Console.WriteLine
(
String.Format
(
"Recognized number for file {0} is : '{1}' [{2}]",
filename,
recognizednumber,
(recognizednumber == number ? "OK" : "Error")
)
);
if (!machine_svm.IsProbabilistic)
{
// Normalize responses
double max = responses.Max();
double min = responses.Min();
responses = Accord.Math.Tools.Scale(min, max, 0, 1, responses);
//int minIndex = Array.IndexOf(responses, 0);
}
} AForge.Imaging.Filters.ResizeBicubic AForge.Imaging.Filters.ResizeBilinear AForge.Imaging.Filters.ResizeNearestNeighbor Accord.Imaging.Converters.ArrayToImage Accord.Imaging.Converters.ImageToArray Accord.Imaging.Converters.ImageToMatrix Accord.Imaging.Converters.MatrixToImage