Линейная регрессия плохая характеристика градиентного спуска

Я реализовал простой пример линейной регрессии (пока что одного варианта) в C ++, чтобы помочь мне разобраться в концепциях. Я уверен, что алгоритм ключа правильный, но моя производительность ужасна.

Это метод, который фактически выполняет градиентный спуск:

void LinearRegression::BatchGradientDescent(std::vector<std::pair<int,int>> & data,float& theta1,float& theta2)
{

float weight = (1.0f/static_cast<float>(data.size()));
float theta1Res = 0.0f;
float theta2Res = 0.0f;

for(auto p: data)
{

float cost = Hypothesis(p.first,theta1,theta2) - p.second;
theta1Res += cost;
theta2Res += cost*p.first;
}

theta1 = theta1 - (m_LearningRate*weight* theta1Res);
theta2 = theta2 - (m_LearningRate*weight* theta2Res);
}

С другими ключевыми функциями, представленными как:

float LinearRegression::Hypothesis(float x,float theta1,float theta2) const
{
return theta1 + x*theta2;
}float LinearRegression::CostFunction(std::vector<std::pair<int,int>> & data,
float theta1,
float theta2) const
{
float error = 0.0f;
for(auto p: data)
{

float prediction = (Hypothesis(p.first,theta1,theta2) - p.second) ;
error += prediction*prediction;
}

error *= 1.0f/(data.size()*2.0f);
return error;
}

void LinearRegression::Regress(std::vector<std::pair<int,int>> & data)
{
for(unsigned int itr = 0; itr < MAX_ITERATIONS; ++itr)
{
BatchGradientDescent(data,m_Theta1,m_Theta2);
//Some visualisation code
}
}

Теперь проблема в том, что если скорость обучения больше, чем около 0,000001, значение функции стоимости после градиентный спуск выше, чем есть до. То есть алгоритм работает в обратном порядке. Линия довольно быстро формирует прямую линию через начало координат миллионы итераций, чтобы на самом деле достичь достаточно хорошо подходящей линии.

При скорости обучения 0,01 после шести итераций получается: (где разница равна costAfter-costBefore)

Cost before 102901.945312, cost after 517539430400.000000, difference 517539332096.000000
Cost before 517539430400.000000, cost after 3131945127824588800.000000, difference 3131944578068774912.000000
Cost before 3131945127824588800.000000, cost after 18953312418560698826620928.000000, difference 18953308959796185006080000.000000
Cost before 18953312418560698826620928.000000, cost after 114697949347691988409089177681920.000000, difference 114697930004878874575022382383104.000000
Cost before 114697949347691988409089177681920.000000, cost after inf, difference inf
Cost before inf, cost after inf, difference nan

В этом примере тэты установлены в ноль, скорость обучения — 0,000001, и есть 8 000 000 итераций! Код визуализации обновляет график только после каждых 100 000 итераций.

введите описание изображения здесь

Функция, которая создает точки данных:

static void SetupRegressionData(std::vector<std::pair<int,int>> & data)
{
srand (time(NULL));

for(int x = 50; x < 750; x += 3)
{
data.push_back(std::pair<int,int>(x+(rand() % 100), 400 + (rand() % 100) ));
}
}

Короче говоря, если моя скорость обучения слишком высока, алгоритм градиентного спуска эффективно работает в обратном направлении и стремится к бесконечности, а если он опускается до точки, где он фактически сходится к минимуму, то число итераций, необходимых для этого, недопустимо велико.

Я что-то пропустил / сделал ошибку в основном алгоритме?

5

Решение

Похоже, что все ведет себя, как ожидалось, но у вас возникают проблемы при выборе разумного уровня обучения. Это не совсем тривиальная проблема, и существует множество подходов, начиная от заранее определенных расписаний, которые постепенно снижают скорость обучения (см., Например, Эта бумага) к адаптивным методам, таким как AdaGrad или AdaDelta.

Для вашей ванильной реализации с фиксированной скоростью обучения вы должны упростить свою жизнь, нормализуя данные до нулевого среднего и стандартного отклонения единицы, прежде чем вводить их в алгоритм градиентного спуска. Таким образом, вы сможете легче рассуждать о скорости обучения. Тогда вы можете просто изменить свой прогноз соответственно.

5

Другие решения


По вопросам рекламы [email protected]