åå¦çã«ãã£ã¼ãã©ã¼ãã³ã°ã使ã
åå¦çã«ãã£ã¼ãã©ã¼ãã³ã°ã使ã
ç®ç
- ã¹ã¯ã¬ã¤ãã¼ãªã©ã§éããç»åã«ã¯ãã¿ã¼ã²ããã¨ããç»å以å¤å¿ è¦ãªãã±ã¼ã¹ã度ã ãã
- ãã¼ã¿ã»ããã¥ããã¨å¼ã°ããç»åãããã¤ãºç»åãåãé¤ãã¹ã¯ãªã¼ãã³ã°ã®ä½æ¥ã®ç°¡ç¥åã®å¿ è¦æ§
- ç»åã®ã¹ã¯ãªã¼ãã³ã°ãæ©æ¢°å¦ç¿ã§ãã£ã¦ãã¾ããã¨ãã試ã¿ã§ã
åå¦çãã®ãã®ã«ãã£ã¼ãã©ã¼ãã³ã°ãæå ¥ãã
- ç»åå¦çã«ããã¦ãå¦ç¿ãããç»åãã©ãããã¹ã¯ãªã¼ãã³ã°ãããã¨ã¯è¨å¤§ãªã³ã¹ãããããã®ã§ããã®ä½æ¥èªä½ãèªååããã
- ä»åã¯ã¹ã¯ã¬ã¤ãã¼ã§ããå æ¸ã«ãã¤ããã°ã©ãã¢å¥³åªã®ç»å7ä¸æè¶ ãããæåã§ã¹ã¯ãªã¼ãã³ã°ããã®ã¯æ¥µãã¦å°é£ãªã®ã§ãVGG16ã転移å¦ç¿ããã¦ãã£ã«ã¿ãä½ã£ã¦ããã¾ã
- ä¸æ10åã§500æã®ãã¢ï¼positiveã¨negativeï¼ã®ãã¼ã¿ã»ãããç¥ãåãã®ãã¼ãã«ä½ã£ã¦ããã
- ãã¼ãã®ä½æãããã¼ã¿ã»ããããã¨ã«ã転移å¦ç¿ããã¦ãã£ã«ã¿ãæ§ç¯
ã·ã¹ãã æ§æå³
人éã¨ã®æ¯è¼
- å®ã¯äººéããã©ããããæ©ãã§ãããã¨ããã¨ãæ¤è¨¼ãããã¦ãèªåã®ç®ã§è¦ã¦å¤æãã¦åé¡ãã¦ããã®ã¨ãæ©æ¢°ã§ã¯ã©ã®ç¨åº¦ã®å·®ãããã試ãã
- 人éã¯6æéã§5000æãããã®ãã§ãã¯ãéçã§ãã£ãï¼ç²¾ç¥çã«å¤§ãã«ç²å¼ããï¼
- 対ãã¦75000æãGTX 1080 ï¼åºã§ 50åä½ã§ãããå§åçã«æ©æ¢°å¦ç¿ã®æ¹ããã
ãããã¯ã¼ã¯ã®åºåã®ç¹æ§ãç¥ã£ã¦ãã
- æ´»æ§åé¢æ°ãæå°åããç®çé¢æ°ã®è¨è¨ã¯å®ã«ãã©ã¨ãã£ã«å¯ãã§ãããçµã¿åããã¯èãå§ããã¨ç¡æ°ã«ããããã«è¦ãã
- å é¨ããªãã¢ã§ããããã®ãã¸ãããåã£ããã¸ã¹ãã£ãã¯å帰ã確ç表ç¾ã¨ãã¦åªç§ãªã®ã§ãã使ã
- softmax, categorical crossentropyã¨ãã¯åºåå¤ãå¯ããã£ã¦ãã¾ãã®ã§ããã¾ã確ç表ç¾ã«åãã¦ããªãããã«è¦ãã
- ä»åã¯ãã¸ããã使ã
éå¦ç¿ã®é²æ¢
- ã©ã®ç¨åº¦ããã¼ã¿ã»ããã«ãã£ããã£ã³ã°ããã¦ãããããããªãéè¦ãªã®ã§ãè¨ç·´ãã¼ã¿ã¨ããªãã¼ã·ã§ã³ãã¼ã¿ã«åãã¦æªç¥ã®ãã¼ã¿ã»ããã«å¯¾ãã¦ãæ±åæ§è½ã確èªãã
- ä»åã¯epochãã¨ã«modelãä¿åãã¦ãã¹ããªã¢ãã«ãæ¢ç´¢ãããã¨ã§é¸ãã§ãã£ã -> æé©ã¯85epochããããããã£ã
ãããå¤ã®æ±ºå®
- 0~1ã«å¤åããå¤ã§ãã
- å½ç¶0.5ããããå¤ã§ããã0.5ããå§ãã¦ããããããå¤ã調æ´ãã
-> ãããã調æ´ãããå¤ãã«ã¹ã¯ãªã¼ãã³ã°ããã¨ãã¦ããããå¤ã0.65ã¨ããã
ææ³
- ä½ããä½ããã¨æã£ã¦å¾åãã«ãã¦ãæ¡ä»¶ã§ã
- ã§ãã¦ããã£ãã§ã
- ãã¼ãã¯ç¤¾ä¼çè©ä¾¡ãæ¬äººè©ä¾¡ãè²ã ããã©ãããããæ©å«ãã¨ãã®ã大å¤ã ã£ãã®ã§ããããªãã¯ã©ã¦ãã¯ã¼ã¯ã¹ã®ã»ããè¯ããã§ã
å ¨ä½ã®æµã
ã³ã¼ãã¯githubã«ããã¦ããã¾ããéåç¨ã»ç 究ç®çã§ã¯å¥½ãã«ä½¿ã£ã¦ãã ãã
bitbucket.org
bitbucketããããã£ã¦ãªãã®ã§ãä½ãä¸å
·åãããã°twitterã§æãã¦ããã ããã¨å¹¸ãã§ãã
$ git clone https://${YOUR_ID?}@bitbucket.org/nardtree/maeshori-toolkit-for-deeplearning.git
step1. å ¥åãµã¤ãºã«åããã¦å¤å½¢ãã
ãã¼ããã帰ã£ã¦ãããã¼ã¿ã¯500ã®positive,negativeã®ãã©ã«ãã«å¥ãããã¼ã¿ã»ããã§ãã£ã
ãã©ã«ãåãçãã¨ãã¦ã224Ã224ã®ãµã¤ãºã«å¤å½¢ããããã®æåç´ãªå¤å½¢ã«ãã¦ãã¾ãã¨ç¸¦æ¨ªæ¯ãå´©å£ãã¦ãã¾ãã®ã§ç¶æããç´°å·¥ãå
¥ããã
å®è¡
$ python3 image-resizer.py --gravia_noisy
ã³ã¼ã
def gravia_noisy(): target_size = (224,224) dir_path = "./gravia-noisy-dataset/gravia/*/*" max_size = len(glob.glob(dir_path)) for i, name in enumerate(glob.glob(dir_path)): if i%10 == 0: print(i, max_size, name) save_name = name.split("/")[-1] type_name = name.split("/")[-2] if Path("gravia-noisy-dataset/{type_name}/{save_name}.minify" \ .format(type_name=type_name, save_name=save_name)).is_file(): continue try: img = Image.open(name) except OSError as e: continue w, h = img.size if w > h : blank = Image.new('RGB', (w, w)) if w <= h : blank = Image.new('RGB', (h, h)) try: blank.paste(img, (0, 0) ) except OSError as e: continue blank = blank.resize( target_size ) os.system("mkdir -p gravia-noisy-dataset/{type_name}".format(type_name=type_name)) blank.save("gravia-noisy-dataset/{type_name}/{save_name}.mini.jpeg" \ .format(type_name=type_name, save_name=save_name), "jpeg" )
step2. å¦ç¿ãã
æçµçã«ã¯ResNetã使ãããé度ãã»ããåå¦çã®ã¿ã¹ã¯ã®ããVGG16ã§å¦ç¿ãè¡ã
softmaxã§ãªãã¦ãsigmoid + binary_crossentropyã§ã
å®è¡
$ python3 deep_gravia_maeshori.py --train
ã³ã¼ã
from keras.applications.vgg16 import VGG16 def build_model(): input_tensor = Input(shape=(224, 224, 3)) model = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor) dense = Flatten()( \ Dense(2048, activation='relu')( \ BN()( \ model.layers[-1].output ) ) ) result = Activation('sigmoid')( \ Dense(1, activation="linear")(\ dense) ) model = Model(input=model.input, output=result) for layer in model.layers[:11]: if 'BatchNormalization' in str(layer): ... else: layer.trainable = False model.compile(loss='binary_crossentropy', optimizer='adam') return model
step3. å ¨ä½ã®ãã¼ã¿ã»ããã«é©å¿ãã
é©åã«ãã©ã«ãã«ç»åãé
ç½®ãã¦è¡ã£ã¦ãã ãã
å®è¡
$ python3 deep_gravia_maeshori.py --classify
ã³ã¼ã
def classify(): os.system("mkdir ok") os.system("mkdir ng") model = build_model() model = load_model(sorted(glob.glob('models/*.model'))[-1]) files = glob.glob("bwh_resize/*") random.shuffle(files) for gi, name in enumerate(files): try: img = Image.open('{name}'.format(name=name)) except FileNotFoundError as e: continue img = [np.array(img.convert('RGB'))] if not os.path.exists(name): continue result = model.predict(np.array(img) ) result = result.tolist()[0] result = { i:w for i,w in enumerate(result)} for i,w in sorted(result.items(), key=lambda x:x[1]*-1): if w > 0.65: os.system("mv {name} ok/".format(name=name)) else: os.system("mv {name} ng/".format(name=name)) print(gi, name, w, file=sys.stderr)