ãã®æç« ã§ã¯CNNå®è£ ã§ããCaffeãçšããŠïŒç¹åŸŽãã¯ãã«ã®æœåºããã©ã¡ãŒã¿ã®åŠç¿ãè¡ãããã®æ¹æ³ã«ã€ããŠèª¬æããïŒ
以äžã®äœæ¥ãè¡ãããã®ã§ããã°ïŒCaffeãçšããããšãæãŸããïŒ
- CNNãå©çšããç»åã®å€ã¯ã©ã¹åé¡
- CNNã«ããç¹åŸŽãã¯ãã«ã®æœåº
- CNNã®è»¢ç§»åŠç¿
- Stacked Auto Encoder
Caffeã¯(äŸãmasterãã©ã³ãã ããã)é »ç¹ã«ä»æ§ãå€ããã®ã§ååãããã€ãä»ã¯åããªããªããŠããšããã°ãã°ããïŒãã®æç« ãæããæ°ã«æåŸã«ã¯åããªãç®æãåºãŠãããšæããã :(
åºæ¬çãªã€ã³ã¹ããŒã«æ¹æ³ã¯Installationãåç §ããã°ãããïŒããã ãã§ã¯åŸ®åŠã«èºããããªç®æã«ã€ããŠç°¡åã«èšèŒããïŒ
ãŸãïŒCaffeãPythonäžã§åããããã«Pythonã®ç§åŠç ç©¶é¢é£ã®ããã±ãŒãžãäžåŒæããå¿ èŠãããïŒãã®ã€ã³ã¹ããŒã«äœæ¥ãäžããè¡ããšé¢åã ãïŒAnacondaãšåŒã°ããç§åŠç ç©¶ç³»ããã±ãŒãžãå šéšæã£ãŠããããã±ãŒãžã䜿ããšäŸ¿å©ïŒã¢ã³ã€ã³ã¹ããŒã«ããã£ã¬ã¯ããªãåé€ããã ãã§ããã®ã§æ¥œïŒ
Download AnacondaããanacondaãããŠã³ããŒãïŒå®è¡æš©éãäžããŠã·ã§ã«ãå®è¡ïŒåŸã¯æµãã«ä»»ããŠé©åœã«çããã ãã§ããïŒæåŸã«~/.bashrcã®æ«å°Ÿã«ïŒ
export PATH=$HOME/anaconda/bin:$PATH
export LD_LIBRARY_PATH=$HOME/anaconda/lib:$LD_LIBRARY_PATHã远å ãïŒãã¹ãéã(å€åæåã®PATHã«é¢ããŠã¯æ¢ã«AnacondaåŽããããããã£ãŠãããŠããç)ïŒipythonãå®è¡ãïŒ
$ ipython
Python 2.7.8 |Anaconda 2.0.1 (64-bit)| (default, Jul 2 2014, 18:08:02)
Type "copyright", "credits" or "license" for more information.
IPython 2.1.0 -- An enhanced Interactive Python.
Anaconda is brought to you by Continuum Analytics.
Please check out: http://continuum.io/thanks and https://binstar.org
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]:ãšAnacondaåŽã®ipythonãåŒã³åºãããŠããããšã確èªïŒ
次ã«ïŒcaffeã§äœ¿çšããOpenCVã®ããã±ãŒãžãAnacondaçµç±ã§ã€ã³ã¹ããŒã«ãã(OpenCVã®ããã±ãŒãžããã¹ãŠAnacondaåŽãçšæããŠãããŠãã)ïŒapt/yumãšåæ§ã«ïŒanacondaã®ããã±ãŒãžç®¡çãœããã¯condaãéããŠå®è¡ããïŒ
$ conda update opencvã§OpenCVãã€ã³ã¹ããŒã«ïŒæ¬¡ã«ïŒCaffeã§äœ¿çšããProtocol Bufferã®Pythonãã€ã³ãã£ã³ã°ãpipçµç±ã§ã€ã³ã¹ããŒã«ãã(OpenCVçã®ã€ã³ã¹ããŒã«ãé¢åãªããã±ãŒãžã¯å€§äœAnacondaãçšæããŠãããŠããã®ã§condaã§ã€ã³ã¹ããŒã«ãããïŒããã§ãªãå Žåã¯Pythonã®ããã±ãŒãžç®¡çã·ã¹ãã ã§ããpipçµç±ã§ã€ã³ã¹ããŒã«ãã)ïŒ
$ pip install protobufã§Protocol Bufferãã€ã³ã¹ããŒã«ã§ããïŒ
åŸã¯LevelDBãBoostãªã©ïŒCaffeã®C++çšã©ã€ãã©ãªãaptçµç±ã§ã€ã³ã¹ããŒã«ãããïŒããã蟺ã¯InstallationèŠããšå€§äœåããã¯ãïŒã³ã³ãã€ã«æ¹æ³ãåæ§ïŒAnacondaã®å Žåã¯Anacondaçšã«Makefile.configãæžãæããã°è¯ãïŒ
Ubuntu 12.04ã®å Žåã¯åºæ¬çã«ãã®æµãã§ããããïŒUbuntu 14.04ã®å Žåã¯gcc-4.6ãåŒã³åºãããã«æç€ºçã«æžãæããå¿
èŠãããïŒããã蟺ã¯ç¢ºãGithubã«åã質åå
å®¹ãæµããŠããã¯ãïŒ
$ make runtestãå®è¡ããŠïŒç¹ã«ãšã©ãŒãåºãªããã°æ£åžžã«ãã«ããå®äºããŠããïŒ
次ã«ïŒPythonçšã®Caffeããã±ãŒãžããã«ãããïŒãã®ããã«ã¯$ make pycaffeãåŒã³åºããŠmakeãããå¿
èŠããïŒãŸãïŒPYTHONPATHç°å¢å€æ°ã«caffeã®Pythonãã£ã¬ã¯ããªã远å ããããšãå¿
èŠïŒPythonäžã§
>>> import caffeãšæã£ãŠãšã©ãŒã§ãªããã°å€§äžå€«ïŒProtocol bufferé¢ä¿ã®ãšã©ãŒåºãå Žåã¯å€åprotobufããã±ãŒãžãã€ã³ã¹ããŒã«ããŠããªãã ããªã®ã§ã€ã³ã¹ããŒã«ããïŒ
ãŸãã¯ããã«ïŒåçŽã«SIFT/BoFãšåæ§ã«ç»åããç¹åŸŽãã¯ãã«ãæœåºãããå Žåã®Caffeã®äœ¿ç𿹿³ã説æããïŒç¹åŸŽéã®åãåºãã¯ãããŸãã«2ã€ã®æ¹æ³ãããïŒ1ã€ãcaffe/build/tools/extract_features.binãåŒã³åºãæ¹æ³ã§ïŒãã1ã€ãPythonçµç±ã§ç¹åŸŽãã¯ãã«ãåãåºãæ¹æ³ïŒæ¥œãªã®ã¯åŸè
ïŒä»åã¯ãããäžã«å
¬éãããŠããImagenetã®åŠç¿ãã©ã¡ãŒã¿ã䜿çšããŠïŒPythonçµç±ã§ç¹åŸŽãã¯ãã«ãåãåºãæ¹æ³ã«ã€ããŠèª¬æããïŒ
caffe/examples/imagenet/ã«ç§»åãïŒ
$ ./get_caffe_reference_imagenet_model.shãå®è¡ïŒDropboxãã200MBäœã®åŠç¿ãã©ã¡ãŒã¿ãããŠã³ããŒãããã(caffe_reference_imagenet_model)ïŒããäžåºŠget_caffe_reference_imagenet_model.shãå®è¡ãããšããŠã³ããŒããã¡ã€ã«ãæ£ãããã©ãã確èªããããã®ãã§ãã¯ãµã ã®èšç®ãè¡ããããïŒäœæ
ãå
šç¶åããªãããšãããïŒãã®å Žåã¯ãã§ãã¯ãµã åã£ãŠããããŒãžã§ã³ãéããŸãã®ã§ïŒé£çµ¡ãããããé¡ãããããŸãïŒ
次ã«ïŒPythonäžããCaffeãåŒã³åºããŠç¹åŸŽãã¯ãã«ãåãåºãæ¹æ³ã«ã€ããŠèª¬æããïŒCaffeã®åé¡åšã®äœæã«ã¯ïŒ3ã€ã®ãã¡ã€ã«ãçšæããå¿
èŠãããïŒäžã€ã¯CNNãã©ã®ããã«æ§æãããŠããã®ãã衚ã.prototxtãã¡ã€ã«ïŒããäžã€ã¯ãã©ã¡ãŒã¿ã®å®æ
ãå«ãŸããmodelãã¡ã€ã«ïŒæåŸã«å¹³åç»åãå«ã.npyãã¡ã€ã«(Numpyã®è¡åãã¡ã€ã«ã¯ïŒäžè¬ã«æ¡åŒµå.npyãã€ããŠä¿åããããšãäžè¬ç)ïŒåé¡åšã®ã€ã³ã¹ã¿ã³ã¹ã¯æ¬¡ã®ãããªåœ¢ã§çæããïŒ
import caffe
import numpy as np
net_path = "caffe/examples/imagenet/imagenet_deploy.prototxt"
model_path = "caffe/examples/imagenet/caffe_reference_imagenet_model"
mean_path = "caffe/python/caffe/imagenet/ilsvrc_2012_mean.npy"
net = caffe.Classifier(
net_path, model_path, mean=np.load(mean_path),
channel_swap=(2, 1, 0), raw_scale=255,
image_dims=(256, 256), gpu=True)ILSVRC2012ã®åŠç¿ãã©ã¡ãŒã¿ã¯å
¥åããå¹³åç»åãåŒããŠããã®ã§ïŒãã®ããã®å¹³åç»åãèªã¿èŸŒãŸããå¿
èŠããïŒchannel_swapã¯ã©ã®ãããªé çªã§è²æ
å ±ãã¹ã¯ãããããã®ãã«ã€ããŠã®æå®(Caffeã®reference modelã¯è²æ
å ±ãRGBã§ãªãBGRãªãŒããŒã§æ±ãããïŒäœæ
BGRããšãããšïŒBGRãªãŒããŒã§ç»åãæ±ãOpenCVãå
éšã§äœ¿ã£ãŠãããã)ïŒraw_scaleã¯èªã¿èŸŒãŸããå
¥åç»åãã©ãäœã¹ã±ãŒã«ãããã«ã€ããŠã®æå®(詳现ã¯åŸè¿°)ïŒimage_dimsã¯èªã¿èŸŒãŸããå
¥åç»åãã©ã®è§£å床ã§ãªãµã€ãºãããã®æå®ïŒgpuãªãã·ã§ã³ã¯GPUã䜿ã£ãŠèšç®ãé«éåããããåŠã(10åäœé
ããªããïŒäœ¿ããããªãå Žåã¯Falseãæå®)ïŒ
ãªãïŒCaffeã®åé¡åšã¯2ã€ã®ã¢ãŒãTRAINãšTESTããã€ïŒç¹åŸŽãã¯ãã«ã®åãåºãã ãã§ããã°ïŒç¹ã«TRAINã¢ãŒããèæ
®ããå¿
èŠã¯ãªãïŒãŸãïŒcaffe.Classifierã®ã³ã³ã¹ãã©ã¯ã¿å
éšã§èªåçã«TESTã¢ãŒãã«èšå®ãããã®ã§ïŒæç€ºçã«net.set_phase_test()ãåŒã³åºãå¿
èŠããªãïŒ
次ã«ïŒç»åã®èªã¿èŸŒã¿ãšèå¥ïŒç¹åŸŽãã¯ãã«ã®æœåºã«ç§»ãïŒèå¥ã«ã¯net.predict()ã䜿çšããïŒç»åã¯è€æ°æå
¥ããããšãã§ããïŒè¿ãå€ã«ã¯ããããã®ã¯ã©ã¹ã®ç¢ºä¿¡åºŠã衚ããã¯ãã«ãç»åææ°åæ ŒçŽãããè¡åãè¿ãããïŒããªãã¡(n_images, n_classes)ïŒãŸãïŒç¹åŸŽãã¯ãã«ã®æœåºããããå Žåã¯ç¹ã«çç±ããªããã°oversample=Falseãæå®ããã®ãæãŸããïŒçç±ã¯åŸè¿°ïŒïŒç»åã®èªã¿èŸŒã¿ã«ã¯caffe.io.load_image()ã䜿çšããïŒããªãã¡ïŒ
image = caffe.io.load_image("cat.jpg")
pred = net.predict([image], oversample=False)ã§ããïŒç»åã®å®æ
ã¯RGBãªãŒããŒã®3éã®ãã³ãœã«(width, height, 3)ãå«ãŸããnumpy.ndarrayã§ããïŒç»åã®åãã£ãã«ã¯[0, 255]ã§ãªã[0, 1]ã«æ£èŠåãããŠããããšã«æ³šæïŒããã§CNNå
ã®ãã¹ãŠã®ã¬ã€ã€ã«ããããã®ç¹åŸŽéãæ ŒçŽãããïŒ
次ã«ïŒäžå±€ã®ã¬ã€ã€fc7ãã4096次å
ã®ç¹åŸŽãã¯ãã«ãåãåºãïŒfc7ã®ç¹åŸŽãã¯ãã«ã®åãåºãã¯æ¬¡ã®ããã«ããŠè¡ãïŒ
feature = net.blobs['fc7'].data
feature = feature.reshape(10, 4096)[0, :]dataã®å®æ
ã¯4éã®ãã³ãœã«(n_batches, n_channels, height, width)ã§ããïŒä»åã®å Žåã ãšããã容éã¯10åïŒfc7ã¯4096åã®ãŠããããæã£ãŠããã®ã§(10, 4096, 1, 1)ã§ããïŒãããæ°ã¯predictã§åŠçããç»åã®ããã容éã衚ãïŒå€ããšäžæ°ã«åŠçã§ããç»åã®ææ°ãå¢ããããã®åGPUã¡ã¢ãªãé£ãïŒãŸã1æ1æpredict()ãåŒã³åºãããå Žåã«ã¯äžå©ïŒimagenet_deploy.prototxtã§ã¯10ã«èšå®ãããŠããïŒããã(10, 4096)ã®è¡åã«çŽãäžçªåãã®ç¹åŸŽãã¯ãã«ã ãåãåºãããšã§ïŒ4096次å
ã®ãã¯ãã«ãåŸãïŒä»¥éã®åŠçãMatlabã§è¡ãããå Žåã¯scipy.io.savemat()ãåŒã³åºãïŒ.matãã¡ã€ã«ãä¿åããã®ãè¯ãïŒ
Classifier.predict()ã®oversampleã¯èå¥çµæãåäžãããããã®ãªãã·ã§ã³ã§ãã(ããã©ã«ãã¯True)ïŒçµè«ã端çã«è¿°ã¹ããšïŒããã¯Classifierå
ã®image_dimsãæç€ºçã«æå®ããªãéãèšç®ãéããªãã ãã§ã»ãšãã©æ§èœåäžã«ã¯è²¢ç®ããªãïŒãŸãç¹åŸŽãã¯ãã«ã ãåãåºãããã ãã®å Žåã¯ç¡é§ãªã®ã§Falseãæå®ãã¹ãã§ããïŒ
predict()ã®è©³çŽ°ãªæåãæ¬¡ã«ç€ºãïŒãŸãïŒpredict()ã¯å¯Ÿè±¡ã®ç»åãClassifier.image_dimsã®å€§ããã«ãªãµã€ãºããïŒæå®ãããŠããªãå Žåã¯.prototxtã§æå®ããcrop_sizeã®å€ã䜿çšãããïŒæ¬¡ã«ïŒoversampleãæå®ãããå ŽåïŒClassifierã¯å¯Ÿè±¡ã®ç»åã®äžäžå·Šå³4ç®æãšïŒäžå€®ã®1ç®æãåãåãïŒåãåãç»åã®å€§ããã¯ãã¹ãŠ(crop_size, crop_size)ã§ããïŒå ããŠïŒããããå·Šå³å転ãããç»åãäœãïŒåæ§ã«5ç®æåãæãïŒçµæãšããŠ10æã®(crop_size, crop_size)ã®ç»åãçæãããïŒoversampleãæå®ãããªãå Žåã¯äžå€®ã®1ç®æã ãã䜿çšãããïŒåŸã¯ãããã¹ã±ãŒã«å(raw_scale)ãããå¹³åç»ååŒãããããåŸã«CNNã®ãããã¯ãŒã¯ã«éãïŒåºåçµæãåŸãïŒoversampleãæå®ããå ŽåïŒãããã®çµæãå¹³åãããã¯ãã«ãè¿ãããïŒ
Caffeã®å¹³åç»åã®åãæ±ãã¯çµæ§é©åœïŒãŸãïŒå¹³åç»åã¯èªã¿èŸŒãŸããåŸïŒ(crop_size, crop_size)ã®å€§ããã«ãªãµã€ãºãããŠæ ŒçŽãããïŒpredict()ã¯ãã®å¹³åç»åãïŒ(crop_size, crop_size)ã§åãåãããç»åã«å¯ŸããŠåŒãïŒCNNã®ãããã¯ãŒã¯ã«éãïŒå
ã
ã®åŠç¿éçšïŒåŸè¿°ïŒãèãããšçµæ§å€§éæãªããšããã£ãŠããïŒãŸãïŒextract_features.binã¯ãŸãéã圢ã§å¹³åç»åãåãæ±ã£ãŠããã®ã§ïŒPythonã§æœåºããç¹åŸŽãã¯ãã«ãšextract_features.binã§åãåºããç¹åŸŽãã¯ãã«ã®å€ã¯ç°ãªãïŒè奿§èœã埮åŠã«å€ããïŒïŒ
äŸãšããŠïŒImagenetãã£ã¬ã¯ããªã«å«ãŸããç»åãã¹ãŠã®ç¹åŸŽãã¯ãã«ãæœåºãïŒãããLevelDBãšåŒã°ããKVSã«æ ŒçŽããã³ãŒãã瀺ã(äœæ
ãã®ãããªDBã䜿ãå¿
èŠãããã®ããšãããšïŒImagenetã®ãããªæ°çŸäžæãã¹ãŠã®ç¹åŸŽãã¯ãã«ãã¡ã¢ãªã«æ ŒçŽããããšã¯å°é£ãªãã)ïŒçŸåšïŒImagenetã®ãã£ã¬ã¯ããª/path/to/imagenet/trainå
ã«ã¯ã«ããŽãªæ¯ã®ãã£ã¬ã¯ããª1,000åãååšãïŒããããã®ãã£ã¬ã¯ããªã«ã¯ç»å1,300æãæ ŒçŽãããŠããïŒäžã®ãµã³ãã«ããã°ã©ã ã¯ããããèªã¿èŸŒã¿ïŒ4096次å
ã®floatåã®ç¹åŸŽãã¯ãã«ãæœåºãïŒç»åã®ãã¡ã€ã«åãKeyïŒãã®ç¹åŸŽãã¯ãã«ãValueãšããŠLevelDBå
ã«é æ¬¡æ ŒçŽããŠããïŒCaffeã®å¿çšäŸã®äžã€ãšããŠåèã«ããããïŒã¡ãªã¿ã«ïŒGTX Titan Blackã§è©Šãããšããå®è¡é床ã¯çŽ20-30 images/secïŒå€§äœ16æéäœãèŠããïŒ
# -*- coding: utf-8 -*-
import sys
import os
import logging
import numpy as np
import leveldb
import caffe
PROJ_ROOT = "/path/to/proj"
CAFFE_ROOT = "/path/to/caffe"
DATA_ROOT = "/path/to/imagenet/train"
LEVELDB_PATH = PROJ_ROOT + "/data/imagenet"
CAFFE_PROTO = CAFFE_ROOT + "/examples/imagenet/imagenet_deploy.prototxt"
CAFFE_MODEL = CAFFE_ROOT + "/examples/imagenet/caffe_reference_imagenet_model"
CAFFE_MEAN = CAFFE_ROOT + "/python/caffe/imagenet/ilsvrc_2012_mean.npy"
LAYERNAME = "fc7"
logging.basicConfig(
format="%(asctime)s [%(levelname)s] %(message)s",
level=logging.DEBUG)
logger = logging.getLogger(__name__)
def main():
def filter_by(db, filename):
ext = os.path.splitext(filename)[1].lower()
if ext not in [".jpeg", ".jpg", ".png"]:
return False
try:
db.Get(filename)
except KeyError:
return True
else:
return False
logger.info("load fundamental components...")
net = caffe.Classifier(
CAFFE_PROTO, CAFFE_MODEL,
mean=np.load(CAFFE_MEAN),
channel_swap=(2, 1, 0), raw_scale=255,
image_dims=(256, 256), gpu=True)
db = leveldb.LevelDB(LEVELDB_PATH)
n_batches = net.blobs[LAYERNAME].data.shape[0]
categories = os.listdir(DATA_ROOT)
logger.info("# of categories: {0}".format(len(categories)))
for i, category in enumerate(categories):
logger.info("processing category {0}/{1}...({2:.2%})".format(
i, len(categories), float(i)/len(categories)))
category_path = os.path.join(DATA_ROOT, category)
filenames = [f for f in os.listdir(category_path) if filter_by(db, f)]
for s_begin in xrange(0, len(filenames), n_batches):
s_end = s_begin + n_batches
queue_filename = filenames[s_begin:s_end]
queue_data = [caffe.io.load_image(
os.path.join(category_path, f)) for f in queue_filename]
net.predict(queue_data, oversample=False)
blobs = net.blobs[LAYERNAME].data
n_queues = len(queue_data)
n_dim = np.prod(blobs.shape[1:])
features = blobs.reshape(n_batches, n_dim)
batch = leveldb.WriteBatch()
for j in xrange(n_queues):
batch.Put(queue_filename[j], features[j, :].tostring())
db.Write(batch, sync=True)
return 0
if __name__ == "__main__":
sys.exit(main())次ã«ïŒå€§éã®ç»åãå©çšããŠCNNãåŠç¿ããããã®æ¹æ³ã«ã€ããŠè¿°ã¹ãïŒCaffeãå©çšããåŠç¿ã¯æ¬¡ã®æé ã§è¡ã: (1)ç»åãã¡ã€ã«åãšã«ããŽãªIDã®ãã¢ããLevelDBã®ããŒã¿ã»ãããäœæãã (2)å¹³åç»åãäœæãã (3)LevelDBã®ããŒã¿ã»ãããçšããŠCNNãåŠç¿ãã
ããŒã¿ã»ããã®äœæã¯æ¬¡ã®ããã«ããŠè¡ãïŒåãã«ïŒå¯Ÿè±¡ã®ç»åãšãã®ã«ããŽãªIDã®ãã¢ãå«ãŸããããã¹ããã¡ã€ã«ãäœæããïŒäŸã次ã«ç€ºãïŒ
42813a4366850c30e2dcdccf7f2c634e2f44d947.jpg 4
76a62e47bf96d0695f123885442ebf543fecfa3c.jpg 127
85c35b0935d370cea801ad9fdcbe55f0d1b33dee.jpg 115
...
ããã¹ããã¡ã€ã«ã¯train, validation, testã®äžçš®é¡ãçšæããïŒtrainã¯åŠç¿ïŒvalidationã¯åŠç¿çµæã®æ€èšŒïŒtestã¯è奿§èœã®ãã¹ãã«çšããïŒåŠç¿çšã®ãã£ã¬ã¯ããªãäœãïŒãã®äžã«ããããtrain.txt, val.txt, test.txtãšããŠä¿åããŠããããšãæãŸããïŒ
次ã«ïŒ/caffe/build/tools/convert_imageset.binãåŒã³åºãïŒç»åãLevelDBã®ããŒã¿ããŒã¹å
ã«æ ŒçŽããŠããïŒåŒã³åºãäŸã次ã«ç€ºã:
GLOG_logtostderr=1 $HOME/caffe/build/tools/convert_imageset.bin \
/path/to/image/dir/ \
/path/to/proj/train.txt \
train_leveldb 1 leveldb
256 256ç°å¢å€æ°GLOG_logtostderrã«1ãæå®ããããšã§ïŒãã°ããã¹ãŠstderrã«åºãããšãã§ãã(GLOGã®æ©èœã®äžã€)ïŒåŒæ°ã®æå³ã¯æ¬¡ã®éã:
- ç»åãã¡ã€ã«ã®å Žæ(åŸãã®"/"ãå¿ããªãããš)
- ããã¹ããã¡ã€ã«ã®å Žæ
- LevelDBã®åºåå
- æ ŒçŽããç»åãã¡ã€ã«ã®é åºãã·ã£ããã«ãããåŠã(ããã¹ããã¡ã€ã«ã®æ£è§£IDããœãŒããããŠããå Žåã¯1ãæå®ïŒæ¬äŒŒä¹±æ°ã®ã·ãŒãã®é¢ä¿ã§ïŒã·ã£ããã«ãããé åºã¯ åžžã«åºå® )ïŒ
- ããŒã¿ããŒã¹ã®ããã¯ãšã³ãã«äœã䜿çšãããïŒ
leveldbã®ä»ã«ãlmdb(LevelDBããã髿©èœãªKVS)ãæå®ããããšãå¯èœïŒ -
- ãªãµã€ãºããç»åã®çžŠãšæšªã®ãµã€ãº(ã¢ã¹ãã¯ãæ¯ã¯ç¡èŠïŒãã¹ãŠ0ãæå®ããå ŽåïŒãã¹ãŠã®ç»åãäºãåãè§£å床ã«ãªãµã€ãºãããŠãããšå€æããªãµã€ãºãè¡ããªãïŒçžŠãšæšªã®ãµã€ãºã¯åãã§ãªããŠãæ§ããªããïŒCaffeã®ä»æ§äžïŒãã¹ãŠã®ç»åã®è§£å床ã¯åãã§ãªããã°ãªããªãããšã«æ³šæ)ïŒ
詳现ãªäŸã¯/caffe/examples/imagenet/create_imagenet.shãåç
§(å®ã¯è¥å¹²å€ãã®ã§ïŒãµã³ãã«ãã®ãŸãŸã§ã¯åããªãïŒ)ïŒ
ãŸãïŒLevelDBã«æ ŒçŽãããããŒã¿ã®å®æ
ã瀺ãïŒkeyã¯çªå·ã®æ¥é èŸãçãããã¡ã€ã«åïŒvalueã¯/caffe/src/caffe/proto/caffe.protoã§æå®ãããæ§é äœDatumãProtocol Bufferã§ã·ãªã¢ã©ã€ãºåããæåå(èšãæãããšïŒç»åããŒã¿ãšã©ãã«ã®ãã¢ãå«ãæåå)ïŒããèªåã§LevelDBã®ããŒã¿ã»ãããäœãããå Žåã«ã¯ïŒkeyãšvalueããã®ããã«æå®ããŠLevelDBã«çªã£èŸŒãã§ãããã ãã§ããïŒ
次ã«ïŒtrainããŒã¿ã»ããããåŠç¿ãè¡ãããã®å¹³åç»åãäœæããïŒå¹³åç»åã¯/caffe/build/tools/compute_image_mean.binããäœãããšãã§ããïŒåŒã³åºãäŸã次ã«ç€ºãïŒ
$HOME/caffe/build/tools/compute_image_mean.bin /path/to/train_leveldb /path/to/meanfile.binaryproto第äžåŒæ°ã«trainããŒã¿ã»ããã®å ŽæïŒç¬¬äºåŒæ°ã«å¹³åç»åã®åºåå
ãæå®ãã(æ¡åŒµåã¯æ
£ç¿çã«.binaryprotoãçšãã)ïŒ.binaryprotoã®å®æ
ã¯/caffe/src/caffe/proto/caffe.protoã§æå®ãããæ§é äœBlobProtoãã·ãªã¢ã©ã€ãºåãããã®ïŒããªãã¡ïŒ.binaryprotoãPythonäžããèªã¿åºãããã«ããããã«ã¯ïŒæ¬¡ã®æé ã§å€æããã°è¯ãïŒ
import caffe
from caffe.io import blobproto_to_array
from caffe.proto import caffe_pb2
blob = caffe_pb2.BlobProto()
with open("/path/to/meanfile.binaryproto", "rb") as fp:
blob.ParseFromString(fp.read())
numpy_array = blobproto_to_array(blob)次ã«ïŒtrainåã³validationã«äœ¿ãïŒCNNã®ã¬ã€ã€æ§æã衚ãããã©ã¡ãŒã¿ãã¡ã€ã«ãäœãïŒäžå°ã¯/caffe/examples/imagenet/imagenet_train_val.prototxtã«ããã®ã§ïŒããããããžã§ã¯ããã£ã¬ã¯ããªã«ã³ããŒããã®ãè¯ãïŒå€ããªããã°ãªããªãã®ã¯æ¬¡ã®ç®æ:
data/data_param/source: çæããããŒã¿ã»ããã®å Žæãæå®data/data_param/mean_file: çæããå¹³åç»åã®å Žæãæå®data/data_param/batch_size: ããããµã€ãºãæå®ïŒããã©ã«ãã®256ã¯å€§ããããŠå€åã¡ã¢ãªäžè¶³ã§èœã¡ãïŒ128ã96ããããæå®ããããšïŒfc8/inner_product_param/num_output: çŸåšè§£ãããåé¡ã®ã«ããŽãªæ°ãæå®
次ã«ïŒ/caffe/examples/imagenet/imagenet_solver.prototxtãåæ§ã«ãããžã§ã¯ããã£ã¬ã¯ããªã«ã³ããŒãïŒæ¬¡ã®ç®æãé©åœã«å€æŽãã:
net: CNNã®ã¬ã€ã€æ§æã衚ãããã©ã¡ãŒã¿ãã¡ã€ã«ã®å ŽæïŒåãã£ã¬ã¯ããªã«ãã£ãŠååå€ããŠãªããã°ãã®ãŸãŸã§è¯ãsnapshot_prefix: ã¹ãããã·ã§ãããã¡ã€ã«ã®æ¥é èŸïŒç¹ã«æ°ã«ãªããªããã°ãã®ãŸãŸã§è¯ã
ãã©ã¡ãŒã¿ãã¡ã€ã«ã«ã¯ïŒCNNã®åã¬ã€ã€ã衚ãlayersãçŸ
åããŠããïŒlayersã¯åºæã®åånameãšãã®å
·äœçãªçš®é¡typeãæã€ïŒCaffeã®layersã¯è«æäžã§æžãããã¬ã€ã€ãšã¯å°ã
ç°ãªãïŒããã åŠçåäœ ãšãã£ãæå³åãã匷ãïŒäŸãã°ïŒå
ç©(ãããã¯ç³èŸŒã¿)ãåã£ãåŸã«ReLUã§éç·åœ¢åŠçãè¡ãå ŽåïŒCaffeã¯2ã€ã®ã¬ã€ã€INNER_PRODUCT(or CONVOLUTION)ãšRELUã«åããŠèšè¿°ããïŒ
ã¬ã€ã€ã®ç¹ããã衚ããã©ã¡ãŒã¿ãbottomãštopã§ããïŒããã¯ã©ã¡ãããšèšããšinputãšoutputã§èããã»ããçè§£ããããïŒãœã«ããŒã¯ãã¡ã€ã«ã«èšè¿°ãããé çªã§ïŒåã¬ã€ã€ã«å¯ŸãForward()颿°ãå®è¡ãã(åŠç¿ã®å Žåã¯éé åºã§Backward()ãå®è¡ãã)ïŒbottomãštopã¯è€æ°ãã£ãŠãè¯ãïŒäŸãã°ïŒè€æ°ã®ã¬ã€ã€ãç¹ããCONCATã¬ã€ã€ã¯è€æ°åã®bottomãæã€ïŒbottomãštopã«æå®ããååã¯nameãšç°ãªã£ãŠããŠãè¯ãïŒäŸãã°ïŒDATAã¬ã€ã€ã¯topã«ïŒnameã«ã¯ç¡ãæ°ããåålabelãæå®ããŠããïŒ
CNNã¯2ã€ã®ã¢ãŒãTRAINãšTESTãæã€ïŒincludeãæå®ããå ŽåïŒå¯Ÿè±¡ã®ã¢ãŒãã«ãªã£ãå Žåã«ã ããã®ã¬ã€ã€ãCNNå
ã«å«ãŸããïŒ
次ã«ïŒãã©ã¡ãŒã¿ãã¡ã€ã«ãšããŒã¿ã»ããããCNNãåŠç¿ããïŒCNNã®åŠç¿ã«ã¯caffe/build/tools/caffeã䜿ãïŒå
·äœçã«ã¯ïŒä»¥äžã®ã³ãã³ããçšããŠåŠç¿ãè¡ãïŒ
$HOME/caffe/build/tools/caffe train --solver=/path/to/imagenet_solver.prototxtCaffeã¯TRAINã¢ãŒããšTESTã¢ãŒãã亀äºã«è¡ãïŒTRAINã¯ç»åãããã©ã¡ãŒã¿ãæŽæ°ããã¢ãŒãïŒTESTã¯validationããŒã¿ã»ããããçŸåšã®å€§ãŸããªç²ŸåºŠãå€å®ããã¢ãŒãã§ïŒå¹³åæå€±ãšç²ŸåºŠã衚瀺ãããïŒ
GTX Titanã䜿ã£ãå Žåã®åŠç¿ã¯å€§äœ3-5æ¥ãèŠããïŒæå®ãããååŸ©åæ°ããš(ããã©ã«ãã¯10,000å)ã«Caffeã¯ã¹ãããã·ã§ãããåãïŒã¹ãããã·ã§ããã«ã¯2çš®é¡ååšãïŒ.solverstateãã€ããŠãããã¡ã€ã«ãšã€ããŠããªããã¡ã€ã«ã®äž¡æ¹ãçæãããïŒåè
ã¯åŠç¿çãªã©ã®ç¶æ
ãå«ãŸãããã¡ã€ã«ã§ïŒåŠç¿ãåéããå Žåã«çšããïŒåŸè
ã¯CNNã®ãã©ã¡ãŒã¿ã ããå«ãŸãããã¡ã€ã«ã§ïŒPythonçµç±ã®åŒã³åºãã®éã«çšããïŒåéã®æ¹æ³ã¯åè¿°ã®ã³ãã³ãã«ïŒ--snapshotãªãã·ã§ã³ãå«ããã ãã§ãã:
$HOME/caffe/build/tools/caffe train --solver=/path/to/imagenet_solver.prototxt \
--snapshot=/path/to/caffe_imagenet_train_10000.solverstateã¯ããã«ïŒCaffeã¯ããŒã¿ããŒã¹ãã察象ã®ãã¡ã€ã«ããããæ°åã ãèªã¿èŸŒãïŒTRAINã¢ãŒãã®å ŽåïŒCaffeã¯ç»åããå¹³åç»åãåŒããåŸã«ïŒcrop_sizeã§æå®ãã倧ããã®ç»åãã©ã³ãã ã«åãæãïŒãŸãïŒmirror=trueã®å Žå50%ã®ç¢ºçã§å·Šå³å転ããïŒ[0, 1]ã«æ£èŠåãããªã©ã®åŠçã¯è¡ãªã£ãŠããªãïŒTESTã¢ãŒãã®å ŽåïŒCaffeã¯äžå€®éšåã ããåãæãå転ã¯è¡ããªãïŒ
CNNã®åŠç¿ã¯éåžžã«æéã®ããããã®ã§ãããã€å€§éã®ç»åãå¿ èŠãšãããïŒæ¢åã®ãã©ã¡ãŒã¿ãå¥ã®ã¿ã¹ã¯ã§ã䜿ããŸãã転移åŠç¿ãè¡ãããšã§ïŒå¹ççãã€é«éã«åŠç¿ãè¡ããïŒæ¬ç¯ã§ã¯ILSVRC2012ã§äºãåŠç¿ããããã©ã¡ãŒã¿ãå©çšããCNNã®è»¢ç§»åŠç¿ã«ã€ããŠèª¬æããïŒ
Caffeã®ããŒã¿ã»ããã®äœæã¯åè¿°ãåç
§ïŒå¹³åç»åã«é¢ããŠã¯æ¢åã®imagenet_mean.binaryprotoã䜿ãã°ããã®ã§çç¥ïŒ
ãã©ã¡ãŒã¿ãã¡ã€ã«ã«é¢ããŠã¯åè¿°ã®åŠç¿ã®å€æŽç®æã«å ãïŒããå€ãã®ç®æã倿Žããå¿
èŠãããïŒcaffeã¯ãŸãdeployã«äœ¿çšããã¢ãã«ãã¡ã€ã«ãšCNNã®ãã©ã¡ãŒã¿ãã¡ã€ã«ã®äž¡æ¹ãèªã¿èŸŒã¿ïŒãã¹ãŠã®ã¬ã€ã€ãšã¢ãã«ãã¡ã€ã«å
ã®ã¬ã€ã€ãç
§ããåããïŒã¬ã€ã€åãåäžã§ããã°ãã©ã¡ãŒã¿ã転移ãããåŠçãè¡ãïŒããªãã¡ïŒè»¢ç§»ãããããªãäžäœã®ãã©ã¡ãŒã¿ã®ååã倿Žããããšã§ïŒè»¢ç§»ãé²ãå¿
èŠãããïŒåãã«ïŒäžããåŠç¿ããããã¬ã€ã€ã®ååã倿ŽããïŒããã¯imagenet_train_val.prototxtå
ã®ã¬ã€ã€åãäœãå¥ã®ååã«å€æŽãã(e.g. fc7 -> fc7mod)ã ãã§ããïŒ
次ã«ïŒè»¢ç§»ãããã¬ã€ã€å
ã®ãã©ã¡ãŒã¿ã¯å€æŽãããªããã調æŽããïŒããã¯åŠç¿çã0ã«ããã ãã§ããïŒããªãã¡ïŒè»¢ç§»ã¬ã€ã€ã®blobs_lrãªãã³ã«weight_decayã0ã«å€æŽããïŒ
転移åŠç¿ã®å ŽåïŒãã®ãŸãŸã®åŠç¿çã§åŠç¿ãè¡ã£ãå Žåãã©ã¡ãŒã¿ãçºæ£ããŠããŸãïŒãã®ããïŒimagenet_solver.prototxtã®base_lrã0.01ãã0.001ã«å€æŽããïŒããããã§ãçºæ£ããå Žåã¯1/2ãã€äžããŠããã°ããïŒ
æåŸã«ïŒcaffeãåŒã³åºããŠCNNã®è»¢ç§»åŠç¿ãéå§ããïŒãã©ã¡ãŒã¿ã®è»¢ç§»ã¯--weightsãªãã·ã§ã³ãä»äžããïŒããªãã¡:
$HOME/caffe/build/tools/caffe train --solver=/path/to/imagenet_solver.prototxt \
--weights=$HOME/caffe/examples/caffe_reference_imagenet_modelçã®ãããªåœ¢ã§åŒã³åºããŠããã°ããïŒ
æåŸã«ïŒãã£ãŠã¯ããªããã®ã®ã§ãããããããªãæ©èœã«ã€ããŠèšåããïŒ
CONCATã¬ã€ã€ã®ååšãããã®ã§ïŒå
¥å(DATAã¬ã€ã€)ã2ã€ä»¥äžæãããããšã¯ã§ããïŒãã ïŒãã®å ŽåPythonã®ãã€ãã£ããµããŒãã¯ãªãã®ã§ïŒé©å®é 匵ãå¿
èŠãããïŒ
ã§ããïŒå
¥åãšåºåã®ããŒã¿ã»ããã2ã€çšæãïŒããããDATAã¬ã€ã€ã§èªã¿èŸŒãŸãïŒLOSSã¬ã€ã€ã®bottomã®ãã¡äžã€ãåºåçšã®DATAã¬ã€ã€ã«æå®ããïŒ
埮åŠïŒILSVRC2014ã§ã¯éæ¹é ã§Multiple GPUã«å¯Ÿå¿ããã°ã«ãŒããããããããïŒå°ãªããšãçŸç¶ã®Caffeã§ã¯ãµããŒããããŠããªãïŒ
åèã«ãããŠããã ããŠãããŸãã
èªåã¯ç»åããã®ç¹åŸŽéæœåºãããããšæããimagenetã®åŠç¿ãã©ã¡ãŒã¿ãŒãããŠã³ããŒãããããšããã®ã§ãããæå®ã®ãã£ã¬ã¯ããªã§_caffe_reference_imagenet_model.shãèŠã€ãããå°ã£ãŠããŸããäœããåç¥ã ã£ããããŸããã§ããããïŒ