Các ảnh đưa vào huấn luyện được chuẩn hóa với độ phân giải là trung bình chiều dài × trung bình chiều cao, thường lân cận 1000 pixels.
Lựa chọn kiến trúc mạng đa lớp (Multilayer Peceptron - MLP) với giải thuật học lan truyền. Để có thể tạo mô hình học tốt, các yêu cầu theo tiêu chí dưới đây được đề nghị:
Các ảnh có chứa bộ phận “đen” được càng nhiều thay đổi của bộ phận “đen” càng tốt, khi đó khả năng nhận dạng càng cao.
Chất lượng ảnh càng rõ nét thì càng dễ huấn luyện.
Bên cạnh đó, bằng thực nghiệm tác giả thấy rằng khi giữ nguyên số điểm ảnh làm số nơ-ron đầu vào (ví dụ ảnh bộ phận có kích thước là 50×30 = 1500 điểm ảnh) thì thời gian huấn luyện của mạng là rất lâu (tính bằng giờ) nên tác giả đã đề xuất cải tiến cài đặt lại một số tham số của mạng nơ-ron như sau:
Số nơ-ron đầu vào: 0.33 × (tích trung bình chiều cao × trung bình chiều rộng)
Số nơ-ron lớp ẩn: 0.11 × (tích trung bình chiều cao × trung bình chiều rộng)
Số nơ-ron lớp ra: bằng số mẫu huấn luyện.
Khi đó thời gian huấn luyện sẽ giảm xuống (tính bằng phút). Quá trình huấn luyện mạng được diễn ra như sau:
Đưa nơ-ron đầu vào vào lớp Tính toán giá trị đầu vào
Tính toán kết quả đầu ra với giá trị đầu ra mong muốn với giá trị đầu vào. Quá trình này gọi là xác định lỗi.
Thay đổi trọng số của nơ-ron dựa trên các lỗi trước.
Lặp lại quá trình này cho đến khi đạt đến lỗi ít nhất mà có thể chấp nhận được (ví dụ, error < 1.1), tức là mạng nơ-ron được huấn luyện thành công hay đạt đến tối đa quá trình lặp, tức là quá trình huấn luyện mạng nơ-ron không thành công.
Quá trình huấn luyện được cài đặt như sau:
public bool Train() {
double currentError = 0; int currentIteration = 0;
NeuralEventArgs Args = new NeuralEventArgs() ; do
{
currentError = 0;
foreach (KeyValuePair<T, double[]> p in TrainingSet) {
NeuralNet.ForwardPropagate(p.Value, p.Key); NeuralNet.BackPropagate();
currentError += NeuralNet.GetError(); }
currentIteration++;
if (IterationChanged != null && currentIteration % 5 == 0) {
Args.CurrentError = currentError;
Args.CurrentIteration = currentIteration; IterationChanged(this, Args);
}
} while (currentError > maximumError && currentIteration < maximumIteration && !Args.Stop);
if (IterationChanged != null) { Args.CurrentError = currentError; Args.CurrentIteration = currentIteration; IterationChanged(this, Args); }
if (currentIteration >= maximumIteration || Args.Stop) return false; //Huan luyen loi
return true; }
Trong đó hàm ForwardPropagate() và BackPropagate() được cài đặt cụ thể như sau:
// Ham lan truyen xuoi
publicvoid ForwardPropagate(double[] pattern, T output) {
int i, j;
double total;
//Apply input cho mang
for (i = 0; i < PreInputNum; i++) {
PreInputLayer[i].Value = pattern[i]; }
//Tinh Inputs va Outputs cho lop Input
for (i = 0; i < InputNum; i++) {
total = 0.0;
for (j = 0; j < PreInputNum; j++) {
total += PreInputLayer[j].Value * PreInputLayer[j].Weights[i];
}
InputLayer[i].InputSum = total; InputLayer[i].Output = F(total); }
//Tinh Inputs va Outputs cho lop Hidden
for (i = 0; i < HiddenNum; i++) {
total = 0.0;
for (j = 0; j < InputNum; j++) {
total += InputLayer[j].Output * InputLayer[j].Weights[i];
}
HiddenLayer[i].InputSum = total; HiddenLayer[i].Output = F(total); }
//Tinh Inputs, Outputs, Targets, Errors cua lop Ouput
for (i = 0; i < OutputNum; i++) {
total = 0.0;
for (j = 0; j < HiddenNum; j++) {
total += HiddenLayer[j].Output * HiddenLayer[j].Weights[i];
} OutputLayer[i].InputSum = total; OutputLayer[i].output = F(total); OutputLayer[i].Target = OutputLayer[i].Value.CompareTo(output) == 0 ? 1.0 : 0.0; OutputLayer[i].Error = (OutputLayer[i].Target - OutputLayer[i].output) * (OutputLayer[i].output) * (1 - OutputLayer[i].output); } }
// Ham truyen nguoc de cap nhat trong so (weight)
publicvoid BackPropagate() {
int i, j;
double total;
//Fix Error tang Hidden
for (i = 0; i < HiddenNum; i++) {
total = 0.0;
for (j = 0; j < OutputNum; j++) {
total += HiddenLayer[i].Weights[j] * OutputLayer[j].Error;
}
HiddenLayer[i].Error = total; }
//Fix Error tang Layer
for (i = 0; i < InputNum; i++) {
total = 0.0;
for (j = 0; j < HiddenNum; j++) {
total += InputLayer[i].Weights[j] * HiddenLayer[j].Error;
}
InputLayer[i].Error = total; }
// Cap nhat trong so lop dau tien
for (i = 0; i < InputNum; i++) {
for (j = 0; j < PreInputNum; j++) {
PreInputLayer[j].Weights[i] +=
learningRate * InputLayer[i].Error * PreInputLayer[j].Value; }
}
//Cap nhat trong so lop thu 2
for (i = 0; i < HiddenNum; i++) {
for (j = 0; j < InputNum; j++) {
learningRate * HiddenLayer[i].Error * InputLayer[j].Output; }
}
//Cap nhat tron so lop thu 3
for (i = 0; i < OutputNum; i++) {
for (j = 0; j < HiddenNum; j++) {
HiddenLayer[j].Weights[i] +=
learningRate * OutputLayer[i].Error * HiddenLayer[j].Output; }
} }