2017-10-11 5 views
0

30 분 간격으로 탄소 플럭스 간격을 채우려고합니다. train-test-validate 교차 검증을 사용하여 사용 가능한 모든 입력이있는 모델을 교육 한 다음 점수가 개선되지 않을 때까지 정리 (pruning)하여 가장 간결한 LSTM 모델을 식별합니다. 각 모델에 대해 k-fold CV를 사용하여 90 % 열차를 분리하고 10 % 유효성을 검사 한 다음 model.fit()에서 기차를 열차 및 테스트 세트로 더 분할합니다. 나는 런타임을 최소화하고 ModelCheckpoint를 사용하여 최상의 가중치 (가장 낮은 "val_loss"를 가진 신기원)를 저장하기 위해 조기 중지를 사용하고 있습니다. 그런 다음 그 모델 가중치를로드하고 테스트 세트에서 가장 잘 수행 된 가중치를 사용하여 모델 외부에서 검증을 위해 10 %의 데이터에 대한 유효성 검사 점수 (MSE)를 계산하려고합니다. 여기Keras가 MXNet 백엔드를 사용할 때 모델 가중치를로드하지 못합니다.

9 개 요인과 13 timestimes (각 관측에 이르기까지의 6 시간)

import time 
import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
from itertools import combinations 
from functools import partial 
from multiprocessing import Pool 
from sklearn.neural_network import MLPRegressor as MPR 
from sklearn.preprocessing import StandardScaler 
from sklearn import metrics 
from sklearn.model_selection import RepeatedKFold 
import keras 
from keras.models import Sequential 
from keras.layers import Dense 
from keras.layers import Dropout 
from keras.layers import LSTM 
from keras.wrappers.scikit_learn import KerasRegressor 
from keras.callbacks import EarlyStopping,ModelCheckpoint 
import warnings 
warnings.filterwarnings('ignore') 
import tensorflow as tf 
config = tf.ConfigProto() 
config.gpu_options.per_process_gpu_memory_fraction = 0.9 
session = tf.Session(config=config) 

def TimeShape(rolls,X1): 
    X = np.zeros(shape = (X1.shape[0],rolls+1,X1.shape[1])) 
    X[:,0,:] = X1 
    if rolls > 0: 
     for roll in range(0,rolls): 
      X2 = np.roll(X1,(roll+1),axis=0) 
      X[:,roll+1,:] = X2 
    return(X) 

def LSTM_Model(time_steps,inputs,load=None): 
    model = Sequential() 
    model.add(LSTM(12, input_shape=(time_steps+1,inputs),return_sequences=True,init='normal', activation='tanh')) 
    model.add(LSTM(6,init='normal', activation='tanh')) 
    model.add(Dense(1, init='normal',activation='linear')) 
    NUM_GPU = 1 # or the number of GPUs available on your machine 
    gpu_list = [] 
    for i in range(NUM_GPU): gpu_list.append('gpu(%d)' % i) 
    model.compile(loss='mean_squared_error', optimizer='adam',context=gpu_list) # - Add if using MXNET 
    return(model) 

class LossHistory(keras.callbacks.Callback): 
    def on_train_begin(self, logs={}): 
     self.train_losses = [] 
     self.test_losses = [] 
    def on_epoch_end(self, batch, logs={}): 
     self.train_losses.append(logs.get('loss')) 
     self.test_losses.append(logs.get('val_loss')) 

class LSTM_Optimize: 
    def __init__(self,Path,y_var): 
#  **Read and prep Data Data** 
     self.Master = pd.read_csv(Path,delimiter = ',',header = 0,na_values = -9999) 
     self.Master = self.Master.set_index(pd.DatetimeIndex(pd.to_datetime(self.Master['datetime']))) 
     self.Master['DOY'] = self.Master.index.dayofyear*1.0 
     self.Master['HR'] = self.Master.index.hour*1.0 
     self.Data = self.Master[np.isfinite(self.Master[y_var])] 
     self.Data = self.Data.interpolate().bfill() 
     self.Data = self.Data.interpolate().ffill() 
#  ** Nomralize Y variable** 
#  ** Pipeline takes care of X, but not Y, I've foun the models work better when normalizing Y ** 
     self.y = self.Data[y_var].values 
     self.YStandard = StandardScaler() 
     self.YScaled = self.YStandard.fit(self.y.reshape(-1, 1)) 
     Yscale = self.YScaled.transform(self.y.reshape(-1, 1)) 
     self.y = np.ndarray.flatten(Yscale) 
     self.Ytru = self.YScaled.inverse_transform(self.y.reshape(-1,1)) 

    def Run(self,Inputs): 
     # Preparing the input data 
     time_steps = 12 
     X = self.Data[Inputs] 
     input_shape = len(Inputs) 
     self.XStandard = StandardScaler() 
     self.XScaled= self.XStandard.fit(X) 
     Xscale = self.XScaled.transform(X) 
     Xscale = TimeShape(time_steps,Xscale) 
     Xscale = Xscale[time_steps+1:,:,:] 
     self.y = self.y[time_steps+1:] 


     ES = EarlyStopping(monitor='val_loss', min_delta=0.0, patience=25, verbose=1, mode='auto') 
     CH = ModelCheckpoint(filepath='weights.hdf5',monitor='val_loss', verbose=0, save_best_only=True) 
     HS=LossHistory() 
     MSE = [] 
     kf = RepeatedKFold(n_splits=10,n_repeats=2) 
     batch_size=25 
     Mod = LSTM_Model(time_steps,input_shape) 
     plt.figure(figsize = (7,7)) 
     for train,test in kf.split(Xscale,self.y): 
      Mod.fit(Xscale[train],self.y[train],batch_size=batch_size, nb_epoch=1000,validation_split=0.1, 
        shuffle=True,callbacks=[ES,CH,HS],verbose=0) 
      Y = Mod.predict(Xscale[test],batch_size = batch_size) 
      Mod.load_weights('weights.hdf5') 
      Y = Mod.predict(Xscale[test],batch_size = batch_size) 
      MSE.append(metrics.mean_squared_error(self.y[test],Y)) 
      plt.plot(HS.test_losses,linestyle='--') 
      plt.plot(HS.train_losses) 

     print(Mod.summary()) 
     print(np.asanyarray(MSE).mean()) 

Path = 'FluxData.csv' 
% matplotlib inline 
start_time = time.time() 
if __name__ == '__main__': 
    CH4_Model = ['Sedge','Shrubby','Temp','VWC','ustar','wind_speed','air_pressure', 
      'PPFD_Avg','NR_Wm2_Avg','AirTC_Avg'] 
    y_var = 'ch4_flux' 
    Model = CH4_Model 
    Best = LSTM_Optimize(Path,y_var) 
    Best.Run(Model) 
    print() 
    print("--- %s seconds ---" % (time.time() - start_time)) 

그리고 여기 내 데이터 세트의 몇 행이다와 함께 LSTM 훈련 내 코드의 작동 예이다 - 실제 시리즈 1000 관측

datetime,co2_flux,ch4_flux,ustar,wind_speed,AirTC_Avg,air_pressure,AirTC_Min,RH,PPFD_Avg,NR_Wm2_Avg,VWC,Temp,Sedge,Shrubby 
7/11/2016 8:00,-0.337747167,0.011732699,0.404379747,3.887986435,15.07,101118.6513,15.03,92.7,414.2,225.1,0.5895,7.950660426,0.001292044,0.823794007 
7/11/2016 8:30,-1.021087283,0.010256442,0.424094541,3.94983083,14.89,101144.0926,14.84,92.8,339.7,177.1,0.5895,8.24119905,0.001058732,0.826866339 
7/11/2016 9:00,-0.146511388,0.008503355,0.456274817,4.687202214,14.71,101177.3176,14.63,93.4,354.4,183.7,0.5895,8.146344257,0.000474955,0.84272365 
7/11/2016 9:30,0.144368521,0.009458078,0.462915317,4.810986576,14.27,101203.9191,14.2,93.3,370.2,188.4,0.5895,7.995179025,0.00147768,0.854715683 
7/11/2016 10:00,1.471425801,0.014895985,0.47095652,5.098075355,13.7,1.9171,13.62,94.3,462.9,233.9,0.5895,7.521166721,4.64E-05,0.871581919 
7/11/2016 10:30,0.889911286,0.01564225,0.487227522,4.969666239,13.13,101277.0195,13.04,96,309.9,155.2,0.5895,7.923818563,8.14E-06,0.880709962 

Tensorflow가 지원되는이 제품을 실행하면 모든 것이 부드럽게 진행되어 나옵니다. 나는 MXNet 백엔드를 실행하려고 Howeverif, 그것은로드 모델 가중치를 저장 실패하고 나는이 역 추적 얻을 :

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-1-14c6597a2feb> in <module>() 
    114  Model = CH4_Model 
    115  Best = LSTM_Optimize(Path,y_var) 
--> 116  Best.Run(Model) 
    117  print() 
    118  print("--- %s seconds ---" % (time.time() - start_time)) 

<ipython-input-1-14c6597a2feb> in Run(self, Inputs) 
    96      shuffle=True,callbacks=[ES,CH,HS],verbose=0) 
    97    Y = Mod.predict(Xscale[test],batch_size = batch_size) 
---> 98    Mod.load_weights('weights.hdf5') 
    99    Y = Mod.predict(Xscale[test],batch_size = batch_size) 
    100    MSE.append(metrics.mean_squared_error(self.y[test],Y)) 

/usr/local/lib/python3.5/dist-packages/Keras-1.2.2-py3.5.egg/keras/engine/topology.py in load_weights(self, filepath, by_name) 
    2718    self.load_weights_from_hdf5_group_by_name(f) 
    2719   else: 
-> 2720    self.load_weights_from_hdf5_group(f) 
    2721 
    2722   if hasattr(f, 'close'): 

/usr/local/lib/python3.5/dist-packages/Keras-1.2.2-py3.5.egg/keras/engine/topology.py in load_weights_from_hdf5_group(self, f) 
    2804       weight_values[0] = w 
    2805     weight_value_tuples += zip(symbolic_weights, weight_values) 
-> 2806    K.batch_set_value(weight_value_tuples) 
    2807 
    2808  def load_weights_from_hdf5_group_by_name(self, f): 

/usr/local/lib/python3.5/dist-packages/Keras-1.2.2-py3.5.egg/keras/backend/mxnet_backend.py in batch_set_value(tuples) 
    2205  """ 
    2206  for p, w in tuples: 
-> 2207   set_value(p, w) 
    2208 
    2209 

/usr/local/lib/python3.5/dist-packages/Keras-1.2.2-py3.5.egg/keras/backend/mxnet_backend.py in set_value(x, value) 
    2193  if isinstance(value, Number): 
    2194   value = [value] 
-> 2195  x.bind(mx.nd.array(value)) 
    2196 
    2197 

/usr/local/lib/python3.5/dist-packages/mxnet-0.11.0-py3.5.egg/mxnet/ndarray.py in array(source_array, ctx, dtype) 
    1295     raise TypeError('source_array must be array like object') 
    1296  arr = empty(source_array.shape, ctx, dtype) 
-> 1297  arr[:] = source_array 
    1298  return arr 
    1299 

/usr/local/lib/python3.5/dist-packages/mxnet-0.11.0-py3.5.egg/mxnet/ndarray.py in __setitem__(self, key, value) 
    384     _internal._set_value(float(value), out=self) 
    385    elif isinstance(value, (np.ndarray, np.generic)): 
--> 386     self._sync_copyfrom(value) 
    387    else: 
    388     raise TypeError(

/usr/local/lib/python3.5/dist-packages/mxnet-0.11.0-py3.5.egg/mxnet/ndarray.py in _sync_copyfrom(self, source_array) 
    556    print(self.shape) 
    557    raise ValueError('Shape inconsistent: expected %s vs got %s'%(
--> 558     str(self.shape), str(source_array.shape))) 
    559   check_call(_LIB.MXNDArraySyncCopyFromCPU(
    560    self.handle, 

ValueError: Shape inconsistent: expected() vs got (1,) 

을 왜 MXNet를 사용 하시겠습니까? 그것은 tensorflow보다 빠르다고 보입니다. 그리고 다양한 입력과 다양한 노드와 하이퍼 파라미터를 가진 많은 모델에서 train-test-validation을 수행해야 할 것입니다. 여러 개의 다른 모델을 병렬로 교육하기 위해 멀티 프로세싱을 사용하여 MXNet 백엔드를 사용하여 케라 모델의 속도를 크게 높일 수있었습니다. 그러나, tensroflow 백 엔드를 사용하면 다중 처리를 시도 할 때 스레드 잠금 오류가 발생합니다.

맥락에서 p2.xlarge 인스턴스에서 Deep Learning AMI Ubuntu Linux - 2.3_Sep2017 (ami-d6ee1dae) 환경을 사용하고 있습니다.

모든 아이디어를 높이 평가하겠습니다!

+0

안녕하세요, 알아 냈습니까? – HalaKuwatly

+0

MXNet과 함께, 나는 그것을 포기하고 tensorflow로 바 꾸었습니다. train-test-validate 모델에 대해 tensorflow를 사용하여 다중 처리를 구현하는 방법을 알아 냈습니다. –

답변

3

MXNet 백엔드 LSTM 계층은 버킷 크기 (길이)를 정적으로 선언해야하는 MXNet의 bucketing module을 사용하지만 Keras 및 TF는 동적 길이를 지원합니다. 따라서 모델 가중치를로드하고 잘못 일치하는 문제가 발생합니다.

현재 Kerb2 지원을 MXNet 백엔드와 함께 추가하기 위해 노력하고 있으며이 문제는 Keras2에서주의를 기울여야합니다. https://github.com/deep-learning-tools/keras/tree/keras2_mxnet_backend https://github.com/keras-team/keras/issues/8697