From 7f39f884fc1333d27ec09863bbd7531194052e36 Mon Sep 17 00:00:00 2001 From: colin Date: Fri, 20 Sep 2019 12:48:45 +0800 Subject: [PATCH] Refine Distance of kernels --- FilterEvaluator/Evaluator copy.py | 113 ---------------------------- FilterEvaluator/Evaluator.py | 41 +++++++--- FilterEvaluator/EvaluatorUnsuper.py | 51 ++++++++++++- FilterEvaluator/TrainNetwork.py | 13 ++-- FilterEvaluator/bestweightTrain.npy | Bin 416 -> 416 bytes FilterEvaluator/checkpointTrain.pkl | Bin 14040 -> 14040 bytes FilterEvaluator/image/0-1024.png | Bin 0 -> 413 bytes FilterEvaluator/visdom.server.log | Bin 3818261 -> 3918716 bytes tools/WebVisual.py | 21 ++++++ visdom.server.log | 5 +- 10 files changed, 110 insertions(+), 134 deletions(-) delete mode 100644 FilterEvaluator/Evaluator copy.py create mode 100644 FilterEvaluator/image/0-1024.png diff --git a/FilterEvaluator/Evaluator copy.py b/FilterEvaluator/Evaluator copy.py deleted file mode 100644 index a25d007..0000000 --- a/FilterEvaluator/Evaluator copy.py +++ /dev/null @@ -1,113 +0,0 @@ -from __future__ import print_function -import os -import sys -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.optim as optim -import torchvision -from torchvision import datasets, transforms -import torchvision.models as models -import matplotlib.pyplot as plt -import numpy as np -from torch.utils.data import Dataset, DataLoader -from PIL import Image -import random -import cv2 - - - -CurrentPath = os.path.split(os.path.realpath(__file__))[0]+"/" -print("Current Path :" + CurrentPath) - -sys.path.append(CurrentPath+'../tools') -sys.path.append(CurrentPath+'../') - -import Model as Model -from tools import utils, Train, Loader -import EvaluatorUnsuper - - - -batchsize = 128 - - -# model = utils.SetDevice(Model.Net5Grad35()) -# model = utils.SetDevice(Model.Net31535()) -model = utils.SetDevice(Model.Net3Grad335()) -# model = utils.SetDevice(Model.Net3()) - - -layers = model.PrintLayer() -layer = 0 - -model = utils.LoadModel(model, CurrentPath+"/checkpoint.pkl") - -weight = np.load(CurrentPath+"WeightSearch.npy") - - - - - -# traindata, testdata = Loader.MNIST(batchsize) -# traindata, testdata = Loader.RandomMnist(batchsize, style="Vertical") -# traindata, testdata = Loader.RandomMnist(batchsize, style="Horizontal") -# traindata, testdata = Loader.RandomMnist(batchsize, style="VerticalOneLine") -# traindata, testdata = Loader.RandomMnist(batchsize, style="VerticalZebra") -# traindata, testdata = Loader.Cifar10Mono(batchsize) -traindata, testdata = Loader.Cifar10Mono(batchsize, num_workers=0, shuffle=True) - - - - -# weight = EvaluatorUnsuper.UnsuperLearnSearchWeight(model, layer, traindata, NumSearch=100000, SearchChannelRatio=8, Interation=10) -# np.save("WeightSearch.npy", weight) - -# weight = EvaluatorUnsuper.UnsuperLearnTrainWeight(model, layer, traindata) -# np.save("WeightTrain.npy", weight) - - - - -weight = np.load(CurrentPath+"WeightSearch.npy") - - -def DistanceOfKernel(k1,k2): - k1 = k1.reshape((1,-1)) - k1r = 1.0/k1.reshape((-1,1)) - k1dot = np.dot(k1r,k1) - k2 = k2.reshape((1,-1)) - k2r = 1.0/k2.reshape((-1,1)) - k2dot = np.dot(k2r,k2) - diff = np.abs(np.mean(k1dot - k2dot)) - return diff - - -indexs = np.random.randint(0,weight.shape[0],(10000,2)) - -mindis = 0 -manindex = [] -for i in indexs: - if i[0] == i[1]: - continue - dis = DistanceOfKernel(weight[i[0]], weight[i[1]]) - if dis > mindis: - manindex = i - mindis = dis - -a = weight[manindex[0]] -b = weight[manindex[1]] - -utils.NumpyToImage(a, CurrentPath+"image","a") -utils.NumpyToImage(b, CurrentPath+"image","b") - -a = 0 - - - - - - -# utils.NumpyToImage(weight, CurrentPath+"image") -# utils.SaveModel(model,CurrentPath+"/checkpoint.pkl") -print("save model sucess") diff --git a/FilterEvaluator/Evaluator.py b/FilterEvaluator/Evaluator.py index b4e5ee6..a93c1c8 100644 --- a/FilterEvaluator/Evaluator.py +++ b/FilterEvaluator/Evaluator.py @@ -24,7 +24,7 @@ sys.path.append(CurrentPath+'../tools') sys.path.append(CurrentPath+'../') import Model as Model -from tools import utils, Train, Loader +from tools import utils, Train, Loader, WebVisual import EvaluatorUnsuper @@ -67,16 +67,32 @@ traindata, testdata = Loader.Cifar10Mono(batchsize, num_workers=0, shuffle=True) # weight = np.load(CurrentPath+"WeightSearch.npy") -# bestweight = EvaluatorUnsuper.UnsuperLearnFindBestWeight(model,layer,weight,traindata,128,100000) +# bestweight,index = EvaluatorUnsuper.UnsuperLearnFindBestWeight(model,layer,weight,traindata,128,100000) # np.save(CurrentPath+"bestweightSearch.npy", bestweight) # utils.NumpyToImage(bestweight, CurrentPath+"image") -weight = np.load(CurrentPath+"WeightTrain.npy") -bestweight = EvaluatorUnsuper.UnsuperLearnFindBestWeight( - model, layer, weight, traindata, databatchs=128, interation=100000) -np.save(CurrentPath+"bestweightTrain.npy", bestweight) -utils.NumpyToImage(bestweight, CurrentPath+"image") +# weight = np.load(CurrentPath+"WeightTrain.npy") +# bestweight, index = EvaluatorUnsuper.UnsuperLearnFindBestWeight( +# model, layer, weight, traindata, databatchs=16, interation=1000000) +# np.save(CurrentPath+"bestweightTrain.npy", bestweight) +# utils.NumpyToImage(bestweight, CurrentPath+"image") + + + + +# weight = np.load(CurrentPath+"WeightTrain.npy") +# WebVisual.InitVisdom() +# window = WebVisual.LineWin() +# HisLine = WebVisual.Line(window, "HisLine") +# dis = EvaluatorUnsuper.CrossDistanceOfKernel(weight,weight,weight.shape[0],weight.shape[0]) +# his = np.histogram(dis,512) +# HisLine.AppendData(his[1],his[0]) + + + + + @@ -84,9 +100,14 @@ utils.NumpyToImage(bestweight, CurrentPath+"image") # EvaluatorUnsuper.SetModelConvWeight(model,layer,weight) # utils.SaveModel(model,CurrentPath+"/checkpointSearch.pkl") -# weight = np.load(CurrentPath+"bestweightTrain.npy") -# EvaluatorUnsuper.SetModelConvWeight(model,layer,weight) -# utils.SaveModel(model,CurrentPath+"/checkpointTrain.pkl") + +weight = np.load(CurrentPath+"bestweightTrain.npy") +EvaluatorUnsuper.SetModelConvWeight(model,layer,weight) +utils.SaveModel(model,CurrentPath+"/checkpointTrain.pkl") + + + + diff --git a/FilterEvaluator/EvaluatorUnsuper.py b/FilterEvaluator/EvaluatorUnsuper.py index a25bcfa..83a4f1a 100644 --- a/FilterEvaluator/EvaluatorUnsuper.py +++ b/FilterEvaluator/EvaluatorUnsuper.py @@ -171,11 +171,60 @@ def UnsuperLearnFindBestWeight(netmodel, layer, weight, dataloader, databatchs=1 entropy = (histc.log2()*histc).sum() entropys.append(entropy.detach().cpu().numpy()) interationbar.update(1) + sortindex = np.argsort(entropys) argmin = np.argmin(entropys) bestweight = weight[indexs[argmin]] interationbar.close() - return bestweight + return bestweight,indexs[sortindex] def SetModelConvWeight(model, layer, weight): w = utils.SetDevice(torch.from_numpy(weight)) model.features[layer].weight.data = w + + +def DistanceOfKernel(k1, k2, BatchSize=1): + """ + Distance of Kernel with N scale value + BatchSize : Kernel number in k1 and k2 + + scalek1 = (each value of K1 / each value of K1) + scalek2 = (each value of K2 / each value of K2) + so if N = 9 , size(scaleK1) = 81 + return diff = abs(mean(scalek1 - scalek2)) + """ + k1revert = k1.reshape((BatchSize, -1, 1)) + k1 = 1.0 / k1.reshape((BatchSize, 1, -1)) + k2revert = k2.reshape((BatchSize, -1, 1)) + k2 = 1.0 / k2.reshape((BatchSize, 1, -1)) + diff = np.abs(np.mean((np.matmul(k1revert, k1)- np.matmul(k2revert, k2)).reshape(BatchSize, -1), 1)) + return diff + + +def CrossDistanceOfKernel(k1, k2, BatchSize1=1, BatchSize2=1): + """ + Distance of Kernel with N scale value + BatchSize : Kernel number in k1 and k2 + K1 k2 dims must >= 2 + + scalek1 = (each value of K1 / each value of K1) + scalek2 = (each value of K2 / each value of K2) + so if N = 9 , size(scaleK1) = 81 + return diff = abs(mean(scalek1 - scalek2)) + """ + + tileshape = np.array(k2.shape) + tileshape[1:] = 1 + tileshape[0] = k1.shape[0] + right = np.tile(k2, tileshape) + + tileshape = np.array(k1.shape) + tileshape[1] = k2.shape[0] + tileshape[0] = 1 + tileshape[2:] = 1 + left = np.tile(k1, tileshape) + + leftshape = np.array(k1.shape) + leftshape[0] = -1 + left = left.reshape(leftshape) + + return DistanceOfKernel(right, left, left.shape[0]) \ No newline at end of file diff --git a/FilterEvaluator/TrainNetwork.py b/FilterEvaluator/TrainNetwork.py index d50903a..884589b 100644 --- a/FilterEvaluator/TrainNetwork.py +++ b/FilterEvaluator/TrainNetwork.py @@ -14,7 +14,6 @@ from torch.utils.data import Dataset, DataLoader from PIL import Image import random import cv2 -from visdom import Visdom from tqdm import tqdm @@ -45,7 +44,7 @@ batchsize = 128 # traindata, testdata = Loader.RandomMnist(batchsize, num_workers=4, style="Horizontal") # traindata, testdata = Loader.RandomMnist(batchsize, num_workers=4, style="VerticalOneLine") # traindata, testdata = Loader.RandomMnist(batchsize, num_workers=4, style="VerticalZebra") -traindata, testdata = Loader.Cifar10Mono(batchsize, num_workers=4,shuffle=True,trainsize=140) +traindata, testdata = Loader.Cifar10Mono(batchsize, num_workers=4,shuffle=True,trainsize=500) WebVisual.InitVisdom() @@ -65,15 +64,15 @@ Train.TrainEpochs(model,traindata,optimizer,testdata,3000,30,linePretrainTrain) model = utils.SetDevice(Model.Net3335()) -model = utils.LoadModel(model, CurrentPath+"/checkpointTrain.pkl") +# model = utils.LoadModel(model, CurrentPath+"/checkpointTrain.pkl") optimizer = optim.SGD(model.parameters(), lr=0.1) Train.TrainEpochs(model,traindata,optimizer,testdata,3000,30,lineNoPre) -model = utils.SetDevice(Model.Net3Grad335()) -model = utils.LoadModel(model, CurrentPath+"/checkpointSearch.pkl") -optimizer = optim.SGD(model.parameters(), lr=0.1) -Train.TrainEpochs(model,traindata,optimizer,testdata,3000,30,linePretrainSearch) +# model = utils.SetDevice(Model.Net3Grad335()) +# model = utils.LoadModel(model, CurrentPath+"/checkpointSearch.pkl") +# optimizer = optim.SGD(model.parameters(), lr=0.1) +# Train.TrainEpochs(model,traindata,optimizer,testdata,3000,30,linePretrainSearch) diff --git a/FilterEvaluator/bestweightTrain.npy b/FilterEvaluator/bestweightTrain.npy index c1aa5acc59db3d0f7f5a4c2ed5bbbde946002f1c..d842fac7615ab4ea228b8ebd670080887db96da5 100644 GIT binary patch delta 297 zcmV+^0oMMY1E2$tfPZ;afWMX@q`uLZpgpE`EIvaeIllAU=)GUMn7%zw4?cx#cRrnQ zK)>@Jv_6aT0YALEc|V9O3qOYmkiKj?_r2CQn?9>fXg?{z+pyTCp>dQHD`tpz@2 vEN8we^OwJ&H6lH~l1~A?HD`D~tCTfARMG}N(~}WDHU!2#ro0`$!Au1{{e_DA delta 297 zcmV+^0oMMY1E2$tfPef5T0Z+HS-&22KtCbmfIfs;Gd{R-{Jys*4!`YPZ$F_MkUvmu zgul#kX1{^m06zj+(LO04h&?xD2EQBhCBNT{+di!`Xg;iaY(7PPfW5m!d_RhaJiqNt zyS;YG;X5K{@jlMyiayJn6+VY6Gr!MEV7^i!;A5@9947fC;~LVK+Y{>{7q-=&QboTn|5c5n{fAVDo_7xOK@pG1qt diff --git a/FilterEvaluator/checkpointTrain.pkl b/FilterEvaluator/checkpointTrain.pkl index 7bdf15b4ab183b111ff79cfc29930dee611d9f98..cadd6c3d15a5c9e8d4cb5882b026db9fd7832a15 100644 GIT binary patch literal 14040 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 g2a_K?!r|(%-T(jq literal 14040 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 delta 4373 zcmZu#TW?&|71lTx$3wz67>C%7@z~=40cSij*s`L2cSJ@_;wddK@c8xvX=4`WFYcH@Z_Cnig z*V&8gdfR5(ZHL`pJMG1`%jRvj?Xd;hYd6|U?4|ZHyUAW|udsb~vn|?wTe4+au~*sw zJ7~AqAv^qL_35|e+V7(aW#)a;B-yjk+GPX9vXpN(k+lCDt(VfxrXc_Mli4L>H<`A% zk4(EvoQ+m4FBb=^^1*$kECnwS1->Ipi>&;^_K5w?j6D{T*IXG%+vONm}NV_02tKht;&poS3v1-iRah!edYV(H7 z9|3evtTX-cSr<<5>-cu_S6QR+Ae7qNZj+URGbZO!VG!GHg4Yw>W->D@FMf!C{&k}d za?e)tu=Cd02n)wf0oyPCY4Ryg8i9=MNZmLo|Gv?omX-YV2)FHL;CJH3s5LVrbauLC z9;=UJt`p}Lfy1NB_nBkxTbhSo06Qc%4*^s7?Qu2wXj@$br~hakksGc<{;bD?S=56C zcwrXk^dB=72M3BgBIl;-tb{D#t;-xY{cq znN!;kLBOT-YqU-&P?P+hJve-JGQtf2^0?44Ar7g2y9z z)}k?w8Xl?1XAM5fY|e3#l&VUAWcL^xX^rGmFRs1YQ5QWi2!YS%VcxT=U-Am#{B}I6 zy=pc%f`r3+R-libzXeAo&P9`%Esg>_{$2+v$4&w__sQ3Adlr__dTca3(jc0iW;<%YGWVc^l|RiMMsGZ5Cz8_dYuTToL58kf)~Sg4l{ zCjx|}bTv3gCY)|a0i*!SmH%}mo|e+>D9-->M`&L4&w`QfziQRuz%$1|G&pW&7%vS# zM4ET{#w88B!Ge>Mpix2n#v0+694&R=6H^P=!Mj;16%2*FF33=NSc*GtcDX60fSr<0 z4nx)!Rd6XzGVRc%EER>TE}LG5$ALQlg|?lW32D`$ZAFgA+^3Nm*Mu3d2il}ReiMy6jtaT1tY;q`FV+Q3)Re7B_b^UIoNx(u?h!Z~ zNiknfgiI12sh%X2!VaRKGz`1Ng%_7%0nw*yViY*pL^*H$0aAi!+T>duE`+!0L^&=v z2QRjvNnt|dOt25Bjwc0W4aM$~WO`(MW~J+O^F8ALyfcu zic+agYAGINUA#;~U)yzI zT6#xw&U2XWfmdPvaKUDq#^k(9*9xi%=b)!-T&!tVR+W55*qFwY@I}Q4NFapCRDUrd zPuKJa^*A}D@KvBQ_K&ZJF43gNu+TArm~x~6TFKhOdri8&bL-cJSO%qX2Q^mDG$m<6 zH3lAjDwkJL=^^&GU?0kju5lp^)rw&@|}w-vE|66vv4u2czUs+8cU77 zUnDqt&#||77BVRCc^s80Cz2Nb7=|00XVKQr82Em|Ef@P2hFaYk;Y;8pFKB}TlAsgn z&W;P4N>vEJ=WC3HS8^|K`nu;)+jAJgNmN1|d;=+Gj}Dq~NN+jDgME8(qZwqfq4B&- z1G$)#ESTSV@UGN|y>gMZhfN4T#2nEblsms~C8iekTfRYsbk7Z%QI6Wbv_fepOZe20 z{7cXxe^`i;e*>E2wsF%c&F^5}#=ikuW#=q*w$D%E>$$VhD(Sup>p^}Yx)gH|N`_ba Z_