def train_model(model_id, idx_train, idx_val, idx_test): ''' @Description : @Time :2020/07/24 13:59:21 @Author :sam.qi @Param : @Return : ''' # data preprare use_cuda = True if use_cuda: device = torch.device(str.format( 'cuda:{}', model_id)) if torch.cuda.is_available() else 'cpu' else: device = torch.device('cpu') adj = g_adj.to(device) features = g_features.to(device) labels = g_labels.to(device) # 3 Setup victim model print("Creating GCN model...") victim_model = GCN.GCN(nfeat=features.shape[1], lr=0.001, nclass=int(labels.max().item()) + 1, nhid=100, dropout=0.5, weight_decay=5e-4, device=device) victim_model = victim_model.to(device) print("Start fitting GCN...") victim_model.fit(features, adj, labels, idx_train, idx_val, train_iters=100000, normalize=False, verbose=True) # setattr(victim_model, 'norm_tool', GraphNormTool(normalize=True, gm='gcn', device=device)) # 4 validation on 80% test data output = victim_model.predict(features, adj) loss_test = F.nll_loss(output[idx_test], labels[idx_test]) acc_test = GCN.accuracy(output[idx_test], labels[idx_test]) print("Init test set results:", "loss= {:.4f}".format(loss_test.item()), "accuracy= {:.4f}".format(acc_test.item())) torch.save(victim_model.state_dict(), 'gcn_%s.pth' % (str(model_id))) print(str.format("Finished Model :{}", i))
def __init__(self, n: int, ea: int, na: int, h_dim: int = 512, z_dim: int = 2): """ Graph Variational Auto Encoder Args: n : Number of nodes na : Number of node attributes ea : Number of edge attributes h_dim : Hidden dimension z_dim : latent dimension """ super().__init__() self.n = n self.na = na self.ea = ea input_dim = n * n + n * na + n * n * ea self.input_dim = input_dim self.z_dim = z_dim nfeat = na + ea * n # We concat the edge attribute matrix with the node attribute matrix. Lets see what happens. self.encoder = GCN(nfeat, h_dim, z_dim) self.decoder = nn.Sequential(nn.Linear(z_dim, 2 * h_dim), nn.ReLU(), nn.Dropout(.2), nn.Linear(2 * h_dim, h_dim), nn.ReLU(), nn.Linear(h_dim, input_dim), nn.Sigmoid()) # Need to init? for m in self.modules(): if isinstance(m, nn.Linear): nn.init.xavier_uniform(m.weight, gain=0.01)
def applyGCN(img): flatimg = np.array(np.reshape(img, 32 * 32), ndmin=2) gcn = GCN.global_contrast_normalize(flatimg, scale=1., subtract_mean=True, use_std=True, sqrt_bias=10., min_divisor=1e-8) return gcn.reshape((32, 32, 1))
def forward_propagation(self): with tf.variable_scope('weights_n'): A = tf.reshape(self.a, [self.meta, self.nodes*self.nodes]) A_ = tf.transpose(A, [1, 0]) #dimention exchange WW = tf.nn.sigmoid(tf.get_variable('W', shape=[self.meta, 1], initializer=tf.contrib.layers.xavier_initializer())) weighted_adj = tf.matmul(A_, WW)# add all meta based matrix # (5000*5000, 1) weighted_adj = tf.reshape(weighted_adj, [1, self.nodes, self.nodes]) # Wone = tf.constant([[1.0], [1.0], [1.0]], dtype=tf.float32 ) # weighted_oneadj = tf.matmul(A_, Wone) # weighted_oneadj = tf.reshape(weighted_oneadj, [1, self.nodes, self.nodes]) WL2 = tf.nn.sigmoid(tf.get_variable('WL2', shape=[self.meta, 1], initializer=tf.contrib.layers.xavier_initializer())) weighted_L2adj = tf.matmul(A_, WL2) weighted_L2adj = tf.reshape(weighted_L2adj, [1, self.nodes, self.nodes]) with tf.variable_scope('spectral_gcn'): outputlist = [self.gcn_output2, self.encoding_size] L1out = GCN(tf.expand_dims(self.x, 0), weighted_adj, [self.gcn_output1]).build() L2out = GCN(tf.expand_dims(L1out[0], 0), weighted_L2adj, [self.gcn_output1]).build() for output in outputlist: #gcn_out = GCN(tf.expand_dims(self.x, 0), weighted_adj, [self.gcn_output1, self.gcn_output2, self.encoding_size]).build() L1out = GCN(tf.expand_dims(L2out[0], 0), weighted_adj, [output]).build() L2out = GCN(tf.expand_dims(L1out[0], 0), weighted_L2adj, [output]).build() with tf.variable_scope('classification'): batch_data = tf.matmul(tf.one_hot(self.batch_index, self.nodes), L2out[0]) #batch_data = tf.matmul(tf.one_hot(self.batch_index, self.nodes), gcn_out[0]) W = tf.get_variable(name='weights', shape=[self.encoding_size, self.class_size], initializer=tf.contrib.layers.xavier_initializer()) #W = tf.get_variable(name='weights', shape=[self.encoding_size, self.class_size], initializer=tf.random_normal_initializer()) b = tf.get_variable(name='bias', shape=[1, self.class_size], initializer=tf.zeros_initializer()) logits = tf.matmul(batch_data, W) + b #loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=self.t, logits=logits) loss = tf.losses.softmax_cross_entropy(onehot_labels=self.t, logits=logits) return loss, tf.nn.softmax(logits), L2out[0]
def predict(adj, features, output_prob=False): start = datetime.datetime.now() use_cuda = True if use_cuda: device = torch.device('cuda') if torch.cuda.is_available() else 'cpu' else: device = torch.device('cpu') # load the trained GCN to attack victim_model = GCN.GCN(nfeat=100, lr=0.01, nclass=20, nhid=100, dropout=0.5, weight_decay=5e-4, device=device) victim_model.load_state_dict( torch.load(str.format('neutrino/gcn_{}.pth', 32))) victim_model = victim_model.to(device) stage1 = datetime.datetime.now() time_span = (stage1 - start).seconds print(str.format("--------------GCN [model To Devide] : {}s", time_span)) # normalize adj_norm = utils.normalize_adj(adj) adj_norm = utils.sparse_mx_to_torch_sparse_tensor(adj_norm).to(device) features = torch.FloatTensor(features).to(device) stage2 = datetime.datetime.now() time_span = (stage2 - stage1).seconds print(str.format("--------------GCN [Data To Devide] : {}s", time_span)) output = victim_model.predict(features, adj_norm) stage3 = datetime.datetime.now() time_span = (stage3 - start).seconds print(str.format("--------------GCN [Model Predict] : {}s", time_span)) if output_prob == False: result = output.max(1)[1].cpu().detach().numpy() else: result = output.cpu().detach().numpy() stage4 = datetime.datetime.now() time_span = (stage4 - stage3).seconds print(str.format("--------------GCN [Result Collect] : {}s", time_span)) return result
def sub_GIN(self): gcn_outs = [] for i in range(self.num_subg): self.d_matrix = self.sub_adj[:, i, :, :] gcn_out = GCN( self.sub_feature[:, i, :, :], self.d_matrix, self.output_dim, dropout=0.5).build() for i in range(1): gcn_out = self.mlp( gcn_out, self.output_dim[i], self.GIN_dim[i]) gcn_outs.append(tf.reshape( gcn_out, [-1, 1, gcn_out.shape[1] * gcn_out.shape[2]])) self.gcn_result = tf.concat(gcn_outs, 1) gcn_outs_dsi = [] for i in range(self.num_subg): self.d_matrix_dsi = self.sub_adj[:, i, :, :] gcn_out_dsi = GCN( self.sub_feature_dsi[:, i, :, :], self.d_matrix_dsi, self.output_dim, dropout=0.5).build() for i in range(1): gcn_out_dsi = self.mlp( gcn_out_dsi, self.output_dim[i], self.GIN_dim[i]) gcn_outs_dsi.append(tf.reshape( gcn_out_dsi, [-1, 1, gcn_out_dsi.shape[1] * gcn_out_dsi.shape[2]])) self.gcn_result_dsi = tf.concat(gcn_outs_dsi, 1)
def sub_GCN(self): gcn_outs = [] W = tf.Variable(tf.random.truncated_normal( [self.subg_size, 1], stddev=0.1)) for i in range(self.num_subg): self.d_matrix = self.sub_adj[:, i, :, :] gcn_out = GCN( self.sub_feature[:, i, :, :], self.d_matrix, self.output_dim, dropout=0.5).build() gcn_out = tf.matmul(tf.transpose(gcn_out, [0, 2, 1]), W) gcn_outs.append(tf.reshape(gcn_out, [-1, 1, gcn_out.shape[1]])) self.gcn_result = tf.concat(gcn_outs, 1) gcn_outs_dsi = [] W_dsi = tf.Variable(tf.random.truncated_normal( [self.subg_size, 1], stddev=0.1)) for i in range(self.num_subg): self.d_matrix_dsi = self.sub_adj[:, i, :, :] gcn_out_dsi = GCN( self.sub_feature_dsi[:, i, :, :], self.d_matrix_dsi, self.output_dim, dropout=0.5).build() gcn_out_dsi = tf.matmul(tf.transpose( gcn_out_dsi, [0, 2, 1]), W_dsi) gcn_outs_dsi.append(tf.reshape( gcn_out_dsi, [-1, 1, gcn_out_dsi.shape[1]])) self.gcn_result_dsi = tf.concat(gcn_outs_dsi, 1)
def forward_propagation(self): # input ==> (13, 5000, 5000) # self.x ==> (5000, 1000) # self.t ==> (5000,) # attention ==> (1, 5000, 2084) with tf.variable_scope('weights_n'): A = tf.reshape(self.a, [self.meta, self.nodes*self.nodes]) A_ = tf.transpose(A, [1, 0]) W = tf.nn.sigmoid(tf.get_variable('W', shape=[self.meta, 1], initializer=tf.contrib.layers.xavier_initializer())) weighted_adj = tf.matmul(A_, W) # (5000*5000, 1) weighted_adj = tf.reshape(weighted_adj, [1, self.nodes, self.nodes]) with tf.variable_scope('spectral_gcn'): gcn_out = GCN(tf.expand_dims(self.x, 0), weighted_adj, [self.gcn_output1, self.gcn_output2, self.class_size]).build() ''' with tf.variable_scope('attention_n'): attention_output = attention_model.inference(gcn_out,64,0,hid_units,n_heads,nonlinearity,residual) ''' with tf.variable_scope('extract_n'): p1 = tf.one_hot(self.p1, tf.to_int32(self.nodes)) p1 = tf.matmul(p1, gcn_out[0]) p2 = tf.one_hot(self.p2, tf.to_int32(self.nodes)) p2 = tf.matmul(p2, gcn_out[0]) # p3 = tf.one_hot([3000], tf.to_int32(self.nodes)) # p3 = tf.matmul(p3, gcn_out[0]) with tf.variable_scope('cosine'): # p ==> (batch_size, feature) p1_norm = tf.sqrt(tf.reduce_sum(tf.square(p1), axis=1)) p2_norm = tf.sqrt(tf.reduce_sum(tf.square(p2), axis=1)) # p1_p2 = tf.reduce_sum(tf.multiply(p1, p2), axis=1) # cosine = p1_p2 / (p1_norm * p2_norm) # c = tf.expand_dims(cosine, -1) # prob = tf.concat([-c, c], axis=1) c = p1_norm / p2_norm c = tf.expand_dims(c, -1) # batch, 1 c = tf.concat([c, 1/c], axis=1) true_prob = -tf.log(tf.reduce_max(c, axis=1)-1+1e-8) true_p = tf.expand_dims(true_prob, -1) prob = tf.concat([-true_p, true_p], axis=1) loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=tf.one_hot(self.t, 2), logits=prob) return loss, tf.nn.sigmoid(true_prob), W, p1[0], p2[0]
def train_gcn(_An, _X_obs, _Z_obs, sizes, gpu_id=0): split_train = [i for i in range(493486)] split_val = [i + 493486 for i in range(50000)] split_test = [i + 543486 for i in range(50000)] with tf.Graph().as_default(): surrogate_model = GCN.GCN(sizes, _An, _X_obs, with_relu=False, name="surrogate", gpu_id=gpu_id) #surrogate_model.train(_An, _X_obs, split_train, split_val, _Z_obs, n_iters=400) surrogate_model.train(split_train, split_val, _Z_obs, n_iters=1000) ''' W1 = surrogate_model.W1.eval(session=surrogate_model.session) W2 = surrogate_model.W2.eval(session=surrogate_model.session) logits = surrogate_model.logits.eval(session = surrogate_model.session) ''' surrogate_model.session.close()
def fit(self): self.params.feat_dim = self.graph.feat_dim self.params.num_node = self.graph.num_node self.params.kernel_sizes = self.kernel_sizes self.params.num_kernel = self.num_kernel self.params.num_label = self.num_label random.shuffle(self.data) split_idx = int(len(self.data) / 10) train, test = self.data[:-split_idx], self.data[-split_idx:] with tf.Session(config=tf.ConfigProto( allow_soft_placement=True, gpu_options=tf.GPUOptions(per_process_gpu_memory_fraction=self.params.memory_fraction, allow_growth=True))) as sess: self.model = GCN(self.params, self.graph) sess.run(tf.global_variables_initializer()) for _ in tqdm(range(self.params.epoch), ncols=100): for i in tqdm(range(len(train)), ncols=100): data = train[i] sess.run(self.model.gradient_descent, feed_dict=self.feed_dict(data, True)) train_accuracy = self.eval(sess, train) test_accuracy = self.eval(sess, test) return train_accuracy, test_accuracy
def forward_propagation(self): with tf.variable_scope('weights_n'): A = tf.reshape(self.a, [self.meta, self.nodes * self.nodes]) A_ = tf.transpose(A, [1, 0]) #dimention exchange W = tf.nn.sigmoid( tf.get_variable( 'W', shape=[self.meta, 1], initializer=tf.contrib.layers.xavier_initializer())) weighted_adj = tf.matmul(A_, W) # add all meta based matrix weighted_adj = tf.reshape(weighted_adj, [1, self.nodes, self.nodes]) with tf.variable_scope('spectral_gcn'): gcn_out = GCN( tf.expand_dims(self.x, 0), weighted_adj, [self.gcn_output1, self.gcn_output2, self.encoding_size ]).build() with tf.variable_scope('classification'): batch_data = tf.matmul(tf.one_hot(self.batch_index, self.nodes), gcn_out[0]) #W = tf.get_variable(name='weights', shape=[self.encoding_size, self.class_size], initializer=tf.contrib.layers.xavier_initializer()) W = tf.get_variable(name='weights', shape=[self.encoding_size, self.class_size], initializer=tf.random_normal_initializer( mean=0.0, stddev=0.1)) b = tf.get_variable(name='bias', shape=[1, self.class_size], initializer=tf.zeros_initializer()) logits = tf.matmul(batch_data, W) + b #loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=self.t, logits=logits) #loss = tf.losses.softmax_cross_entropy(onehot_labels=self.t, logits=logits) loss = tf.losses.softmax_cross_entropy(onehot_labels=self.t, logits=logits) return loss, tf.nn.softmax(logits), gcn_out[0], logits
def adaptive_train(self, sizes, idx, split_train, split_val, perturb_features = True, direct_attack=True, verbose=True,): """ adaptive attack, AFGSM-ada :param sizes: list, the hidden size of GCN :param idx: int, the target node ID :param split_train: list, train set for GCN :param split_val: list, valuation set for GCN :param perturb_features: bool, if True, perturb features :param direct_attack: bool, if True, direct attack :param verbose: bool, whether to show losses """ true_label = np.argmax(self.Z[idx, :]) for i in range(self.num_vicious_nodes): with tf.Graph().as_default(): _An = utils.preprocess_graph(self.A) surrogate_model = GCN.GCN(sizes, _An, self.X, with_relu=False, name="surrogate",gpu_id=0) surrogate_model.train(split_train, split_val, self.Z) W1 = surrogate_model.W1.eval(session=surrogate_model.session) W2 = surrogate_model.W2.eval(session=surrogate_model.session) logits = surrogate_model.logits.eval(session=surrogate_model.session) surrogate_model.session.close() W = np.dot(W1, W2) best_wrong_label = np.argmax(logits[idx, :] - 1000 * self.Z[idx, :]) w = W[:, best_wrong_label] - W[:, true_label] w_idx = np.argsort(w)[::-1] for j in range(w_idx.shape[0]): if w[w_idx[j]] < 0: w_idx = w_idx[0:j] break self.D_inv = sp.diags(1 / self.degree) self.D_inv_sqrt = sp.diags(1 / np.sqrt(self.degree)) self.d_inv_sqrt = 1 / np.sqrt(self.degree) self.d_inv_sqrt = np.squeeze(self.d_inv_sqrt) if direct_attack: M1 = np.squeeze(1 / np.sqrt(self.dv[0]) * self.d_inv_sqrt*(self.X.dot(w))) else: M1 = None A_idx = self.A[:, idx] A_idx[idx] = 1 M2 = np.squeeze(self.d_inv_sqrt * A_idx) e = sp.csr_matrix(np.zeros((self.A.shape[0], 1))) x = self.X[np.random.randint(0, self.X.shape[0]), :] x_nnz = np.array(x.nonzero()) if x_nnz.shape[1] > self.X_d: sample_idx = np.random.randint(0, x_nnz.shape[1], size=[x_nnz.shape[1] - self.X_d]) x[:, x_nnz[:, sample_idx][1, :]] = 0 X_mod = sp.vstack((self.X, x)) z_vi = np.random.randint(0, self.Z.shape[1]) Z_vi = np.zeros((1, self.Z.shape[1]), dtype=np.int32) Z_vi[0, z_vi] = 1 Z = np.vstack((self.Z, Z_vi)) self.labels.append(np.random.randint(0, self.Z.shape[1])) if perturb_features: x = self.get_sampled_features(w, w_idx, False) X_mod = sp.vstack((self.X, x)) if direct_attack: grad_e = np.squeeze(M1 + M2 * (x.dot(w))) grad_e[idx] = 999999 else: grad_e = np.squeeze(M2 * (x.dot(w))) grad_e[idx] = -999999 gradients_idx = np.argsort(grad_e)[::-1][0:self.dv[i]] if np.sum(grad_e > 0) < self.dv[i]: e[grad_e > 0, 0] = 1 else: e[gradients_idx, 0] = 1 A_mod = sp.hstack((sp.vstack((self.A, e.T)), sp.vstack((e, 0)))) if verbose: with tf.Graph().as_default(): _An_mod = utils.preprocess_graph(A_mod) logits_attacked = _An_mod.dot(_An_mod).dot(X_mod).dot(W) loss_ = self.cal_loss(logits_attacked, idx) print("losses:", loss_) self.A = A_mod.tocsr() self.X = X_mod.tocsr() self.Z = Z self.old_degree = self.degree self.degree = list(self.degree) self.degree.append(np.sum(e) + 1) self.degree = np.array(self.degree) self.degree[e.nonzero()[0]] += 1
def forward_propagation(self): # node_size = 5000: # input ==> (13, 5000, 5000) # self.x ==> (5000, 1000) # self.t ==> (5000,) # attention ==> (1, 5000, 2084) # init 权重矩阵 with tf.variable_scope('weights_n'): A = tf.reshape(self.a, [self.meta, self.nodes * self.nodes]) A_ = tf.transpose(A, [1, 0]) # 转置,第二个参数是新的维度序列 # 返回一个用于初始化权重的初始化程序 “Xavier” 。这个初始化器是用来保持每一层的梯度大小都差不多相同。 W = tf.nn.sigmoid( tf.get_variable( 'W', shape=[self.meta, 1], initializer=tf.contrib.layers.xavier_initializer())) weighted_adj = tf.matmul(A_, W) # (5000*5000, 1) weighted_adj = tf.reshape(weighted_adj, [1, self.nodes, self.nodes]) with tf.variable_scope('spectral_gcn'): # gcn_out: [1, 5000, class_size] gcn_out = GCN( tf.expand_dims(self.x, 0), weighted_adj, # x是个2维tensor [self.gcn_output1, self.gcn_output2, self.class_size ]).build() # 【512,256,128】 print("gcn_out shape:", gcn_out.shape) ''' with tf.variable_scope('attention_n'): attention_output = attention_model.inference(gcn_out,64,0,hid_units,n_heads,nonlinearity,residual) ''' with tf.variable_scope('extract_n'): p1 = tf.one_hot(self.p1, tf.cast(self.nodes, tf.int32)) # 第一个参数指定独热位置,第2个参数是每个独热向量的维度 p1 = tf.matmul(p1, gcn_out[0]) p2 = tf.one_hot(self.p2, tf.cast(self.nodes, tf.int32)) p2 = tf.matmul(p2, gcn_out[0]) # gcn_out[0]: [5000,class_size] with tf.variable_scope('cosine'): # p ==> (batch_size, feature) p1_norm = tf.sqrt(tf.reduce_sum( tf.square(p1), axis=1)) # tf.reduce_sum: arg0表示要求和的数据,arg1=0表示纵向求和,=1横向求和 p2_norm = tf.sqrt(tf.reduce_sum(tf.square(p2), axis=1)) # p1_p2 = tf.reduce_sum(tf.multiply(p1, p2), axis=1) # cosine = p1_p2 / (p1_norm * p2_norm) # c = tf.expand_dims(cosine, -1) # prob = tf.concat([-c, c], axis=1) c = p1_norm / p2_norm c = tf.expand_dims(c, -1) # batch, 1 c = tf.concat([c, 1 / c], axis=1) # 将多个张量在维度上合并 true_prob = -tf.math.log( tf.reduce_max(c, axis=1) - 1 + 1e-8) # 同类得出的结果区间应在0~8 true_p = tf.expand_dims(true_prob, -1) prob = tf.concat([-true_p, true_p], axis=1) loss = tf.losses.sigmoid_cross_entropy( multi_class_labels=tf.one_hot(self.t, 2), logits=prob) # logits: 神经网络最后一层的输出 # loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=tf.one_hot(self.t, 2), logits=prob) # logits: 神经网络最后一层的输出 # tf.nn.sigmoid将true_prob映射到(0,1)区间 return loss, tf.nn.sigmoid(true_prob), W, p1[0], p2[0]
def forward_propagation(self): # input ==> (2187, 2187) # self.x ==> (2187, 1433) # self.t ==> (2187, 7) with tf.variable_scope('weights_n'): A = tf.reshape(self.a, [self.meta, self.nodes * self.nodes]) A_ = tf.transpose(A, [1, 0]) #dimention exchange WW = tf.nn.sigmoid( tf.get_variable( 'W', shape=[self.meta, 1], initializer=tf.contrib.layers.xavier_initializer())) weighted_adj = tf.matmul(A_, WW) # add all meta based matrix weighted_adj = tf.reshape(weighted_adj, [1, self.nodes, self.nodes]) # Wone = tf.constant([[1.0], [1.0], [1.0]], dtype=tf.float32, ) # weighted_oneadj = tf.matmul(A_, Wone) # weighted_oneadj = tf.reshape(weighted_oneadj, [1, self.nodes, self.nodes]) WL2 = tf.nn.sigmoid( tf.get_variable( 'WL2', shape=[self.meta, 1], initializer=tf.contrib.layers.xavier_initializer())) weighted_L2adj = tf.matmul(A_, WL2) weighted_L2adj = tf.reshape(weighted_L2adj, [1, self.nodes, self.nodes]) with tf.variable_scope('spectral_gcn'): #L1out = GCN(tf.expand_dims(self.x, 0), weighted_adj, [self.gcn_output1, self.gcn_output2, self.encoding_size]).build() L1out = GCN(tf.expand_dims(self.x, 0), weighted_adj, [self.gcn_output2]).build() print('self.x_type:', type(self.x)) print('self.x:', tf.expand_dims(self.x, 0)) _, L2out = modeL2.inference(L1out, self.class_size, self.nodes, self.is_train, self.attn_drop, self.ffd_drop, bias_mat=weighted_L2adj, hid_units=self.hid_units, n_heads=self.n_heads, residual=self.residual, activation=self.nonlinearity) #gcn_out = GCN(tf.expand_dims(self.x, 0), weighted_adj, [self.gcn_output1, self.gcn_output2, self.encoding_size]).build() # logits, out = modeL2.inference(gcn_out[0], self.class_size, self.nodes, self.is_train, # self.attn_drop, self.ffd_drop, # bias_mat=weighted_adj, # hid_units=self.hid_units, n_heads=self.n_heads, # residual=self.residual, activation=self.nonlinearity) with tf.variable_scope('classification'): batch_data = tf.matmul(tf.one_hot(self.batch_index, self.nodes), L2out[0]) W = tf.get_variable( name='weights', shape=[self.encoding_size, self.class_size], initializer=tf.contrib.layers.xavier_initializer()) #W = tf.get_variable(name='weights', shape=[self.encoding_size, self.class_size], initializer=tf.random_normal_initializer()) b = tf.get_variable(name='bias', shape=[1, self.class_size], initializer=tf.zeros_initializer()) logits = tf.matmul(batch_data, W) + b #loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=self.t, logits=logits) loss = tf.losses.softmax_cross_entropy(onehot_labels=self.t, logits=logits) return loss, tf.nn.softmax(logits), L2out[0]
next_train_data, next_train_label = train_iterator.get_next() test_dataset = tf.data.Dataset.from_generator(test_data_handle, output_types=(tf.float32, tf.float32)) test_dataset = test_dataset.shuffle(20).batch(BATCH_SIZE, drop_remainder=True).repeat() test_iterator = test_dataset.make_one_shot_iterator() next_test_data, next_test_label = test_iterator.get_next() print("*******************************************************") print("* Finish step 1: preparing data. *") X = tf.placeholder(tf.float32, [None, IMG_H, IMG_W, IMG_C], name="X") Y = tf.placeholder(tf.float32, [None, IMG_H, IMG_W, NUM_CLASSES]) _pred = GCN.build_gcn(X, NUM_CLASSES) tf.add_to_collection("infrence", _pred) #logits 是前向传播的结果,labels 是正确的标签 #print(_pred.shape, Y.shape) _pred_flatten = _pred #utils.label_before_cal_loss(_pred) Y_flatten = Y #utils.label_before_cal_loss(Y) #_pred_flatten = tf.concat() #print(_pred_flatten[0].shape) #print("len of prepare: ", utils.label_before_cal_loss(_pred).shape) #tf.layers.Flatten()(_pred) #Y_flatten = tf.layers.Flatten()(Y) #print(_pred_flatten.shape) #print(Y_flatten.shape) #softmax = tf.nn.softmax_cross_entropy_with_logits(logits = _pred_flatten, labels = Y_flatten) loss = utils.weighted_loss_v1(logits=_pred_flatten, labels=Y_flatten) #tf.reduce_mean(softmax)
def forward_propagation(self): # input ==> (13, 5000, 5000) # self.x ==> (5000, 1000) # self.t ==> (5000,) # attention ==> (1, 5000, 2084) # variable_scope: 一种共享变量的机制,管理传给get_variable()的变量名称的作用域 # 获取元路径权重,根据KIES的计算方式与adj矩阵相乘求和,得到邻接矩阵的数值 with tf.variable_scope('weights_n'): A = tf.reshape( self.a, [self.meta, self.nodes * self.nodes]) # 每个adj矩阵二维转一维 A_ = tf.transpose(A, [1, 0]) # 转置 # 创建元路径权重的变量(一个一维向量),初始由xavier_initializer创建 W = tf.nn.sigmoid( tf.get_variable( 'W', shape=[self.meta, 1], initializer=tf.contrib.layers.xavier_initializer())) weighted_adj = tf.matmul(A_, W) # 元路径权重在此! # (5000*5000, 1) # 尝试邻接矩阵归一化 wei_max = tf.reduce_max(weighted_adj, axis=0) wei_max = tf.expand_dims(wei_max, 1) wei_min = tf.reduce_min(weighted_adj, axis=0) wei_min = tf.expand_dims(wei_min, 1) p_up = weighted_adj - wei_min p_down = wei_max - wei_min weighted_adj = tf.divide(p_up, p_down) weighted_adj = tf.reshape(weighted_adj, [1, self.nodes, self.nodes]) # 一维转二维,搞回去 # GCN的操作,输入特征矩阵和邻接矩阵,输出为(1, 事件数, 分类数)的矩阵,即分类结果 with tf.variable_scope('spectral_gcn'): gcn_out = GCN(tf.expand_dims(self.x, 0), weighted_adj, [self.class_size]).build() ''' with tf.variable_scope('attention_n'): attention_output = attention_model.inference(gcn_out,64,0,hid_units,n_heads,nonlinearity,residual) ''' # 获取event instance在GCN内训练后对应的分类向量 with tf.variable_scope('extract_n'): p = tf.one_hot(self.p, tf.to_int32(self.nodes)) p = tf.matmul(p, gcn_out[0]) # p.shape=>(train_size, class_size) ''' # 生成one-hot向量的矩阵,即根据id确定行向量里哪个是1,其余都为0 p1 = tf.one_hot(self.p1, tf.to_int32(self.nodes)) # 和GCN的分类矩阵相乘,即把属于自己的那一行分类向量提出来 p1 = tf.matmul(p1, gcn_out[0]) p2 = tf.one_hot(self.p2, tf.to_int32(self.nodes)) p2 = tf.matmul(p2, gcn_out[0]) # p3 = tf.one_hot([3000], tf.to_int32(self.nodes)) # p3 = tf.matmul(p3, gcn_out[0]) ''' # 计算事件pair的模之比,得到是否属于同一类的预测值,交叉熵求loss with tf.variable_scope('cosine'): ''' # p ==> (batch_size, feature) p1_norm = tf.sqrt(tf.reduce_sum(tf.square(p1), axis=1)) p2_norm = tf.sqrt(tf.reduce_sum(tf.square(p2), axis=1)) # p1_p2 = tf.reduce_sum(tf.multiply(p1, p2), axis=1) # cosine = p1_p2 / (p1_norm * p2_norm) # c = tf.expand_dims(cosine, -1) # prob = tf.concat([-c, c], axis=1) c = p1_norm / p2_norm c = tf.expand_dims(c, -1) # batch, 1 c = tf.concat([c, 1 / c], axis=1) # c中为每个事件pair的向量模之比的[原值、倒数],然后做下面的对数变换 ''' # true_prob = -tf.log(tf.reduce_max(c, axis=1) - 1 + 1e-8) # true_p = tf.expand_dims(true_prob, -1) # prob = tf.concat([-true_p, true_p], axis=1) ''' p_max = tf.reduce_max(p, axis=1) p_max = tf.expand_dims(p_max, 1) p_min = tf.reduce_min(p, axis=1) p_min = tf.expand_dims(p_min, 1) p_up = p - p_min p_down = p_max - p_min prob = tf.divide(p_up, p_down) ''' prob = p # 交叉熵函数计算loss # 交叉熵刻画的是两个概率分布之间的距离,或可以说它刻画的是通过概率分布q来表达概率分布p的困难程度 # self.t代表正确答案,prob代表的是预测值,交叉熵越小,两个概率的分布约接近 # loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=tf.one_hot(self.t, class_size), logits=prob) loss = tf.nn.softmax_cross_entropy_with_logits_v2( logits=prob, labels=tf.one_hot(self.t, class_size)) loss = tf.reduce_mean(loss) # loss += tf.nn.l2_loss(W) # 整个前向传播过程最终返回:损失函数,pair是否同类的预测值、元路径权重、pair在GCN中得到的分类特征向量 return loss, prob, W, p
val_share = 0.1 train_share = 1 - unlabeled_share - val_share np.random.seed(seed) label_idx = _z_obs[idx] split_train, split_val, split_test = utils.train_val_test_split_tabular( np.arange(_N), train_size=train_share, val_size=val_share, test_size=unlabeled_share, stratify=_z_obs, random_state=seed) with tf.Graph().as_default(): surrogate_model = GCN.GCN(sizes, _An, _X_obs, with_relu=False, name="surrogate", gpu_id=gpu_id) surrogate_model.train(split_train, split_val, _Z_obs) W1 = surrogate_model.W1.eval(session=surrogate_model.session) W2 = surrogate_model.W2.eval(session=surrogate_model.session) logits = surrogate_model.logits.eval(session=surrogate_model.session) surrogate_model.session.close() ''' perform AFGSM ''' with tf.Graph().as_default(): afgsm = AFGSM.AFGSM(_A_obs, _X_obs, _Z_obs, num_vicious_nodes,
def main(argv): data_dir = FLAGS.data_dir data_name = FLAGS.data_name epochs = FLAGS.epochs learning_rate = FLAGS.learning_rate sparse = FLAGS.sparse input_size = FLAGS.input_size message_sizes = [ int(element) for element in FLAGS.message_sizes.strip().split(',') ] message_mlp_sizes = [ int(element) for element in FLAGS.message_mlp_sizes.strip().split(',') ] class_fn = data_dir + "/" + data_name + "/" + data_name + ".class" vertex_fn = data_dir + "/" + data_name + "/" + data_name + ".vertex" edge_fn = data_dir + "/" + data_name + "/" + data_name + ".edge" feature_fn = data_dir + "/" + data_name + "/" + data_name + ".feature" meta_fn = data_dir + "/" + data_name + "/" + data_name + ".meta" train_fn = data_dir + "/" + data_name + "/" + data_name + ".train" val_fn = data_dir + "/" + data_name + "/" + data_name + ".val" test_fn = data_dir + "/" + data_name + "/" + data_name + ".test" print('Data name:', data_name) data = Dataset.Dataset(class_fn, vertex_fn, edge_fn, feature_fn, meta_fn, train_fn, val_fn, test_fn) data.sparse_adj() data.sparse_feature() print('Number of vertices:', data.nVertices) print('Number of papers:', data.nPapers) print('Number of papers without features:', data.nNoFeatures) print('Number of edges:', data.nEdges) print('Vocabulary size:', data.nVocab) print('Number of classes:', data.nClasses) print('Classes:', data.classes) print('Density:', data.density) assert len(data.edges) == data.nEdges print('Training examples:', len(data.train)) print('Validation examples:', len(data.val)) print('Testing examples:', len(data.test)) assert len(data.vertices) == data.nPapers print('Adjacency matrix:', data.sparse_adj) print('Feature matrix:', data.sparse_feature) # Model creation input_size = [data.nVocab, input_size] model = GCN.GCN(input_size, message_sizes, message_mlp_sizes, data.nClasses) optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, amsgrad=True) print('\n--- Training -------------------------------') for epoch in range(epochs): print('\nEpoch', epoch) # Training optimizer.zero_grad() output = model(data, 'train', sparse) target = torch.from_numpy(np.array(data.train_label)).to(torch.long) loss = F.nll_loss(output, target) loss.backward() optimizer.step() print('Training loss =', loss.item()) # Validation with torch.no_grad(): output = model(data, 'val', sparse) target = torch.from_numpy(np.array(data.val_label)).to(torch.long) predict = output.argmax(dim=1, keepdim=True) correct = predict.eq(target.view_as(predict)).sum().item() accuracy = 100.0 * correct / len(data.val_label) print('Validation accuracy =', accuracy) # Validation print('\n--- Testing -------------------------------') with torch.no_grad(): output = model(data, 'test', sparse) target = torch.from_numpy(np.array(data.test_label)).to(torch.long) predict = output.argmax(dim=1, keepdim=True) correct = predict.eq(target.view_as(predict)).sum().item() accuracy = 100.0 * correct / len(data.test_label) print('Testing accuracy =', accuracy)
visdom_plot = True criterion = nn.CrossEntropyLoss() start = 0 learning_rate = 0.00555 train_batch_size = 150 val_batch_size = 50 n_epochs = 1000 optimizer_path = './checkpoints/checkpoint.pth' training_dataset_path = "./saved_datasets/mnist_on_plane/training/balanced_500.dat" test_dataset_path = "./saved_datasets/mnist_on_plane/testing/random_100.dat" #--------------------------------------------- vis_i = 0 #Inizializzazione rete----------------------------- net = GCN([mnist_width, mnist_height], conv_channels, linear_channels) optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate) if load_optimizer: if os.path.isfile(optimizer_path): start, vis_i = nn_utils.load_checkpoint( net, optimizer, optimizer_path) vis_i += 1 for g in optimizer.param_groups: g['lr'] = learning_rate else: print("No checkpoint found. Starting a new training.") else: print("Starting a new training.") #------------------------------------------------------------