位置: IT常识 - 正文

Pytorch实现GAT(基于PyTorch实现)(pytorch基础)

编辑:rootadmin
Pytorch实现GAT(基于PyTorch实现) 文章目录前言一、导入相关库二、加载Cora数据集三、定义GAT网络3.1 定义GAT层3.1.1 将节点信息进行空间映射3.1.2 注意力分数3.1.3 获取邻接矩阵3.1.4 获得注意力分数矩阵3.1.5 加权融合特征3.1.6 GATConv层3.2 定义GAT网络四、定义模型五、模型训练六、模型验证七、结果完整代码前言

推荐整理分享Pytorch实现GAT(基于PyTorch实现)(pytorch基础),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:pytorch geometric gat,pytorch vgg,pytorch gat,pytorch基础,pytorch gan 例子,pytorch基础,pytorch gather,pytorch gather,内容如对您有帮助,希望把文章链接给更多的朋友!

大家好,我是阿光。

本专栏整理了《图神经网络代码实战》,内包含了不同图神经网络的相关代码实现(PyG以及自实现),理论与实践相结合,如GCN、GAT、GraphSAGE等经典图网络,每一个代码实例都附带有完整的代码。

正在更新中~ ✨

🚨 我的项目环境:

平台:Windows10语言环境:python3.7编译器:PyCharmPyTorch版本:1.11.0PyG版本:2.1.0

💥 项目专栏:【图神经网络代码实战目录】

本文我们将使用PyTorch来简易实现一个GAT(图注意力网络),不使用PyG库,让新手可以理解如何PyTorch来搭建一个简易的图网络实例demo。

一、导入相关库

本项目是采用自己实现的GAT,并没有使用 PyG 库,原因是为了帮助新手朋友们能够对GAT的原理有个更深刻的理解,如果熟悉之后可以尝试使用PyG库直接调用 GATConv 这个图层即可。

import numpy as npimport torchimport torch.nn as nnimport torch.nn.functional as Ffrom scipy.sparse import coo_matrixfrom torch_geometric.datasets import Planetoid二、加载Cora数据集

本文使用的数据集是比较经典的Cora数据集,它是一个根据科学论文之间相互引用关系而构建的Graph数据集合,论文分为7类,共2708篇。

Genetic_AlgorithmsNeural_NetworksProbabilistic_MethodsReinforcement_LearningRule_LearningTheory

这个数据集是一个用于图节点分类的任务,数据集中只有一张图,这张图中含有2708个节点,10556条边,每个节点的特征维度为1433。

# 1.加载Cora数据集dataset = Planetoid(root='./data/Cora', name='Cora')三、定义GAT网络3.1 定义GAT层

这里我们就不重点介绍GCN网络了,相信大家能够掌握基本原理,本文我们使用的是PyTorch定义网络层。

对于GATConv的常用参数:

in_channels:每个样本的输入维度,就是每个节点的特征维度out_channels:经过注意力机制后映射成的新的维度,就是经过GAT后每个节点的维度长度add_self_loops:为图添加自环,是否考虑自身节点的信息bias:训练一个偏置b

我们在实现时也是考虑这几个常见参数

对于GAT的传播公式为:

Pytorch实现GAT(基于PyTorch实现)(pytorch基础)

xi′=αi,iθxi+∑j∈N(i)αi,jθxjx_i'=\alpha_{i,i}\theta x_i+ \sum_{j\in N(i)}\alpha_{i,j}\theta x_jxi′​=αi,i​θxi​+j∈N(i)∑​αi,j​θxj​

上式子的意思就是对自己和邻居的特征进行按照权重聚合,其中的 α\alphaα 代表注意力分数,θ\thetaθ 代表可学习参数, xjx_jxj​ 代表邻居节点的特征向量。

其中注意力分数的计算方式如下:

αi,j=exp(LeakyReLU(αT[θxi∣∣θxj]))∑k∈N(i)∪iexp(LeakyReLU(αT[θxi∣∣θxj]))\alpha_{i,j}=\frac{exp(LeakyReLU(\alpha^{T}[\theta x_i||\theta x_j]))}{\sum_{k\in N(i)\cup{i}}exp(LeakyReLU(\alpha^{T}[\theta x_i||\theta x_j]))}αi,j​=∑k∈N(i)∪i​exp(LeakyReLU(αT[θxi​∣∣θxj​]))exp(LeakyReLU(αT[θxi​∣∣θxj​]))​

所以我们的任务无非就是获取这几个变量,然后进行传播计算即可

3.1.1 将节点信息进行空间映射

在注意力公式中,它是首先对邻居节点先进行空间上的映射,实现代码如下:

# 1.计算wh,进行节点空间映射wh = torch.mm(x, self.weight_w)3.1.2 注意力分数

第二步就是计算注意力分数,注意一点这个分数并没有被激活,实现的部分就是 LeakyReLU 括号内的部分。

# 2.计算注意力分数e = torch.mm(wh, self.weight_a[: self.out_channels]) + torch.matmul(wh, self.weight_a[self.out_channels:]).T3.1.3 获取邻接矩阵

由于我们使用的是内置数据集 Cora,他给出的数据集并没有给出对应的邻接矩阵,所以我们需要手动实现获取该图对应的邻接矩阵。

# 4.获取邻接矩阵if self.adj == None: self.adj = to_dense_adj(edge_index).squeeze() # 5.添加自环,考虑自身加权 if self.add_self_loops: self.adj += torch.eye(x.shape[0])3.1.4 获得注意力分数矩阵

在上述GAT的传播公式中我们可以看到,每次加权的节点信息为自身和其邻居节点,所以为了实现非邻居节点不参与加权,我们需要对注意力分数矩阵非邻居节点的位置将其置为一个很小的值,这样在矩阵乘法时就不会发挥什么作用。

# 6.获得注意力分数矩阵attention = torch.where(self.adj > 0, e, -1e9 * torch.ones_like(e))

该代码的意思就是如果邻接矩阵中位置大于0,也就是该条边存在,那么注意力矩阵对应的位置分数不变,否则将其置为 -1e9 这个很小的数。

3.1.5 加权融合特征

这个部分就是将获得的注意力分数进行归一化,然后将这个矩阵和映射后的特征矩阵进行相乘,实现聚合操作,最终在结果上面添加偏置信息。

# 7.归一化注意力分数attention = F.softmax(attention, dim=1)# 8.加权融合特征output = torch.mm(attention, wh)# 9.添加偏置if self.bias != None: return output + self.bias.flatten()else: return output 3.1.6 GATConv层

接下来就可以定义GATConv层了,该层实现了2个函数,分别是 init_parameters() 、forward()

init_parameters():初始化可学习参数forward():这个函数定义模型的传播过程,也就是上面公式的 xi′=αi,iθxi+∑j∈N(i)αi,jθxjx_i'=\alpha_{i,i}\theta x_i+ \sum_{j\in N(i)}\alpha_{i,j}\theta x_jxi′​=αi,i​θxi​+∑j∈N(i)​αi,j​θxj​,如果设置了偏置在加上偏置返回即可# 2.定义GATConv层class GATConv(nn.Module): def __init__(self, in_channels, out_channels, heads=1, add_self_loops=True, bias=True): super(GATConv, self).__init__() self.in_channels = in_channels # 输入图节点的特征数 self.out_channels = out_channels # 输出图节点的特征数 self.adj = None self.add_self_loops = add_self_loops # 定义参数 θ self.weight_w = nn.Parameter(torch.FloatTensor(in_channels, out_channels)) self.weight_a = nn.Parameter(torch.FloatTensor(out_channels * 2, 1)) if bias: self.bias = nn.Parameter(torch.FloatTensor(out_channels, 1)) else: self.register_parameter('bias', None) self.leakyrelu = nn.LeakyReLU() self.init_parameters() # 初始化可学习参数 def init_parameters(self): nn.init.xavier_uniform_(self.weight_w) nn.init.xavier_uniform_(self.weight_a) if self.bias != None: nn.init.zeros_(self.bias) def forward(self, x, edge_index): # 1.计算wh,进行节点空间映射 wh = torch.mm(x, self.weight_w) # 2.计算注意力分数 e = torch.mm(wh, self.weight_a[: self.out_channels]) + torch.matmul(wh, self.weight_a[self.out_channels:]).T # 3.激活 e = self.leakyrelu(e) # 4.获取邻接矩阵 if self.adj == None: self.adj = to_dense_adj(edge_index).squeeze() # 5.添加自环,考虑自身加权 if self.add_self_loops: self.adj += torch.eye(x.shape[0]) # 6.获得注意力分数矩阵 attention = torch.where(self.adj > 0, e, -1e9 * torch.ones_like(e)) # 7.归一化注意力分数 attention = F.softmax(attention, dim=1) # 8.加权融合特征 output = torch.mm(attention, wh) # 9.添加偏置 if self.bias != None: return output + self.bias.flatten() else: return output

对于我们实现这个网络的实现效率上来讲比PyG框架内置的 GCNConv 层稍差一点,因为我们是按照公式来一步一步利用矩阵计算得到,没有对矩阵计算以及算法进行优化,不然初学者可能看不太懂,不利于理解GCN公式的传播过程,有能力的小伙伴可以看下官方源码学习一下。

3.2 定义GAT网络

上面我们已经实现好了 GATConv 的网络层,之后就可以调用这个层来搭建 GAT 网络。

# 3.定义GAT网络class GAT(nn.Module): def __init__(self, num_node_features, num_classes): super(GAT, self).__init__() self.conv1 = GATConv(in_channels=num_node_features, out_channels=16, heads=2) self.conv2 = GATConv(in_channels=16, out_channels=num_classes, heads=1) def forward(self, data): x, edge_index = data.x, data.edge_index x = self.conv1(x, edge_index) x = F.relu(x) x = F.dropout(x, training=self.training) x = self.conv2(x, edge_index) return F.log_softmax(x, dim=1)

上面网络我们定义了两个GATConv层,第一层的参数的输入维度就是初始每个节点的特征维度,输出维度是16。

第二个层的输入维度为16,输出维度为分类个数,因为我们需要对每个节点进行分类,最终加上softmax操作。

四、定义模型

下面就是定义了一些模型需要的参数,像学习率、迭代次数这些超参数,然后是模型的定义以及优化器及损失函数的定义,和pytorch定义网络是一样的。

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备epochs = 10 # 学习轮数lr = 0.003 # 学习率num_node_features = dataset.num_node_features # 每个节点的特征数num_classes = dataset.num_classes # 每个节点的类别数data = dataset[0].to(device) # Cora的一张图# 3.定义模型model = GAT(num_node_features, num_classes).to(device)optimizer = torch.optim.Adam(model.parameters(), lr=lr) # 优化器loss_function = nn.NLLLoss() # 损失函数五、模型训练

模型训练部分也是和pytorch定义网络一样,因为都是需要经过前向传播、反向传播这些过程,对于损失、精度这些指标可以自己添加。

# 训练模式model.train()for epoch in range(epochs): optimizer.zero_grad() pred = model(data) loss = loss_function(pred[data.train_mask], data.y[data.train_mask]) # 损失 correct_count_train = pred.argmax(axis=1)[data.train_mask].eq(data.y[data.train_mask]).sum().item() # epoch正确分类数目 acc_train = correct_count_train / data.train_mask.sum().item() # epoch训练精度 loss.backward() optimizer.step() if epoch % 20 == 0: print("【EPOCH: 】%s" % str(epoch + 1)) print('训练损失为:{:.4f}'.format(loss.item()), '训练精度为:{:.4f}'.format(acc_train))print('【Finished Training!】')六、模型验证

下面就是模型验证阶段,在训练时我们是只使用了训练集,测试的时候我们使用的是测试集,注意这和传统网络测试不太一样,在图像分类一些经典任务中,我们是把数据集分成了两份,分别是训练集、测试集,但是在Cora这个数据集中并没有这样,它区分训练集还是测试集使用的是掩码机制,就是定义了一个和节点长度相同纬度的数组,该数组的每个位置为True或者False,标记着是否使用该节点的数据进行训练。

# 模型验证model.eval()pred = model(data)# 训练集(使用了掩码)correct_count_train = pred.argmax(axis=1)[data.train_mask].eq(data.y[data.train_mask]).sum().item()acc_train = correct_count_train / data.train_mask.sum().item()loss_train = loss_function(pred[data.train_mask], data.y[data.train_mask]).item()# 测试集correct_count_test = pred.argmax(axis=1)[data.test_mask].eq(data.y[data.test_mask]).sum().item()acc_test = correct_count_test / data.test_mask.sum().item()loss_test = loss_function(pred[data.test_mask], data.y[data.test_mask]).item()print('Train Accuracy: {:.4f}'.format(acc_train), 'Train Loss: {:.4f}'.format(loss_train))print('Test Accuracy: {:.4f}'.format(acc_test), 'Test Loss: {:.4f}'.format(loss_test))七、结果【EPOCH: 】1训练损失为:1.9481 训练精度为:0.0714【EPOCH: 】21训练损失为:1.8783 训练精度为:0.3571【EPOCH: 】41训练损失为:1.7687 训练精度为:0.6071【EPOCH: 】61训练损失为:1.6368 训练精度为:0.7143【EPOCH: 】81训练损失为:1.5093 训练精度为:0.7500【EPOCH: 】101训练损失为:1.3747 训练精度为:0.8214【EPOCH: 】121训练损失为:1.2433 训练精度为:0.8500【EPOCH: 】141训练损失为:1.1180 训练精度为:0.8714【EPOCH: 】161训练损失为:1.0113 训练精度为:0.9000【EPOCH: 】181训练损失为:0.9571 训练精度为:0.8714【Finished Training!】>>>Train Accuracy: 0.9857 Train Loss: 0.8360>>>Test Accuracy: 0.7460 Test Loss: 1.2454训练集测试集Accuracy0.98570.7460Loss0.83601.2454完整代码import numpy as npimport torchimport torch.nn as nnimport torch.nn.functional as Ffrom scipy.sparse import coo_matrixfrom torch_geometric.datasets import Planetoid# 1.加载Cora数据集dataset = Planetoid(root='./data/Cora', name='Cora')# 2.定义GATConv层class GATConv(nn.Module): def __init__(self, in_channels, out_channels, heads=1, add_self_loops=True, bias=True): super(GATConv, self).__init__() self.in_channels = in_channels # 输入图节点的特征数 self.out_channels = out_channels # 输出图节点的特征数 self.adj = None self.add_self_loops = add_self_loops # 定义参数 θ self.weight_w = nn.Parameter(torch.FloatTensor(in_channels, out_channels)) self.weight_a = nn.Parameter(torch.FloatTensor(out_channels * 2, 1)) if bias: self.bias = nn.Parameter(torch.FloatTensor(out_channels, 1)) else: self.register_parameter('bias', None) self.leakyrelu = nn.LeakyReLU() self.init_parameters() # 初始化可学习参数 def init_parameters(self): nn.init.xavier_uniform_(self.weight_w) nn.init.xavier_uniform_(self.weight_a) if self.bias != None: nn.init.zeros_(self.bias) def forward(self, x, edge_index): # 1.计算wh,进行节点空间映射 wh = torch.mm(x, self.weight_w) # 2.计算注意力分数 e = torch.mm(wh, self.weight_a[: self.out_channels]) + torch.matmul(wh, self.weight_a[self.out_channels:]).T # 3.激活 e = self.leakyrelu(e) # 4.获取邻接矩阵 if self.adj == None: self.adj = to_dense_adj(edge_index).squeeze() # 5.添加自环,考虑自身加权 if self.add_self_loops: self.adj += torch.eye(x.shape[0]) # 6.获得注意力分数矩阵 attention = torch.where(self.adj > 0, e, -1e9 * torch.ones_like(e)) # 7.归一化注意力分数 attention = F.softmax(attention, dim=1) # 8.加权融合特征 output = torch.mm(attention, wh) # 9.添加偏置 if self.bias != None: return output + self.bias.flatten() else: return output # 3.定义GAT网络class GAT(nn.Module): def __init__(self, num_node_features, num_classes): super(GAT, self).__init__() self.conv1 = GATConv(in_channels=num_node_features, out_channels=16, heads=2) self.conv2 = GATConv(in_channels=16, out_channels=num_classes, heads=1) def forward(self, data): x, edge_index = data.x, data.edge_index x = self.conv1(x, edge_index) x = F.relu(x) x = F.dropout(x, training=self.training) x = self.conv2(x, edge_index) return F.log_softmax(x, dim=1)device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备epochs = 200 # 学习轮数lr = 0.0003 # 学习率num_node_features = dataset.num_node_features # 每个节点的特征数num_classes = dataset.num_classes # 每个节点的类别数data = dataset[0].to(device) # Cora的一张图# 4.定义模型model = GCN(num_node_features, num_classes).to(device)optimizer = torch.optim.Adam(model.parameters(), lr=lr) # 优化器loss_function = nn.NLLLoss() # 损失函数# 训练模式model.train()for epoch in range(epochs): optimizer.zero_grad() pred = model(data) loss = loss_function(pred[data.train_mask], data.y[data.train_mask]) # 损失 correct_count_train = pred.argmax(axis=1)[data.train_mask].eq(data.y[data.train_mask]).sum().item() # epoch正确分类数目 acc_train = correct_count_train / data.train_mask.sum().item() # epoch训练精度 loss.backward() optimizer.step() if epoch % 20 == 0: print("【EPOCH: 】%s" % str(epoch + 1)) print('训练损失为:{:.4f}'.format(loss.item()), '训练精度为:{:.4f}'.format(acc_train))print('【Finished Training!】')# 模型验证model.eval()pred = model(data)# 训练集(使用了掩码)correct_count_train = pred.argmax(axis=1)[data.train_mask].eq(data.y[data.train_mask]).sum().item()acc_train = correct_count_train / data.train_mask.sum().item()loss_train = loss_function(pred[data.train_mask], data.y[data.train_mask]).item()# 测试集correct_count_test = pred.argmax(axis=1)[data.test_mask].eq(data.y[data.test_mask]).sum().item()acc_test = correct_count_test / data.test_mask.sum().item()loss_test = loss_function(pred[data.test_mask], data.y[data.test_mask]).item()print('Train Accuracy: {:.4f}'.format(acc_train), 'Train Loss: {:.4f}'.format(loss_train))print('Test Accuracy: {:.4f}'.format(acc_test), 'Test Loss: {:.4f}'.format(loss_test))
本文链接地址:https://www.jiuchutong.com/zhishi/300424.html 转载请保留说明!

上一篇:YOLOv5源码逐行超详细注释与解读(6)——网络结构(1)yolo.py(yolov1 实现)

下一篇:OpenCV安装配置教程VS2022(超级顺利)(opencv1.0安装)

  • 到底应该怎么样做软文推广(到底应该怎么样才能度过一生)

    到底应该怎么样做软文推广(到底应该怎么样才能度过一生)

  • 无线网设置入口(网络管理系统)

    无线网设置入口(网络管理系统)

  • vivov2156a是什么型号(vivov2065a是什么手机)

    vivov2156a是什么型号(vivov2065a是什么手机)

  • 淘宝旗舰店和官方旗舰店有什么区别(淘宝旗舰店和官网的东西是一样的吗)

    淘宝旗舰店和官方旗舰店有什么区别(淘宝旗舰店和官网的东西是一样的吗)

  • iqoo3耗电快怎么解决(iqoo3掉电太快)

    iqoo3耗电快怎么解决(iqoo3掉电太快)

  • e2未通过实名校验,不允许支付是什么意思

    e2未通过实名校验,不允许支付是什么意思

  • 拼多多没有拼单成功怎么取消订单(拼多多没有拼单成功怎么退款取消订单)

    拼多多没有拼单成功怎么取消订单(拼多多没有拼单成功怎么退款取消订单)

  • 全功能nfc和多功能nfc有什么区别(nfc多功能和全功能的区别)

    全功能nfc和多功能nfc有什么区别(nfc多功能和全功能的区别)

  • 苹果a1432是什么型号(苹果a1432是什么时候出的)

    苹果a1432是什么型号(苹果a1432是什么时候出的)

  • qq通话怎么关闭自己麦克风(qq通话怎么关闭对方打电话提醒)

    qq通话怎么关闭自己麦克风(qq通话怎么关闭对方打电话提醒)

  • 摄像头为什么用着用着就离线了(摄像头为什么用着用着就离线了,录有录进去)

    摄像头为什么用着用着就离线了(摄像头为什么用着用着就离线了,录有录进去)

  • qq拉黑了还能发好友请求吗(qq拉黑了还能发消息吗?)

    qq拉黑了还能发好友请求吗(qq拉黑了还能发消息吗?)

  • switch如何区分续航版(switch怎么区分续航)

    switch如何区分续航版(switch怎么区分续航)

  • 微信能发30分钟视频吗(微信能发30分钟的录音吗)

    微信能发30分钟视频吗(微信能发30分钟的录音吗)

  • 好省邀请口令填在哪里(好省app邀请口令)

    好省邀请口令填在哪里(好省app邀请口令)

  • 华为nova5pro耳机没声音(华为nova5pro耳机模式怎么取消)

    华为nova5pro耳机没声音(华为nova5pro耳机模式怎么取消)

  • 华为手机拨号背景怎么设置(华为手机拨号背景图怎么取消)

    华为手机拨号背景怎么设置(华为手机拨号背景图怎么取消)

  • 怎么送流量给别人(怎么送流量给别人使用)

    怎么送流量给别人(怎么送流量给别人使用)

  • 删除好友对方还能举报吗(删除好友对方还能收到我的转账吗)

    删除好友对方还能举报吗(删除好友对方还能收到我的转账吗)

  • ps暂存盘在哪里清理(ps暂存盘在哪里改)

    ps暂存盘在哪里清理(ps暂存盘在哪里改)

  • oppo手机水印怎么设置日期(oppo手机水印怎么变大)

    oppo手机水印怎么设置日期(oppo手机水印怎么变大)

  • 三星g8750是什么型号(g8750是三星s几)

    三星g8750是什么型号(g8750是三星s几)

  • 360极速浏览器如何切换极速模式(360极速浏览器如何快速播放)

    360极速浏览器如何切换极速模式(360极速浏览器如何快速播放)

  • 播放ppt快捷键(怎么停止ppt自动播放)

    播放ppt快捷键(怎么停止ppt自动播放)

  • 拍的抖音怎么删除(拍的抖音怎么删除掉)

    拍的抖音怎么删除(拍的抖音怎么删除掉)

  • 全局变量和局部变量(全局变量和局部变量同名哪个优先)

    全局变量和局部变量(全局变量和局部变量同名哪个优先)

  • 金蝶kis专业版的优缺点
  • 公司出租房营业税税率是多少
  • 银行借记和贷记的区别是什么
  • 已付工资在资产负债表中体现
  • 新成立的企业都有哪些
  • 煤矿企业维简费税务规定
  • 差旅费超支金额允许报销吗
  • 金税三期实收资本的印花税在哪缴?
  • 材料含税价怎么算
  • 劳服企业可以安差额税上税吗?
  • 物业公司前期工作计划
  • 购入的工具应计入哪个科目?
  • 住房租赁补贴
  • 以前年度亏损本季度盈利所得税申报
  • 社保公积金会计分录怎么写
  • 小规模纳税人核定征收怎么报税
  • 日用品专用发票可以抵税嘛
  • 醋开票属于什么类
  • 鉴证咨询公司成本是什么
  • 发票已认证对方起诉有效吗
  • 合理损耗算入账价值吗
  • 小规模纳税人能抵扣进项发票吗
  • 进项税留抵需要转出吗
  • 总公司资金转入私人账户
  • 其他应收款押金计提坏账吗
  • 全免增值税企业所得税吗
  • 用友t3新账套总账设置
  • 路由器ip分配数量
  • vue项目中的package.json是( )?
  • 调整以前年度所得税汇算清缴报表,在哪调减虚增的成本
  • 现金流量表的内涵及其编制基础
  • 文化事业建设费2023年是否减免了
  • 个人多交社保划不划算
  • 一个药厂能够生产药品的三个前提条件
  • 股东以债权出资,公司怎么处理
  • 为什么连接无线网超时
  • 问题解决能力
  • 固定资产残料收税吗
  • 国有企业正常60岁退休到什么鉴字
  • 阿尔山火山
  • 纽格尔官网
  • php数组求最大值
  • 其他应付款转入管理费用
  • php中preg_replace_callback函数简单用法示例
  • 土地出让与土地划拨有什么区别
  • 非限定性资产和业务活动表关系
  • python中的函数调用
  • 供应商发票多开了如何处理?
  • sqlalchemy 封装
  • 从事特殊行业
  • 预缴增值税后税款怎么算
  • 同控和非同控的企业合并的分录
  • 预缴增值税的账务处理
  • 以前年度费用怎么记账
  • 出口转内销补交进口增值税时间
  • 老板垫付货款
  • 公司车辆做账交增值税吗
  • 存货报废计入
  • 手写账目表格怎么做
  • 支付劳务费需要什么原始凭证
  • 设置出纳权限的操作步骤
  • 会计凭证,报告怎么做
  • 关于存储过程的描述
  • mysql根据另一张表更新
  • winxp和win7共享
  • 输入法是全角在哪里设置
  • linux怎样安装
  • 如何通过mac找到具体地址
  • Linux进入图形界面卡顿
  • windows xp系
  • linux cr3
  • windows7访问windows10
  • win8怎么找开始程序
  • javascript中声明变量的关键字
  • 批处理set命令
  • bash shell脚本编程经典实例(第2版)
  • python字符串连接join
  • android,ios,apicloud 同时开发两个平台应用,方便简单一体化,自带svn,云编译,中文IDE
  • 企业所得税年度申报表A类
  • 耕地占用税和契税
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设