#cifar10에서 데이터를 로드#from keras.datasets import cifar10 이 필요(X_train,y_train),(X_test,y_test)=cifar10.load_data()print("Training data:")print("Number of examples: ",X_train.shape[0])print("Number of channels:",X_train.shape[3])print("Image size:",X_train.shape[1],X_train.shape[2])printprint("Test data:")print("Number of examples:",X_test.shape[0])print("Number of channels:",X_test.shape[3])print("Image size:",X_test.shape[1],X_test.shape[2])
트레이닝에 사용할 5만장의 이미지와 테스트에 사용할 1만장의 이미지(32x32, 3channel)가 로드된 것을 확인할 수 있습니다.
머신러닝에서의 핵심중 하나는 cost를 구하고 Gradient Descent와 같은 알고리즘을 사용하여 cost를 최소화 시키는 것입니다. 그렇게 하기 위해 적당한 Learning Rate값을 찾는 것이 중요합니다.
근데, Learning Rate와 데이터에 대한 정규화가 어떤 상관이 있을까요?
다음 그림을 보면 좀 더 직관적으로 이해할 수 있습니다.
정규화되지 않은 데이터셋은 타원모양으로 길게 늘어져 Learning Rate를 매우 작게 해야지만 학습이 될 수 있다는 것을 확인할 수 있습니다. 만약 충분히 작지 않다면 수평으로 이동할 때와 수직으로 이동할 때 불균형이 발생하여 Gradient Descent 알고리즘을 적용하기 어려울 수 있습니다.
반면에 정규화된 데이터셋은 구의 모양을 띄고 있습니다. 때문에 Gradient Descent알고리즘을 적용하여 쉽고 빠르게 최적화 지점을 찾을 수 있습니다.
앞선 이유 때문에 최적의 머신러닝을 하기 위해선 데이터에 대한 정규화작업을 거치는 것이 반드시 필요합니다.
Data Normalization에는 크게 두가지 방법이 있습니다. (하나 더있는데 추후 서술)
1. Normalization(Min/Max)
전체 구간을 [0,1]로 맞춰줍니다.
2. Standardization
original data : 정규화 하기 전의 데이터 분포 zero-centered data : 원 데이터에 평균을 뺌. 이로써 데이터의 분포가 가운데에 모이게 됩니다. normalized data : 표준편차를 나눠줌으로써 데이터의 분포가 일정해지는 효과를 얻게 됩니다. (가로 세로 길이가 같아짐)
+) 반드시 정규화를 하기 위한 평균, 표준편차, min, max등의 값들은 train set에 있는 값만 사용하여 구하고 validation, test set에 적용하여야 합니다. 참고링크 : cs231n
내가 몰라서 적는 표준편차 구하는 법) 표준편차는 자료의 관찰값이 얼마나 흩어져 있는지를 나타내는 값 관측값에서 평균을 뺀 모든 값의 제곱을 구하고 그 값의 평균을 제곱근하면 된다.
다시 본론으로 돌아와서 소스코드를 보겠습니다. 아래 소스코드는 위의 설명 중 Standardization을 사용해서 정규화를 진행하였습니다.
print("mean before normalization:",np.mean(X_train))print("std before normalization:",np.std(X_train))mean=[0,0,0]std=[0,0,0]newX_train=np.ones(X_train.shape)newX_test=np.ones(X_test.shape)#train set에 있는 데이터로만 평균과 표준편차를 구함foriinrange(3):mean[i]=np.mean(X_train[:,:,:,i])std[i]=np.std(X_train[:,:,:,i])#train과 test셋 모두 정규화 작업 foriinrange(3):newX_train[:,:,:,i]=X_train[:,:,:,i]-mean[i]newX_train[:,:,:,i]=newX_train[:,:,:,i]/std[i]newX_test[:,:,:,i]=X_test[:,:,:,i]-mean[i]newX_test[:,:,:,i]=newX_test[:,:,:,i]/std[i]X_train=newX_trainX_test=newX_testprint("mean after normalization:",np.mean(X_train))print("std after normalization:",np.std(X_train))print(X_train.max())
batchSize=512#-- Training Batch Sizenum_classes=10#-- Number of classes in CIFAR-10 datasetnum_epochs=50#-- Number of epochs for training learningRate=0.001#-- Learning rate for the networklr_weight_decay=0.95#-- Learning weight decay. Reduce the learn rate by 0.95 after epochimg_rows=32#-- input image dimensionsimg_cols=32Y_train=np_utils.to_categorical(y_train,num_classes)Y_test=np_utils.to_categorical(y_test,num_classes)