ããã«ã¡ã¯ãããã©ãï¼@t_andouï¼ã§ããÂ
ååãããå°ãªããã¼ã¿ã§å¹çããå¦ç¿ãããfinetuningã®è¨äºã翻訳ãã¦ãã¾ãããä»åã¯å ¨3åä¸ã®ç¬¬2åã§ãã
å ¨3åã®äºå®
- ãã¼ã¿ã®æºåã»ãã¼ã¿ã®æ°´å¢ã
- 1ããå°ããªç³ã¿è¾¼ã¿ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ãä½ã£ã¦ã¿ãï¼<-ä»åã¯ããï¼
- å¦ç¿æ¸ã¿ãããã¯ã¼ã¯ãæµç¨ãã
ååã®è¨äºã¯ãã¡ãÂ
ååã¯å¦ç¿ã«ä½¿ããã¼ã¿ã®æºåãè¡ãã¾ããã
ä»åã¯å°ããªç³ã¿è¾¼ã¿ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ã1ããä½ã£ã¦ãååæºåãããã¼ã¿ãå¦ç¿ããã¦ã¿ã¾ãã
å°ããªCNNã0ããä½ãï¼40è¡ã®ã³ã¼ãã§80%ã®æ£è§£ç
ç»åã®ã¯ã©ã¹åé¡å¨ã«ãµãããããã¼ã«ã¯ç³ã¿è¾¼ã¿ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ï¼ä»¥éCNNï¼ã§ããããã§ã¯æåã®ä¸æ©ã¨ãã¦ãç¬ã»ç«ã®ãã¼ã¿ãå¦ç¿ããã¦ã¿ã¾ãããã
ä»åã¯å°ãªãç»åã§å¦ç¿ãé²ãã¾ãã®ã§ãä¸çªã®æ¸å¿µç¹ã¯éå¦ç¿ã§ãããã
éå¦ç¿ã¨ã¯ãå°éã®å¦ç¿ãã¼ã¿ã«ç¹åãéããä¸è¬åã§ãã¦ããªããã¨ã§ãæ°ããå ¥ã£ã¦ãããã¼ã¿ã«å¯¾å¿ã§ããªãç¶æ ã«ãªããã¨ã§ãã
ä¾ãã°ãä¸è¬çãªäººã§ããã°ãæ¨ãããã¨ãè¹ä¹ããã®ç»åã3æãã¤è¦ã¦ããã®æ¬¡ã«ä¸äººã ãï¼è¹ä¹ãã®ï¼ï¼å¸½åããã¶ã£ãæ¨ããã®åçãè¦ããããã¯ä½ããã®ãµã¤ã³ã ã¨èãå§ããã§ãããããæ¨ãããã¨ãè¹ä¹ããã®åé¡ã¨ãã¦ã¯ã¢ã¤ã£ã¨ããã¯ãã§ããï¼â»ãããããã¾ããã§ããï¼
ãã¼ã¿ã®æ°´å¢ãã¯éå¦ç¿ã«å¯¾ããä¸ã¤ã®æ¹æ³ã§ããååã§ã¯ããã¾ããããªããªããæã
ã®æ°´å¢ããããã¼ã¿ã¯ã¾ã å
ç»åã«ããä¼¼ã¦ããããã§ããããªããéå¦ç¿å¯¾çã¨ãã¦éä¸ããã¹ããªã®ã¯ã¢ãã«ã®entropic capacity*1ã§ããã¤ã¾ããããªãã®ã¢ãã«ãã©ã®ãããã®æ
å ±ãæ ¼ç´ã§ããã®ãã¨ãããã¨ã§ãã
大éã®æ
å ±ãæ ¼ç´ã§ããã¢ãã«ã¯ããå¤ãã®ç¹å¾´ãåç
§ã§ããã®ã§ã精度ãé«ããªãã¾ããããããããã¯åæã«ç¡æå³ãªç¹å¾´ã®åç
§ããéå§ãããªã¹ã¯ãããã¨ãããã¨ã§ãããã¾ãã
ä¸æ¹ã§ãå°éã®ç¹å¾´ã ãæ ¼ç´ãã¦ããã¢ãã«ã¯æãéè¦ãªç¹å¾´éã«ãã©ã¼ã«ã¹ãããã¨ãã§ãã¾ãããããã®ç¹å¾´éã¯ç¸é¢ããããããä¸è¬åããããã«æ£ãããã®ã§ãããã
entropic capacityã調ç¯ããã«ã¯äºã¤ã®æ¹æ³ãããã¾ããä¸ã¤ã¯ãã¤ãã¼ãã©ã¡ã¼ã¿ã¼ã®é¸æã§ããä¾ãã°ãã¬ã¤ã¤ã¼ã®æ°ã»åã¬ã¤ã¤ã¼ã®ãµã¤ãºãªã©ãä»ã«ã¯ãL1ãL2æ£ååã®ãããªéã¿ã®æ£ååã使ãæ¹æ³ãããã¾ããããã¯ã¢ãã«ã®éã¿ãããå°ããªå¤ãåãããã«ãªã£ã¦ãã¾ãã
ä»åã¯å°ãã®å±¤ã¨å層ã«ã¡ãã£ã¨ã®ãã£ã«ã¿ã¼ããä½ããã¦ããé常ã«å°ããªCNNããã¼ã¿ã®æ°´å¢ãã»ããããã¢ã¦ãã¨ä¸ç·ã«ä½¿ãã¾ããããããã¢ã¦ãã¯åããã¿ã¼ã³ãäºåè¦ããã¨ãé²ãã®ã§ãéå¦ç¿ãé²ãæå©ãã«ãªãã¾ããã¤ã¾ããããããã¢ã¦ãã¯ãã¼ã¿æ°´å¢ãã¨åããããªæ©è½ã»å¹æãæã¤ã®ã§ããï¼ããããã¢ã¦ãããã¼ã¿æ°´å¢ããå ±ã«ãåé¡ä¸ã®ç¹å¾´ãã¼ã¿ã解æããä¸ã§çºçããï¼èå¥ã«ï¼ç¡é¢ä¿ãªå ±éç¹ãæé¤ãã¦ãããå¾åãããã¨è¨ãã¾ãï¼
Â
ä¸ã®ã³ã¼ãã¯ãæ´»æ§åé¢æ°ï¼ReLUï¼ã¨Maxãã¼ãªã³ã°å±¤ãç³ã¿è¾¼ã¿å±¤ãä¸ã¤ãã¤éãããã·ã³ãã«ãªã¢ãã«ã§ãããããæåã«è©¦ãã¢ãã«ã«ãªãã¾ãã
ããã¯Yann LeCunã1990年代ã«æå±ããç»ååé¡ã®ã¢ã¼ããã¯ãã£ã¨é常ã«ããä¼¼ã¦ãã¾ããï¼ReLUã使ãã¨ããã¯å¥ï¼
å ¨é¨ã®ã³ã¼ãã¯ãã¡ãããã©ããã
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
model = Sequential()
model.add(Convolution2D(32, 3, 3, input_shape=(3, 150, 150)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# the model so far outputs 3D feature maps (height, width, features)
æå¾ã«2ã¤ã®å ¨çµå層ããã£ã¤ãã¾ããããããã¯ã¼ã¯ã®æå¾ã¯ä¸ã¤ã®ã¦ãããã§ãã·ã°ã¢ã¤ãé¢æ°ã¨ããæ´»æ§åé¢æ°ã§çµãããã¾ããããã¯2å¤åé¡ã«ã¯ã´ã£ããã®é¢æ°ã§ããã¾ãã2å¤åé¡ãããããã«ãbinary_crossentropyã¨ããæ失é¢æ°ã使ãã¾ãã
model.add(Flatten()) # this converts our 3D feature maps to 1D feature vectors
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
次ã«ãã¼ã¿ã®æºåããã¾ããããããããã®ãã©ã«ãã«ããJPGã®ãã¡ã¤ã«ããç´æ¥ãç»åãã¼ã¿ï¼ã¨ã©ãã«ï¼ã®ãããï¼=ï¼åº¦ã«å¦çããå¡ã®ãã¨ï¼ãçæããããã«.flow_from_directory()ã使ãã¾ãã
# this is the augmentation configuration we will use for training train_datagen = ImageDataGenerator( rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) # this is the augmentation configuration we will use for testing: # only rescaling test_datagen = ImageDataGenerator(rescale=1./255) # this is a generator that will read pictures found in # subfolers of 'data/train', and indefinitely generate # batches of augmented image data train_generator = train_datagen.flow_from_directory( 'data/train', # this is the target directory target_size=(150, 150), # all images will be resized to 150x150 batch_size=32, class_mode='binary') # since we use binary_crossentropy loss, we need binary labels # this is a similar generator, for validation data validation_generator = test_datagen.flow_from_directory( 'data/validation', target_size=(150, 150), batch_size=32, class_mode='binary')
ãããã®ã¸ã§ãã¬ã¼ã¿ã¯ç§ãã¡ã®ã¢ãã«ãå¦ç¿ãããããã«ããã«ä½¿ãã¾ãã1EpochãããGPUã使ãã°20~30ç§ãCPUã§ããã°300~400ç§ãããã§åºæ¥ã¾ããã§ãã®ã§ãæ¥ãã§ãªãéããCPUã§ãå®è¡å¯è½ãªé度ã§ããã
model.fit_generator(
train_generator,
samples_per_epoch=2000,
nb_epoch=50,
validation_data=validation_generator,
nb_val_samples=800)
model.save_weights('first_try.h5') # always save your weights after training or during training
ãã®ã¢ããã¼ãã§50epochãå¦ç¿ãããã¨æ¤è¨¼ã®ç²¾åº¦ã¯79~81%ã«ãªãã¾ããï¼50epochã¯ä»»æã®åæ°ã§ãããã®æç¹ã§ã¯ã¢ãã«ãå°ãããç©æ¥µçã«ããããã¢ã¦ããå©ç¨ãã¦ããã®ã§ãéå¦ç¿ãèµ·ãããã¨ã¯ãã¾ãããã¾ãããï¼
ã¤ã¾ããKaggleã®ã³ã³ããã£ã·ã§ã³ãå§ã¾ã£ãæç¹ã§è¨ããã¦ãããæå 端ãã«ãªã£ãã¨ãããã¨ã«ãªãã¾ããï¼ããããç¹ã«ã¬ã¤ã¤ã¼ããã¤ãã¼ãã©ã¡ã¼ã¿ã®æé©åã®åªåããã¦ããªãä¸ã«ããã£ã8%ã®ãã¼ã¿ã ãã§ï¼
å®éããã®ã¢ãã«ã¯Kaggleã®ã³ã³ããã£ã·ã§ã³ã§100ä½ãããã®ã¹ã³ã¢ãåãã§ãããï¼215ã®åå è ã®ãã¡ï¼ããããããããããä¸ã®115ã®åå è ã¯ãã£ã¼ãã©ã¼ãã³ã°ã使ã£ã¦ãªãã®ã§ãããã
æ¤è¨¼ã®ç²¾åº¦ã®åæ£ã¯ããªãé«ãã§ãããªããªãã精度ã¯åæ£ã大ããmetricã§ãç§ãã¡ã¯800ããæ¤è¨¼ãã¼ã¿ãå©ç¨ãã¦ããªãããã§ããæ¤è¨¼ããã®ã«ããæ¹æ³ã¯k-fold cross-validationãè¡ããã¨ã§ããããããããããã¯æ¤è¨¼ã®æã«æ¯åk modelsãå¦ç¿ãããå¿ è¦ãããã¾ããï¼â»ãããããã¾ããã§ããï¼Â Â
ä»åã¯CNNãä¸ããä½ã£ã¦å¦ç¿ã¾ã§ãã£ã¦ã¿ã¾ããã
次åã¯å¦ç¿æ¸ã¿ã¢ãã«ãæµç¨ãããã¨ã§ããé«ç²¾åº¦ãªåé¡ãããã¾ããï¼ä¸é±éå¾ãããã«å ¬éãã¾ããï¼
å è¨äºã¯ãã¡ã
Building powerful image classification models using very little data
*1:ã¨ã³ãããã¼ã®å®¹éï¼ã©ããããã®ç¨®é¡ã®ãã¼ã¿ãæã¤ãã¨ããæå³ã§ãããã