기계 학습 - 증 량 훈련 방법

기계 학습 - 증 량 훈련 방법
1. 왜 훈련 을 늘 려 야 하 는가
기계 공 부 를 한 적 이 있 는 학우 들 은 모두 알 고 있다. 어떤 때 는 훈련 데이터 가 매우 많 고, 몇 십 만 몇 백만 도 흔히 있 는 일이 다.몇 십 만 몇 백만 원 이 기록 만 보 는 것 은 많 지 않 지만 수백 개의 특징 이 있다 면 데이터 세트 는 매우 무 서운 것 이다. 만약 에 numpy.float 유형 으로 저장 하면 메모리 가 폭발 하 는 것 이다.나 는 이런 상황 에서 증 량 모델 의 증 량 훈련 을 고려 하기 시작 했다.현재 의 기 계 는 모두 매우 싸 졌 는데, 왜 서버 위 에 놓 고 실행 할 수 없 습 니까?저도 이 문 제 를 생각해 본 적 이 있 습 니 다. 하지만 셸 에서 조작 하 는 것 과 Windows 에서 조작 하 는 개발 테스트 속도 의 차이 가 매우 큽 니 다. 그리고 경험 상 데 이 터 를 준비 하면 훈련 하 는 데 시간 이 많이 걸 리 지 않 습 니 다. 메모리 에 담 을 수 없 는 데 이 터 를 사용 하 더 라 도 훈련 하 는 데 몇 분 밖 에 걸 리 지 않 습 니 다.빅 데이터 클 러 스 터 를 동원 할 필 요 는 없 잖 아.
초대형 데이터 세트 에 있어 서 일반적으로 몇 가지 방법 이 있다. 1. 데이터 에 대해 강 차원, 2. 증분 훈련 을 하고 흐름 식 또는 유사 한 흐름 식 처 리 를 사용한다. 3. 큰 기계, 높 은 메모리 또는 spark 클 러 스 터 를 사용한다.
여기 서 내 가 말 하고 자 하 는 것 은 증분 학습 이다.증분 훈련 에 대해 말하자면 온라인 학습 과 같은 뜻 이다. 온라인 학습 의 전형 적 인 대 표 는 SGD 로 최적화 한 logistics regress 이다. 먼저 데이터 로 파 라 메 터 를 초기 화하 고 라인 에 있 는 데이터 로 파 라 메 터 를 업데이트 하 는 것 이다. 비록 시간의 추이 에 따라 효과 가 점점 좋아 지지 만.이렇게 하면 오프라인 업데이트 모델 의 문 제 를 피 할 수 있다.
자, 여기까지 말 하면 증분 훈련 의 주요 용 도 를 이미 알 고 있 겠 지? 주로 두 가지 역할 이 있 는데 하 나 는 모든 데 이 터 를 이용 하 는 것 이 고 다른 하 나 는 새로운 데 이 터 를 제때에 이용 하 는 것 이다.
2. 특징 적 인 증분 훈련 방법
특징 적 인 기계 학습 모델 의 식량, 특징 에 대한 처리 와 같은 증 량 훈련 이 직면 해 야 할 문제.만약 에 데이터 양 이 많 으 면 우 리 는 보통 표본 추출 훈련, 즉 100 만 개의 데이터 에서 10 만 또는 5 만 개의 데 이 터 를 추출 하여 훈련 모델 로 하고 여러 번 표본 추출 훈련 을 한 다음 에 여러 모델 의 예측 결 과 를 가중 시 키 는 경향 이 있다.이것 은 좋 은 방법 이지 만, 가장 좋 은 방법 은 아니다.
표본 추출 후 데이터 의 분 포 는 사실 파괴 되 었 기 때문이다. 예 를 들 어 데이터 의 분 포 는 편 태 이 고 이상 값 이 존재 하기 때문에 결과 표본 추출 후 이상 값 을 잃 어 버 렸 다. 이때 데 이 터 는 이상 값 처 리 를 할 필요 가 없고 다음 표본 추출 에 이상 값 이 존재 하기 때문에 이상 값 처리 가 필요 하 며 전체 데이터 절 차 는 엉망 이 될 것 이다.따라서 전체 데이터 에 대해 데이터 분포 분석 을 해 야 한다. 특징 에 대한 계산 과 변환 은 전체 데이터 분 포 를 바탕 으로 하 는 것 이지 표본 추출 후의 10 만 개의 견본 의 데이터 분포 가 아니다.
우 리 는 특징 변환 을 할 때 주로 특징의 최소 치 최대 치, 평균치, 분산, 변이 계수, k 단계 원점 모멘트, k 단계 중심 거리, 편도, 피크 등 몇 가지 기본 적 인 통 계량 을 사용 하기 때문에 우 리 는 모든 특징의 이런 통 계량 을 계산 해 야 한다. 새로운 수치 가 올 때 이 통 계량 을 업데이트 하고 훈련 모델 전에전체적인 통 계량 으로 국부 데이터 (표본 데이터) 를 업데이트 하여 데이터 의 전체적인 분포 정 보 를 충분히 이용 할 수 있 도록 한다.
전량 데 이 터 를 계산 하 는 기본 통 계량 의 가장 큰 문 제 는 무엇 입 니까?
앞에서 말 했 잖 아, 메모리 가 부족 하 다 고.무슨 해결책 이 있 을까요?네, 빅 데이터 클 러 스 터 에 올 라 가 spark 가 뛰 자마자 모두 나 왔 습 니 다.
이것 은 우리 가 여기 서 말 하고 자 하 는 중점 이 아니다. 우리 가 말 하고 자 하 는 것 은 유한 한 메모리 에서 증 량 훈련 방법 을 통 해 특징의 증 량 훈련 을 실현 하 는 것 이다.핵심 적 인 방법 은 데 이 터 를 한 번 만 옮 겨 다 니 면 이런 통 계량 을 계산 할 수 있 는 방법 이다.
이 는 알 리 바 바 양 욱 의 저서 인 을 참고 하여 제2 장 에서 양 욱 선생님 은 데 이 터 를 한 번 만 옮 겨 다 니 면 대부분의 기본 통 계량 방법 을 계산 할 수 있 는 방법 을 유도 했다.다음은 기본 적 인 기본 통 계량 의 계산 방법 이다.
n: 데 이 터 량 sum: 데이터 더하기 sum 2: 제곱 과 sum 3: 입방 과 sum 4: 4 차원 과
단순 구 화: sum = ∑ Xi s u m = ∑ X i 제곱 과: sum 2 = ∑ X2i s u m 2 = ∑ X i 2 입방 과: sum 3 = ∑ Xi 3 s u m 3 = ∑ X i 3 4 차방 과: sum 4 = ∑ X4i s u m 4 = ∑ X i 4
평균치: X ¯ = 1n ∑ Xi = sumn X ¯ = 1 n ∑ X i = s u m n
분산: var = 1n − 1 ∑ i = 1n (Xi − X ¯) 2 = 1n − 1 (sum 2 − sum ∗ X ¯) var = 1 n − 1 ∑ i = 1 n (X i − X ¯) 2 = 1 n − 1 (s u m 2 − s u m ∗ X ¯)
표준 차: std = var − − √ s t d = var
변이 계수: stdX * 175 ° s t d X * 175 °
2 단계 원점 모멘트: 1n > i = 1nX2i = sum2n 1 n > i = 1 n X i 2 = s u m 2 n
2 단계 중심 거리: 1n ∑ i = 1n (Xi − X ¯) 2 = 1n (sum 2 − sum ∗ X ¯) 1 n ∑ i = 1 n (X i − X ¯) 2 = 1 n (s u m 2 − s u m ∗ X ¯)
위의 기본 통 계량 을 제외 하고 최소 치 의 최대 치 는 많이 사용 되 고 계산 도 간단 하 며 더 이상 군말 하지 않 는 다.
자, 우 리 는 데 이 터 를 한 번 만 옮 겨 다 니 면 이런 통 계량 을 계산 할 수 있다 는 것 을 알 고 있 습 니 다. 그 다음 에 데 이 터 를 블록 으로 나 누 어 매번 에 한 조각 을 읽 은 다음 에 특징 계산 을 하고 전환 한 후에 특징 을 증분 계산 을 허용 하 는 모델 에 보 내 면 됩 니 다.
다음은 위조 코드 입 니 다.
#    :          
#     10    

statistic=None

for sub_data in pd.read_csv(file, chunksize=100000):
    sub_statistic = calculate_statistic(sub_data)  #   
    update_statistic(sub_statistic)                #   

#    :                ,  
for sub_data in pd.read_csv(file, chunksize=100000):
    new_feature = calculate_new_feature(sub_data, statistic)

    #    :                
    model.train_on_batchs(new_feature)

3. 모델 의 증 량 훈련 방법
이론 적 으로 SGD 나 유사 한 mini 를 사용 할 수만 있다 면batch SGD 가 최적화 한 모델 은 모두 증분 훈련 을 실현 할 수 있 는데 그 중에서 Linear ModelDeep Learning 가 가장 전형 적 이 고 기 존 도구 의 사용 을 간략하게 소개 한다.
3.1. sklearn 의 증분 훈련
sklearn 에 서 는 많은 증분 학습 알고리즘 을 제공 합 니 다.모든 알고리즘 이 증분 학습 할 수 있 는 것 은 아니 지만 학습 기 는 parial 을 제공 합 니 다.fit 의 함수 들 은 모두 증분 학습 을 할 수 있 습 니 다.사실 작은 batch 의 데 이 터 를 사용 하여 증분 학습 을 하 는 것 이 이러한 학습 방식 의 핵심 입 니 다. 왜냐하면 그것 은 어느 시간 동안 메모리 에 소량의 데이터 만 있 을 수 있 기 때 문 입 니 다.sklearn 은 많은 증분 학습 알고리즘 을 제공 합 니 다.
  • Classification
  • sklearn.naive_bayes.MultinomialNB
  • sklearn.naive_bayes.BernoulliNB
  • sklearn.linear_model.Perceptron
  • sklearn.linear_model.SGDClassifier
  • sklearn.linear_model.PassiveAggressiveClassifier

  • Regression
  • sklearn.linear_model.SGDRegressor
  • sklearn.linear_model.PassiveAggressiveRegressor

  • Clustering
  • sklearn.cluster.MiniBatchKMeans

  • Decomposition/feature Extraction
  • sklearn.decomposition.MiniBatchDictionaryLearning
  • sklearn.decomposition.IncrementalPCA
  • sklearn.decomposition.LatentDirichletAllocation

  • sklearn.cluster.MiniBatchKMeans

  • sklearn 의 학습 방법 에 대해 우리 가 해 야 할 일 은 주로 위 에서 말 한 특징 증분 훈련 을 실현 하 는 방법 이면 된다.
    3.2 lightGBM 의 증 량 훈련 방법
    lightGBM 은 xgboost 의 유력 한 경쟁자 로 서 증분 훈련 을 사용 하 는 것 도 편리 하 다. lightGBM 디자인 초기 에 도 초대형 데이터 세트 의 응용 을 고려 하여 분포 식 훈련 지원 을 제외 하고 증분 훈련 방법 도 제공 했다.다음은 회귀 예측 의 증 량 훈련 방법 이다.
    #    ,      None,      
    gbm=None
    params = {
            'task': 'train',
            'application': 'regression',
            'boosting_type': 'gbdt',
            'learning_rate': 0.2,
            'num_leaves': 31,
            'tree_learner': 'serial',
            'min_data_in_leaf': 100,
            'metric': ['l1','l2','rmse'],  # l1:mae, l2:mse
            'max_bin': 255,
            'num_trees': 300
        }
    #    ,      (  10 )
    i=1
    for sub_data in pd.read_csv(file, chunksize=100000)
        #     x   Y
        x_data = sub_data[x_cols]
        y_data = sub_data[y_col]
    
        #   lgb    
        lgb_train = lgb.Dataset(x_data, y_data.values)
        lgb_eval = lgb.Dataset(test[x_cols], test[y_col].values, reference=lgb_train)
    
        #    :      
        #     ,   init_model   keep_training_booster           
        gbm = lgb.train(params,
                        lgb_train,
                        num_boost_round=1000,
                        valid_sets=lgb_eval,
                        init_model=gbm,             #   gbm  None,               
                        feature_name=x_cols,
                        early_stopping_rounds=10,
                        verbose_eval=False,
                        keep_training_booster=True) #      
    
        #         
        score_train = dict([(s[1], s[2]) for s in gbm.eval_train()])
        score_valid = dict([(s[1], s[2]) for s in gbm.eval_valid()])
        print('            :mae=%.4f, mse=%.4f, rmse=%.4f'%(score_train['l1'], score_train['l2'], score_train['rmse']))
        print('            :mae=%.4f, mse=%.4f, rmse=%.4f' % (score_valid['l1'], score_valid['l2'], score_valid['rmse']))
        i += 1

    인쇄 결 과 를 보면 효과 가 이상 적 이지 않 고 특징 이 약 한 것 일 수도 있 습 니 다.예 를 들 어 나 는 매번 10 만 데 이 터 를 읽 는데, 아마도 이 10 만 데 이 터 는 이미 전체 데이터 세트 를 대표 할 수 있 을 것 이다.
    [2018.08.06 15:08:30]   1         
    [2018.08.06 15:08:30]             :mae=3.8034, mse=186.6290, rmse=13.6612
    [2018.08.06 15:08:30]             :mae=4.1202, mse=376.4796, rmse=19.4031
    [2018.08.06 15:08:46]   2         
    [2018.08.06 15:08:46]             :mae=4.0651, mse=346.0248, rmse=18.6017
    [2018.08.06 15:08:46]             :mae=4.1143, mse=370.8750, rmse=19.2581
    [2018.08.06 15:09:02]   3         
    [2018.08.06 15:09:02]             :mae=3.9073, mse=502.9016, rmse=22.4255
    [2018.08.06 15:09:02]             :mae=4.1229, mse=373.6719, rmse=19.3306
    [2018.08.06 15:09:19]   4         
    [2018.08.06 15:09:19]             :mae=4.2073, mse=525.9846, rmse=22.9344
    [2018.08.06 15:09:19]             :mae=4.1955, mse=415.1820, rmse=20.3760
    [2018.08.06 15:09:37]   5         
    [2018.08.06 15:09:37]             :mae=3.8308, mse=208.4748, rmse=14.4387
    [2018.08.06 15:09:37]             :mae=4.1798, mse=389.9514, rmse=19.7472
    [2018.08.06 15:09:55]   6         
    [2018.08.06 15:09:55]             :mae=4.0334, mse=226.4893, rmse=15.0496
    [2018.08.06 15:09:55]             :mae=4.1701, mse=374.0758, rmse=19.3410
    [2018.08.06 15:10:14]   7         
    [2018.08.06 15:10:14]             :mae=4.3154, mse=459.7565, rmse=21.4419
    [2018.08.06 15:10:14]             :mae=4.1799, mse=382.8426, rmse=19.5664
    [2018.08.06 15:10:26]   8         
    [2018.08.06 15:10:26]             :mae=4.2520, mse=293.1202, rmse=17.1208
    [2018.08.06 15:10:26]             :mae=4.1891, mse=382.2080, rmse=19.5501

    3.3. keras 의 증분 훈련 방법
    keras 는 깊이 있 는 학습 의 API 패키지 로 서 증분 훈련 방법 을 실현 했다.딥 러 닝 에 서 는 훈련 주기 가 길 기 때문에 몇 주, 심지어 한두 달 이 흔 하 다. 이상 하 게 빠 지면 다시 훈련 하 는 것 이 무섭다.이에 따라 텐 서 플 로 우 등의 틀 에 서 는 지난번 이상 하 게 빠 진 곳 에서 훈련 을 이 어 가 는 방법 이 있다.사실 1 만 번 훈련 할 때마다 훈련 과정의 네트워크 구조 적 매개 변수 와 가중치 를 저장 하고 문제 가 없 으 면 훈련 을 이 어 가 며 문제 가 있 으 면 최근 에 저 장 된 매개 변수 와 가중치 를 불 러 와 네트워크 를 초기 화하 고 훈련 을 이 어 가 는 것 도 이해 하기 쉽다.이렇게 하면 설령 잘못 을 저 지 르 더 라 도 문제 가 크 지 않다.keras 의 증분 훈련 방법 도 일리 가 있 습 니 다. 매번 에 일부 데 이 터 를 네트워크 훈련 에 넣 은 다음 에 네트워크 를 저장 하고 다음 에 새로운 데 이 터 를 와 서 네트워크 를 불 러 와 훈련 을 받 습 니 다.
    다음은 모델 위조 코드 입 니 다.
    import keras
    
    def normalize(array, min_, max_):
        """                 """
        write your normalize function here
    
    def y_normaloize(array, min_, max_):
        """                 """
        write your normalize function here
    
    
    #    :      None,        
    model = None
    model_file = r'E:\data_tmp
    n_data
    n_model_last_train.h5'
    # : 10 i = 1 for train in pd.read_csv(file, chunksize=100000): # : # X Y x_data = train[x_cols] y_data = train[[y_col]] # , # ( ) # (1) X for col in x_data.columns: min_, max_ = df_min[col], df_max[col] x_data[col] = normalize(x_data[col], min_, max_) # (2) y col = y_col min_, max_ = df_min[col], df_max[col] y_data[y_col] = y_normaloize(y_data[col], min_, max_) # : # , None, , if model == None: k = len(x_cols) model = Sequential() model.add(Dense(80, activation='relu', input_shape=(k,), )) model.add(Dropout(0.5)) model.add(Dense(32, activation='relu')) model.add((Dropout(0.5))) model.add(Dense(8, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(1, activation='linear')) model.summary() print(' ') model.compile(loss='mape', optimizer='adam', metrics=['mse', 'mae', 'mape']) print(' ') else: model = load_model(model_file) print(' ') # : os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' history = model.fit(x=x_data, y=y_data[y_col], batch_size=5000, epochs=20,verbose=10000) log.info(' ') # : model.save(model_file) # : # loss = history.history['loss'][-1] mse = history.history['mean_squared_error'][-1] mae = history.history['mean_absolute_error'][-1] mape = history.history['mean_absolute_percentage_error'][-1] print(' %2d ,loss=%.4f, mse=%.4f, mae=%.4f, mape=%.4f' % (i, loss, mse, mae, mape)) i += 1

    loss 가 계속 떨 어 지고 있다 는 것 은 증분 훈련 이 유용 하 다 는 것 을 알 수 있다.
    [2018.08.07 14:15:23]   1loss=0.0225, mse=0.0225, mae=0.1221, mape=13.5878
    [2018.08.07 14:16:37]   2loss=0.0028, mse=0.0028, mae=0.0379, mape=4.4841
    [2018.08.07 14:17:50]   3loss=0.0023, mse=0.0023, mae=0.0325, mape=3.7667
    [2018.08.07 14:19:06]   4loss=0.0023, mse=0.0023, mae=0.0324, mape=3.7899
    [2018.08.07 14:20:20]   5loss=0.0021, mse=0.0021, mae=0.0313, mape=3.5558
    [2018.08.07 14:21:37]   6loss=0.0022, mse=0.0022, mae=0.0323, mape=3.7333
    [2018.08.07 14:22:56]   7loss=0.0023, mse=0.0023, mae=0.0322, mape=5.5631
    [2018.08.07 14:23:46]   8loss=0.0024, mse=0.0024, mae=0.0332, mape=3.8871
    

    참고: Strategies to scale computationally: 더 큰 데 이 터 는 sklearn 을 사용 하여 증분 학습 lightGBM keeptraining_booster Incremental learning using Dataset. subset LightGBM 2.1.1 python API 는 훈련 된 Keras 모델 을 어떻게 불 러 오고 훈련 을 계속 합 니까? How to Check - Point Deep Learning Models in Keras Keras 중국어 문서
    내 칼럼 을 주목 하고 더 의미 있 는 지식 공 유 를 기대한다.

    좋은 웹페이지 즐겨찾기