From d751602d1066f5afb16efeed09d9aac4991250dd Mon Sep 17 00:00:00 2001
From: Ignacio Oguiza <11656416+oguiza@users.noreply.github.com>
Date: Sun, 16 Feb 2025 12:00:06 +0100
Subject: [PATCH] updated multimodal models
---
nbs/022_tslearner.ipynb | 128 +++++++++++---
nbs/029_models.layers.ipynb | 30 ++--
nbs/030_models.utils.ipynb | 70 +++++---
nbs/068_models.TSiTPlus.ipynb | 122 ++++++++------
nbs/077_models.multimodal.ipynb | 287 ++++++++++++--------------------
nbs/models/test.pth | Bin 1099944 -> 1100008 bytes
setup_old.py | 59 -------
tsai/models/TSiTPlus.py | 79 ++++-----
tsai/models/multimodal.py | 6 +-
tsai/models/utils.py | 16 +-
tsai/tslearner.py | 4 +-
11 files changed, 399 insertions(+), 402 deletions(-)
delete mode 100644 setup_old.py
diff --git a/nbs/022_tslearner.ipynb b/nbs/022_tslearner.ipynb
index 2061edb91..77027fd05 100644
--- a/nbs/022_tslearner.ipynb
+++ b/nbs/022_tslearner.ipynb
@@ -265,11 +265,11 @@
"
\n",
" \n",
" 0 | \n",
- " 1.446255 | \n",
- " 0.266667 | \n",
- " 1.403359 | \n",
+ " 1.458827 | \n",
" 0.300000 | \n",
- " 00:00 | \n",
+ " 1.362652 | \n",
+ " 0.300000 | \n",
+ " 00:02 | \n",
"
\n",
" \n",
""
@@ -339,9 +339,9 @@
" \n",
" \n",
" 0 | \n",
- " 1.286023 | \n",
- " 0.400000 | \n",
- " 00:00 | \n",
+ " 1.457477 | \n",
+ " 0.200000 | \n",
+ " 00:01 | \n",
"
\n",
" \n",
""
@@ -369,11 +369,95 @@
"cell_type": "code",
"execution_count": null,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " \n",
+ " epoch | \n",
+ " train_loss | \n",
+ " valid_loss | \n",
+ " accuracy | \n",
+ " time | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 0.749274 | \n",
+ " 0.721294 | \n",
+ " 0.666667 | \n",
+ " 00:00 | \n",
+ "
\n",
+ " \n",
+ "
"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "num_classes = 2\n",
+ "X = np.random.rand(16, 5, 128)\n",
+ "y = np.random.randint(0, num_classes, (16, 3))\n",
+ "splits = RandomSplitter()(range_of(X))\n",
+ "arch = 'TSiTPlus'\n",
+ "vocab = np.arange(num_classes)\n",
+ "learn = TSClassifier(X, y, splits=splits, arch=arch, metrics=accuracy, vocab=vocab, device=default_device())\n",
+ "learn.fit_one_cycle(1, 1e-3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "torch.Size([8, 2, 50]) torch.Size([8, 7])\n"
+ ]
+ }
+ ],
"source": [
"num_classes = 5\n",
"X = torch.rand(8, 2, 50)\n",
- "y = torch.randint(0, num_classes, (len(X), 3, 50))\n",
+ "y = torch.randint(0, num_classes, (len(X), 7))\n",
+ "print(X.shape, y.shape)\n",
"splits = TimeSplitter(show_plot=False)(y)\n",
"vocab = np.arange(num_classes)\n",
"\n",
@@ -600,11 +684,11 @@
" \n",
" \n",
" 0 | \n",
- " 221.239578 | \n",
- " 14.241582 | \n",
- " 208.787231 | \n",
- " 14.034328 | \n",
- " 00:00 | \n",
+ " 204.070648 | \n",
+ " 13.636603 | \n",
+ " 199.854218 | \n",
+ " 13.712566 | \n",
+ " 00:01 | \n",
"
\n",
" \n",
""
@@ -808,7 +892,7 @@
},
{
"data": {
- "image/png": "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nz9f5mdyxx13qLS0VDk5OXbnryzWS1L9+vUlSadPn66yOAEAAICajuIyAADAL7i7u6tDhw568cUX9cYbb6ioqEgLFiyo7rB+tS5duujQoUP65z//qZYtW2ru3Llq166d5s6dW+E+6tatW6kxXbla+EpVtfr7WlxdXcs8f+XDBwEAAADYo7gMAABwHXfffbckKTc31+58WVtLfP/99/L09HRo24hrFVfLEhAQoLp165Y59v79+yvUh7+/v4YMGaIPPvhAOTk5at26tVJSUm4onvKUlpbq8OHDdue+//57SVJ4eLikn1cI5+Xl2bUrazuKisYWEBAgT0/PMj+T7777Ti4uLmrSpEmF+gIAAABwbRSXAQAAJK1du7bMVapLly6VdPW2ExkZGfrmm29s73NycrR48WLFxcVdcxVsWby8vCRdXVwti6urq+Lj4/XJJ58oOzvbdn7fvn1asWJFufefOnXK7r23t7eaNWumS5cu3VA8FfH666/bXhtj9Prrr8vNzU3du3eXJIWFhcnV1VXr16+3u2/27NlX9VXR2FxdXRUXF6fFixfbbb/xww8/6P3331enTp3k4+NzgzMCAAAAcFmd6g4AAADgZjB69GidP39eiYmJuv3221VYWKivv/5a8+fPV3h4uIYMGWLXvmXLloqPj9eYMWNktVptxdDU1FSHxo2MjJSfn5/efPNN1atXT15eXoqJibnm3sapqalavny5OnfurBEjRqi4uFgzZ85UixYtyt0/+c4771TXrl3Vvn17+fv7a+vWrfr444/tHrp3+SGFY8aMUXx8vFxdXTVgwACH5nSZh4eHli9frkGDBikmJkbLli3T559/rueee862utvX11e///3vNXPmTFksFkVGRuqzzz7TiRMnrurPkdgmT56sVatWqVOnThoxYoTq1KmjOXPm6NKlS5o6deoNzQcAAACAPYrLAAAAkl555RUtWLBAS5cu1VtvvaXCwkKFhoZqxIgRev755+Xn52fX/v7771dsbKxSU1OVnZ2tO++8U2lpaWrdurVD47q5uemdd97RxIkTNXz4cBUXF2vevHnXLC63bt1aK1as0Lhx45SUlKTbbrtNqampys3NLbe4PGbMGC1ZskQrV67UpUuXFBYWpsmTJ2vChAm2Nv369dPo0aP14Ycf6t1335Ux5oaLy66urlq+fLmeeuopTZgwQfXq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",
+ "image/png": "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",
"text/plain": [
""
]
@@ -860,11 +944,11 @@
" \n",
" \n",
" 0 | \n",
- " 4616.225098 | \n",
- " 53.340523 | \n",
- " 7969.317871 | \n",
- " 74.670258 | \n",
- " 00:00 | \n",
+ " 4539.636719 | \n",
+ " 50.971386 | \n",
+ " 7981.193848 | \n",
+ " 74.748787 | \n",
+ " 00:01 | \n",
"
\n",
" \n",
""
@@ -932,9 +1016,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "/Users/nacho/notebooks/tsai/nbs/022_tslearner.ipynb saved at 2024-02-11 13:56:13\n",
+ "/Users/nacho/notebooks/tsai/nbs/022_tslearner.ipynb saved at 2025-01-22 18:45:21\n",
"Correct notebook to script conversion! 😃\n",
- "Sunday 11/02/24 13:56:16 CET\n"
+ "Wednesday 22/01/25 18:45:24 CET\n"
]
},
{
diff --git a/nbs/029_models.layers.ipynb b/nbs/029_models.layers.ipynb
index fbc0cae54..9e0d52035 100644
--- a/nbs/029_models.layers.ipynb
+++ b/nbs/029_models.layers.ipynb
@@ -1022,7 +1022,7 @@
"outputs": [
{
"data": {
- "image/png": "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S+ftt9/W/fff7x2/ZMkSvfrqq945BljUCwCIChYjTJzoyp06BfEitgie5RXxX6hFiyBdDJEkweez//2ss5aQRo0a6fkjmW4OHz7stXb07t3bCzrS69WrlxeEzJw5M/m5u+++W/PmzdOcOXOydM3t27erWLFi2rZtm4oWLZqd6gIAAmDSJOnKK6X8+e13spSUFISLWCt7kyau3L27S/PK7/yoltXP72y1jOzfv18LFy5Uq1atUk6QJ4/3eO7cuRm+plmzZt5r/F05y5cv18cff6w2bdpkep19+/Z530DqDQAQvvTvFoiYLl2CFIjs2CG1bu3KpUpJL71EIBJHsrVq76ZNm3To0CGVLVs2zfP2+Ndff83wNZ06dfJed+6558oaYQ4ePKgePXocs5tm6NChGuJfDhIAEFYjRri9xQbDhwfpIm++6QasmmHDgnQRxO1smlmzZunxxx/XCy+84I0x+fDDDzV16lQ94p+ylYH+/ft7TTr+bc2aNcGuJgAgEzNmuP1TT0lFigTpIq+9ljKN15pfEFey1TJSqlQpJSYmav369Wmet8flypXL8DUDBw7U9ddfr5ttUJKkM844Q7t27dItt9yiBx54wOvmSS8pKcnbAADhNXu2tHChK198cZAusnWr9P33rnzOOUG6CGKmZSR//vxq0KBBmsGoNoDVHjdt2jTD1+zevfuogMMCGpPNsbMAgBDr18/tr7pKql49SBexbhlbf8YSm11xRZAugphpGTE2rbdr165q2LChGjdu7OUQsZaObt26eV/v0qWLKlas6I37MG3bttXw4cN11llneTNxli1b5rWW2PP+oAQAEJkZV/1zE4KW/n3z5pSBKE8/LeXN9scSYkC2/9c7dOigjRs3atCgQVq3bp3q1aunadOmJQ9qXb16dZqWkAcffFAJCQnefu3atSpdurQXiDz22GOB/U4AAAH18stuf8opUu3aQbqIzZrZs0c6/XSpZ88gXQQxl2ckHMgzAgChZZ8M1i2zapVL93H33UG4yP797iJ//eVW4Lv++iBcBDGXZwQAEB9sPKkFIgUKSLfeGsSmFwtEbP2ZDh2CdBFEA4IRAMBRxoxxextPWrhwEC6wcqX147uy7S21K+IWwQgA4ChLlrj91VcH4eSHDrl5wpbkzLppjqR+QPwiGAEAHGXjRrcvUyYIJ//4Y+n33135ww9pFQHB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",
+ "image/png": "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gccBICE88og0ZIgr33671hauovHj3cMuXXytGRA7wUi7du20du1a9e/f3xu02rBhQ02cODFtUOuyZcu8GTYAgAPs2pWW9l3NmtlofS37xTWSVK4sHXWU3xUE/JEUCATbCqOXTe21WTU2mLVEiRJ+VwcA8mbUKOnKK6UjjpD+/tv6vvXJJ9JFF0n160s//+x3BQF/vr9pwgCASLDB+w8/7Mo9eniBiNmfZsRrKAESFcEIAETCM89Iv/7qyh07ph2eOtXt27XzqV5AFCAYAYBw27DBG6zq6d07bXDIpk2ut8Y0aeJj/QCfEYwAQLhZS4gNzytXzs2m2W/ePLevVEkqWdK/6gF+IxgBgHCypo9x41x50CDL6pj21A8/uP3xx/tUNyBKEIwAQDj17On2pUtL+/MxHRiMnHWWD/UCogjBCACEy5Il0pgxrvzii1JSUqant2xxe1bpRaIjGAGAcBkxwu0to9nll//r6e3b3b5YsQjXC4gyBCMAEA67d0uvvebKTzzxr1YRs3/RXh12WITrBkQZghEACEeCs+uuk1ascGNFLr74X6csXSrNnu3KtlovkMgIRgAg1Pr1k956y5WffTbLfpi5c92+dm2pVq0I1w+IMgQjABBKe/a4warmwQelq6/O8rQ1a9y+evUI1g2IUgQjABBK69e7jKumT59sT/vsM7e3PGhAoiMYAYBQ+ugjty9bVipUKNvTvvnG7Vu2jFC9gChGMAIAobJggfTkk6589tnZnrZ2rbRypSufeWaE6gZEsYJ+VwAA4sLixVKjRi55iM3VHTw421OnT08v2wBWINHRMgIAofDAAy4QOeII6fvvpYoVsz31k0/c/sYbs0w/AiQcghEAyK/586W333ZlS3RWr162p+7cKb3yiitfckmE6gdEOYIRAMivsWOlvXulZs2kCy886Klt27q95UI744zIVA+IdgQjAJAfP/4o9e3ryhdccNBTLV754gtXfuSRg062ARIKwQgA5Gf2THDWjI0R6djxoKfPmOEyxds4ka5dI1NFIBYwmwYA8uKXX6RTT5W2bHH53OfMkQ4//KAvmTo1PW4pyF9fIA2/DgCQl2m8LVpIW7e6xxMnHjIQMfPmuf0114S5fkCMoZsGAHK79oyNDbFApGZNadky6aijcvTSX391+8aNw1tFINYQjABAbvTund7EYbNoqlbN0ct273Y9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",
"text/plain": [
""
]
@@ -2291,7 +2291,7 @@
{
"data": {
"text/plain": [
- "(TensorBase(1.7974, grad_fn=),\n",
+ "(TensorBase(1.7252, grad_fn=),\n",
" create_conv_lin_nd_head(\n",
" (0): Conv1d(32, 5, kernel_size=(1,), stride=(1,))\n",
" (1): Dropout(p=0.5, inplace=False)\n",
@@ -2329,7 +2329,7 @@
{
"data": {
"text/plain": [
- "(TensorBase(1.7111, grad_fn=),\n",
+ "(TensorBase(1.6647, grad_fn=),\n",
" create_conv_lin_nd_head(\n",
" (0): Dropout(p=0.5, inplace=False)\n",
" (1): Linear(in_features=10, out_features=16, bias=True)\n",
@@ -2367,7 +2367,7 @@
{
"data": {
"text/plain": [
- "(TensorBase(0.5055, grad_fn=),\n",
+ "(TensorBase(0.7063, grad_fn=),\n",
" create_conv_lin_nd_head(\n",
" (0): Dropout(p=0.5, inplace=False)\n",
" (1): Linear(in_features=10, out_features=2, bias=True)\n",
@@ -2405,7 +2405,7 @@
{
"data": {
"text/plain": [
- "(TensorBase(0.6870, grad_fn=),\n",
+ "(TensorBase(0.6203, grad_fn=),\n",
" create_conv_lin_nd_head(\n",
" (0): Dropout(p=0.5, inplace=False)\n",
" (1): Linear(in_features=10, out_features=6, bias=True)\n",
@@ -2522,7 +2522,7 @@
{
"data": {
"text/plain": [
- "(TensorBase(1.8153, grad_fn=),\n",
+ "(TensorBase(1.7711, grad_fn=),\n",
" lin_nd_head(\n",
" (0): Dropout(p=0.5, inplace=False)\n",
" (1): Reshape(bs)\n",
@@ -2559,7 +2559,7 @@
{
"data": {
"text/plain": [
- "(TensorBase(1.8502, grad_fn=),\n",
+ "(TensorBase(1.8884, grad_fn=),\n",
" lin_nd_head(\n",
" (0): Dropout(p=0.5, inplace=False)\n",
" (1): Reshape(bs)\n",
@@ -2596,7 +2596,7 @@
{
"data": {
"text/plain": [
- "(TensorBase(0.8992, grad_fn=),\n",
+ "(TensorBase(0.7737, grad_fn=),\n",
" lin_nd_head(\n",
" (0): Dropout(p=0.5, inplace=False)\n",
" (1): Reshape(bs)\n",
@@ -2633,7 +2633,7 @@
{
"data": {
"text/plain": [
- "(TensorBase(0.8099, grad_fn=),\n",
+ "(TensorBase(0.8873, grad_fn=),\n",
" lin_nd_head(\n",
" (0): Dropout(p=0.5, inplace=False)\n",
" (1): Reshape(bs)\n",
@@ -2816,7 +2816,7 @@
{
"data": {
"text/plain": [
- "(TensorBase(1.6665, grad_fn=),\n",
+ "(TensorBase(1.8352, grad_fn=),\n",
" create_conv_3d_head(\n",
" (0): ConvBlock(\n",
" (0): Conv1d(32, 5, kernel_size=(1,), stride=(1,))\n",
@@ -2853,7 +2853,7 @@
{
"data": {
"text/plain": [
- "(TensorBase(0.6966, grad_fn=),\n",
+ "(TensorBase(0.6711, grad_fn=),\n",
" create_conv_3d_head(\n",
" (0): ConvBlock(\n",
" (0): Conv1d(32, 1, kernel_size=(1,), stride=(1,))\n",
@@ -3225,8 +3225,8 @@
{
"data": {
"text/plain": [
- "(tensor(-7.5748e-11, grad_fn=),\n",
- " tensor(1.0723, grad_fn=))"
+ "(tensor(-2.3159e-10, grad_fn=),\n",
+ " tensor(0.9743, grad_fn=))"
]
},
"execution_count": null,
@@ -3679,9 +3679,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "/Users/nacho/notebooks/tsai/nbs/029_models.layers.ipynb saved at 2025-01-20 10:23:58\n",
+ "/Users/nacho/notebooks/tsai/nbs/029_models.layers.ipynb saved at 2025-01-22 18:40:22\n",
"Correct notebook to script conversion! 😃\n",
- "Monday 20/01/25 10:24:01 CET\n"
+ "Wednesday 22/01/25 18:40:25 CET\n"
]
},
{
diff --git a/nbs/030_models.utils.ipynb b/nbs/030_models.utils.ipynb
index d17d36757..244a2ce5c 100644
--- a/nbs/030_models.utils.ipynb
+++ b/nbs/030_models.utils.ipynb
@@ -329,6 +329,46 @@
"create_model = build_ts_model"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from tsai.data.core import get_ts_dls, TSClassification\n",
+ "from tsai.models.TSiTPlus import TSiTPlus\n",
+ "from fastai.losses import CrossEntropyLossFlat"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "arch: TSiTPlus(c_in=3 c_out=2 seq_len=128 arch_config={} kwargs={'custom_head': functools.partial(, d=3)})\n",
+ "torch.Size([13, 3, 2])\n",
+ "TensorBase(0.8796, grad_fn=)\n"
+ ]
+ }
+ ],
+ "source": [
+ "X = np.random.rand(16, 3, 128)\n",
+ "y = np.random.randint(0, 2, (16, 3))\n",
+ "tfms = [None, [TSClassification()]]\n",
+ "dls = get_ts_dls(X, y, splits=RandomSplitter()(range_of(X)), tfms=tfms)\n",
+ "model = build_ts_model(TSiTPlus, dls=dls, pretrained=False, verbose=True)\n",
+ "xb, yb = dls.one_batch()\n",
+ "output = model(xb)\n",
+ "print(output.shape)\n",
+ "loss = CrossEntropyLossFlat()(output, yb)\n",
+ "print(loss)\n",
+ "assert output.shape == (dls.bs, dls.d, dls.c)"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -495,15 +535,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "[W NNPACK.cpp:64] Could not initialize NNPACK! Reason: Unsupported hardware.\n"
- ]
- }
- ],
+ "outputs": [],
"source": [
"c_in = 3\n",
"seq_len = 30\n",
@@ -555,14 +587,14 @@
{
"data": {
"text/plain": [
- "(array([ 0.74775537, 1.41245663, 2.12445924, 2.8943163 , 3.56384351,\n",
- " 4.23789602, 4.83134182, 5.18560431, 5.30551186, 6.29076506,\n",
- " 6.58873471, 7.03661275, 7.0884361 , 7.57927022, 8.21911791,\n",
- " 8.59726773, 9.37382718, 10.17298849, 10.40118308, 10.82265631]),\n",
- " array([ 6.29076506, 6.58873471, 7.03661275, 7.0884361 , 7.57927022,\n",
- " 8.21911791, 8.59726773, 9.37382718, 10.17298849, 10.40118308]),\n",
- " array([ 6.58873471, 7.03661275, 7.0884361 , 7.57927022, 8.21911791,\n",
- " 8.59726773, 9.37382718, 10.17298849, 10.40118308, 10.82265631]))"
+ "(array([0.99029138, 1.68463991, 2.21744589, 2.65448222, 2.85159354,\n",
+ " 3.26171729, 3.67986707, 4.04343956, 4.3077458 , 4.44585435,\n",
+ " 4.76876866, 4.85844441, 4.93256093, 5.52415845, 6.10704489,\n",
+ " 6.74848957, 7.31920741, 8.20198208, 8.78954283, 9.0402 ]),\n",
+ " array([4.44585435, 4.76876866, 4.85844441, 4.93256093, 5.52415845,\n",
+ " 6.10704489, 6.74848957, 7.31920741, 8.20198208, 8.78954283]),\n",
+ " array([4.76876866, 4.85844441, 4.93256093, 5.52415845, 6.10704489,\n",
+ " 6.74848957, 7.31920741, 8.20198208, 8.78954283, 9.0402 ]))"
]
},
"execution_count": null,
@@ -595,9 +627,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "/Users/nacho/notebooks/tsai/nbs/030_models.utils.ipynb saved at 2024-01-31 13:03:06\n",
+ "/Users/nacho/notebooks/tsai/nbs/030_models.utils.ipynb saved at 2025-01-22 18:23:18\n",
"Correct notebook to script conversion! 😃\n",
- "Wednesday 31/01/24 13:03:08 CET\n"
+ "Wednesday 22/01/25 18:23:21 CET\n"
]
},
{
diff --git a/nbs/068_models.TSiTPlus.ipynb b/nbs/068_models.TSiTPlus.ipynb
index 455b3ec8f..f97c58fae 100644
--- a/nbs/068_models.TSiTPlus.ipynb
+++ b/nbs/068_models.TSiTPlus.ipynb
@@ -48,7 +48,7 @@
"source": [
"#|export\n",
"class _TSiTEncoderLayer(nn.Module):\n",
- " def __init__(self, d_model:int, n_heads:int, q_len:int=None, attn_dropout:float=0., dropout:float=0, drop_path_rate:float=0., \n",
+ " def __init__(self, d_model:int, n_heads:int, q_len:int=None, attn_dropout:float=0., dropout:float=0, drop_path_rate:float=0.,\n",
" mlp_ratio:int=1, lsa:bool=False, qkv_bias:bool=True, act:str='gelu', pre_norm:bool=False):\n",
" super().__init__()\n",
" self.mha = MultiheadAttention(d_model, n_heads, attn_dropout=attn_dropout, proj_dropout=dropout, lsa=lsa, qkv_bias=qkv_bias)\n",
@@ -57,8 +57,8 @@
" self.ff_norm = nn.LayerNorm(d_model)\n",
" self.drop_path = DropPath(drop_path_rate) if drop_path_rate != 0 else nn.Identity()\n",
" self.pre_norm = pre_norm\n",
- " \n",
- " if lsa and q_len is not None: \n",
+ "\n",
+ " if lsa and q_len is not None:\n",
" self.register_buffer('attn_mask', torch.eye(q_len).reshape(1, 1, q_len, q_len).bool())\n",
" else: self.attn_mask = None\n",
"\n",
@@ -66,7 +66,7 @@
" if self.pre_norm:\n",
" if self.attn_mask is not None:\n",
" x = self.drop_path(self.mha(self.attn_norm(x), attn_mask=self.attn_mask)[0]) + x\n",
- " else: \n",
+ " else:\n",
" x = self.drop_path(self.mha(self.attn_norm(x))[0]) + x\n",
" x = self.drop_path(self.pwff(self.ff_norm(x))) + x\n",
" else:\n",
@@ -86,7 +86,7 @@
"source": [
"#|export\n",
"class _TSiTEncoder(nn.Module):\n",
- " def __init__(self, d_model, n_heads, depth:int=6, q_len:int=None, attn_dropout:float=0., dropout:float=0, drop_path_rate:float=0., \n",
+ " def __init__(self, d_model, n_heads, depth:int=6, q_len:int=None, attn_dropout:float=0., dropout:float=0, drop_path_rate:float=0.,\n",
" mlp_ratio:int=1, lsa:bool=False, qkv_bias:bool=True, act:str='gelu', pre_norm:bool=False):\n",
" super().__init__()\n",
" dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]\n",
@@ -112,22 +112,22 @@
"source": [
"#|export\n",
"class _TSiTBackbone(Module):\n",
- " def __init__(self, c_in:int, seq_len:int, depth:int=6, d_model:int=128, n_heads:int=16, act:str='gelu', \n",
- " lsa:bool=False, qkv_bias:bool=True, attn_dropout:float=0., dropout:float=0., drop_path_rate:float=0., mlp_ratio:int=1, \n",
- " pre_norm:bool=False, use_token:bool=True, use_pe:bool=True, n_cat_embeds:Optional[list]=None, cat_embed_dims:Optional[list]=None, \n",
- " cat_padding_idxs:Optional[list]=None, cat_pos:Optional[list]=None, feature_extractor:Optional[Callable]=None, \n",
+ " def __init__(self, c_in:int, seq_len:int, depth:int=6, d_model:int=128, n_heads:int=16, act:str='gelu',\n",
+ " lsa:bool=False, qkv_bias:bool=True, attn_dropout:float=0., dropout:float=0., drop_path_rate:float=0., mlp_ratio:int=1,\n",
+ " pre_norm:bool=False, use_token:bool=True, use_pe:bool=True, n_cat_embeds:Optional[list]=None, cat_embed_dims:Optional[list]=None,\n",
+ " cat_padding_idxs:Optional[list]=None, cat_pos:Optional[list]=None, feature_extractor:Optional[Callable]=None,\n",
" token_size:int=None, tokenizer:Optional[Callable]=None):\n",
"\n",
" # Categorical embeddings\n",
" if n_cat_embeds is not None:\n",
" n_cat_embeds = listify(n_cat_embeds)\n",
- " if cat_embed_dims is None: \n",
+ " if cat_embed_dims is None:\n",
" cat_embed_dims = [emb_sz_rule(s) for s in n_cat_embeds]\n",
" self.to_cat_embed = MultiEmbedding(c_in, n_cat_embeds, cat_embed_dims=cat_embed_dims, cat_padding_idxs=cat_padding_idxs, cat_pos=cat_pos)\n",
" c_in, seq_len = output_size_calculator(self.to_cat_embed, c_in, seq_len)\n",
" else:\n",
" self.to_cat_embed = nn.Identity()\n",
- " \n",
+ "\n",
" # Sequence embedding\n",
" if token_size is not None:\n",
" self.tokenizer = SeqTokenizer(c_in, d_model, token_size)\n",
@@ -136,7 +136,7 @@
" if isinstance(tokenizer, nn.Module): self.tokenizer = tokenizer\n",
" else: self.tokenizer = tokenizer(c_in, d_model)\n",
" c_in, seq_len = output_size_calculator(self.tokenizer, c_in, seq_len)\n",
- " else: \n",
+ " else:\n",
" self.tokenizer = nn.Identity()\n",
"\n",
" # Feature extractor\n",
@@ -146,13 +146,13 @@
" c_in, seq_len = output_size_calculator(self.feature_extractor, c_in, seq_len)\n",
" else:\n",
" self.feature_extractor = nn.Identity()\n",
- " \n",
+ "\n",
" # Linear projection\n",
" if token_size is None and tokenizer is None and feature_extractor is None:\n",
" self.linear_proj = nn.Conv1d(c_in, d_model, 1)\n",
" else:\n",
" self.linear_proj = nn.Identity()\n",
- " \n",
+ "\n",
" self.transpose = Transpose(1,2)\n",
"\n",
" # Position embedding & token\n",
@@ -171,19 +171,19 @@
"\n",
" # Categorical embeddings\n",
" x = self.to_cat_embed(x)\n",
- " \n",
+ "\n",
" # Sequence embedding\n",
" x = self.tokenizer(x)\n",
"\n",
" # Feature extractor\n",
" x = self.feature_extractor(x)\n",
- " \n",
+ "\n",
" # Linear projection\n",
" x = self.linear_proj(x)\n",
- " \n",
+ "\n",
" # Position embedding & token\n",
" x = self.transpose(x)\n",
- " if self.use_pe: \n",
+ " if self.use_pe:\n",
" x = x + self.pos_embed\n",
" if self.use_token: # token is concatenated after position embedding so that embedding can be learned using self.supervised learning\n",
" x = torch.cat((self.cls_token.expand(x.shape[0], -1, -1), x), dim=1)\n",
@@ -191,7 +191,7 @@
"\n",
" # Encoder\n",
" x = self.encoder(x)\n",
- " \n",
+ "\n",
" # Output\n",
" x = x.transpose(1,2)\n",
" return x"
@@ -221,10 +221,10 @@
" depth: number of blocks in the encoder.\n",
" n_heads: parallel attention heads. Default:16 (range(8-16)).\n",
" act: the activation function of positionwise feedforward layer.\n",
- " lsa: locality self attention used (see Lee, S. H., Lee, S., & Song, B. C. (2021). Vision Transformer for Small-Size Datasets. \n",
+ " lsa: locality self attention used (see Lee, S. H., Lee, S., & Song, B. C. (2021). Vision Transformer for Small-Size Datasets.\n",
" arXiv preprint arXiv:2112.13492.)\n",
" attn_dropout: dropout rate applied to the attention sublayer.\n",
- " dropout: dropout applied to to the embedded sequence steps after position embeddings have been added and \n",
+ " dropout: dropout applied to to the embedded sequence steps after position embeddings have been added and\n",
" to the mlp sublayer in the encoder.\n",
" drop_path_rate: stochastic depth rate.\n",
" mlp_ratio: ratio of mlp hidden dim to embedding dim.\n",
@@ -240,15 +240,15 @@
" cat_pos: list with the position of the categorical variables in the input.\n",
" token_size: Size of the embedding function used to reduce the sequence length (similar to ViT's patch size)\n",
" tokenizer: nn.Module or callable that will be used to reduce the sequence length\n",
- " feature_extractor: nn.Module or callable that will be used to preprocess the time series before \n",
+ " feature_extractor: nn.Module or callable that will be used to preprocess the time series before\n",
" the embedding step. It is useful to extract features or resample the time series.\n",
- " flatten: flag to indicate if the 3d logits will be flattened to 2d in the model's head if use_token is set to False. \n",
+ " flatten: flag to indicate if the 3d logits will be flattened to 2d in the model's head if use_token is set to False.\n",
" If use_token is False and flatten is False, the model will apply a pooling layer.\n",
- " concat_pool: if True the head begins with fastai's AdaptiveConcatPool2d if concat_pool=True; otherwise, it uses traditional average pooling. \n",
+ " concat_pool: if True the head begins with fastai's AdaptiveConcatPool2d if concat_pool=True; otherwise, it uses traditional average pooling.\n",
" fc_dropout: dropout applied to the final fully connected layer.\n",
" use_bn: flag that indicates if batchnorm will be applied to the head.\n",
" bias_init: values used to initialized the output layer.\n",
- " y_range: range of possible y values (used in regression tasks). \n",
+ " y_range: range of possible y values (used in regression tasks).\n",
" custom_head: custom head that will be applied to the network. It must contain all kwargs (pass a partial function)\n",
" verbose: flag to control verbosity of the model.\n",
"\n",
@@ -257,20 +257,20 @@
" \"\"\"\n",
"\n",
" def __init__(self, c_in:int, c_out:int, seq_len:int, d_model:int=128, depth:int=6, n_heads:int=16, act:str='gelu',\n",
- " lsa:bool=False, attn_dropout:float=0., dropout:float=0., drop_path_rate:float=0., mlp_ratio:int=1, qkv_bias:bool=True, \n",
- " pre_norm:bool=False, use_token:bool=False, use_pe:bool=True, \n",
+ " lsa:bool=False, attn_dropout:float=0., dropout:float=0., drop_path_rate:float=0., mlp_ratio:int=1, qkv_bias:bool=True,\n",
+ " pre_norm:bool=False, use_token:bool=False, use_pe:bool=True,\n",
" cat_pos:Optional[list]=None, n_cat_embeds:Optional[list]=None, cat_embed_dims:Optional[list]=None, cat_padding_idxs:Optional[list]=None,\n",
- " token_size:int=None, tokenizer:Optional[Callable]=None, feature_extractor:Optional[Callable]=None, \n",
- " flatten:bool=False, concat_pool:bool=True, fc_dropout:float=0., use_bn:bool=False, \n",
+ " token_size:int=None, tokenizer:Optional[Callable]=None, feature_extractor:Optional[Callable]=None,\n",
+ " flatten:bool=False, concat_pool:bool=True, fc_dropout:float=0., use_bn:bool=False,\n",
" bias_init:Optional[Union[float, list]]=None, y_range:Optional[tuple]=None, custom_head:Optional[Callable]=None, verbose:bool=True, **kwargs):\n",
"\n",
- " if use_token and c_out == 1: \n",
+ " if use_token and c_out == 1:\n",
" use_token = False\n",
" pv(\"use_token set to False as c_out == 1\", verbose)\n",
" backbone = _TSiTBackbone(c_in, seq_len, depth=depth, d_model=d_model, n_heads=n_heads, act=act,\n",
- " lsa=lsa, attn_dropout=attn_dropout, dropout=dropout, drop_path_rate=drop_path_rate, \n",
- " pre_norm=pre_norm, mlp_ratio=mlp_ratio, use_pe=use_pe, use_token=use_token, \n",
- " n_cat_embeds=n_cat_embeds, cat_embed_dims=cat_embed_dims, cat_padding_idxs=cat_padding_idxs, cat_pos=cat_pos, \n",
+ " lsa=lsa, attn_dropout=attn_dropout, dropout=dropout, drop_path_rate=drop_path_rate,\n",
+ " pre_norm=pre_norm, mlp_ratio=mlp_ratio, use_pe=use_pe, use_token=use_token,\n",
+ " n_cat_embeds=n_cat_embeds, cat_embed_dims=cat_embed_dims, cat_padding_idxs=cat_padding_idxs, cat_pos=cat_pos,\n",
" feature_extractor=feature_extractor, token_size=token_size, tokenizer=tokenizer)\n",
"\n",
" self.head_nf = d_model\n",
@@ -280,11 +280,12 @@
" # Head\n",
" if custom_head:\n",
" if isinstance(custom_head, nn.Module): head = custom_head\n",
- " else: head = custom_head(self.head_nf, c_out, seq_len, **kwargs)\n",
+ " else:\n",
+ " head = custom_head(self.head_nf, c_out, seq_len, **kwargs)\n",
" else:\n",
" nf = d_model\n",
" layers = []\n",
- " if use_token: \n",
+ " if use_token:\n",
" layers += [TokenLayer()]\n",
" elif flatten:\n",
" layers += [Reshape(-1)]\n",
@@ -294,10 +295,10 @@
" layers = [GACP1d(1) if concat_pool else GAP1d(1)]\n",
" if use_bn: layers += [nn.BatchNorm1d(nf)]\n",
" if fc_dropout: layers += [nn.Dropout(fc_dropout)]\n",
- " \n",
+ "\n",
" # Last layer\n",
" linear = nn.Linear(nf, c_out)\n",
- " if bias_init is not None: \n",
+ " if bias_init is not None:\n",
" if isinstance(bias_init, float): nn.init.constant_(linear.bias, bias_init)\n",
" else: linear.bias = nn.Parameter(torch.as_tensor(bias_init, dtype=torch.float32))\n",
" layers += [linear]\n",
@@ -305,8 +306,8 @@
" if y_range: layers += [SigmoidRange(*y_range)]\n",
" head = nn.Sequential(*layers)\n",
" super().__init__(OrderedDict([('backbone', backbone), ('head', head)]))\n",
- " \n",
- " \n",
+ "\n",
+ "\n",
"TSiT = TSiTPlus"
]
},
@@ -378,6 +379,31 @@
"test_eq(model.head[1].bias.data, tensor(bias_init))"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from tsai.models.layers import lin_nd_head"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "bs = 16\n",
+ "nvars = 4\n",
+ "seq_len = 50\n",
+ "c_out = 2\n",
+ "d = 7\n",
+ "xb = torch.rand(bs, nvars, seq_len)\n",
+ "model = TSiTPlus(nvars, c_out, seq_len, d=7, custom_head=lin_nd_head)\n",
+ "test_eq(model(xb).shape, (bs, d, c_out))"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -404,7 +430,7 @@
"outputs": [
{
"data": {
- "image/png": "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s9V+J+3atZPValVxcbHD+MVlvSQ1a9ZMknTy5Emn5QQAAAAaOsplAACAn/H29lZCQoJmzJihF198URUVFXr99dfdHavObrvtNh05ckR//etf1aFDBy1dulTdunXT0qVLa30NPz+/es108Wrhizlr9fflWCyWascv/vFBAAAAAI4olwEAAK6ge/fukqTjx487jFe3tcShQ4fUpEkTU9tGXK5crU5oaKj8/PyqnfvgwYO1ukZISIhGjx6tf/zjHyouLlanTp2UlZV1VXlqYrVadfToUYexQ4cOSZKio6Ml/bRC+NSpUw7HVbcdRW2zhYaGqkmTJtV+J59//rk8PDzUunXrWl0LAAAAwOVRLgMAAEh6//33q12lunr1akmXbjuxbds27d692/66uLhYb7/9tgYNGnTZVbDV8ff3l3RpuVodi8WipKQkvfXWWyoqKrKPHzhwQOvWravx/G+//dbhddOmTXXTTTfp/PnzV5WnNubPn29/brPZNH/+fHl5eal///6SpKioKFksFm3evNnhvIULF15yrdpms1gsGjRokN5++22H7Te++eYbLV++XL1791ZgYOBVfiIAAAAAF3i6OwAAAMC1YOLEiTp79qyGDRumm2++WeXl5frwww+1YsUKRUdHa/To0Q7Hd+jQQUlJSUpNTZWPj4+9DM3OzjY1b2xsrIKDg7Vo0SIFBATI399fiYmJl93bODs7W2vXrlWfPn00btw4VVZWat68eWrfvn2N+yffcsst6tu3r+Lj4xUSEqKdO3fqjTfecPjRvQs/UpiamqqkpCRZLBaNGDHC1Ge6wNfXV2vXrlVKSooSExO1Zs0avfvuu3riiSfsq7uDgoJ03333ad68eTIMQ7GxsXrnnXdUUlJyyfXMZJs+fbo2bNig3r17a9y4cfL09NTixYt1/vx5zZo166o+DwAAAABHlMsAAACSnn/+eb3++utavXq1lixZovLyckVGRmrcuHF68sknFRwc7HD87bffrh49eig7O1tFRUW65ZZblJubq06dOpma18vLS3/729+Unp6uRx99VJWVlVq2bNlly+VOnTpp3bp1SktLU0ZGhm688UZlZ2fr+PHjNZbLqampWrVqldavX6/z588rKipK06dP15QpU+zH3H333Zo4caJeffVVvfzyy7LZbFddLlssFq1du1Z/+MMfNGXKFAUEBCgzM1MZ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",
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAABZcAAABoCAYAAACNDM73AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAGEBJREFUeJzt3Ql0lPXVx/GbDQLZICyBQCAUgyKrBESQIhwF0UolihRFBVRcUNI24hKPJqBIVJRDWaJQWtJToaJWMFWxAhUCuLDjAkR2YkVBhYSgEAjznvt/nXQCQ5InycyTmfl+zpkzmfW584SHTH65c/9BDofDIQAAAAAAAAAAWBBs5c4AAAAAAAAAACjCZQAAAAAAAACAZYTLAAAAAAAAAADLCJcBAAAAAAAAAJYRLgMAAAAAAAAALCNcBgAAAAAAAABYRrgMAAAAAAAAALCMcBkAAAAAAAAAYBnhMgAAAAAAAADAMsJlAAAAD8nJyZGgoCDZv39/2XUDBgwwp9o2adIksy1XiYmJMmbMGPE0fX26bX29TrrdyMhI8Rbdvu4DAAAAAN5DuAwAAPCLzz//XIYPHy5t27aV8PBwadWqlQwaNEhmzZrlsW1+8803JhTdunWr1AXvvfdenQ1p63JtAAAAQCAKtbsAAACAuuCjjz6SgQMHSps2bWTcuHHSokULKSgokE8++UT+9Kc/yYQJE2plOx988MF54fLkyZNNl3H37t2lNuXn50twcLDlAHfOnDmWQlwN43/++WcJCwurRpW1U5tuPzSUt7YAAACAN/EOHAAAQESeffZZiYmJkQ0bNkijRo3K3Xb48OFa2069evXEW+rXr+/R5z9z5oycPXvWvCbt9LaT3dsHAAAAAhFjMQAAAERkz5490qlTp/OCZdW8efPz5vs+9NBDsnDhQrn44otNsJmcnCx5eXmVbsd15vKqVaukV69e5uuxY8ea5z13drE7a9euNY/T7bZv317mzp3r9n7nzlw+ffq06ZJOSkoyj23SpIn069dPli9fbm7X+2pnsPM1Ok+uc5VffPFFmTFjhtmuhtfbt293O3PZae/evXLttddKRESExMfHy9NPPy0Oh6Psdt0H+lg9d3Xuc1ZUm/O6czuat2zZItddd51ER0eb+c9XX3216UR3Nxd73bp1kpaWJs2aNTO1pqSkyJEjRyr8PgAAAACBjs5lAACAX0Y7fPzxx/LFF19I586dK73/6tWrZfHixZKammpC1uzsbBkyZIisX7++So9XHTt2NGFrRkaG3HvvvfLrX//aXN+3b98K50IPHjzYhKAapmr3cGZmpsTFxVW6Pb1/VlaW3HPPPXL55ZdLUVGRbNy4UTZv3mxmS993331mTIeGzX//+9/dPseCBQvk5MmTpl593bGxsaZ72Z3S0lKzT6644gp54YUX5P333ze1as36uq2oSm2uvvzyS7M/NVh+9NFHzcgODeE12NfvXe/evcvdX8eeNG7c2NSnwbYG6PoHBP0eAwAAAHCPcBkAAEBEJk6caLpcde6xBq8aTGqnq85hdjdLWENoDWa1Y1mNHDnSdDFrUPzWW29VaZsaCOs29TF9+vSR22+/vdLH6H2183fNmjVmPrS6+eabpUuXLpU+9t1335Xrr79e5s2b5/Z2raFDhw4mwL1QLV9//bXs3r3bhNtOGsa6oyG0hsszZ840l8ePHy9Dhw6V559/3oTyTZs2rbRmK7W5evLJJ02ntnZ5/+pXvzLX3XnnneZ7pGGzBsyutItb52E7u6E1MNe6CwsLzbgUAAAAAOdjLAYAAICI6dzVzuXf/va3sm3bNtNpq+McWrVqJbm5uW7DTmewrDTovfHGG+Xf//636dj1BH1eff5hw4aVBcvODmittTI68kM7enft2lXtGjTIdg2WK6Pdv+eOEykpKZEVK1aIp+h+0qBY95MzWFYtW7aU2267zQTO2rXtSjuxXcds6B8X9HkOHDjgsToBAAAAX0e4DAAA8AudY6xdx0ePHjXjLdLT0+X48eMyfPhwM1vYlc4tPpd21v70008em9Wrz/vzzz+73bZ25FZGR1EcO3bM1Kmdzo888oh89tlnlmpo165dle8bHBxcLtxVuu2Kup1raz/p98HdPtEgXruSCwoKyl3vGtYrHZGh9N8CAAAAAPcIlwEAAM5Rr149EzRPnTpVXn75ZTNe4Y033hBf179/f7Nw4V//+lczF3r+/PnSo0cPc15VDRo0qNWaXLuFXXmq+/tCQkJC3F7vuvggAAAAgPIIlwEAACrQs2dPc37o0KFy17sbLfHVV19Jw4YNLY2NuFC46o4+r4a77radn59fpefQBfjGjh0r//jHP0z3bteuXc1Cf9WppzLaIbx3797z9pFKTEws1yGsHdWu3I2jqGptup/0++Bun+zcudN0VCckJFh4JQAAAADcIVwGAAAQkQ8//NBtl+p7771nzs8dsaDzmTdv3lx2WYPat99+WwYPHnzBLlh3IiIi3Iar7ujz6mzlpUuXysGDB8uu37Fjh5nFXJkffvih3OXIyEi56KKL5NSpU9Wqpypmz55d9rXuX72sCyTqYomqbdu25nXl5eWVe1x2dvZ5z1XV2vT59Pug3w/X8RvfffedLFq0SPr16yfR0dE1fm0AAABAoAu1uwAAAIC6YMKECWZOb0pKilxyySVm0bmPPvpIFi9ebLpstdvXlY6V0KA3NTVV6tevXxaGTp482dJ227dvbxbae+WVVyQqKsoEqL17977gbGN9/vfff98sODd+/Hg5c+aMzJo1Szp16lTp/ORLL71UBgwYYBYi1A7mjRs3yptvvllu0T3nIoX6uvT1aVA7cuRIqY7w8HBT6+jRo81rWrZsmbz77rvyxBNPlHV3x8TEyC233GJeg3Ym6/5455135PDhw+c9n5XapkyZIsuXLzdBsu6n0NBQmTt3rgnSdbFGAAAAADVHuAwAACAiL774opmrrJ3K8+bNM+GyLvKmweSTTz5pAmBXV111lfTp08eEvdpFrMFtTk6OGTNhhXbx/u1vfzOLB95///0mLF6wYMEFw2V9fu1STktLk4yMDGndurWpQcd2VBYuayibm5srH3zwgQlZtWtYQ1hd2M/ppptuMkH7a6+9Jq+++qrpNq5uuKzhr4bLDzzwgNmGhueZmZmmblcaLOtcaw3YNagfMWKETJs2zQT4rqzUpmH7mjVrzH7NysoyIzo04NbH6TkAAACAmgtysEoJAACAJdph++CDD5Yb+QAAAAAAgYaZywAAAAAAAAAAywiXAQAAAAAAAACWES4DAAAAAAAAACxjQT8AAACLWLICAAAAAOhcBgAAAAAAAABUA+EyAAAAAAAAAKDuj8U4e/asfPPNNxIVFSVBQUHe3jwAAAAAAADg82Pajh8/LvHx8RIcTO8oAihc1mA5ISHB25sFAAAAAAAA/EpBQYG0bt3a7jIQwLweLmvH8v8rEJFob28eNui2ur/dJcCLtl2VZ3cJAAAAqADvzwML788Bf1UkIgkuORsQIOHy/0ZhaLBMuBwIQiJD7C4BXsVxDQAAUJfx/jzQ8P4c8GeMnIXdGMoCAAAAAAAAALCMcBkAAAAAAAAAYBnhMgAAAAAAAACg7s9cBgAAAAAAAABPKC0tldOnT9tdhs8KCQmR0NDQKs/zJlwGAAAAAAAA4POKi4vl66+/FofDYXcpPq1hw4bSsmVLqVevXqX3JVwGAAAAAAAA4PMdyxosazDarFmzKnfe4n80lC8pKZEjR47Ivn37JCkpSYKDK56qTLgMAAAAAAAAwKfpKAwNRzVYbtCggd3l+Czdd2FhYXLgwAETNIeHh1d4fxb0AwAAAAAAAOAX6Fiuucq6lcvdtxa2BwAAAAAAAAAIMITLAAAAAAAAAADLCJcBAAAAAAAAwE8kJibKjBkzvLItwmUAAAAAAAAAfklHMHvzZHU+dEWnSZMmSXVs2LBB7r33XqmT4XJeXp4MHTpU4uPjzYtcunSpZyoDAAAAAAAAAD916NChspN2GkdHR5e7buLEiWX3dTgccubMmSo9b7NmzaRhw4ZSJ8PlEydOSLdu3WTOnDmeqQgAAAAAAAAA/FyLFi3KTjExMaaR13l5586dEhUVJcuWLZPk5GSpX7++rF27Vvbs2SM33nijxMXFSWRkpPTq1UtWrFhR4VgMfd758+dLSkqKCZ2TkpIkNzfXnnD5uuuukylTpphiAAAAAAAAAACe8fjjj8tzzz0nO3bskK5du0pxcbFcf/31snLlStmyZYsMGTLETJk4ePBghc8zefJkGTFihHz22Wfm8aNGjZIff/yx7s9cPnXqlBQVFZU7AQAAAAAAAAAq9vTTT8ugQYOkffv2EhsbayZK3HfffdK5c2fTgfzMM8+Y2yrrRB4zZozceuutctFFF8nUqVNNSL1+/Xqp8+FyVlaWaet2nhISEjy9SQAAAAAAAADweT179ix3WUNhncXcsWNHadSokRmNoV3NlXUua9ezU0REhJnvfPjw4bofLqenp0thYWHZqaCgwNObBAAAAAAAAACfFxERUe6yBstLliwx3cdr1qyRrVu3SpcuXaSkpKTC5wkLCyt3Wecwnz17tsb1hYqH6bBpPQEAAAAAAAAAqm/dunVmxIVzPTztZN6/f7/YxeOdywAAAAAAAACAmtM5y2+99ZbpWN62bZvcdttttdKB7LXOZU3Dd+/eXXZ537595sXoQOk2bdrUdn0AAAAAAAAAUC0Oh/iV6dOny1133SV9+/aVpk2bymOPPSZFRUW21RPkcFjbxatWrZKBAweed/3o0aMlJyen0sfri9WF/UQKRSTaWrXwST02JdtdArxoc/Imu0sAAABABXh/Hlh4fw74Kw0TY8z6ZrowG0ROnjxpmmDbtWsn4eHhdpcTMPvScufygAEDxGIeDQAAAAAAAADwM8xcBgAAAAAAAABYRrgMAAAAAAAAALCMcBkAAAAAAAAAYBnhMgAAAAAAAADAMsJlAAAAAAAAAIBlhMsAAAAAAAAAAMsIlwEAAAAAAAAAlhEuAwAAAAAAAAAsI1wGAAAAAAAAAFgWav0hAAAAAAAAAFD3JW9O9ur2NvXYVOX7BgUFVXh7ZmamTJo0qVp16HMvWbJEhg0bJp5EuAwAAAAAAAAAXnbo0KGyrxcvXiwZGRmSn59fdl1kZKTUdV4Plx0Oxy9fFXl707BJaXGp3SXAqzi2AQAA6jLenwca3p8D/nxs/y9ngy9q0aJF2dcxMTGm29j1uvnz58tLL70k+/btk8TERElNTZXx48eb20pKSiQtLU3++c9/ytGjRyUuLk7uv/9+SU9PN/dVKSkp5rxt27ayf/9+/wiXf/jhh1++SvD2pmGTbVfZXQG8K8buAgAAAFAB3p8HGt6fA/5MczYNJeF/Fi5caDqZZ8+eLZdddpls2bJFxo0bJxERETJ69GiZOXOm5Obmyuuvvy5t2rSRgoICc1IbNmyQ5s2by4IFC2TIkCESEhLisTq9Hi7Hxsaa84MHD/KPH/AzRUVFkpCQYP4zi46OtrscALWI4xvwXxzfgP/i+Ab8V2FhoQkUnTkb/E9mZqbpWr7pppvM5Xbt2sn27dtl7ty5JlzWbDUpKUn69etnOp61O9mpWbNm5rxRo0blOqH9IlwODg425xos88MN8E96bHN8A/6J4xvwXxzfgP/i+Ab8lzNng385ceKE7NmzR+6++27Trex05syZsmbdMWPGyKBBg+Tiiy823ck33HCDDB482Ou1sqAfAAAAAAAAANQRxcXF5vzPf/6z9O7du9xtzhEXPXr0MLOYly1bJitWrJARI0bINddcI2+++aZXayVcBgAAAAAAAIA6Ii4uTuLj42Xv3r0yatSoC95PP5Xyu9/9zpyGDx9uOph//PFHMy4lLCxMSktL/S9crl+/vpkZoucA/AvHN+C/OL4B/8XxDfgvjm/Af3F8+7/JkydLamqqGYOhofGpU6dk48aNcvToUUlLS5Pp06dLy5YtzWJ/Oh7ljTfeMPOVdc6ySkxMlJUrV8qVV15p/p00btzYI3UGORwOh0eeGQAAAAAAAAC84OTJk2ZMhC58Fx4eLr4mJydH/vCHP8ixY8fKrlu0aJFMmzbNLOQXEREhXbp0MfdJSUkxIzOys7Nl165dZlRGr169zH01bFb/+te/TAi9f/9+adWqlTn3xL4kXAYAAAAAAADg03w9XPbVfcmSkgAAAAAAAAAAywiXAQAAAAAAAACWES4DAAAAAAAAACwjXAYAAAAAAAAA1O1wec6cOZKYmGgGQffu3VvWr1/vzc0D8ICsrCyzImlUVJQ0b95chg0bJvn5+XaXBcADnnvuOQkKCjKrEwPwff/973/l9ttvlyZNmkiDBg3M6uMbN260uywANVRaWipPPfWUWYRJj+327dvLM888Iw6Hw+7SAFiUl5cnQ4cOlfj4ePM+fOnSpeVu1+M6IyNDWrZsaY73a665Rnbt2iWBjv/vvLsPvRYuL168WNLS0iQzM1M2b94s3bp1k2uvvVYOHz7srRIAeMDq1avlwQcflE8++USWL18up0+flsGDB8uJEyfsLg1ALdqwYYPMnTtXunbtancpAGrB0aNH5corr5SwsDBZtmyZbN++XV566SVp3Lix3aUBqKHnn39eXn75ZZk9e7bs2LHDXH7hhRdk1qxZdpcGwCL9vVrzM23WdEeP7ZkzZ8orr7win376qURERJis7eTJkxKIQkJCzHlJSYndpfi8n376yZzre8XKBDm8FOdrp7J2N+oPOHX27FlJSEiQCRMmyOOPP+6NEgB4wZEjR0wHs4bO/fv3t7scALWguLhYevToIdnZ2TJlyhTp3r27zJgxw+6yANSAvv9et26drFmzxu5SANSyG264QeLi4uQvf/lL2XU333yz6Wp89dVXba0NQPVp5/KSJUvMp4WVxnna0fzwww/LxIkTzXWFhYXm+M/JyZGRI0dKoNF9cvDgQdP0pvsmOJhpwNXZhxosazNwo0aNTFd8ZULFC/QvBps2bZL09PSy6/QbrO36H3/8sTdKAOAl+sNMxcbG2l0KgFqin074zW9+Y35ua7gMwPfl5uaazqZbbrnF/EG4VatWMn78eBk3bpzdpQGoob59+8q8efPkq6++kg4dOsi2bdtk7dq1Mn36dLtLA1CL9u3bJ99++615j+4UExNjmjs1awvEcFkDeA1Ddd8cOHDA7nJ8mgbLLVq0qNJ9vRIuf//992buk/71xJVe3rlzpzdKAOAF+okEncWqH7Pt3Lmz3eUAqAWvvfaaGWelYzEA+I+9e/eaj83r2LonnnjCHOOpqalSr149GT16tN3lAajhJxOKiorkkksuMR8R19/Fn332WRk1apTdpQGoRRosK3dZm/O2QKTvZZKSkhiNUQM6CsM5YqTOhMsAAqe78YsvvjCdEQB8X0FBgfz+978389R1MV4A/vUH4Z49e8rUqVPN5csuu8z8DNeZjYTLgG97/fXXZeHChbJo0SLp1KmTbN261TSA6EfEOb4BBAKdlsDvL97jleEjTZs2NYn3d999V+56vVzVFmsAddtDDz0k77zzjnz44YfSunVru8sBUAt0pJXO2tJ5y6GhoeakH5/XRUP0a+2EAuCb9COjl156abnrOnbsaOYUAvBtjzzyiOle1o/Ed+nSRe644w754x//KFlZWXaXBqAWOfM0sjYERLisLenJycmycuXKct0SerlPnz7eKAGAB4e9a7CsCwv85z//kXbt2tldEoBacvXVV8vnn39uOp6cJ+101I/V6tdWPioFoG7REVb5+fnlrtP5rG3btrWtJgC1QxdiOncRK/2Zrb+DA/Af+ru3hsiuWZuOxPn000/J2uBVXhuLofPc9CM4+kvp5ZdfblaZP3HihIwdO9ZbJQDw0CgM/cjd22+/LVFRUWWznXQhAV2RGoDv0mP63PnpERER0qRJE+aqAz5Ouxh10S8dizFixAhZv369WQBMTwB829ChQ82M5TZt2pixGFu2bDGL+d111112lwbAouLiYtm9e3fZZV2oTps8YmNjzTGuI290wW2dMaxh81NPPWVG4AwbNszWuhFYghzadugls2fPlmnTppnwqXv37uZjtbqKJQDfXo3VnQULFsiYMWO8Xg8AzxowYID5Ga5/JAbg23ScVXp6uuzatcv8QqrNIOPGjbO7LAA1dPz4cRMw6ScLdbyVBk233nqrZGRkmE8VA/Adq1atkoEDB553vTZv5uTkmE8SZ2Zmmj8OHzt2TPr16yfZ2dnSoUMHW+pFYPJquAwAAAAAAAAA8A9embkMAAAAAAAAAPAvhMsAAAAAAAAAAMsIlwEAAAAAAAAAlhEuAwAAAAAAAAAsI1wGAAAAAAAAAFhGuAwAAAAAAAAAsIxwGQAAAAAAAABgGeEyAAAAAAAAAMAywmUAAAAAAAAAgGWEywAAAAAAAAAAywiXAQAAAAAAAABi1f8BZzPNteRwk6wAAAAASUVORK5CYII=",
"text/plain": [
""
]
@@ -424,7 +450,7 @@
}
],
"source": [
- "X = np.zeros((10, 3, 5000)) \n",
+ "X = np.zeros((10, 3, 5000))\n",
"y = np.random.randint(0,2,X.shape[0])\n",
"splits = get_splits(y)\n",
"dls = get_ts_dls(X, y, splits=splits)\n",
@@ -563,15 +589,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "[W NNPACK.cpp:53] Could not initialize NNPACK! Reason: Unsupported hardware.\n"
- ]
- }
- ],
+ "outputs": [],
"source": [
"a = alphabet[np.random.randint(0,3,40)]\n",
"b = ALPHABET[np.random.randint(6,10,40)]\n",
@@ -664,9 +682,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "/Users/nacho/notebooks/tsai/nbs/068_models.TSiTPlus.ipynb saved at 2023-03-25 08:58:44\n",
+ "/Users/nacho/notebooks/tsai/nbs/068_models.TSiTPlus.ipynb saved at 2025-01-22 18:24:36\n",
"Correct notebook to script conversion! 😃\n",
- "Saturday 25/03/23 08:58:47 CET\n"
+ "Wednesday 22/01/25 18:24:39 CET\n"
]
},
{
diff --git a/nbs/077_models.multimodal.ipynb b/nbs/077_models.multimodal.ipynb
index 0794bcfc5..33c692624 100644
--- a/nbs/077_models.multimodal.ipynb
+++ b/nbs/077_models.multimodal.ipynb
@@ -416,186 +416,6 @@
"backbone"
]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "\n",
- "# class MultInputWrapper(nn.Module):\n",
- "# \"Model wrapper for input tensors with static and/ or observed, categorical and/ or numerical features.\"\n",
- "\n",
- "# def __init__(self,\n",
- "# arch,\n",
- "# c_in:int=None, # number of input variables\n",
- "# c_out:int=None, # number of output variables\n",
- "# seq_len:int=None, # input sequence length\n",
- "# d:tuple=None, # shape of the output tensor\n",
- "# dls:TSDataLoaders=None, # TSDataLoaders object\n",
- "# s_cat_idxs:list=None, # list of indices for static categorical variables\n",
- "# s_cat_embeddings:list=None, # list of num_embeddings for each static categorical variable\n",
- "# s_cat_embedding_dims:list=None, # list of embedding dimensions for each static categorical variable\n",
- "# s_cont_idxs:list=None, # list of indices for static continuous variables\n",
- "# o_cat_idxs:list=None, # list of indices for observed categorical variables\n",
- "# o_cat_embeddings:list=None, # list of num_embeddings for each observed categorical variable\n",
- "# o_cat_embedding_dims:list=None, # list of embedding dimensions for each observed categorical variable\n",
- "# o_cont_idxs:list=None, # list of indices for observed continuous variables. All features not in s_cat_idxs, s_cont_idxs, o_cat_idxs are considered observed continuous variables.\n",
- "# patch_len:int=None, # Number of time steps in each patch.\n",
- "# patch_stride:int=None, # Stride of the patch.\n",
- "# flatten:bool=False, # boolean indicating whether to flatten bacbone's output tensor\n",
- "# use_bn:bool=False, # boolean indicating whether to use batch normalization in the head\n",
- "# fc_dropout:float=0., # dropout probability for the fully connected layer in the head\n",
- "# custom_head=None, # custom head to replace the default head\n",
- "# **kwargs\n",
- "# ):\n",
- "# super().__init__()\n",
- "\n",
- "# # attributes\n",
- "# c_in = c_in or dls.vars\n",
- "# c_out = c_out or dls.c\n",
- "# seq_len = seq_len or dls.len\n",
- "# d = d or (dls.d if dls is not None else None)\n",
- "# self.c_in, self.c_out, self.seq_len, self.d = c_in, c_out, seq_len, d\n",
- "\n",
- "# # tensor splitter\n",
- "# if o_cont_idxs is None:\n",
- "# o_cont_idxs = get_o_cont_idxs(c_in, s_cat_idxs=s_cat_idxs, s_cont_idxs=s_cont_idxs, o_cat_idxs=o_cat_idxs)\n",
- "# self.splitter = TensorSplitter(s_cat_idxs, s_cont_idxs, o_cat_idxs, o_cont_idxs)\n",
- "# s_cat_idxs, s_cont_idxs, o_cat_idxs, o_cont_idxs = self.splitter.s_cat_idxs, self.splitter.s_cont_idxs, self.splitter.o_cat_idxs, self.splitter.o_cont_idxs\n",
- "# assert c_in == sum([len(s_cat_idxs), len(s_cont_idxs), len(o_cat_idxs), len(o_cont_idxs)])\n",
- "\n",
- "# # embeddings\n",
- "# self.s_embeddings = Embeddings(s_cat_embeddings, s_cat_embedding_dims)\n",
- "# self.o_embeddings = Embeddings(o_cat_embeddings, o_cat_embedding_dims)\n",
- "\n",
- "# # patch encoder\n",
- "# if patch_len is not None:\n",
- "# patch_stride = patch_stride or patch_len\n",
- "# self.patch_encoder = PatchEncoder(patch_len, patch_stride, seq_len=seq_len)\n",
- "# c_mult = patch_len\n",
- "# seq_len = (seq_len + self.patch_encoder.pad_size - patch_len) // patch_stride + 1\n",
- "# else:\n",
- "# self.patch_encoder = nn.Identity()\n",
- "# c_mult = 1\n",
- "\n",
- "# # backbone\n",
- "# n_s_features = len(s_cont_idxs) + self.s_embeddings.embedding_dims\n",
- "# n_o_features = (len(o_cont_idxs) + self.o_embeddings.embedding_dims) * c_mult\n",
- "# s_backbone = StaticBackbone(c_in=n_s_features, c_out=c_out, seq_len=1, **kwargs)\n",
- "# if isinstance(arch, str):\n",
- "# arch = get_arch(arch)\n",
- "# if isinstance(arch, nn.Module):\n",
- "# o_model = arch\n",
- "# else:\n",
- "# o_model = build_ts_model(arch, c_in=n_o_features, c_out=c_out, seq_len=seq_len, d=d, **kwargs)\n",
- "# assert hasattr(o_model, \"backbone\"), \"the selected arch must have a backbone\"\n",
- "# o_backbone = getattr(o_model, \"backbone\")\n",
- "\n",
- "# # head\n",
- "# o_head_nf = output_size_calculator(o_backbone, n_o_features, seq_len)[0]\n",
- "# s_head_nf = s_backbone.head_nf\n",
- "# self.backbone = nn.ModuleList([o_backbone, s_backbone])\n",
- "# self.head_nf = o_head_nf + s_head_nf\n",
- "# if custom_head is not None:\n",
- "# if isinstance(custom_head, nn.Module): self.head = custom_head\n",
- "# else:self. head = custom_head(self.head_nf, c_out, seq_len, d=d)\n",
- "# else:\n",
- "# if \"rocket\" in o_model.__name__.lower():\n",
- "# self.head = rocket_nd_head(self.head_nf, c_out, seq_len=seq_len, d=d, use_bn=use_bn, fc_dropout=fc_dropout)\n",
- "# else:\n",
- "# self.head = lin_nd_head(self.head_nf, c_out, seq_len=seq_len, d=d, flatten=flatten, use_bn=use_bn, fc_dropout=fc_dropout)\n",
- "\n",
- "# def forward(self, x):\n",
- "# # split x into static cat, static cont, observed cat, and observed cont\n",
- "# s_cat, s_cont, o_cat, o_cont = self.splitter(x)\n",
- "\n",
- "# # create categorical embeddings\n",
- "# s_cat = self.s_embeddings(s_cat)\n",
- "# o_cat = self.o_embeddings(o_cat)\n",
- "\n",
- "# # contatenate static and observed features\n",
- "# s_x = torch.cat([s_cat, s_cont], 1)\n",
- "# o_x = torch.cat([o_cat, o_cont], 1)\n",
- "\n",
- "# # patch encoder\n",
- "# o_x = self.patch_encoder(o_x)\n",
- "\n",
- "# # pass static and observed features through their respective backbones\n",
- "# for i,(b,xi) in enumerate(zip(self.backbone, [o_x, s_x])):\n",
- "# if i == 0:\n",
- "# x = b(xi)\n",
- "# if x.ndim == 2:\n",
- "# x = x[..., None]\n",
- "# else:\n",
- "# x = torch.cat([x, b(xi)[..., None].repeat(1, 1, x.shape[-1])], 1)\n",
- "\n",
- "# # head\n",
- "# x = self.head(x)\n",
- "# return x"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# from tsai.models.InceptionTimePlus import InceptionTimePlus"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# c_in = 6\n",
- "# c_out = 3\n",
- "# seq_len = 97\n",
- "# d = None\n",
- "\n",
- "# s_cat_idxs=2\n",
- "# s_cont_idxs=4\n",
- "# o_cat_idxs=[0, 3]\n",
- "# o_cont_idxs=None\n",
- "# s_cat_embeddings = 5\n",
- "# s_cat_embedding_dims = None\n",
- "# o_cat_embeddings = [7, 3]\n",
- "# o_cat_embedding_dims = [3, None]\n",
- "\n",
- "# t0 = torch.randint(0, 7, (16, 1, seq_len)) # cat\n",
- "# t1 = torch.randn(16, 1, seq_len)\n",
- "# t2 = torch.randint(0, 5, (16, 1, seq_len)) # cat\n",
- "# t3 = torch.randint(0, 3, (16, 1, seq_len)) # cat\n",
- "# t4 = torch.randn(16, 1, seq_len)\n",
- "# t5 = torch.randn(16, 1, seq_len)\n",
- "\n",
- "# t = torch.cat([t0, t1, t2, t3, t4, t5], 1).float()\n",
- "\n",
- "# patch_lens = [None, 5, 5, 5, 5]\n",
- "# patch_strides = [None, None, 1, 3, 5]\n",
- "# for patch_len, patch_stride in zip(patch_lens, patch_strides):\n",
- "# for arch in [\"InceptionTimePlus\", InceptionTimePlus, \"MultiRocketPlus\"]:\n",
- "# print(f\"arch: {arch}, patch_len: {patch_len}, patch_stride: {patch_stride}\")\n",
- "\n",
- "# model = MultInputWrapper(\n",
- "# arch=arch,\n",
- "# c_in=c_in,\n",
- "# c_out=c_out,\n",
- "# seq_len=seq_len,\n",
- "# d=d,\n",
- "# s_cat_idxs=s_cat_idxs, s_cat_embeddings=s_cat_embeddings, s_cat_embedding_dims=s_cat_embedding_dims,\n",
- "# s_cont_idxs=s_cont_idxs,\n",
- "# o_cat_idxs=o_cat_idxs, o_cat_embeddings=o_cat_embeddings, o_cat_embedding_dims=o_cat_embedding_dims,\n",
- "# o_cont_idxs=o_cont_idxs,\n",
- "# patch_len=patch_len,\n",
- "# patch_stride=patch_stride,\n",
- "# )\n",
- "\n",
- "# test_eq(model(t).shape, (16,3))"
- ]
- },
{
"cell_type": "code",
"execution_count": null,
@@ -1146,6 +966,103 @@
" test_eq(model(t).shape, (bs, c_out))"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class CustomHead(nn.Module):\n",
+ " def __init__(self, head_nf, c_out, seq_len, d):\n",
+ " super().__init__()\n",
+ " self.d = d\n",
+ " self.c_out = c_out\n",
+ " self.fc = nn.Linear(head_nf, d * c_out)\n",
+ "\n",
+ " def forward(self, x):\n",
+ " x = self.fc(x) # [batch_size, d*c]\n",
+ " x = x.view(x.shape[0], self.d, self.c_out)\n",
+ " return x"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "arch: InceptionTimePlus, patch_len: None, patch_stride: None\n",
+ "arch: , patch_len: None, patch_stride: None\n",
+ "arch: TSiTPlus, patch_len: None, patch_stride: None\n",
+ "arch: InceptionTimePlus, patch_len: 5, patch_stride: None\n",
+ "arch: , patch_len: 5, patch_stride: None\n",
+ "arch: TSiTPlus, patch_len: 5, patch_stride: None\n",
+ "arch: InceptionTimePlus, patch_len: 5, patch_stride: 1\n",
+ "arch: , patch_len: 5, patch_stride: 1\n",
+ "arch: TSiTPlus, patch_len: 5, patch_stride: 1\n",
+ "arch: InceptionTimePlus, patch_len: 5, patch_stride: 3\n",
+ "arch: , patch_len: 5, patch_stride: 3\n",
+ "arch: TSiTPlus, patch_len: 5, patch_stride: 3\n",
+ "arch: InceptionTimePlus, patch_len: 5, patch_stride: 5\n",
+ "arch: , patch_len: 5, patch_stride: 5\n",
+ "arch: TSiTPlus, patch_len: 5, patch_stride: 5\n"
+ ]
+ }
+ ],
+ "source": [
+ "bs = 8\n",
+ "c_in = 6\n",
+ "c_out = 3\n",
+ "seq_len = 97\n",
+ "d = 7\n",
+ "\n",
+ "s_cat_idxs=None\n",
+ "s_cont_idxs=None\n",
+ "o_cat_idxs=None\n",
+ "o_cont_idxs=None\n",
+ "s_cat_embeddings = None\n",
+ "s_cat_embedding_dims = None\n",
+ "o_cat_embeddings = None\n",
+ "o_cat_embedding_dims = None\n",
+ "\n",
+ "fusion_layers = 128\n",
+ "\n",
+ "t0 = torch.randint(0, 7, (bs, 1, seq_len)) # cat\n",
+ "t1 = torch.randn(bs, 1, seq_len)\n",
+ "t2 = torch.randint(0, 5, (bs, 1, seq_len)) # cat\n",
+ "t3 = torch.randint(0, 3, (bs, 1, seq_len)) # cat\n",
+ "t4 = torch.randn(bs, 1, seq_len)\n",
+ "t5 = torch.randn(bs, 1, seq_len)\n",
+ "\n",
+ "t = torch.cat([t0, t1, t2, t3, t4, t5], 1).float().to(default_device())\n",
+ "\n",
+ "patch_lens = [None, 5, 5, 5, 5]\n",
+ "patch_strides = [None, None, 1, 3, 5]\n",
+ "for patch_len, patch_stride in zip(patch_lens, patch_strides):\n",
+ " for arch in [\"InceptionTimePlus\", InceptionTimePlus, \"TSiTPlus\"]:\n",
+ " print(f\"arch: {arch}, patch_len: {patch_len}, patch_stride: {patch_stride}\")\n",
+ " model = MultInputWrapper(\n",
+ " arch=arch,\n",
+ " custom_head=CustomHead,\n",
+ " c_in=c_in,\n",
+ " c_out=c_out,\n",
+ " seq_len=seq_len,\n",
+ " d=d,\n",
+ " s_cat_idxs=s_cat_idxs, s_cat_embeddings=s_cat_embeddings, s_cat_embedding_dims=s_cat_embedding_dims,\n",
+ " s_cont_idxs=s_cont_idxs,\n",
+ " o_cat_idxs=o_cat_idxs, o_cat_embeddings=o_cat_embeddings, o_cat_embedding_dims=o_cat_embedding_dims,\n",
+ " o_cont_idxs=o_cont_idxs,\n",
+ " patch_len=patch_len,\n",
+ " patch_stride=patch_stride,\n",
+ " fusion_layers=fusion_layers,\n",
+ " ).to(default_device())\n",
+ "\n",
+ " test_eq(model(t).shape, (bs, d, c_out))"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -1165,9 +1082,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "/Users/nacho/notebooks/tsai/nbs/077_models.multimodal.ipynb saved at 2024-02-10 21:58:47\n",
+ "/Users/nacho/notebooks/tsai/nbs/077_models.multimodal.ipynb saved at 2025-02-05 13:48:37\n",
"Correct notebook to script conversion! 😃\n",
- "Saturday 10/02/24 21:58:50 CET\n"
+ "Wednesday 05/02/25 13:48:40 CET\n"
]
},
{
@@ -1205,9 +1122,13 @@
],
"metadata": {
"kernelspec": {
- "display_name": "python3",
+ "display_name": "py311t25",
"language": "python",
"name": "python3"
+ },
+ "language_info": {
+ "name": "python",
+ "version": "3.11.11"
}
},
"nbformat": 4,
diff --git a/nbs/models/test.pth b/nbs/models/test.pth
index a4262641f7188d5ea65ec68ccbf796306cbefc1a..c5e6490cd4f59136eaf950108a4cbd7f1ec7b996 100644
GIT binary patch
literal 1100008
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