def forward_propagate(self, X): X_col = im2col(X, [self.f_H, self.f_W], pad=[self.pad_H, self.pad_W], stride=[self.stride_H, self.stride_W ]) #shape=(in_D*f_H*f_W,out_H*out_W*BS) X_col_channel = X_col.reshape( self.in_D, self.f_H * self.f_W, self.out_H * self.out_W * self.BS) #shape=(in_D,f_H*f_W,out_H*out_W*BS) cord_1 = np.argmax(X_col_channel, axis=1).reshape( self.in_D * self.out_H * self.out_W * self.BS) #shape=(in_D*out_H*out_W*BS) cord_0 = np.repeat(np.arange(self.in_D), self.out_H * self.out_W * self.BS) cord_2 = np.tile(np.arange(self.out_H * self.out_W * self.BS), self.in_D) self.iomat = np.zeros( shape=(self.in_D, self.f_H * self.f_W, self.out_H * self.out_W * self.BS)) #shape=(in_D,f_H*f_W,out_H*out_W*BS) self.iomat[cord_0, cord_1, cord_2] = 1 out = np.max(X_col_channel * self.iomat, axis=1) #shape=(in_D,out_H*out_W*BS) out = out.reshape( self.in_D, self.out_H, self.out_W, self.BS) # shape=(in_D,out_H*out_W*BS)->(in_D,out_H,out_W,BS) out = out.transpose(3, 0, 1, 2) #shape=(BS,out_D,out_H,out_W) return out
def forward(self, input): # in_col : [f_H*f_W*in_D, out_H*out_W*BS] self.in_col = im2col(input,[self.f_H, self.f_W], [self.s_H, self.s_W], [self.p_H, self.p_W]) out_col = np.matmul(self.w_col, self.in_col) + self.b #[out_D, out_H*out_W*BS] out = out_col.reshape((self.out_D, self.out_H, self.out_W, input.shape[0])) #[out_D, out_H, out_W, BS] out = np.transpose(out,(3,0,1,2)) #[BS, out_D, out_H, out_W] return out
def medfilt(A, RADIUS): N = (RADIUS * 2) + 1 X = Y = RADIUS + 1 [COL, ROW] = numpy.meshgrid(numpy.linspace(1, N, N), numpy.linspace(1, N, N)) M = (ROW - Y)**2 + (COL - X)**2 <= (RADIUS**2) + 1 M_col = M.reshape((numpy.size(M), 1)) A_pad = numpy.lib.pad(A, ((int(math.floor(N / 2.)), int(math.floor(N / 2.))), (int(math.floor(N / 2.)), int(math.floor(N / 2.)))), 'constant') A_col = im2col(A_pad, (N, N)) A_weighted = numpy.multiply(A_col, M_col) A_sort = numpy.sort(A_weighted, 0) A_median = A_sort[int(math.floor(N * N / 2) + 1), :] A_im = col2im(A_median, (N, N), numpy.shape(A_pad)) return A_im
def max_pooling_forward(x, pool_params): # get max-pooling parameters stride = pool_params['stride'] HF = pool_params['HF'] WF = pool_params['WF'] pad = pool_params['pad'] # get input size H, W, D, N = x.shape x_reshaped = x.reshape(H, W, 1, -1) #(H,W,1,D*N) # get output size HO = 0 WO = 0 if type(pad) is int: HO = (H + 2 * pad - HF) / stride + 1 WO = (W + 2 * pad - WF) / stride + 1 else: HO = (H + pad[0] + pad[1] - HF) / stride + 1 WO = (W + pad[2] + pad[3] - WF) / stride + 1 x_col = im2col(x_reshaped, HF, WF, pad, stride) #x_col的维度是(HF*WF,N*Hout*Wout) x_col_argmax = np.argmax(x_col, axis=0) #求每个feature_map的最大值所在的下标 #x_col_argmax的维度是(1,N*Hout*Wout),每列是一个卷积核的最大值的下标 x_col_max = x_col[x_col_argmax, np.arange(x_col.shape[1])] out = x_col_max.reshape((HO, WO, D, N)) return out
def conv_forward(x, w, b, params): # get convolution parameters stride = params['stride'] pad = params['pad'] # get input size H, W, D, N = x.shape HF, WF, DF, NF = w.shape _, _, DB, NB = b.shape # check input size assert D == DF, 'dimension does not work' assert NF == NB, 'batch size does not work' # check params assert (H + 2 * pad - HF) % stride == 0, 'pad and stride do not work' assert (W + 2 * pad - WF) % stride == 0, 'pad and stride do not work' # get output size HO = (H + 2 * pad - HF) / stride + 1 WO = (W + 2 * pad - WF) / stride + 1 x_col = im2col(x, HF, WF, pad, stride) #转换成一列是一个感受野的形式 w_col = w.transpose(3, 0, 1, 2).reshape( (NF, -1)) #先转置成(NF,HF, WF, DF),再转置成(NF,HF*WF*DF),这样就变成一行是一个卷积核, output_col = w_col.dot(x_col) + b.reshape(-1, 1) #卷积操作,结果便是一行是一个卷积核的结果 #纬度是(NF,N*Hout*Wout) output_col = output_col.reshape((NF, HO, WO, N)) output_col = output_col.transpose(1, 2, 0, 3) #变成(HO,WO,NF,N) return output_col
def gaussmedfilt(A,RADIUS,SIGMA): N = (RADIUS*2)+1 G = gausskern((N,N),SIGMA) G_norm = G/np.amax(G) g = gausskern((N,N),SIGMA/1.5) g_norm = g/np.amax(g) Gg = G_norm-g_norm Gg_norm = Gg/np.amax(Gg) Gg_col = Gg_norm.reshape((np.size(Gg_norm),1)) A = np.lib.pad(A,((int(math.floor(N/2.)),int(math.floor(N/2.))),(int(math.floor(N/2.)),int(math.floor(N/2.)))),'constant') A_pad_shape = np.shape(A) A = im2col(A, (N, N)) A = np.multiply(A,Gg_col) A = np.sort(A,0) A = A[int(math.floor(N*N/2)+1),:] A = col2im(A, (N, N), A_pad_shape[::-1]) return A
def forward(self, x): filter_num, channels, filter_height, filter_width = self.W.shape data_num, channels, height, width = x.shape # FN, C, FH, FW = self.W.shape # N, C, H, W = x.shape # 畳み込み演算 out_height = int(1 + (height + 2 * self.pad - filter_height) / self.stride) out_width = int(1 + (width + 2 * self.pad - filter_width) / self.stride) # 計算のしやすいように,行列の変換・整形を行う col = im2col(x, filter_height, filter_width, self.stride, self.pad) col_W = self.W.reshape(filter_num, -1).T out = np.dot(col, col_W) + self.b # 2次元配列を4次元配列に変換 # transpose: 多次元配列の順番を入れ替える関数 out = out.reshape(data_num, out_height, out_width, -1).transpose(0, 3, 1, 2) self.x = x self.col = col self.col_W = col_W return out
def gaussmedfilt(A, RADIUS, SIGMA): N = (RADIUS * 2) + 1 G = gausskern((N, N), SIGMA) G_norm = G / np.amax(G) g = gausskern((N, N), SIGMA / 1.5) g_norm = g / np.amax(g) Gg = G_norm - g_norm Gg_norm = Gg / np.amax(Gg) Gg_col = Gg_norm.reshape((np.size(Gg_norm), 1)) A = np.lib.pad(A, ((int(math.floor(N / 2.)), int(math.floor(N / 2.))), (int(math.floor(N / 2.)), int(math.floor(N / 2.)))), 'constant') A_pad_shape = np.shape(A) A = im2col(A, (N, N)) A = np.multiply(A, Gg_col) A = np.sort(A, 0) A = A[int(math.floor(N * N / 2) + 1), :] A = col2im(A, (N, N), A_pad_shape[::-1]) return A
def max_pooling_backward(x, dout, pool_params): H, W, D, N = x.shape x_reshaped = x.reshape(H, W, 1, -1) x_col = im2col(x_reshaped, pool_params['HF'], pool_params['WF'], pool_params['pad'], pool_params['stride']) x_col_argmax = np.argmax(x_col, axis=0) dx_col = np.zeros_like(x_col) dx_col[x_col_argmax, np.arange(x_col.shape[1])] = dout.ravel() dx_shaped = col2im(dx_col, x_reshaped.shape, pool_params['HF'], pool_params['WF'], pool_params['pad'], stride=pool_params['stride']) dx = dx_shaped.reshape(x.shape) return [dx]
def forward_propagate(self, X): self.X_col = im2col(X, [self.f_H, self.f_W], pad=[self.pad_H, self.pad_W], stride=[self.stride_H, self.stride_W ]) #shape=(f_H*f_W*in_D,out_H*out_W*BS) out = np.matmul(self.W_col, self.X_col) + self.b #shape=(out_D,out_H*out_W*BS) out = out.reshape( self.out_D, self.out_H, self.out_W, self.BS) #shape=(out_D,out_H*out_W*BS)->(out_D,out_H,out_W,BS) out = out.transpose(3, 0, 1, 2) #shape=(BS,out_D,out_H,out_W) return out
def forward(self, input): # in_col : [f_H*f_W*in_D, out_H*out_W*BS] self.in_col = im2col(input, [self.f_H, self.f_W], [self.s_H, self.s_W], [self.p_H, self.p_W]) in_col_reshape = self.in_col.reshape((self.f_H*self.f_W,-1),order='F') # [f_H*f_W, out_H*out_W*BS*in_D] ??????? out_col = np.max(in_col_reshape, axis=0) # [1, out_H*out_W*BS*in_D] out = out_col.reshape((self.in_D, -1),order='F') out = out.reshape((self.in_D, self.out_H, self.out_W, input.shape[0])) # [in_D, out_H, out_W, BS] out = np.transpose(out, (3, 0, 1, 2)) # [BS, in_D, out_H, out_W] arg_index = np.argmax(in_col_reshape, axis=0) # [1, out_H*out_W*BS*in_D] self.W = np.zeros(in_col_reshape.shape) self.W[arg_index, np.arange(in_col_reshape.shape[1])] = 1. # [f_H*f_W, out_H*out_W*BS*in_D] return out
def conv_backward(x, w, b, conv_param, dout): HF, WF, DF, NF = w.shape x_col = im2col(x, HF, WF, conv_param['pad'], conv_param['stride']) w_col = w.transpose(3, 0, 1, 2).reshape((NF, -1)) db = np.sum(dout, axis=(0, 1, 3)) dout = dout.transpose(2, 0, 1, 3) dout = dout.reshape((w_col.shape[0], x_col.shape[-1])) dx_col = w_col.T.dot(dout) dw_col = dout.dot(x_col.T) dx = col2im(dx_col, x.shape, HF, WF, conv_param['pad'], conv_param['stride']) dw = dw_col.reshape((dw_col.shape[0], HF, WF, DF)) dw = dw.transpose(1, 2, 3, 0) return [dx, dw, db]
def forward(self, x): """卷积层的前向传播""" N, C, H, W = x.shape # batch_num, channel, height, width FN, C, FH, FW = self.W.shape # 滤波器数量, channel, height, width;滤波器通道数必须与输入数据通道数相等 out_h, out_w, col = im2col( x, FH, FW, self.stride, self.pad) # (输出高,输出宽,x的二维展开);col.shape=(N*out_h*out_w, C*FH*FW) col_W = self.W.reshape(FN, -1).T # 滤波器合适的二维展开(C*FH*FW, FN) out = np.dot(col, col_W) + self.b # out.shape=(N*out_h*out_w, FN) out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2) # out.shape=(N, FN, out_h, out_w) self.x = x self.col = col self.col_W = col_W return out
def conv_fw(inputs, weight, bias): n_filters, d_filter, h_filter, w_filter = weight.shape d_x, h_x, w_x = inputs.shape h_out = h_x - h_filter + 1 w_out = w_x - w_filter + 1 h_out, w_out = int(h_out), int(w_out) inputs_col = im2.im2col(inputs, h_filter, w_filter) weights_col = weight.reshape(n_filters, -1) out = np.dot(weights_col, inputs_col) + bias out = out.reshape(n_filters, h_out, w_out) out = out.transpose(0, 1, 2) cache = (inputs, weight, bias, inputs_col) return out, cache
def forward(self, x): N, C, H, W = x.shape out_h = int(1 + (H - self.pool_h) / self.stride) out_w = int(1 + (W - self.pool_w) / self.stride) #展开(1) col = Im2col.im2col(x, self.pool_h, self.pool_w, self.stride, self.pad) col = col.reshape(-1, self.pool_h * self.pool_w) #最大值(2) out = np.max(col, axis=1) #取最大值坐标反向传播用 arg_max = np.argmax(col, axis=1) self.x = x self.arg_max = arg_max #转换(3) out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2) return out
def forward(self, x): FN, C, FH, FW = self.w.shape N, C, H, W = x.shape out_h = int(1 + (H + 2 * self.pad - FH) / self.stride) out_w = int(1 + (W + 2 * self.pad - FW) / self.stride) col = Im2col.im2col(x, FH, FW, self.stride, self.pad) #得到 ( OH*OW*N ,FH*FW*C)的数组,之后和滤波器相乘。 col_w = self.w.reshape(FN, -1).T #滤波器展开,-1为自动调整的值即FN*-1<==>FN*C*FW*FH out = np.dot(col, col_w) + self.b out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2) #这部实际上是把数据维度调回原来的 self.x = x self.col = col self.col_w = col_w return out
def forward(self, x): """池化层的前向传播""" N, C, H, W = x.shape out_h, out_w, col = im2col( x, self.pool_h, self.pool_w, self.stride, self.pad) # col.shape=(N*out_h*out_w, c*self.pool_h*self.pool_w) col = col.reshape( -1, self.pool_h * self.pool_w ) # col.shape=(N*out_h*out_w*c, self.pool_h*self.pool_w) arg_max = np.argmax(col, axis=1) out = np.max(col, axis=1) # 每一行的最大值(Max池化) out = out.reshape((N, out_h, out_w, C)).transpose(0, 3, 1, 2) # out.shape=(N, C, out_h, out_w) self.x = x self.arg_max = arg_max # Max池化 return out
def medfilt(A,RADIUS): N = (RADIUS*2)+1 X = Y = RADIUS+1 [COL, ROW] = numpy.meshgrid(numpy.linspace(1,N,N),numpy.linspace(1,N,N)) M = (ROW-Y)**2 + (COL-X)**2 <= (RADIUS**2)+1 M_col = M.reshape((numpy.size(M),1)) A_pad = numpy.lib.pad(A,((int(math.floor(N/2.)),int(math.floor(N/2.))),(int(math.floor(N/2.)),int(math.floor(N/2.)))),'constant') A_col = im2col(A_pad, (N, N)) A_weighted = numpy.multiply(A_col,M_col) A_sort = numpy.sort(A_weighted,0) A_median = A_sort[int(math.floor(N*N/2)+1),:] A_im = col2im(A_median, (N, N), numpy.shape(A_pad)) return A_im
def max_pooling_backward(x, dout, pool_params): print "in max_pooling_backward" print "dout.shape", dout.shape print "x.shape", x.shape H, W, D, N = x.shape x_reshaped = x.reshape(H, W, 1, -1) x_col = im2col(x_reshaped, pool_params['HF'], pool_params['WF'], pool_params['pad'], pool_params['stride']) x_col_argmax = np.argmax(x_col, axis=0) dx_col = np.zeros_like(x_col) #和x_col同样纬度的0矩阵 print " 1 dx_col.shape", dx_col.shape dx_col[x_col_argmax, np.arange(x_col.shape[1])] = dout.ravel() #把dout平铺 print " 2 dx_col.shape", dx_col.shape dx_shaped = col2im(dx_col, x_reshaped.shape, pool_params['HF'], pool_params['WF'], pool_params['pad'], stride=pool_params['stride']) dx = dx_shaped.reshape(x.shape) return [dx]
def forward(self, x): data_num, channels, height, width = x.shape out_height = int( 1 + (height - self.pool_h) / self.stride ) out_width = int( 1 + (width - self.pool_w) / self.stride ) col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad) col = col.reshape(-1, self.pool_h*self.pool_w) arg_max = np.argmax(col, axis=1) out = np.max(col, axis=1) out = out.reshape( data_num, out_height, out_width, channels ).transpose(0, 3, 1, 2) self.x = x self.arg_max = arg_max return out
def conv_forward(x, w, b, params): # get convolution parameters stride = params['stride'] pad = params['pad'] # get input size H, W, D, N = x.shape HF, WF, DF, NF = w.shape _, _, DB, NB = b.shape # check input size assert D == DF, 'dimension does not work' assert NF == NB, 'batch size does not work' # check params assert (H + 2 * pad - HF) % stride == 0, 'pad and stride do not work' assert (W + 2 * pad - WF) % stride == 0, 'pad and stride do not work' # get output size HO = (H + 2 * pad - HF) / stride + 1 WO = (W + 2 * pad - WF) / stride + 1 x_col = im2col(x, HF, WF, pad, stride) w_col = w.transpose(3, 0, 1, 2).reshape((NF, -1)) output_col = w_col.dot(x_col) + b.reshape(-1, 1) output_col = output_col.reshape((NF, HO, WO, N)) output_col = output_col.transpose(1, 2, 0, 3) return output_col
def max_pooling_forward(x, pool_params): # get max-pooling parameters stride = pool_params['stride'] HF = pool_params['HF'] WF = pool_params['WF'] pad = pool_params['pad'] # get input size H, W, D, N = x.shape x_reshaped = x.reshape(H, W, 1, -1) # get output size HO = 0 WO = 0 if type(pad) is int: HO = (H + 2 * pad - HF) / stride + 1 WO = (W + 2 * pad - WF) / stride + 1 else: HO = (H + pad[0] + pad[1] - HF) / stride + 1 WO = (W + pad[2] + pad[3] - WF) / stride + 1 x_col = im2col(x_reshaped, HF, WF, pad, stride) x_col_argmax = np.argmax(x_col, axis=0) x_col_max = x_col[x_col_argmax, np.arange(x_col.shape[1])] out = x_col_max.reshape((HO, WO, D, N)) return out
def conv_backward(x, w, b, conv_param, dout): print " in conv_backward" HF, WF, DF, NF = w.shape print "dout.shape", dout.shape x_col = im2col(x, HF, WF, conv_param['pad'], conv_param['stride']) #转换后变成(HF*WF*DF,N*Hout*Wout) print "x_col.shape", x_col.shape w_col = w.transpose(3, 0, 1, 2).reshape((NF, -1)) #每一行是一个卷积核 #w_col的维度是(NF,HF,WF,DF),reshape成(NF,HF*WF*DF) db = np.sum(dout, axis=(0, 1, 3)) dout = dout.transpose(2, 0, 1, 3) #(NF,Hout,Wout, N) dout = dout.reshape((w_col.shape[0], x_col.shape[-1])) #(NF,N*Hout*Wout) dx_col = w_col.T.dot(dout) #当前层的残差 , (HF*WF*DF, N*Hout*Wout),和x_col的维度相同 dw_col = dout.dot(x_col.T) #当前层关于卷积核的梯度 dx = col2im(dx_col, x.shape, HF, WF, conv_param['pad'], conv_param['stride']) dw = dw_col.reshape((dw_col.shape[0], HF, WF, DF)) dw = dw.transpose(1, 2, 3, 0) return [dx, dw, db]
import col2im as Col2im import im2col as Im2col import numpy as np test=np.random.randn(4,4,4,4) print(test[1,2,3]) print(test.shape) im2col_test=Im2col.im2col(test,5,5,1,0) print(im2col_test.shape) #col2im_test=Col2im.col2im(im2col_test,im2col_test.shape,5,5,1,0)
def DenoiseImage(Image, Param, seed): NN1, NN2 = Image.shape C = 1.15 bb = 8 maxNumBlocksToTrainOn = 1000 sigma = Param.noise K = Param.k class Par(): pass param = Par() param.K = K param.I = range(K) param.itN = 10 param.errorGoal = sigma * C # first, train a dictionary on blocks from the noisy image if np.prod(np.array([NN1, NN2]) - bb + 1) > maxNumBlocksToTrainOn: np.random.seed(seed) randPermutation = np.random.permutation( np.prod(np.array([NN1, NN2]) - bb + 1)) selectedBlocks = randPermutation[0:maxNumBlocksToTrainOn] blkMatrix = np.zeros((bb**2, maxNumBlocksToTrainOn)) for i in range(maxNumBlocksToTrainOn): row, col = np.unravel_index(selectedBlocks[i], tuple(np.array(Image.shape) - bb + 1), order='F') currBlock = Image[row:row + bb, col:col + bb] blkMatrix[:, i] = np.reshape(currBlock, (-1, ), order='F') else: blkMatrix = im2col(Image, (bb, bb)) ######## Make initial dictionary from DCT ########### Pn = int(np.ceil(np.sqrt(K))) DCT = np.zeros((bb, Pn)) for k in range(Pn): V = np.cos(np.array(range(bb)) * k * np.pi / Pn) if k > 0: V = V - np.mean(V) DCT[:, k] = V / np.linalg.norm(V) DCT = np.kron(DCT, DCT) ##################################################### param.initialDictionary = DCT[:, 0:param.K] # reducedc vecOfMeans = np.mean(blkMatrix, axis=0) blkMatrix = blkMatrix - np.dot(np.ones( (blkMatrix.shape[0], 1)), np.reshape(vecOfMeans, (1, -1), order='F')) if (Param.method == 'RSimCo'): print 'Executing RSimCo...' Dictionary = RSimCo(blkMatrix, param) elif (Param.method == 'PSimCo'): print 'Executing PSimCo...' Dictionary = PSimCo(blkMatrix, param) elif (Param.method == 'GDDL'): print 'Executing GDDL...' param.MomentumGamma = 0.5 param.alpha = 0.005 Dictionary = GDDL(blkMatrix, param) elif (Param.method == 'GDBTLS'): print 'Executing GDBTLS...' param.alpha = 0.005 Dictionary = GDBTLS(blkMatrix, param) elif (Param.method == 'RGDBTLS'): print 'Executing RGDBTLS...' param.alpha = 0.005 param.mu = 0.05 Dictionary = RGDBTLS(blkMatrix, param) elif (Param.method == 'MODDL'): print 'Executing MODDL...' Dictionary = MODDL(blkMatrix, param) elif (Param.method == 'KSVDDL'): print 'Executing KSVDDL...' Dictionary = KSVDDL(blkMatrix, param) else: raise ('No Method Defined') #denoise the image using the resulted dictionary errT = sigma * C blocks = im2col(Image, (bb, bb)) idx = range(blocks.shape[1]) # go with jumps of 30000 for jj in range(0, blocks.shape[1], 30000): jumpSize = min(jj + 30000, blocks.shape[1]) #reduceDC vecOfMeans = np.mean(blocks[:, jj:jumpSize], axis=0) blocks[:, jj:jumpSize] = blocks[:, jj:jumpSize] - np.tile( vecOfMeans, (blocks.shape[0], 1)) Coefs = omperr(Dictionary, blocks[:, jj:jumpSize], errT) #reducedc blocks[:,jj:jumpSize] = np.dot(Dictionary,Coefs) + \ np.dot(np.ones((blocks.shape[0],1)),np.reshape(vecOfMeans,(1,-1),order='F')) count = 0 Weight = np.zeros((NN1, NN2)) IMout = np.zeros((NN1, NN2)) rows, cols = np.unravel_index(idx, tuple(np.array(Image.shape) - bb + 1), order='F') for i in range(len(cols)): col = cols[i] row = rows[i] block = np.reshape(blocks[:, count], (bb, bb), order='F') IMout[row:row + bb, col:col + bb] = IMout[row:row + bb, col:col + bb] + block Weight[row:row + bb, col:col + bb] = Weight[row:row + bb, col:col + bb] + np.ones( (bb, bb)) count = count + 1 IOut = (Image + 0.034 * sigma * IMout) / (1.0 + 0.034 * sigma * Weight) return IOut
'./model/cnn.h5', './logs/cnn_history.csv', epoches=400, batch_size=128, names='cnn') #construct and train fully connected network np.random.seed(14343) fcnn = net.fcOneLayer((16, )) #load the initialzation from CNN's initialzation w1new = np.reshape(W1_cnn, (-1, 128)) fcnn.get_layer('conv').set_weights((w1new, )) fcnn.get_layer('dense').set_weights((W2_cnn, )) #prepare data for training fully connected network N, _, _, _ = x_train.shape X_train = conveter.im2col(x_train, (128, 4, 4, 1), 2, (1, 13, 13, 128)) X_test = conveter.im2col(x_test, (128, 4, 4, 1), 2, (1, 13, 13, 128)) X_train = np.reshape(X_train, (1000, -1, 16)) X_test = np.reshape(X_test, (1000, -1, 16)) tr.trainMSE(fcnn, X_train, x_train, X_test, x_test, './logs/fcnn_batch.csv', './model/fcnn.h5', './logs/fc_history.csv', epoches=400, batch_size=128, names='fc')
def decompose_filter(parent_filter_wt, filters=16): lamda = 0.0001 error = 1e-7 c1 = parent_filter_wt.shape[1] c2 = parent_filter_wt.shape[0] k = parent_filter_wt.shape[2] k1 = k k2 = k k_expanded = k1 + k2 - 1 pad_zero = nn.ZeroPad2d((k_expanded - k) / 2) new_weight = pad_zero(parent_filter_wt) # new_weight = add_noise(new_weight, new_weight) new_weight = new_weight.cpu().numpy() # output is the original parent filter which is generated by # convolving an image (=img_col) by filter (=kernel) # output_col is the 2D representation of an output generated after matrix # multiplication # output = new_weight # wt = parent_filter_wt.cpu().numpy() # mean = wt.mean() # std = wt.std() # var = wt.var() output = np.concatenate( (new_weight, np.zeros((c2, c2 - c1, k_expanded, k_expanded))), axis=1) output = np.concatenate( (output, np.zeros((filters - c2, c2, k_expanded, k_expanded))), axis=0) # NOISE_RATIO = 1e-5 # noise_range = NOISE_RATIO * np.ptp(parent_filter_wt.flatten()) # noise = np.random.uniform(-noise_range, noise_range, size=output.shape) # output = output + noise output_col = output.reshape(filters, -1).T # output_col2 = np.random.normal(0, 1e-2, size=output_col.shape) # print np.linalg.norm(output_col2 - output_col) # exit() # Below 2 lines can be removed # kernel is equivalent to filter f1 which will convolve image (=img_col) kernel = np.random.normal(0, 1e-3, size=(filters, c1, k1, k1)) kernel = np.concatenate( (kernel, np.zeros((filters, filters - c1, k1, k1))), axis=1) # kernel = np.random.choice(output.flatten(), size=(c2, filters, k1, k1)) kernel_col = kernel.reshape(filters, -1).T # img is the f2 filter treated as image to be convolved by f1(=kernel) # img_col is the 2D representation of a filter for matrix multiplication img = np.random.normal(0, 1e-3, size=(c2, filters, k2, k2)) # # img = np.random.choice(output.flatten(), size=(c2, filters, k2, k2)) img_col = im2col.im2col(img, k1, k1, stride=1, padding=k_expanded - k) # img_col = np.random.normal( # 0, 1e-2, size=(k_expanded * k_expanded * c2, k1 * k1 * filters)) # img_col_original = img_col.copy() # kernel_col = np.linalg.lstsq(img_col, output_col, rcond=None)[0] print kernel_col.shape print img_col.shape print output_col.shape print 'before calculating prod: ', print np.linalg.norm(np.dot(img_col, kernel_col) - output_col) # exit() for i in range(10): img_col = np.linalg.solve( np.dot(kernel_col, kernel_col.T) + lamda * np.eye( kernel_col.shape[0]), np.dot(kernel_col, output_col.T)).T kernel_col = np.linalg.solve( img_col.T.dot(img_col) + lamda * np.eye(img_col.shape[1]), np.dot(img_col.T, output_col)) print np.linalg.norm(np.dot(img_col, kernel_col) - output_col) if np.linalg.norm(np.dot(img_col, kernel_col) - output_col) < error: break x1 = img_col # c = 0.25 # kernel_col = kernel_col * c # img_col = img_col / c # Using Weighted ALS # print output_col # z = output_col > 0 # z = z.astype(np.float32) # for n in range(20): # for i, zi in enumerate(z): # img_col[i] = np.linalg.solve( # np.dot(kernel_col, np.dot(np.diag(zi), kernel_col.T)) + lamda * np.eye(kernel_col.shape[0]), # np.dot(kernel_col, np.dot(np.diag(zi), output_col[i].T))).T # # for j, zj in enumerate(z.T): # kernel_col[:, j] = np.linalg.solve( # np.dot(img_col.T, np.dot(np.diag(zj), img_col)) + lamda * np.eye(img_col.shape[1]), # np.dot(img_col.T, np.dot(np.diag(zj), output_col[:, j]))) # # print np.linalg.norm(np.dot(img_col, kernel_col) - output_col) # if np.linalg.norm(np.dot(img_col, kernel_col) - output_col) < error: # break print 'after calculating prod: ', new_prod = np.dot(img_col, kernel_col) print np.linalg.norm(new_prod - output_col) kernel = kernel_col.T.reshape(filters, filters, k1, k1) kernel = kernel[:, :c1, ...] print 'diff pad', print k_expanded - k img_calculated = im2col.col2im(col=img_col, input_shape=(c2, filters, k2, k2), filter_h=k1, filter_w=k1, padding=k_expanded - k) # img_calculated = im2col.recover_input( # input=img_col, kernel_size=k1, stride=1, outshape=(c2, filters, k2, k2)) img_calculated = img_calculated / 9 # because original matrix elements are added 9 times , for double padding # img_calculated = img_calculated/[[1, 2, 1], [2, 4, 2], [1, 2, 1]] for zero padding # img = (img / ([[4, 6, 4], [6, 9, 6], [4, 6, 4]]))/ for single padding # print 'image_col error: ', # print np.linalg.norm((img_col - img_col_original)) print 'image error: ', print np.linalg.norm((img_calculated - img)) # img_col2 = im2col.im2col(img_calculated, k1, k1, stride=1, padding=k_expanded - k) print 'after converting, product error = ', print np.linalg.norm(img_col2 - x1) # exit() # exit() # img = im2col.recover_input(input=img_col, kernel_size=k1, stride=1, # outshape=(c2, c, k2, k2)) # exit() # ************************************************************* # img = np.random.normal(0, 1e-2, size=(4, 4, 3, 3)) # original_img = img.copy() # img_col = im2col.im2col(img, 3, 3, 1, 2) # original_img_col = img_col.copy() # # print img_col # # img_col = np.random.randint(0, 4, size=(100, 36)) # # print img_col[0, 0] # # kernel_col = np.random.randint(0, 2, size=(36, 4)) # output_col = np.random.normal(0, 1e-2, size=(100, 4)) # # kernel_col = np.linalg.lstsq(img_col, output_col, rcond=None)[0] # # for i in range(100): # img_col = np.linalg.solve( # np.dot(kernel_col, kernel_col.T) + lamda * np.eye( # kernel_col.shape[0]), # np.dot(kernel_col, output_col.T)).T # # kernel_col = np.linalg.solve( # img_col.T.dot(img_col) + lamda * np.eye(img_col.shape[1]), # np.dot(img_col.T, output_col)) # # # print np.linalg.norm(np.dot(img_col, kernel_col) - output_col) # if np.linalg.norm(np.dot(img_col, kernel_col) - output_col) < error: # break # # print 'before converting after calcultating', # new_prod = np.dot(img_col, kernel_col) # print np.linalg.norm(new_prod - output_col) # # print np.linalg.norm(img_col - original_img_col) # img = im2col.col2im(img_col, (4, 4, 3, 3), 3, 3, padding=2) # img = img / 9 # # print np.linalg.norm(img - original_img) # img_col2 = im2col.im2col(img, 3, 3, padding=2) # new_prod = np.dot(img_col2, kernel_col) # print np.linalg.norm(new_prod - output_col) # exit() # ************************************************************* print parent_filter_wt.shape print kernel.shape print img_calculated.shape exit() return kernel, img_calculated
import im2col as Im2col import numpy as np x1 = np.random.rand(1, 3, 7, 7) print(x1.shape) col1 = Im2col.im2col(x1, 5, 5, stride=1, pad=0) print('这是x1变换之后的样子') print(col1.shape) x2 = np.random.rand(10, 3, 7, 7) print(x2.shape) col2 = Im2col.im2col(x2, 5, 5, stride=1, pad=0) print('这是x2变换之后的样子') print(col2.shape)
#load the fully connected network and construct an intermidate model that can get the output of the first dense layer in fc network. fcnn = net.fcOneLayer((13 * 13, 16)) fcnn.load_weights('./model/fcnn.h5') fcnn_conv = Model(inputs=fcnn.input, outputs=fcnn.get_layer('conv').output) #fecth the weights of the first dense layer in fc network. W2 = fcnn.get_layer('conv').get_weights()[0].flatten() #compute the mean and standard deviation of the weights mean1 = np.mean(W2) s = np.std(W2) print('CNN weight matrix mean {}, std {}'.format(mean1, s)) #convert data to 2D matrices N, _, _, _ = x_train.shape print(x_train.shape) X_train = conveter.im2col(x_train, (128, 4, 4, 1), 2, (1000, 13, 13, 128)) print(X_train.shape) X_train = np.reshape(X_train, (1000, -1, 16)) print(X_train.shape) outfc = fcnn_conv.predict(X_train, batch_size=100, verbose=0) #compute F-norm of the outputs of the two intermidate models difference = 0.0 for i in range(1000): difference = difference + np.linalg.norm( (outcnn[i].flatten() - outfc[i].flatten())) print(difference / 1000.0) K.clear_session() #draw the hist figures of the filters and the weights import numpy
# -*- coding: utf-8 -*- """ Created on Fri Sep 20 15:41:07 2019 @author: HAX """ import sys, os sys.path.append(os.pardir) from im2col import im2col import numpy as np x1 = np.random.rand(1, 3, 7, 7) col1 = im2col(x1, 5, 5, stride=1, pad=0) print(col1.shape) x2 = np.random.rand(10, 3, 7, 7) col2 = im2col(x2, 5, 5, stride=1, pad=0) print(col2.shape)