import torch from torch import nn from torch.nn import functional as F from layer import GraphConvolution from config import args class GCN(nn.Module): # https://www.educba.com/torch-dot-nn-module/ def __init__(self, input_dim, output_dim, num_features_nonzero): super(GCN, self).__init__() """ python中的super(Net, self).__init__() 首先找到Net的父类(比如是类NNet),然后把类Net的对象self转换为类NNet的对象,然后“被转换”的类NNet对象调用自己的init函数 """ self.input_dim = input_dim # 1433 self.output_dim = output_dim print('input dim:', input_dim) print('output dim:', output_dim) print('num_features_nonzero:', num_features_nonzero) # 这个地方实际上定义的是两层,就是说,输入输出之间增加了一个隐含层,然后他配合了一下维度把他连接起来了, # 定义的是两层自己层内的特性,层之间的链接还没有 # https://blog.csdn.net/dss_dssssd/article/details/82980222,Sequential 相当于将各个层加入一个容器里边, # 而且我这个地方调用的时候调用的是类,相当于连接的部分nn.Sequential直接就把forward函数调用进来了, # 这个地方还没有调用forward函数? self.layers = nn.Sequential(GraphConvolution(self.input_dim, args.hidden, num_features_nonzero, activation=F.relu, dropout=args.dropout, is_sparse_inputs=True), # 这个地方是输入->隐层 GraphConvolution(args.hidden, output_dim, num_features_nonzero, activation=F.relu, dropout=args.dropout, is_sparse_inputs=False), # 这个地方是隐层->输出 ) def forward(self, inputs) : # 这个地方调用了forword函数,稍等一下再看那个forward函数,感觉他有点问题哈 x, support = inputs x = self.layers((x, support)) # 这个地方调用了layer里边的forword函数,这个layer这个里边只有一个函数,所以直接用就行了, # 他这个相当于直接调用了一个元组扔进去了,x为feature信息,support为联通矩阵的信息 return x def l2_loss(self): # L2型的损失函数,利用l2范数计算损失情况:(误差的平方)的和,可以有稳定的单一解 # https://zhuanlan.zhihu.com/p/52203156,这个下边的layer是抽取了nn.Model里边的一层 layer = self.layers.children() layer = next(iter(layer)) # todo: 明天看一下Python迭代器的东西 loss = None for p in layer.parameters(): if loss is None: loss = p.pow(2).sum() else: loss += p.pow(2).sum() return loss