Результаты линейного обучения SageMaker не точны?
У меня проблемы с результатами, полученными от линейного ученика AWS (SageMaker).
А именно, я пытался воспроизвести результаты, полученные от R, SAS или Knime (используя линейную регрессию), но, к сожалению, то, что я получаю от линейного ученика, отличается от упомянутых трех других способов его вычисления.
Я пробовал разные гиперпараметры и конфигурации, но получаю неточные результаты регрессии даже в очень тривиальном случае синтетически сгенерированных данных, удовлетворяющих соотношению
Y=X1+2* х2+3
В этом случае существуют точные коэффициенты регрессии, равные 1,2 и точке перехвата 3. В отличие от упомянутого другого программного обеспечения, линейный ученик SageMaker возвращает мне значения, даже не близкие к правильным значениям, например, в одном примере выполнения, который я получаю [0.91547656 1.9826275 3.023757] что просто неудовлетворительно. Здесь вы можете увидеть соответствующую часть моего кода!
study=((1.0,3.0,10.0),(2.0,3.0,11.0),(3.0,2.0,10.0),(4.0,7.0,21.0),(5.0,4.0,16.0))
a = np.array(study).astype('float32')
other_columns=a[:,[0,1]]
labels = a[:,2]
buf = io.BytesIO()
smac.write_numpy_to_dense_tensor(buf, other_columns, labels)
buf.seek(0)
key = 'my-training-data'
boto3.resource('s3').Bucket(bucket).Object(os.path.join(prefix, 'train', key)).upload_fileobj(buf)
s3_train_data = 's3://{}/{}/train/{}'.format(bucket, prefix, key)
output_location = 's3://{}/{}/output'.format(bucket, prefix)
container = get_image_uri(boto3.Session().region_name, 'linear-learner')
import boto3
sess = sagemaker.Session()
linear = sagemaker.estimator.Estimator(container,
role,
train_instance_count=1,
train_instance_type='ml.c4.xlarge',
output_path=output_location,
sagemaker_session=sess)
linear.set_hyperparameters(feature_dim=2,
predictor_type='regressor',
loss='squared_loss',
epochs=50,
early_stopping_patience=100,
mini_batch_size=4)
linear.fit({'train': s3_train_data})
У вас есть какое-то объяснение наблюдаемым неточным результатам?
Спасибо николай
1 ответ
Двумя возможными причинами, по которым вы не получаете точных результатов, являются стохастический градиентный спуск (SGD) и регуляризация, обе из которых используются в Linear Learner. SGD и регуляризация - правильная вещь для многих реальных проблем машинного обучения, но они приводят к неточным результатам в этом игрушечном примере.
SGD - это метод оптимизации, который, помимо прочих преимуществ, хорошо масштабируется с большими наборами данных. Он хорошо масштабируется, так как количество примеров и размерность увеличиваются. SGD плохо подходит для очень маленьких задач. С чрезвычайно большими наборами данных SGD является единственным эффективным решением. С большими, средними и небольшими наборами данных SGD в Linear Learner работает так же, как и другие решатели, благодаря встроенным в алгоритм оптимизациям, таким как параллельное исследование множества настроек скорости обучения и других гиперпараметров. Но для этого примера набора данных, который имеет нулевой шум (взаимосвязь между объектами и меткой является детерминированным) и только 5 примеров, более точный и менее масштабируемый решатель будет работать лучше.
Регуляризация применяется по умолчанию в Linear Learner. Чтобы выключить его, установите 'wd'=0.0
а также 'l1'=0.0
, Алгоритм исследует несколько значений регуляризации, включая отсутствие регуляризации, и выбирает модель с наилучшей точностью на наборе валидации, или, если нет комплекта валидации, наивысшую точность данных обучения. Но из-за очень небольшого количества данных, доступных для изучения в этом случае, этот выбор по существу случайный. Так что вполне вероятно, что в финальной модели использовалась регуляризация. Регуляризация сдвигает веса модели, но не смещение, к нулю, так что это может объяснить оценки параметров, упомянутые в посте: [0.91547656 1.9826275 3.023757] вместо [1.0 2.0 3.0]. Два веса были сдвинуты к нулю, и смещение немного велико, чтобы компенсировать.
Регуляризация чрезвычайно полезна в большинстве реальных приложений. Обучение модели с некоторой степенью регуляризации почти всегда является лучшим способом уменьшить ошибку обобщения, то есть ошибку выборки. Использование регуляризации - правильная вещь для реальных наборов данных, но она даст неточное решение в этом наборе данных, где нет шума и предположение о линейной модели является абсолютно правильным.
Для точного решения задачи линейной регрессии в небольшом наборе данных используйте решатель, такой как QR-разложение. Примеры - SKLearn's LinearRegression
класс или lm
функция в R. Но имейте в виду, что эти методы будут иметь проблемы с масштабированием на большие наборы данных. И, возможно, что еще более важно, мы должны отключить регуляризацию для точного решения в образце, но точное решение обычно будет иметь худшую производительность для невидимых данных по сравнению с решением с регуляризацией.
В SKLearn реализовано несколько оптимизаторов, в том числе SGD. Вот пример применения решателя SGD в SKLearn к данным вашего примера. Регуляризация также включена по умолчанию в SKLearn. Решение является неточным по причинам, описанным выше.
>>> from sklearn import linear_model
>>> import numpy as np
>>> study=((1.0,3.0,10.0),(2.0,3.0,11.0),(3.0,2.0,10.0),(4.0,7.0,21.0),(5.0,4.0,16.0))
>>> a = np.array(study).astype('float32')
>>> other_columns=a[:,[0,1]]
>>> labels = a[:,2]
>>> reg = linear_model.SGDRegressor(max_iter=50)
>>> reg.fit(other_columns, labels)
SGDRegressor(alpha=0.0001, average=False, epsilon=0.1, eta0=0.01,
fit_intercept=True, l1_ratio=0.15, learning_rate='invscaling',
loss='squared_loss', max_iter=50, n_iter=None, penalty='l2',
power_t=0.25, random_state=None, shuffle=True, tol=None, verbose=0,
warm_start=False)
>>> reg.coef_
array([1.39560259, 2.17536485])
>>> reg.intercept_
array([0.77972575])