PQNNSwithADC.m 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. function [Performances, normCCost, iXMinDist] = PQNNSwithADC( kk, mm, nRecall, flagVec)
  2. %clear all
  3. close all
  4. clc
  5. addpath('../Functions');
  6. addpath('./Functions');
  7. addpath('./Functions/Yael Library');
  8. % kk=100; % Number of Centroids for each set
  9. % mm=16; % Number of Centroid Sets to take into account
  10. % kCent=kk^mm; % Total cardinality of search space
  11. % nRecall=1; % Number of Recalls
  12. imgSz=784; % Image Descriptor size
  13. subImgSz=imgSz/mm; % Size of sub images to analyze
  14. %Nlearn=6e4; % Number of pictures learn set
  15. Ntrain=6e4; % Number of pictures train set
  16. Ntests=1e4; % Number of pictures test set
  17. PQCentCompon=flagVec(1); % flag to activate Centroids Computation
  18. Quantizationon=flagVec(2); % flag to activate Data Sub Quantization Indices
  19. ADCCompon=flagVec(3); % flag to activate ADC Computations
  20. dispPQCenton=flagVec(4); % flag to activate Centroids Displayt
  21. justGetResultson=flagVec(5);% flag to just get results from stored data
  22. if(~justGetResultson)
  23. %% Computing/Loading PQ SubCentroids
  24. ndots=10;
  25. str2print='';
  26. ll=10;
  27. while mm/ll>1
  28. ndots=ndots-1;
  29. ll=ll*10;
  30. end
  31. ll=10;
  32. while kk/ll>1
  33. ndots=ndots-1;
  34. ll=ll*10;
  35. end
  36. for ll=0:ndots
  37. str2print=strcat(str2print,'.');
  38. end
  39. %% Reading Binary Learning Data Set
  40. fprintf('Loading Learning Data Set ...................... ');
  41. % TSetMat=fvecs_read('../Data/sift/sift_learn.fvecs');
  42. fileOffset = 16; % bytes of file offset
  43. fileID = fopen('../Data/train-images.idx3-ubyte');
  44. XSetVec = fread(fileID,imgSz*Ntrain+fileOffset,'uint8');
  45. XSetVec = XSetVec(fileOffset+1:end);
  46. XSetMat = zeros(imgSz,Ntrain);
  47. for jj=1:Ntrain
  48. XSetMat(:,jj)=XSetVec((jj-1)*imgSz+1:jj*imgSz);
  49. end
  50. fclose(fileID);
  51. fprintf('Done.\n');
  52. clear XSetVec
  53. if(PQCentCompon)
  54. %% Preparing Training Data for Computation
  55. fprintf('Computing m=%1.0f, k=%1.0f PQ subcentroids ...%s',mm,kk,str2print);
  56. CSubSetMat=zeros(subImgSz,kk,mm);
  57. for jj=1:mm
  58. CSubSetMat(:,:,jj)=yael_kmeans(...
  59. single(XSetMat((jj-1)*subImgSz+1:jj*subImgSz,:)),...
  60. kk, 'niter', 100, 'verbose', 0);
  61. %[~, CCtemp]=kmeans(TSubSetMat(:,:,jj)',kk);
  62. %CSubSetMat(:,:,jj)=CCtemp';
  63. pp=double(jj/mm*100);
  64. if(pp<10)
  65. fprintf('\b\b%2.0f%%',pp);
  66. else
  67. fprintf('\b\b\b%2.0f%%',pp);
  68. end
  69. end
  70. fprintf('\b\b Done.\n');
  71. % clearvars TSetMat
  72. save(strcat('./Data/k',int2str(kk),'m',int2str(mm),'CSubSetMat.mat'),'CSubSetMat');
  73. else
  74. fprintf('Loading m=%1.0f, k=%1.0f PQ subcentroids ....%s',mm,kk,str2print);
  75. load(strcat('./Data/k',int2str(kk),'m',int2str(mm),'CSubSetMat.mat'));
  76. fprintf(' Done.\n');
  77. end
  78. % clearvars TSubSetMat
  79. %% Displaying PQ SubCentroidss
  80. if(dispPQCenton)
  81. fprintf('Displaying PQ subcentroids: ... \n',mm);
  82. mmax=min(3,mm);
  83. for jj=1:mmax
  84. figure('units','normalized','outerposition',[0 0 1 1])
  85. suptitle('Centroid Portions of Pictures')
  86. imshow255_texmex(0,imgSz,[255*ones(kk,(jj-1)*subImgSz) ...
  87. CSubSetMat(:,:,jj)' ...
  88. 255*ones(kk,(mm-jj)*subImgSz)]);
  89. end
  90. end
  91. %% Preparing Training Data for Computation
  92. % fprintf('Loading Training Data Set ...................... ');
  93. % XSetMat=fvecs_read('../Data/sift/sift_base.fvecs');
  94. % fprintf('Done.\n');
  95. %% Computing/Loading PQ SubCentroids for Training Data
  96. if(Quantizationon)
  97. nSteps=100; % number of steps for computation, be sure it divides 1e6
  98. fprintf('Computing PQ subcentroids for Training Data .... ');
  99. iXQ=zeros(mm,Ntrain);
  100. for jj=1:mm
  101. for ll=1:Ntrain/nSteps
  102. [~,iXQ(jj,(ll-1)*nSteps+1:ll*nSteps)]=Quantization(...
  103. XSetMat((jj-1)*subImgSz+1:jj*subImgSz,(ll-1)*nSteps+1:ll*nSteps),...
  104. CSubSetMat(:,:,jj));
  105. end
  106. pp=double(jj/mm*100);
  107. if(pp<10)
  108. fprintf('\b\b%2.0f%%',pp);
  109. else
  110. fprintf('\b\b\b%2.0f%%',pp);fprintf('Computing m=%1.0f, k=%1.0f PQ subcentroids ...%s',mm,kk,str2print);
  111. CSubSetMat=zeros(subImgSz,kk,mm);
  112. for jj=1:mm
  113. CSubSetMat(:,:,jj)=yael_kmeans(...
  114. single(XSetMat((jj-1)*subImgSz+1:jj*subImgSz,:)),...
  115. kk, 'niter', 100, 'verbose', 0);
  116. %[~, CCtemp]=kmeans(TSubSetMat(:,:,jj)',kk);
  117. %CSubSetMat(:,:,jj)=CCtemp';
  118. pp=double(jj/mm*100);
  119. if(pp<10)
  120. fprintf('\b\b%2.0f%%',pp);
  121. else
  122. fprintf('\b\b\b%2.0f%%',pp);
  123. end
  124. end
  125. fprintf('\b\b Done.\n');
  126. end
  127. end
  128. fprintf('\b\b\b\b\b\bDone.\n');
  129. save(strcat('./Data/ADC/ADCk',int2str(kk),'m',int2str(mm),'iXQ.mat'),'iXQ');
  130. else
  131. fprintf('Loading PQ subcentroids for Training Data ...... ');
  132. load(strcat('./Data/ADC/ADCk',int2str(kk),'m',int2str(mm),'iXQ.mat'));
  133. fprintf('Done.\n');
  134. end
  135. clearvars XSetMat
  136. %% Preparing Testing Data for Computation
  137. fprintf('Loading Testing Data Set ....................... ');
  138. % YSetMat=fvecs_read('../Data/sift/sift_query.fvecs');
  139. fileID = fopen('../Data/t10k-images.idx3-ubyte');
  140. YSetVec = fread(fileID,imgSz*Ntests+fileOffset,'uint8');
  141. YSetVec = YSetVec(fileOffset+1:end);
  142. YSetMat = zeros(imgSz,Ntests);
  143. for jj=1:Ntests
  144. YSetMat(:,jj)=YSetVec((jj-1)*imgSz+1:jj*imgSz);
  145. end
  146. fclose(fileID);
  147. fprintf('Done.\n');
  148. clear YSetVec
  149. %% Computing/Loading NNs by applying ADC
  150. if(ADCCompon)
  151. fprintf('Solving NNS Applying ADC ........................ ');
  152. [iXMinDist]= AsymmetricDistanceComputation(CSubSetMat, iXQ, YSetMat, nRecall);
  153. save(strcat('./Data/ADC/ADCk',int2str(kk),'m',int2str(mm),'iXMinDist.mat'),'iXMinDist');
  154. fprintf('\b\b\bDone.\n');
  155. else
  156. fprintf('Loading NNS results with ADC ...................... ');
  157. load(strcat('./Data/ADC/ADCk',int2str(kk),'m',int2str(mm),'iXMinDist.mat'));
  158. fprintf('Done.\n');
  159. end
  160. clearvars iXQ YSetMat CSubSetMat
  161. else
  162. fprintf('Loading NNS results with ADC ...................... ');
  163. load(strcat('./Data/ADC/ADCk',int2str(kk),'m',int2str(mm),'iXMinDist.mat'));
  164. fprintf('Done.\n');
  165. end
  166. %% Loading results
  167. fprintf('Loading Results Data Set ............');
  168. % iSet=ivecs_read('../Data/sift/sift_groundtruth.ivecs')+1;
  169. fileOffsetL = 8; % bytes of file offset
  170. fileIDL = fopen('../Data/train-labels.idx1-ubyte');
  171. XLab = fread(fileIDL,Ntrain+fileOffsetL,'uint8');
  172. XLab = XLab(fileOffsetL+1:end);
  173. fclose(fileIDL);
  174. fileIDL = fopen('../Data/t10k-labels.idx1-ubyte');
  175. YLab = fread(fileIDL,Ntests+fileOffsetL,'uint8');
  176. YLab = YLab(fileOffsetL+1:end);
  177. fclose(fileIDL);
  178. fprintf('Done.\n');
  179. %iSet=iSet(1,:);
  180. %% Testing PQ Data Set
  181. fprintf('Testing PQ Test Data Set ... \n');
  182. % reqRecall=zeros(Ntests,1);
  183. %
  184. % for ii = 1:Ntests
  185. % iXeq=sum(XLab(iXMinDist(ii,:))==YLab(ii));
  186. % if numel(iXeq)==1
  187. % reqRecall(ii)=iXeq;
  188. % else
  189. % reqRecall(ii)=nRecall+1;
  190. % end
  191. % end
  192. %
  193. % reqRecall=sort(reqRecall);
  194. %
  195. % ll=1;
  196. recAtR=[1 2 5 10 20 50 100 200 500 1000 2000 5000 10000];
  197. recAtR=recAtR(recAtR<=nRecall);
  198. % % recAtR=nRecall;
  199. % Performances=zeros(1,length(recAtR));
  200. %
  201. % for ii=recAtR
  202. % if ii <= nRecall
  203. % Performances(ll) = length (find (reqRecall <= ii & reqRecall <= nRecall)) / Ntests * 100;
  204. % fprintf ('Recall@%3d = %.3f\n', ii, Performances(ll));
  205. % ll=ll+1;
  206. % end
  207. % end
  208. %
  209. Performances=zeros(1,length(recAtR));
  210. for rr=1:length(recAtR)
  211. if recAtR(rr)==1
  212. Performances(rr)=sum(XLab(iXMinDist(:,1))==YLab)/(Ntests);
  213. else
  214. Performances(rr)=sum(max((XLab(iXMinDist(:,1:recAtR(rr)))==repmat(YLab,1,recAtR(rr)))'))/(Ntests);
  215. end
  216. fprintf ('Recall@%3d = %.3f\n', recAtR(rr), Performances(rr)*100);
  217. end
  218. %% Computational Cost Evaluation
  219. maxCCost=Ntrain*Ntests*imgSz;
  220. quantCCost=Ntests*kk*imgSz;
  221. PQCCostADC=Ntrain*Ntests*mm+quantCCost;
  222. normCCost=PQCCostADC/maxCCost;
  223. fprintf('Computational Cost: %2.2f %% w.r.t Exhaustive NNS\n',normCCost*100);