ãã®è¨äºã¯@naoya_tãã主å¬ã®機械学習アドベントカレンダーã®12æ25æ¥åã®è¨äºã§ããããã¦æ¨æ¥ã®コンピュータビジョンアドベントカレンダーãScikit-LearnでSparse CodingとDictionary Learning -理論編-ãã®ç¶ãã§ãã
æ©æ¢°å¦ç¿ACã®ãµã¤ãããæ¥ãæ¹ã«ç°¡åã«èªå·±ç´¹ä»ãããã¨ãç§ã¯ã³ã³ãã¥ã¼ã¿ãã¸ã§ã³ãç»åå¦çã®åéã§ããªã¼ã©ã³ã¹ããã¦ããid:takminã¨è¨ãã¾ãããããã£ã¼ã«ã¯ここã«ã¾ã¨ã¾ã£ã¦ã¾ãã
ããã§ã¯scikit-Learnã使ã£ã¦Sparse Codingã¨Dictionary Learningãå®è£ ãã¦ã¿ããã¨æãã¾ããSparse Codingã¨Dictionary Learningã«ã¤ãã¦ç¥ããªãæ¹ã¯ãこちらの記事ãå ã«èªã¾ãããã¨ããå§ããã¾ãã
scikit-learnï¼Pythonãã¼ã¹ã®æ©æ¢°å¦ç¿ã©ã¤ãã©ãªï¼ã§Sparse Codingã¨Dictionary Learningã使ç¨ããã«ããã£ã¦ãåèã«ãªããµã¤ãã¯ä»¥ä¸ã®éãã§ãã
scikit-learnã§ã®Sparse Codingã¨Dictionary Learningæ¦èª¬
http://scikit-learn.org/stable/modules/decomposition.html#dictionary-learning
SparseCoderã¯ã©ã¹è§£èª¬
http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.SparseCoder.html
Sparse Codingãµã³ãã«
http://scikit-learn.org/stable/auto_examples/decomposition/plot_sparse_coding.html
DictionaryLearningã¯ã©ã¹è§£èª¬
http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.DictionaryLearning.html
Dictionary Learningãµã³ãã«
http://scikit-learn.org/stable/auto_examples/decomposition/plot_image_denoising.html
ããã§ã¯ã以ä¸ã®ãããªã°ã¬ã¼ã¹ã±ã¼ã«ã®ç»åã¨ãã¤ãºãå«ãã ç»åããã®ç»ååæ§æã«ææ¦ãããã¨æãã¾ãã
è¾æ¸ã®å¦ç¿
è¾æ¸ã¯8x8ãã¯ã»ã«ã®ç»åãããç´ï¼ä¸æããä½æãã¾ããã
ãããã®ç»åãããã¯Caltech256ã¨ããé¡ãé£è¡æ©ãç¬ãªã©ã256ã«ãã´ãªã®ç©ä½ã®ç»åãéãããç»åèªèç¨ã®ãã¼ã¿ã»ããããã©ã³ãã ã«åãåã£ã¦ä½¿ç¨ãã¾ãããåãåã£ãç»åã®ãµã³ãã«ã¯ä»¥ä¸ã®æ§ãªæãã§ãã
å°ãä¸ã®ãããã¯ã«ã©ã¼ã§ãããã°ã¬ã¼ã¹ã±ã¼ã«ã«ãªããã¦ããå¦ç¿ãè¡ãã¾ããã
è¾æ¸ã®å¦ç¿ã«ã¯sklearn.decomposition.DictionaryLearningã¯ã©ã¹ã使ç¨ãã¾ããããï¼ä¸æã®ç»åãå¦ç¿ããã®ã¯é常ã«æéãããããããããã§ã¯sklearn.decomposition.MiniBatchDictionaryLearningã¨ããç°¡æçã®ã¯ã©ã¹ã使ç¨ãã¾ããããã®ã¯ã©ã¹ã¯å¦ç¿é度ã¯DictionaryLearningã¯ã©ã¹ãããæ©ãã精度ã¯ããå£ãã¨ã®ãã¨ã
以ä¸ãè¾æ¸ä½æã®ãµã³ãã«ã³ã¼ãã«ãªãã¾ãã
import Image import ImageOps import numpy as np from time import time from sklearn.decomposition import MiniBatchDictionaryLearning #ç»åãªã¹ãèªã¿è¾¼ã¿ def ImageListFile2Array(filename): imgArray = None image_list = open(filename) for image_file in image_list: #æ¹è¡ãåé¤ image_file = image_file.rstrip() print image_file #ç»åãèªã¿è¾¼ã¿ im = Image.open(image_file) #ã°ã¬ã¼ã¹ã±ã¼ã«å¤æ gray_im = ImageOps.grayscale(im) data = np.asarray(gray_im) data = data.reshape(1,data.size) if imgArray is None: imgArray = data else: imgArray = np.vstack(ã(imgArray, data)ã) return imgArray #ç»åãããã®ãµã¤ãº patch_size = (8,8) #åºåºã®æ° num_basis = 100 #ç»åãªã¹ãèªã¿è¾¼ã¿ imgArray = ImageListFile2Array('patchlist.txt') # è¾æ¸ã¯ã©ã¹ã®åæå print 'Learning the dictionary... ' t0 = time() dico = MiniBatchDictionaryLearning(n_atoms=num_basis, alpha=1.0, transform_algorithm = 'lasso_lars', transform_alpha=1.0, fit_algorithm = 'lars', n_iter=500) #å¹³åã0ãæ¨æºåå·®ã1ã«ãã(ç½è²å) M = np.mean(imgArray, axis = 0)[numpy.newaxis,:] whiteArray = imgArray - M whiteArray /= np.std(whiteArray, axis = 0) #è¾æ¸ãè¨ç® V = dico.fit(whiteArray).components_ #å¦çæéãåºå dt = time() - t0 print 'done in %.2fs.' % dt #è¾æ¸ãä¿å np.save('Dictionaries.npy', V)
ä¸ã®ã³ã¼ãã§ã¯ããããç»åãã¡ã¤ã«ãã¹ãæ¹è¡ã§åºåã£ãããã¹ããã¡ã¤ã«(patchlist.txt)ãäºåã«ç¨æãã¦ããããããèªã¿è¾¼ãã§è¾æ¸ã®ä½æãè¡ãªã£ã¦ãã¾ãã
MiniBatchDictionaryLearning()ã§ã¤ã³ã¹ã¿ã³ã¹ãä½æããéã«ãä½æããåºåºã®æ°ï¼n_atomsï¼ãè¾æ¸ã®ã¢ãããã¼ããSparse Codingæããããã®æé©åã¢ã«ã´ãªãºã (fit_algorithmãtransform_algorithm)ããã³ãã®ãã©ã¡ã¼ã¿(alpha, transform_alpha, etc)ãæå®ã§ãã¾ããããã§ã¯åºåºã®æ°ã100ã¨ãã¦ãã¾ãã
ä¸è¨ã®ã³ã¼ãã§çæããè¾æ¸ãå¯è¦åããã®ããä¸ã®ç»åã«ãªãã¾ãã
ä½è«ã§ãããã©ããã§Dictionary Learningã§å¦ç¿ããåºåºã¯ç¬ç«æååæ(ICA)ã§åå¾ããåºåºã¨ä¼¼ããã®ãå¾ããããã¨èãããã¨ããã£ãã®ã§ãå®éã«è©¦ãã¦ã¿ã¾ãããICAã§ã®åºåºã®æ±ãæ¹ã¯こちらãåèã«ãã¦ä¸ããã
ãã¼ãããã¾ãä¼¼ã¦ãªãã§ããï¼ç¬ï¼ãã¾ããICAã¨Dictionary Learningã§ã¯ç®çã¨ããã¨ãããéãã®ã§å½ç¶ã®çµæãªã®ããããã¾ãããã
ICAã®æ¹ãå°ããå¨æ³¢æ°ã®åºåºãåã£ã¦ããããã«è¦ãã¾ãã
Sparse Codingã«ããç»åã®åæ§æ
ã§ã¯ç¶ãã¦ãSparse Codingã«ããç»åã®åæ§æã«ãã£ã¬ã³ã¸ãã¾ãã
import Image import ImageOps import numpy as np from time import time from sklearn.decomposition import SparseCoder #ã°ã¬ã¼ã¹ã±ã¼ã«ã®é åãRGBã«å¤æ def GrayArray2RGB(gray_array): gray_shape = gray_array.shape rgb_data = np.zeros*1 im.save(dst_file, 'PNG') print 'save image as ' + dst_file
以ä¸ã®éãSparseCoder()ã§ãã©ã¡ã¼ã¿ãæå®ãã¦ã¤ã³ã¹ã¿ã³ã¹ãçæããtransform()é¢æ°ã§ã¹ãã¼ã¹ãªåºåºã®ä¿æ°ãæ±ãã¾ããä¸ã®ä¾ã§ã¯Orthogonal Matching Pursuit(OMP)ã¢ã«ã´ãªãºã ãç¨ãã¦ã10ã¾ãã¯30åã®åºåºã¨ãã®ä¿æ°ãæ±ãã¦ãã¾ãã
çµæã¯ãããªæãã§ãã
ãã¤ãºç¡ãï¼L0ãã«ã ï¼10, 30ï¼
ãã¤ãºæãï¼L0ãã«ã ï¼10, 30ï¼
å½ç¶ã§ãããL0ãã«ã ã®æ°ï¼åºåºã®æ°ï¼ãå¢ãããæ¹ãåæ§æã®ç²¾åº¦ã¯é«ãã§ããããã¤ãºã®å½±é¿ãåãããããã¨ããããã¾ãã
次ã«ãå¦ç¿ãè¡ããã«ã©ã³ãã ã«çæããè¾æ¸ãå ã«ãåæ§æãè¡ãªã£ã¦ã¿ã¾ããã
ãã¤ãºç¡ãï¼L0ãã«ã ï¼10, 30ï¼
ãã¤ãºæãï¼L0ãã«ã ï¼10, 30ï¼
ã©ã³ãã ãªè¾æ¸ã§ååã¿ãããªè©±ãèããæ°ãããã®ã§ããããã®çµæãè¦ãéãè¾æ¸ãå¦ç¿ãããæ¹ãåæ§æã®ç²¾åº¦çã«ããã¤ãºã®å¼·ãçã«ãè¯ãã¿ããã§ãã
ææ³
ã¨ããããã§çè«ç·¨ã¨å®è·µç·¨ã®ï¼åã«åãã¦ãscikit-learnã§Sparse Codingã¨Dictionary Learningãå®è£
ãã¾ãããã©ããè¦è½ã¨ãã¦ããç¹ãã³ã¡ã³ããªã©ããã¾ãããããã²å¾¡ææä¸ããã
ä»åã¯ç°¡åã«è©¦ãã¦ä½¿ãæ¹ã確èªããç¨åº¦ã§ãããè¾æ¸æ°ã¨èª¤å·®ã®é¢ä¿ãã©ããªæé©åã¢ã«ã´ãªãºã ãé¸ã¶ããªã©è²ã
ã¨èª¿æ´ã®ä»æ¹ãããããã ã¨æãã¾ããã
*1:gray_shape[0], gray_shape[1], 3), dtype=gray_array.dtype) for c in range(3): rgb_data[:,:,c] = gray_array[:,:,0] return rgb_data #復å ããç»å src_file = 'lena_noise.png' #ä¿åããç»å dst_file = 'recon_img.png' #ç»åãããã®ãµã¤ãº patch_size = (8,8) #ä½æããè¾æ¸ããã¼ã V = np.load('Dictionaries.npy') #ç»åãèªã¿è¾¼ã¿ im = Image.open(src_file) #ã°ã¬ã¼ã¹ã±ã¼ã«å¤æ gray_im = ImageOps.grayscale(im) #åºåç»åãåæå dst_array = np.zeros( (gray_im.size[1], gray_im.size[0]) ) #ç»åãpatch_sizeã§åå²ãã¦å¦ç w = gray_im.size[0] - patch_size[0] h = gray_im.size[1] - patch_size[1] y = 0 while y <= h: x = 0 while x <= w: #ããããµã¤ãºã®é åãåãåã box = (x,y,x+patch_size[0],y+patch_size[1]) crop_im = gray_im.crop(box) #arrayã«æ ¼ç´ data = np.asarray(crop_im) data = data.reshape(1,data.size) #Sparse Coding coder = SparseCoder(dictionary=V, transform_algorithm='omp', transform_n_nonzero_coefs=10) u = coder.transform(data) #ä¿¡å·ã復å s = np.dot(u, V) #復å ããç»åãã³ãã¼ s = s.reshape(patch_size[1],patch_size[0]) dst_array[y:y+patch_size[1], x:x+patch_size[0]] = s x+=patch_size[0] y+=patch_size[1] #åæ§æããç»åãä¿å dst_array = dst_array.reshape(gray_im.size[1],gray_im.size[0], 1) rgb_data = GrayArray2RGB(dst_array) im = Image.fromarray(np.uint8(rgb_data