تشخیص حروف با استفاده از شبکه عصبی با متلب
آموزش شبکه عصبی برای تشخیص حروف انگلیسی یک متن انگلیسی با استفاده از دیتا ست خودمان به گونه ای که کلیه حروف انگلیسی رابا ۱۰ فونت مختلف به دو صورت بولد و معمولی در ورد نوشته و از حروف عکس گرفته و ذخیره کنید با استفاده از این دیتاست شبکه را آموزش دهید.
توضیح مسئله
در این تمرین قصد داریم تا با استفاده از دیتاست مربوط به حروف کوچک و بزرگ انگلیسی که در اختیار داریم یک شبکه عصبی چندلایه را آموزش دهیم و سپس با استفاده از این شبکه، حروف یک عکس را تشخیص دهیم.
پروژه در دو مرحله انجام میشود.
در این قسمت اقدام به آموزش شبکه عصبی میکنیم که مراحل آموزش به شرح زیر است
- بارگذاری عکسهای دیتاست
- تبدیل عکسها به باینری در صورت لزوم
- حذف حاشیه اطراف عکسها
- تبدیل ماتریس عکسها به بردار عددی
- ساخت شبکه عصبی
- دادن ماتریس بردارهای عکسها به شبکه و آموزش شبکه
- تست شبکه
این قسمت شامل دو بخش میشود. بخش اول مربوط به تست شبکه با استفاده از عکسهای داخل دیتاست است که تمامی مراحل معادل با بخش آموزش شبکه عصبی است با این تفاوت مرحله ساخت شبکه و آموزش شبکه حذف میشود و مرحله تست شبکه و در نهایت گزارش دقت خروجی را خواهیم داشت
بخش دوم تست شبکه، مربوط به تست یک عکس از طرف کاربر است. در این بخش، کاربر یک عکس با هر تعداد کاراکتر را در برنامه بارگذاری میکند و مراحل زیر برای تشخیص حروف این عکس انجام میشود
- بارگذاری عکس
- تبدیل عکس به خاکستری و سپس عکس باینری در صورت لزوم
- بخشبندی افقی عکس یا به عبارتی جداسازی خطوط عکس
- بخشبندی عمودی عکس یا به عبارتی جدا کردن کاراکترها از هر خط عکس
- حذف حاشیه اطراف عکسها
- تبدیل ماتریس عکس به بردار عددی
- دادن عکس به شبکه و استخراج خروجی شبکه و تعیین برچسب عکس
- نمایش نتایج در خروجی
توضیح کدها
کدها در دو فایل قرار دارند. یکی برای آموزش و تست شبکه با استفاده از عکسهای داخل دیتاست. و دیگری برای تست یک عکس تنها.
آموزش شبکه
کد زیر مربوط به بخش آموزش شبکه و تست شبکه است.
کد نویسی پروژه (Run me)
%% Run_Me
%% Clearing
clc;
clear;
close all;
%% Initializing
Img_Dataset = [];
Label_Cell = {};
Label_Arr = [];
Ordered_Label = {};
Dataset_Path = 'dataset';
All_Data_Size = 0;
%% Read dataset
Folders = dir(Dataset_Path);
Folders = Folders(3:end);
for in_Folders = 1: length(Folders)
Cur_Folder = [Folders(in_Folders).folder '\' Folders(in_Folders).name];
File_Names = dir([Cur_Folder '\*.bmp']);
Ordered_Label{in_Folders} = strtok(Folders(in_Folders).name,'_');
for in_Each_Class = 1 : length(File_Names)
Cur_Img_Path = [File_Names(in_Each_Class).folder '\' File_Names(in_Each_Class).name];
img = imread(Cur_Img_Path);
Org_Size = size(img);
img = Segment_Letters(img);
img = imresize(img,Org_Size);
All_Data_Size = All_Data_Size + 1 ;
Img_Dataset(All_Data_Size,:) = img(:);
Label_Cell{All_Data_Size} = strtok(Folders(in_Folders).name,'_');
Label_Arr(All_Data_Size) = in_Folders;
end
end
%% shuffle data
RR = randperm(All_Data_Size);
Img_Dataset = Img_Dataset(RR,:);
Label_Cell = Label_Cell(RR);
Label_Arr = Label_Arr(RR);
%% Divid data to train and test
Train_Ratio = 75;
Train_Size = floor(All_Data_Size*Train_Ratio / 100);
Train_Dataset = Img_Dataset(1:Train_Size,:);
Test_Dataset = Img_Dataset(Train_Size+1:end,:);
Train_Label_Cell = Label_Cell(1:Train_Size);
Test_Label_Cell = Label_Cell(Train_Size+1:end);
Train_Lebel_Arr = Label_Arr(1:Train_Size);
Test_Lebel_Arr = Label_Arr(Train_Size+1:end);
%% Train Neural Network
trainFcn = 'trainscg';
hiddenLayerSize = [30,30];
net = patternnet(hiddenLayerSize, trainFcn);
net = train(net,Train_Dataset',full(ind2vec(Train_Lebel_Arr)));
%% Test Neural Network
y = net(Test_Dataset');
[val,idx] = max(y);
fprintf('------------------- Network Accuracy ----------------------\n');
fprintf('Network Accuracy = %0.2f %%\n',mean(Test_Lebel_Arr == idx)*100);
fprintf('-----------------------------------------------------------\n');
%% save network
save('Variables','net','Ordered_Label');
%% >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Functions
function [First_Letter,Last_Part_Image] = Segment_Letters(Input_Image)
Input_Image = Find_Letters(Input_Image);
Size_2 = size(Input_Image,2);
for In_Size = 1 : Size_2
Col_Sum = sum(Input_Image(:,In_Size));
if Col_Sum == 0
Temp1 = Input_Image(:,1:In_Size-1);
Temp2 = Input_Image(:,In_Size:end);
First_Letter = Find_Letters(Temp1);
Last_Part_Image=Find_Letters(Temp2);
break
else
First_Letter = Input_Image;
Last_Part_Image = [ ];
end
end
end
function Output = Find_Letters(Input)
[Val,Size] = find(Input);
Output = Input(min(Val):max(Val),min(Size):max(Size));
end
شاید این مطالب نیز برای شما جذاب باشد، پیشنهاد میکنیم به این صفحات نیز سر بزنید:
کدهای تست عکس (Test Single Image)
%% Run_Single_Image
%% Clearing
clc;
clear;
close all;
%% Initialize
Label_Str=[ ];
Final_Seg = {};
%% Load image
load('Variables');
[FileName,Path] = uigetfile('*.*');
Loaded_Image = imread([Path,FileName]);
imagen1 = Loaded_Image;
%% Process image
if size(Loaded_Image,3)==3
Loaded_Image=rgb2gray(Loaded_Image);
end
if ~islogical(Loaded_Image)
threshold = graythresh(Loaded_Image);
Loaded_Image = ~imbinarize(Loaded_Image,threshold);
end
Loaded_Image = bwareaopen(Loaded_Image,15);
Temp_Img = Loaded_Image;
%% Image segmentation and classification
while 1
[First_Line,Temp_Img]=Find_Line_Images(Temp_Img);
Letter_Num = 0;
Temp_First_line_Image = First_Line;
while 1
[First_Letter,Temp_First_line_Image] = Segment_Letters(Temp_First_line_Image);
cur_obj = imresize(First_Letter,[25,20]);
Letter_Num = Letter_Num + 1;
Img_4_Net = cur_obj(:);
Net_Output = net(Img_4_Net);
[~,Net_Output] = max(Net_Output);
Final_Seg{end+1} = cur_obj;
Label_Str = [Label_Str Ordered_Label{Net_Output}];
if isempty(Temp_First_line_Image)
break;
end
end
if isempty(Temp_Img)
break
end
end
%% Show result of segmentation and classification
figure;
numb = length(Final_Seg);
m_row = ceil(sqrt(numb));
m_col =m_row;
for i = 1 : numb
subplot(m_row,m_col,i);
imshow(Final_Seg{i})
title(Label_Str(i))
end
%% >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Functions
function [First_Letter,Last_Part_Image] = Segment_Letters(Input_Image)
Input_Image = Find_Letters(Input_Image);
Size_2 = size(Input_Image,2);
for In_Size = 1 : Size_2
Col_Sum = sum(Input_Image(:,In_Size));
if Col_Sum == 0
Temp1 = Input_Image(:,1:In_Size-1);
Temp2 = Input_Image(:,In_Size:end);
First_Letter = Find_Letters(Temp1);
Last_Part_Image=Find_Letters(Temp2);
break
else
First_Letter = Input_Image;
Last_Part_Image = [ ];
end
end
end
function Output = Find_Letters(Input)
[Val,Size] = find(Input);
Output = Input(min(Val):max(Val),min(Size):max(Size));
end
function [First_Line_Image,Last_Part_of_Image] = Find_Line_Images(Input_Img)
Input_Img = Find_Letters(Input_Img);
Size_1 = size(Input_Img,1);
for In_Size = 1 : Size_1
if sum(Input_Img(In_Size,:))==0
Temp1 = Input_Img(1:In_Size-1, :);
Temp2 = Input_Img(In_Size:end, :);
First_Line_Image = Find_Letters(Temp1);
Last_Part_of_Image=Find_Letters(Temp2);
break
else
First_Line_Image=Input_Img;
Last_Part_of_Image=[ ];
end
end
end
نتایج
دقت شبکه عصبی روی دیتاست با توجه به اجراهای متفاوتی که انجام دادهایم، بین 80 تا 92 درصد است. این دقت روی 52 دسته حروف انگلیسی است که 26 حرف کوچک و 26 حرف بزرگ است. با اجرای فایل Run_Me ، بعد از بارگذاری عکسها ، آموزش شبکه شروع میشود که پنجره زیر نمایش داده میشود که اطلاعات آموزش شبکه را در خود دارد.
به عنوان مثال دکمه Performance ، اطلاعات خطای شبکه را در اپک های مختلف میدهد و مشخص میکند که بهترین وزنهای شبکه در کدام اپک قرا دارد
و دقت شبکه نیز در خروجی به این صورت چاپ خواهد شد
------------------- Network Accuracy ----------------------
Network Accuracy = 79.93 %
-----------------------------------------------------------------------
بعد از اجرای برنامه، متغیرهای خاصی را ذخیره میکنیم که شامل شبکه و برچسبهای خوانده شده است. این موارد را در فایلی به نام Variables در کنار کدها ذخیره میکنیم.
حال برای تست یک عکس به تنهایی فایل Test_Single_Image را اجرا میکنیم. بعد از اجرا پنجرهای باز میشود که به ما امکان انتخاب عکس را میدهد. و در نهایت ، به ازای هر کاراکتر در عکس، یک زیر پلات ترسیم میشود و برچسب آن در بالای عکس نمایش داده میشود. خروجی برنامه به ازای دو عکس ورودی را میتوانید مشاهده نمایید
عکس ورودی
خروجی برنامه
عکس ورودی
خروجی برنامه
چند سوال در مورد پروژه
در متلب نسخه پایین تر از 2016 اجرا نشود.