TCN.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import torch
  2. import torch.nn as nn
  3. from torch.nn.utils.parametrizations import weight_norm
  4. class Chomp1d(nn.Module):
  5. def __init__(self, chomp_size):
  6. super(Chomp1d, self).__init__()
  7. self.chomp_size = chomp_size
  8. def forward(self, x):
  9. return x[:, :, :-self.chomp_size].contiguous()
  10. class TemporalBlock(nn.Module):
  11. def __init__(self, n_inputs, n_outputs, kernel_size, stride, dilation, padding, dropout=0.2):
  12. super(TemporalBlock, self).__init__()
  13. self.conv1 = weight_norm(nn.Conv1d(n_inputs, n_outputs, kernel_size,
  14. stride=stride, padding=padding, dilation=dilation))
  15. self.chomp1 = Chomp1d(padding)
  16. self.relu1 = nn.ReLU()
  17. self.dropout1 = nn.Dropout(dropout)
  18. self.conv2 = weight_norm(nn.Conv1d(n_outputs, n_outputs, kernel_size,
  19. stride=stride, padding=padding, dilation=dilation))
  20. self.chomp2 = Chomp1d(padding)
  21. self.relu2 = nn.ReLU()
  22. self.dropout2 = nn.Dropout(dropout)
  23. self.net = nn.Sequential(self.conv1, self.chomp1, self.relu1, self.dropout1,
  24. self.conv2, self.chomp2, self.relu2, self.dropout2)
  25. self.downsample = nn.Conv1d(n_inputs, n_outputs, 1) if n_inputs != n_outputs else None
  26. self.relu = nn.ReLU()
  27. self.init_weights()
  28. def init_weights(self):
  29. self.conv1.weight.data.normal_(0, 0.01)
  30. self.conv2.weight.data.normal_(0, 0.01)
  31. if self.downsample is not None:
  32. self.downsample.weight.data.normal_(0, 0.01)
  33. def forward(self, x):
  34. out = self.net(x)
  35. res = x if self.downsample is None else self.downsample(x)
  36. return self.relu(out + res)
  37. class TemporalConvNet(nn.Module):
  38. def __init__(self, num_inputs, num_channels, kernel_size=2, dropout=0.2):
  39. super(TemporalConvNet, self).__init__()
  40. self.num_inputs = num_inputs
  41. layers = []
  42. num_levels = len(num_channels)
  43. for i in range(num_levels):
  44. dilation_size = 2 ** i
  45. in_channels = num_inputs if i == 0 else num_channels[i-1]
  46. out_channels = num_channels[i]
  47. layers += [TemporalBlock(in_channels, out_channels, kernel_size, stride=1, dilation=dilation_size,
  48. padding=(kernel_size-1) * dilation_size, dropout=dropout)]
  49. self.network = nn.Sequential(*layers)
  50. def forward(self, x):
  51. x = x.permute(0,2,1)
  52. x = self.network(x).permute(0,2,1)
  53. B,L,M = x.shape
  54. x = x.reshape(B,-1)
  55. return x
  56. if __name__ == '__main__':
  57. ecmwf = torch.randn(64, 96, 13)
  58. model = TemporalConvNet(num_inputs=13, num_channels=[64,32,16,8,1], kernel_size=4, dropout=0.2)
  59. y_hat = model(ecmwf)
  60. print("Output shape:", y_hat.shape)