def WNLL(self, x, target, numKnown1, numKnown2, numUnknown, numTest, num_s=1, num_s_normal=1): #def WNLL(self, x, target, numKnown1, numKnown2, numUnknown, numTest, num_s=5, num_s_normal=2): #def WNLL(self, x, target, numKnown1, numKnown2, numUnknown, numTest, num_s=3, num_s_normal=1): """ WNLL interpolation. #Arguments: x: the entire data to be transformed by the DNN. target: the label of the entire data. numKnown1: the number of the data with known label in training set. numKnown2: the number of data with known label but regared as without in training set. numUnknown: the number of data without label in the training set. numTest: the number of data in the test set. num_s: # of nearest neighbors used for WNLL interpolation. num_s_normal: the index of nearest neighbor for weights normalization. """ if (numTest is not 0) and (numUnknown is not 0): """ Semi-supervised learning. Now, we have two stages, first infer the label for unknown instance. Then use known and unknown data to infer label for Test data. """ # xdata: numpy array representation of the whole data xdata = x.clone().cpu().data.numpy() x_whole = copy.deepcopy(xdata) x_Known = copy.deepcopy(xdata[:(numKnown1+numKnown2)]) x_Unknown = copy.deepcopy(xdata[(numKnown1+numKnown2):(numKnown1+numKnown2+numUnknown)]) x_Test = copy.deepcopy(xdata[-numTest:]) x_whole_Train = np.append(x_Known, x_Unknown, axis=0) # targetdata: numpy array representation of the label for the whole data. targetdata = target.clone().cpu().data.numpy() target_whole = copy.deepcopy(targetdata) target_Known = copy.deepcopy(targetdata[:(numKnown1+numKnown2)]) target_Unknown = copy.deepcopy(targetdata[(numKnown1+numKnown2):(numKnown1+numKnown2+numUnknown)]) target_Test = copy.deepcopy(targetdata[-numTest:]) target_whole_Train = np.append(target_Known, target_Unknown, axis=0) #------------------------------------------------------------------ # First step, infer the label for the unknown data #------------------------------------------------------------------ # f: total number of instances. # dim: the total number of classes. f, dim = int(x_whole_Train.shape[0]), int(np.max(target_whole_Train)+1) # The prior label of all instances in train set by solving the graph Laplacian. u_prior = np.zeros((f, dim)) num_classes = dim; k = num_classes; ndim = x_whole_Train.shape[0] idx_fidelity = range(numKnown1+numKnown2) fidelity = np.asarray([idx_fidelity, target_whole_Train[idx_fidelity]]).T # Compute the similarity matrix, exp(dist(kNN)). # Use num_s nearest neighbors, with the num_s_normal-th neighbor #to normalize the weights. W = weight_ann(x_whole_Train.T, num_s=15, num_s_normal=8) #W = weight_ann(x_whole_Train.T, num_s=5, num_s_normal=2) # Solve the graph Laplacian to get the prior label for each class. for i in range(k): g = np.zeros((fidelity.shape[0],)) tmp = fidelity[:, 1] tmp = tmp - i*np.ones((fidelity.shape[0],)) subset1 = np.where(tmp == 0)[0] g[subset1] = 1 idx_fidelity = fidelity[:, 0] total = range(0, f) idx_diff = [x1 for x1 in total if x1 not in idx_fidelity] # Convert idx_fidelity, idx_diff to integer. idx_fidelity = map(int, idx_fidelity) idx_diff = map(int, idx_diff) tmp = weight_GL(W, g, idx_fidelity, idx_diff, 1) # Assign the estimated prior label for ith class. u_prior[:, i] = tmp # WNLL re-interpolation. # The re-interpolation label. # Predict[-numUnknown:] is the posterior label for the unknown data. #But here in the training procedure, we consider the loss on the entire data. Predict = np.zeros((f, dim), dtype='float32') #num_s = 5; num_s_normal = 2; #Tunable parameters. Use this to maximize the accuracy. num_s = 1; num_s_normal = 1; #Tunable parameters. Use this to maximize the accuracy. # KNN search by ANN. flann = FLANN() idx1, dist1 = flann.nn( x_whole_Train, x_whole_Train, num_s, algorithm="kmeans", branching=32, iterations=50, checks=64 ) if num_s > 1: dist1 = dist1.T dist1 = dist1/(dist1[num_s_normal-1, :]+1.e-8) dist1 = dist1.T dist1 = -(dist1) w1 = np.exp(dist1) for i in range(f): tmp = np.zeros(dim,) if num_s > 1: for j in range(num_s): #print('IDX: ', idx1[i, j]) if idx1[i, j] >=0 and idx1[i, j] <= x_whole.shape[0]: tmp = tmp+w1[i, j]*u_prior[idx1[i, j]] else: print('IDX: ', idx1[i, j]) else: tmp = tmp + w1[i]*u_prior[idx1[i]] if np.sum(tmp): Predict[i, :] = tmp/np.sum(tmp) else: tmp = np.random.rand(10,) Predict[i, :] = tmp/np.sum(tmp) PredictLabel = np.argmax(Predict, axis=1) print('Accuracy in the first step of semi-supervised learning: ', (PredictLabel==target_whole_Train).sum()) #------------------------------------------------------------------ # Second step, infer the label for the test data #------------------------------------------------------------------ # f: total number of instances. # dim: the total number of classes. f, dim = int(x_whole.shape[0]), int(np.max(target_whole)+1) # The prior label of all instances in train set by solving the graph Laplacian. u_prior = np.zeros((f, dim)) num_classes = dim; k = num_classes; ndim = x_whole.shape[0] idx_fidelity = range(numKnown1+numKnown2+numUnknown) fidelity = np.asarray([idx_fidelity, target_whole[idx_fidelity]]).T # Compute the similarity matrix, exp(dist(kNN)). # Use num_s nearest neighbors, with the num_s_normal-th neighbor #to normalize the weights. W = weight_ann(x_whole.T, num_s=15, num_s_normal=8) #W = weight_ann(x_whole.T, num_s=5, num_s_normal=2) # Solve the graph Laplacian to get the prior label for each class. for i in range(k): g = np.zeros((fidelity.shape[0],)) tmp = fidelity[:, 1] tmp = tmp - i*np.ones((fidelity.shape[0],)) subset1 = np.where(tmp == 0)[0] g[subset1] = 1 idx_fidelity = fidelity[:, 0] total = range(0, f) idx_diff = [x1 for x1 in total if x1 not in idx_fidelity] # Convert idx_fidelity, idx_diff to integer. idx_fidelity = map(int, idx_fidelity) idx_diff = map(int, idx_diff) tmp = weight_GL(W, g, idx_fidelity, idx_diff, 1) # Assign the estimated prior label for ith class. u_prior[:, i] = tmp # WNLL re-interpolation. # The re-interpolation label. # Predict[-numUnknown:] is the posterior label for the unknown data. #But here in the training procedure, we consider the loss on the entire data. Predict = np.zeros((f, dim), dtype='float32') #num_s = 5; num_s_normal = 2; #Tunable parameters. Use this to maximize the accuracy. num_s = 1; num_s_normal = 1; #Tunable parameters. Use this to maximize the accuracy. # KNN search by ANN. flann = FLANN() idx1, dist1 = flann.nn( x_whole, x_whole, num_s, algorithm="kmeans", branching=32, iterations=50, checks=64 ) if num_s > 1: dist1 = dist1.T dist1 = dist1/(dist1[num_s_normal-1, :]+1.e-8) dist1 = dist1.T dist1 = -(dist1) w1 = np.exp(dist1) for i in range(f): tmp = np.zeros(dim,) if num_s > 1: for j in range(num_s): #print('IDX: ', idx1[i, j]) if idx1[i, j] >=0 and idx1[i, j] <= x_whole.shape[0]: tmp = tmp+w1[i, j]*u_prior[idx1[i, j]] else: print('IDX: ', idx1[i, j]) else: tmp = tmp + w1[i]*u_prior[idx1[i]] if np.sum(tmp): Predict[i, :] = tmp/np.sum(tmp) else: tmp = np.random.rand(10,) Predict[i, :] = tmp/np.sum(tmp) PredictLabel = np.argmax(Predict, axis=1) print('Accuracy in the second step of semi-supervised learning: ', (PredictLabel==target_whole).sum()) Predict = Variable(torch.Tensor(Predict).cuda()) # NOTE: here we use a FC layer to construct the computational graph, # which is pretrained in stage 1. In stage 2, we replace the data in # fc layer by the WNLL interpolation data. x = self.linear(x) x.data = Predict.data return x else: """ Regular learning. """ # xdata: numpy array representation of he whole data. # x_whole: the whole data (features). # x_Unknown: the features of the unknown instances. xdata = x.clone().cpu().data.numpy() x_whole = copy.deepcopy(xdata) x_Known = copy.deepcopy(xdata[:(x_whole.shape[0]-numKnown2-numUnknown-numTest)]) x_Unknown = copy.deepcopy(xdata[-(numKnown2+numUnknown+numTest):]) # targetdata: numpy array representation of the label for the whole data. targetdata = target.clone().cpu().data.numpy() # f: total number of instances. # dim: the total number of classes. f, dim = int(xdata.shape[0]), int(np.max(targetdata)+1) # The prior label of all instances inferred by solving the graph Laplacian. u_prior = np.zeros((f, dim)) #------------------------------------------------------------------ # Perform the nearest neighbor search and solve WNLL to find the # prior label: u_prior. #------------------------------------------------------------------ num_classes = dim k = num_classes ndim = xdata.shape[1] idx_fidelity = range(numKnown1) fidelity = np.asarray([idx_fidelity, targetdata[idx_fidelity]]).T # Compute the similarity matrix, exp(dist(kNN)). # Use num_s nearest neighbors, with the num_s_normal-th neighbor #to normalize the weights. W = weight_ann(x_whole.T, num_s=15, num_s_normal=8) #W = weight_ann(x_whole.T, num_s=5, num_s_normal=2) # Solve the graph Laplacian to get the prior label for each class. for i in range(k): g = np.zeros((fidelity.shape[0],)) tmp = fidelity[:, 1] tmp = tmp - i*np.ones((fidelity.shape[0],)) subset1 = np.where(tmp == 0)[0] g[subset1] = 1 idx_fidelity = fidelity[:, 0] total = range(0, f) idx_diff = [x1 for x1 in total if x1 not in idx_fidelity] # Convert idx_fidelity, idx_diff to integer. idx_fidelity = map(int, idx_fidelity) idx_diff = map(int, idx_diff) tmp = weight_GL(W, g, idx_fidelity, idx_diff, 1) # Assign the estimated prior label for ith class. u_prior[:, i] = tmp #-------------------------------------------------- # WNLL Re-interpolation #-------------------------------------------------- # The re-interpolation label. # Predict[-numUnknown:] is the posterior label for the unknown data. #But here in the training procedure, we consider the loss on the entire data. Predict = np.zeros((f, dim), dtype='float32') # KNN search by ANN. flann = FLANN() #idx1, dist1 = flann.nn( # x_whole, x_Unknown, num_s, algorithm="kmeans", # branching=32, iterations=50, checks=64 # ) idx1, dist1 = flann.nn( x_whole, x_whole, num_s, algorithm="kmeans", branching=32, iterations=50, checks=64 ) if num_s > 1: dist1 = dist1.T dist1 = dist1/(dist1[num_s_normal-1, :]+1.e-8) dist1 = dist1.T dist1 = -(dist1) w1 = np.exp(dist1) for i in range(f): tmp = np.zeros(dim,) if num_s > 1: for j in range(num_s): #print('IDX: ', idx1[i, j]) if idx1[i, j] >=0 and idx1[i, j] <= x_whole.shape[0]: tmp = tmp+w1[i, j]*u_prior[idx1[i, j]] else: print('IDX: ', idx1[i, j]) else: tmp = tmp + w1[i]*u_prior[idx1[i]] if np.sum(tmp): Predict[i, :] = tmp/np.sum(tmp) else: tmp = np.random.rand(10,) Predict[i, :] = tmp/np.sum(tmp) Predict = Variable(torch.Tensor(Predict).cuda()) # NOTE: here we use a FC layer to construct the computational graph, # which is pretrained in stage 1. In stage 2, we replace the data in # fc layer by the WNLL interpolation data. x = self.linear(x) x.data = Predict.data return x
def WNLL(self, x, target, numTrain, numTest, num_s=1, num_s_normal=1): """ WNLL Interpolation # Argument: x: the entire data to be transformed by the DNN. target: the label of the entire data, x. numTrain: the number of data in the training set. numTest: the number of data in the testing set. num_s: # of nearest neighbors used for WNLL interpolation. num_s_normal: the index of nearest neighbor for weights normalization. """ # xdata: numpy array representation of the whole data # x_whole: the whole data (features) # x_Unknown: the features of the unknown instances xdata = x.clone().cpu().data.numpy() x_whole = copy.deepcopy(xdata) x_Known = copy.deepcopy(xdata[:numTrain]) x_Unknown = copy.deepcopy(xdata[numTrain:]) # targetdata: numpy array representation of the label for the whole data targetdata = target.clone().cpu().data.numpy() # f: total number of instances. # dim: the total number of classes. f, dim = int(xdata.shape[0]), int(np.max(targetdata) + 1) Predict = np.zeros((f, dim)) #---------------------------------------------------------------------- # Perform the nearest neighbor search and solve WNLL to find the predicted #labels: Predict #---------------------------------------------------------------------- num_classes = dim k = num_classes ndim = xdata.shape[1] idx_fidelity = range(numTrain) fidelity = np.asarray([idx_fidelity, targetdata[idx_fidelity]]).T # Compute the similarity matrix, exp(dist(kNN)). # Use num_s nearest neighbors, with the num_s_normal-th neighbor #to normalize the weights. W = weight_ann(x_whole.T, num_s=15, num_s_normal=8) # Solve the graph Laplacian to get the prior label for each class. for i in range(k): g = np.zeros((fidelity.shape[0], )) tmp = fidelity[:, 1] tmp = tmp - i * np.ones((fidelity.shape[0], )) subset1 = np.where(tmp == 0)[0] g[subset1] = 1 idx_fidelity = fidelity[:, 0] total = range(0, f) idx_diff = [x1 for x1 in total if x1 not in idx_fidelity] # Convert idx_fidelity, idx_diff to integer. idx_fidelity = map(int, idx_fidelity) idx_diff = map(int, idx_diff) tmp = weight_GL(W, g, idx_fidelity, idx_diff, 1) # Assign the estimated prior label for ith class. Predict[:, i] = tmp Predict = Variable(torch.Tensor(Predict).cuda()) x = self.linear(x) x.data = Predict.data return x