Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pytorch version #44

Open
WangYibucea opened this issue Jun 11, 2020 · 11 comments
Open

pytorch version #44

WangYibucea opened this issue Jun 11, 2020 · 11 comments

Comments

@WangYibucea
Copy link

Do you have pytorch version?

@hazdzz
Copy link

hazdzz commented Nov 10, 2020

The author does not have a PyTorch version of STGCN. However, there are 4 implementations made by PyTorch by others. Unfortunately, all those PyTorch implementations do not follow the paper.

@jeongwhanchoi
Copy link

The author does not have a PyTorch version of STGCN. However, there are 4 implementations made by PyTorch by others. Unfortunately, all those PyTorch implementations do not follow the paper.

Would you know those 4 implementations are different from the original STGCN?

@hazdzz
Copy link

hazdzz commented Nov 13, 2020

The author does not have a PyTorch version of STGCN. However, there are 4 implementations made by PyTorch by others. Unfortunately, all those PyTorch implementations do not follow the paper.

Would you know those 4 implementations are different from the original STGCN?

  1. https://github.com/FelixOpolka/STGCN-PyTorch
  2. https://github.com/Aguin/STGCN-PyTorch
  3. https://github.com/KimMeen/STGCN
  4. https://github.com/dmlc/dgl/tree/master/examples/pytorch/stgcn_wave

@hazdzz
Copy link

hazdzz commented Nov 24, 2020

I have made a PyTorch version. Here is my code: https://github.com/hazdzz/STGCN

@wanzhixiao
Copy link

wanzhixiao commented Nov 27, 2020

我做了一个PyTorch版本,没有做任何修改。这是我的代码:https : //github.com/hazdzz/STGCN

how do you guarantee your implementation follow the paper?

@wanzhixiao
Copy link

wanzhixiao commented Nov 27, 2020

does this implementation of temporal convoution module correct?

class temporal_conv_layer(nn.Module):

def __init__(self, Kt, c_in, c_out):
    '''
    :param Kt: int, kernel size of temporal convolution.
    :param c_in: int, size of input channel.
    :param c_out: int, size of output channel.
    '''
    super(temporal_conv_layer,self).__init__()
    self.Kt = Kt
    self.c_in = c_in
    self.c_out = c_out

    self.conv1 = nn.Conv2d(in_channels=c_in,out_channels=c_out,kernel_size=(1,1),stride=1,padding=0)
    self.conv2 = nn.Conv2d(in_channels=c_in,out_channels=2*c_out,kernel_size=(Kt,1),stride=1)
    self.conv3 = nn.Conv2d(in_channels=c_in,out_channels=c_out,kernel_size=(Kt,1),stride=1)

    self.act = F.relu

def forward(self,x,act_func):
    '''
    :param x: input tensor ,[batch_size, c_in,time_step, n_route]
    :return: tensor, [batch_size, c_out,time_step-Kt+1, n_route].
    '''
    _,c,T,N = x.shape
    if(self.c_in > self.c_out): 
        x_input = self.conv1(x)
    elif self.c_in < self.c_out:
        # if the size of input channel is less than the output,
        # padding x to the same size of output channel.
        # Note, _.get_shape() cannot convert a partially known TensorShape to a Tensor.
        x_input = torch.cat(x,torch.zeros((x.shape[0],self.c_out-c,T,N)),dim=1)
    else:
        x_input = x
    # keep the original input for residual connection.
    x_input = x_input[:,:,self.Kt - 1:T, :]

    if act_func == 'GLU':
        # gated liner unit
        # GLU h(x) = (X*W+b)×sigmod(X*V+c)
        x_conv = self.conv2(x)
        #residual *sigmod(x)
        #(x+F(x))*sigmod(x)
        return (x_conv[:,0:self.c_out,:,:] + x_input) * torch.sigmoid(x_conv[:,-self.c_out:,:,:])
    else:

        x_conv = self.conv3(x)
        if act_func == 'linear':
            return x_conv
        elif act_func == 'sigmoid':
            return torch.sigmoid(x_conv)
        elif act_func == 'relu':
            return self.act(x_conv + x_input)
        else:
            raise ValueError(f'ERROR: activation function "{act_func}" is not defined.')

@hazdzz
Copy link

hazdzz commented Nov 27, 2020

我做了一个PyTorch版本,没有做任何修改。这是我的代码:https : //github.com/hazdzz/STGCN

how do you guarantee your implementation follow the paper?

I translated the code from the author's which used TensorFlow v1 to mine which used PyTorch. That's it. And I found the author misunderstands the Laplacian matrix in GCN(first-order approximation) which I fixed.

@hazdzz
Copy link

hazdzz commented Nov 27, 2020

does this implementation of temporal convoution module correct?

class temporal_conv_layer(nn.Module):

def __init__(self, Kt, c_in, c_out):
    '''
    :param Kt: int, kernel size of temporal convolution.
    :param c_in: int, size of input channel.
    :param c_out: int, size of output channel.
    '''
    super(temporal_conv_layer,self).__init__()
    self.Kt = Kt
    self.c_in = c_in
    self.c_out = c_out

    self.conv1 = nn.Conv2d(in_channels=c_in,out_channels=c_out,kernel_size=(1,1),stride=1,padding=0)
    self.conv2 = nn.Conv2d(in_channels=c_in,out_channels=2*c_out,kernel_size=(Kt,1),stride=1)
    self.conv3 = nn.Conv2d(in_channels=c_in,out_channels=c_out,kernel_size=(Kt,1),stride=1)

    self.act = F.relu

def forward(self,x,act_func):
    '''
    :param x: input tensor ,[batch_size, c_in,time_step, n_route]
    :return: tensor, [batch_size, c_out,time_step-Kt+1, n_route].
    '''
    _,c,T,N = x.shape
    if(self.c_in > self.c_out): 
        x_input = self.conv1(x)
    elif self.c_in < self.c_out:
        # if the size of input channel is less than the output,
        # padding x to the same size of output channel.
        # Note, _.get_shape() cannot convert a partially known TensorShape to a Tensor.
        x_input = torch.cat(x,torch.zeros((x.shape[0],self.c_out-c,T,N)),dim=1)
    else:
        x_input = x
    # keep the original input for residual connection.
    x_input = x_input[:,:,self.Kt - 1:T, :]

    if act_func == 'GLU':
        # gated liner unit
        # GLU h(x) = (X*W+b)×sigmod(X*V+c)
        x_conv = self.conv2(x)
        #residual *sigmod(x)
        #(x+F(x))*sigmod(x)
        return (x_conv[:,0:self.c_out,:,:] + x_input) * torch.sigmoid(x_conv[:,-self.c_out:,:,:])
    else:

        x_conv = self.conv3(x)
        if act_func == 'linear':
            return x_conv
        elif act_func == 'sigmoid':
            return torch.sigmoid(x_conv)
        elif act_func == 'relu':
            return self.act(x_conv + x_input)
        else:
            raise ValueError(f'ERROR: activation function "{act_func}" is not defined.')

Yes, it is correct.

@wanzhixiao
Copy link

does this implementation of temporal convoution module correct?
class temporal_conv_layer(nn.Module):

def __init__(self, Kt, c_in, c_out):
    '''
    :param Kt: int, kernel size of temporal convolution.
    :param c_in: int, size of input channel.
    :param c_out: int, size of output channel.
    '''
    super(temporal_conv_layer,self).__init__()
    self.Kt = Kt
    self.c_in = c_in
    self.c_out = c_out

    self.conv1 = nn.Conv2d(in_channels=c_in,out_channels=c_out,kernel_size=(1,1),stride=1,padding=0)
    self.conv2 = nn.Conv2d(in_channels=c_in,out_channels=2*c_out,kernel_size=(Kt,1),stride=1)
    self.conv3 = nn.Conv2d(in_channels=c_in,out_channels=c_out,kernel_size=(Kt,1),stride=1)

    self.act = F.relu

def forward(self,x,act_func):
    '''
    :param x: input tensor ,[batch_size, c_in,time_step, n_route]
    :return: tensor, [batch_size, c_out,time_step-Kt+1, n_route].
    '''
    _,c,T,N = x.shape
    if(self.c_in > self.c_out): 
        x_input = self.conv1(x)
    elif self.c_in < self.c_out:
        # if the size of input channel is less than the output,
        # padding x to the same size of output channel.
        # Note, _.get_shape() cannot convert a partially known TensorShape to a Tensor.
        x_input = torch.cat(x,torch.zeros((x.shape[0],self.c_out-c,T,N)),dim=1)
    else:
        x_input = x
    # keep the original input for residual connection.
    x_input = x_input[:,:,self.Kt - 1:T, :]

    if act_func == 'GLU':
        # gated liner unit
        # GLU h(x) = (X*W+b)×sigmod(X*V+c)
        x_conv = self.conv2(x)
        #residual *sigmod(x)
        #(x+F(x))*sigmod(x)
        return (x_conv[:,0:self.c_out,:,:] + x_input) * torch.sigmoid(x_conv[:,-self.c_out:,:,:])
    else:

        x_conv = self.conv3(x)
        if act_func == 'linear':
            return x_conv
        elif act_func == 'sigmoid':
            return torch.sigmoid(x_conv)
        elif act_func == 'relu':
            return self.act(x_conv + x_input)
        else:
            raise ValueError(f'ERROR: activation function "{act_func}" is not defined.')

Yes, it is correct.

Why do we do one-dimensional convolution in feature dimension instead of time dimension

if(self.c_ in > self.c_ out):

x_ input = self.conv1 (x)

@hazdzz
Copy link

hazdzz commented Nov 28, 2020

does this implementation of temporal convoution module correct?

class temporal_conv_layer(nn.Module):

def init(self, Kt, c_in, c_out):

'''
:param Kt: int, kernel size of temporal convolution.
:param c_in: int, size of input channel.
:param c_out: int, size of output channel.
'''
super(temporal_conv_layer,self).__init__()
self.Kt = Kt
self.c_in = c_in
self.c_out = c_out
self.conv1 = nn.Conv2d(in_channels=c_in,out_channels=c_out,kernel_size=(1,1),stride=1,padding=0)
self.conv2 = nn.Conv2d(in_channels=c_in,out_channels=2*c_out,kernel_size=(Kt,1),stride=1)
self.conv3 = nn.Conv2d(in_channels=c_in,out_channels=c_out,kernel_size=(Kt,1),stride=1)
self.act = F.relu

def forward(self,x,act_func):

'''
:param x: input tensor ,[batch_size, c_in,time_step, n_route]
:return: tensor, [batch_size, c_out,time_step-Kt+1, n_route].
'''
_,c,T,N = x.shape
if(self.c_in > self.c_out): 
    x_input = self.conv1(x)
elif self.c_in < self.c_out:
    # if the size of input channel is less than the output,
    # padding x to the same size of output channel.
    # Note, _.get_shape() cannot convert a partially known TensorShape to a Tensor.
    x_input = torch.cat(x,torch.zeros((x.shape[0],self.c_out-c,T,N)),dim=1)
else:
    x_input = x
# keep the original input for residual connection.
x_input = x_input[:,:,self.Kt - 1:T, :]
if act_func == 'GLU':
    # gated liner unit
    # GLU h(x) = (X*W+b)×sigmod(X*V+c)
    x_conv = self.conv2(x)
    #residual *sigmod(x)
    #(x+F(x))*sigmod(x)
    return (x_conv[:,0:self.c_out,:,:] + x_input) * torch.sigmoid(x_conv[:,-self.c_out:,:,:])
else:
    x_conv = self.conv3(x)
    if act_func == 'linear':
        return x_conv
    elif act_func == 'sigmoid':
        return torch.sigmoid(x_conv)
    elif act_func == 'relu':
        return self.act(x_conv + x_input)
    else:
        raise ValueError(f'ERROR: activation function "{act_func}" is not defined.')

Yes, it is correct.

Why do we do one-dimensional convolution in feature dimension instead of time dimension

if(self.c_ in > self.c_ out):

x_ input = self.conv1 (x)

I think you should ask the author. I have no idea either.

@qiubin1997
Copy link

作者没有STGCN的PyTorch版本。但是,其他人通过PyTorch进行了4种实现。不幸的是,所有这些PyTorch的实现都没有遵循本文。

请问一下 我用的windows10运行的程序中的main.py 总是报错UnboundLocalError: local variable 'W' referenced before assignment(赋值前引用的局部变量W)的问题,如何修改,请指教一下。谢谢。

D:\Anaconda\envs\tensorflow-gpu\python.exe D:/PycharmProjects/STGCN_IJCAI-18/STGCN_IJCAI-18-master/main.py
2021-03-10 11:39:36.031711: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudart64_101.dll
2021-03-10 11:39:37.332511: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2021-03-10 11:39:37.338870: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x287b22ae980 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2021-03-10 11:39:37.339049: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): Host, Default Version
2021-03-10 11:39:37.339710: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library nvcuda.dll
2021-03-10 11:39:37.362410: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1561] Found device 0 with properties:
pciBusID: 0000:01:00.0 name: GeForce GTX 1050 Ti computeCapability: 6.1
coreClock: 1.392GHz coreCount: 6 deviceMemorySize: 4.00GiB deviceMemoryBandwidth: 104.43GiB/s
2021-03-10 11:39:37.362663: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudart64_101.dll
2021-03-10 11:39:37.365917: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cublas64_10.dll
2021-03-10 11:39:37.368303: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cufft64_10.dll
2021-03-10 11:39:37.369087: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library curand64_10.dll
2021-03-10 11:39:37.372096: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cusolver64_10.dll
2021-03-10 11:39:37.373803: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cusparse64_10.dll
2021-03-10 11:39:37.381498: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudnn64_7.dll
2021-03-10 11:39:37.381689: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1703] Adding visible gpu devices: 0
2021-03-10 11:39:37.845596: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1102] Device interconnect StreamExecutor with strength 1 edge matrix:
2021-03-10 11:39:37.845754: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1108] 0
2021-03-10 11:39:37.845836: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1121] 0: N
2021-03-10 11:39:37.846049: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1247] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 2988 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1050 Ti, pci bus id: 0000:01:00.0, compute capability: 6.1)
2021-03-10 11:39:37.848793: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x287d618f8c0 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices:
2021-03-10 11:39:37.848965: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): GeForce GTX 1050 Ti, Compute Capability 6.1
Training configs: Namespace(batch_size=50, epoch=50, graph='default', inf_mode='merge', ks=3, kt=3, lr=0.001, n_his=12, n_pred=9, n_route=228, opt='RMSProp', save=10)
ERROR: input file was not found in ./dataset\PeMSD7_W_228.csv.
Traceback (most recent call last):
File "D:/PycharmProjects/STGCN_IJCAI-18/STGCN_IJCAI-18-master/main.py", line 52, in
W = weight_matrix(pjoin('./dataset', f'PeMSD7_W_{n}.csv'))
File "D:\PycharmProjects\STGCN_IJCAI-18\STGCN_IJCAI-18-master\utils\math_graph.py", line 87, in weight_matrix
if set(np.unique(W)) == {0, 1}:
UnboundLocalError: local variable 'W' referenced before assignment

Process finished with exit code 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants