sparsetrace commited on
Commit
4638f13
·
verified ·
1 Parent(s): 693c63e

Update PTST.py

Browse files
Files changed (1) hide show
  1. PTST.py +72 -1
PTST.py CHANGED
@@ -117,6 +117,32 @@ class MultiHeadSelfAttention(nn.Module):
117
  out = nn.Dropout(rate=self.dropout)(out, deterministic=deterministic)
118
  return out
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
  class FeedForward(nn.Module):
122
  d_model: int
@@ -134,7 +160,7 @@ class FeedForward(nn.Module):
134
  return x
135
 
136
 
137
- class TransformerEncoderBlock(nn.Module):
138
  d_model: int
139
  n_heads: int
140
  dropout: float = 0.0
@@ -155,6 +181,51 @@ class TransformerEncoderBlock(nn.Module):
155
  x = x + h2
156
  return x
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
  class PTSTBackbone(nn.Module):
160
  """
 
117
  out = nn.Dropout(rate=self.dropout)(out, deterministic=deterministic)
118
  return out
119
 
120
+ class ChannelSelfAttention(nn.Module):
121
+ d_model: int
122
+ tau: float = 1.0 # softmax temperature
123
+ col_norm: bool = True # match your C^- convention
124
+ init_scale: float = 0.0
125
+
126
+ @nn.compact
127
+ def __call__(self, x, deterministic: bool):
128
+ """
129
+ x: (B, T, d_model)
130
+ returns: (B, T, d_model)
131
+ """
132
+ B, T, D = x.shape
133
+ assert D == self.d_model
134
+
135
+ # Channel affinity per sample: S = x^T x / T => (B, D, D)
136
+ S = jnp.einsum("btd,bte->bde", x, x) / jnp.maximum(T, 1)
137
+
138
+ # Softmax to get mixing weights (row-stochastic by default)
139
+ C_row = nn.softmax(S / self.tau, axis=-1) # rows sum to 1
140
+
141
+ # If you want column-normalized C^- for right-multiply, use transpose:
142
+ C = jnp.swapaxes(C_row, -1, -2) if self.col_norm else C_row # (B,D,D)
143
+
144
+ scale = self.param("scale", lambda k, s: jnp.array(self.init_scale, jnp.float32), ())
145
+ return x + scale * (x @ C) # residual; starts near identity
146
 
147
  class FeedForward(nn.Module):
148
  d_model: int
 
160
  return x
161
 
162
 
163
+ class TransformerEncoderBlockX(nn.Module):
164
  d_model: int
165
  n_heads: int
166
  dropout: float = 0.0
 
181
  x = x + h2
182
  return x
183
 
184
+ class TransformerEncoderBlock(nn.Module):
185
+ d_model: int
186
+ n_heads: int
187
+ dropout: float = 0.0
188
+ mlp_ratio: float = 4.0
189
+
190
+ # new options
191
+ use_cam: bool = False
192
+ use_ffn: bool = True
193
+
194
+ # CAM options
195
+ cam_tau: float = 1.0
196
+ cam_col_norm: bool = True
197
+ cam_init_scale: float = 0.0
198
+
199
+ @nn.compact
200
+ def __call__(self, x, deterministic: bool):
201
+ # --- Token self-attention (always on, per your current design) ---
202
+ h = nn.LayerNorm(name="attn_ln")(x)
203
+ h = MultiHeadSelfAttention(
204
+ d_model=self.d_model, n_heads=self.n_heads, dropout=self.dropout
205
+ )(h, deterministic=deterministic)
206
+ x = x + h
207
+
208
+ # --- Channel self-attention (optional) ---
209
+ if self.use_cam:
210
+ hc = nn.LayerNorm(name="cam_ln")(x)
211
+ hc = ChannelSelfAttention(
212
+ d_model=self.d_model,
213
+ tau=self.cam_tau,
214
+ col_norm=self.cam_col_norm,
215
+ init_scale=self.cam_init_scale,
216
+ name="cam",
217
+ )(hc, deterministic=deterministic)
218
+ x = x + hc # residual around CAM
219
+
220
+ # --- FFN (optional) ---
221
+ if self.use_ffn:
222
+ h2 = nn.LayerNorm(name="ffn_ln")(x)
223
+ h2 = FeedForward(
224
+ d_model=self.d_model, mlp_ratio=self.mlp_ratio, dropout=self.dropout
225
+ )(h2, deterministic=deterministic)
226
+ x = x + h2
227
+
228
+ return x
229
 
230
  class PTSTBackbone(nn.Module):
231
  """