Tôi đã đọc khá nhiều trên Mạng nơron và đào tạo chúng với backprogpagation, chủ yếu là this Coursera course, với việc đọc bổ sung từ here và here. Tôi nghĩ rằng tôi đã có một nắm bắt khá soild của thuật toán cốt lõi, nhưng nỗ lực của tôi để xây dựng một mạng lưới thần kinh được đào tạo backpropagation đã không khá làm việc ra và tôi không chắc chắn lý do tại sao.Các vấn đề về triển khai truyền dẫn mạng thần kinh
Mã này có trong C++ mà không có vectơ nào.
Tôi muốn xây dựng 2 nơron đầu vào đơn giản, 1 nơron ẩn, 1 nơron đầu ra, mạng để mô hình hóa hàm AND. Chỉ cần hiểu cách các khái niệm hoạt động trước khi chuyển sang một ví dụ phức tạp hơn. Mã truyền bá tiếp của tôi làm việc khi tôi mã hóa bằng tay các giá trị cho trọng số và độ lệch.
float NeuralNetwork::ForwardPropagte(const float *dataInput)
{
int number = 0; // Write the input data into the input layer
for (auto & node : m_Network[0])
{
node->input = dataInput[number++];
}
// For each layer in the network
for (auto & layer : m_Network)
{
// For each neuron in the layer
for (auto & neuron : layer)
{
float activation;
if (layerIndex != 0)
{
neuron->input += neuron->bias;
activation = Sigmoid(neuron->input);
} else {
activation = neuron->input;
}
for (auto & pair : neuron->outputNeuron)
{
pair.first->input += static_cast<float>(pair.second)*activation;
}
}
}
return Sigmoid(m_Network[m_Network.size()-1][0]->input);
}
Một số biến này có tên khá kém nhưng về cơ bản, nơron-> đầu raNeuron là một vectơ các cặp. Đầu tiên là con trỏ tới nơron tiếp theo và thứ hai là giá trị trọng số. neuron-> input là giá trị "z" trong phương trình mạng thần kinh, tổng của tất cả các wieghts * activation + bais. Sigmoid được cho bởi:
float NeuralNetwork::Sigmoid(float value) const
{
return 1.0f/(1.0f + exp(-value));
}
Hai thứ này có vẻ như hoạt động như dự định. Sau khi vượt qua tất cả các giá trị 'z' hoặc 'nơron-> đầu vào' được đặt lại về 0 (hoặc sau khi truyền ngược).
Sau đó tôi đào tạo mạng theo mã psudo bên dưới. Mã đào tạo được chạy nhiều lần.
for trainingExample=0 to m // m = number of training examples
perform forward propagation to calculate hyp(x)
calculate cost delta of last layer
delta = y - hyp(x)
use the delta of the output to calculate delta for all layers
move over the network adjusting the weights based on this value
reset network
Mã thực tế là ở đây:
void NeuralNetwork::TrainNetwork(const std::vector<std::pair<std::pair<float,float>,float>> & trainingData)
{
for (int i = 0; i < 100; ++i)
{
for (auto & trainingSet : trainingData)
{
float x[2] = {trainingSet.first.first,trainingSet.first.second};
float y = trainingSet.second;
float estimatedY = ForwardPropagte(x);
m_Network[m_Network.size()-1][0]->error = estimatedY - y;
CalculateError();
RunBackpropagation();
ResetActivations();
}
}
}
Với chức năng lan truyền ngược được cho bởi:
void NeuralNetwork::RunBackpropagation()
{
for (int index = m_Network.size()-1; index >= 0; --index)
{
for(auto &node : m_Network[index])
{
// Again where the "outputNeuron" is a list of the next layer of neurons and associated weights
for (auto &weight : node->outputNeuron)
{
weight.second += weight.first->error*Sigmoid(node->input);
}
node->bias = node->error; // I'm not sure how to adjust the bias, some of the formulas seemed to point to this. Is it correct?
}
}
}
và chi phí tính theo:
void NeuralNetwork::CalculateError()
{
for (int index = m_Network.size()-2; index > 0; --index)
{
for(auto &node : m_Network[index])
{
node->error = 0.0f;
float sigmoidPrime = Sigmoid(node->input)*(1 - Sigmoid(node->input));
for (auto &weight : node->outputNeuron)
{
node->error += (weight.first->error*weight.second)*sigmoidPrime;
}
}
}
}
tôi ngẫu nhiên trọng lượng và chạy nó trên dữ liệu et:
x = {0.0f,0.0f} y =0.0f
x = {1.0f,0.0f} y =0.0f
x = {0.0f,1.0f} y =0.0f
x = {1.0f,1.0f} y =1.0f
Tất nhiên là tôi không nên đào tạo và thử nghiệm với cùng một dữ liệu thiết nhưng tôi chỉ muốn để có được những algortithm lan truyền ngược cơ bản và chạy. Khi tôi chạy mã này tôi thấy trọng lượng/thành kiến như sau:
Layer 0
Bias 0.111129
NeuronWeight 0.058659
Bias -0.037814
NeuronWeight -0.018420
Layer 1
Bias 0.016230
NeuronWeight -0.104935
Layer 2
Bias 0.080982
Việc đào tạo bộ chạy và giá trị trung bình bình phương sai số của đồng bằng [outputLayer] trông somthing như:
Error: 0.156954
Error: 0.152529
Error: 0.213887
Error: 0.305257
Error: 0.359612
Error: 0.373494
Error: 0.374910
Error: 0.374995
Error: 0.375000
... remains at this value for ever...
Và trận chung kết trọng lượng như sau: (họ luôn kết thúc tại roughtly giá trị này)
Layer 0
Bias 0.000000
NeuronWeight 15.385233
Bias 0.000000
NeuronWeight 16.492933
Layer 1
Bias 0.000000
NeuronWeight 293.518585
Layer 2
Bias 0.000000
tôi chấp nhận rằng điều này có vẻ giống như một cách khá vòng xoay của học mạng nơ-ron và thực hiện là (tại m oment) rất không tối ưu. Nhưng bất cứ ai có thể phát hiện bất kỳ điểm nào mà tôi đưa ra một giả định không hợp lệ, hoặc là việc thực hiện hoặc công thức là sai?
EDIT
Cảm ơn thông tin phản hồi cho các giá trị thiên vị, tôi dừng lại chúng được áp dụng cho các lớp đầu vào và dừng lại đi qua các lớp đầu vào thông qua các hàm sigmoid. Hàm bổ sung Sigmoid của tôi không hợp lệ. Nhưng mạng vẫn không hoạt động. Tôi đã cập nhật lỗi và đầu ra ở trên với những gì xảy ra ngay bây giờ.
tại sao bạn có quá nhiều thành kiến? 2-1-1 mạng nên có 5 thông số trong tổng số: 2 trọng số giữa các tế bào thần kinh đầu vào và một ẩn; 1 trọng số giữa độ lệch trong lớp đầu vào và nơron ẩn; 1 trọng lượng giữa lớp ẩn và nơron đầu ra; 1 trọng số giữa độ lệch trong lớp ẩn và nơron đầu ra. Tổng cộng 5 trọng số. Ngay cả mã của bạn cũng cho bạn thấy - bạn và lên mà không có 2 thành kiến dư thừa – lejlot
Cảm ơn sự giúp đỡ của bạn với những thành kiến, hãy xem trả lời của tôi cho galloguille để giải thích thêm. Tôi đã sửa lỗi này nhưng tôi vẫn gặp sự cố với mạng thần kinh luôn luôn huấn luyện trọng số cho các giá trị w11 (15.385233), w12 (16.492933), w21 (293.518585). Tất cả các thành kiến đều trở thành 0. Vì vậy, rõ ràng vẫn còn một vấn đề khác với mã. – Davors72