diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ff04719
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+/notebooks/checkpoints/
+/checkpoints/
+/notebooks/results/
+/results/
+*.npy
+*.pth
+
+# Jupyter NB Checkpoints
+.ipynb_checkpoints/
+
+__pycache__/
diff --git a/exp/exp_main.py b/exp/exp_main.py
index 839f93e..9715c96 100644
--- a/exp/exp_main.py
+++ b/exp/exp_main.py
@@ -237,4 +237,4 @@ class Exp_Main(Exp_Basic):
np.save(folder_path + 'pred.npy', preds)
np.save(folder_path + 'true.npy', trues)
- return
+ return preds, trues
diff --git a/notebook/run.ipynb b/notebook/run.ipynb
new file mode 100644
index 0000000..d91f6a4
--- /dev/null
+++ b/notebook/run.ipynb
@@ -0,0 +1,506 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "0c996f31",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:22:44.659299Z",
+ "start_time": "2022-11-28T22:22:44.657630Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "os.sys.path.append('..')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "3b256fea",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:22:45.762889Z",
+ "start_time": "2022-11-28T22:22:44.660036Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "import argparse\n",
+ "import os\n",
+ "import torch\n",
+ "from exp.exp_main import Exp_Main\n",
+ "import random\n",
+ "import numpy as np\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "b780adb5",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:22:45.769437Z",
+ "start_time": "2022-11-28T22:22:45.764337Z"
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "exp.exp_main.Exp_Main"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "Exp = Exp_Main\n",
+ "Exp"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "23a27691",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:22:45.804455Z",
+ "start_time": "2022-11-28T22:22:45.770278Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "import warnings\n",
+ "warnings.simplefilter(\"ignore\")\n",
+ "\n",
+ "# autoreload import your package\n",
+ "%load_ext autoreload\n",
+ "%autoreload 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "e60bfdb0",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:22:45.824009Z",
+ "start_time": "2022-11-28T22:22:45.805505Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "from loguru import logger\n",
+ "logger.remove()\n",
+ "logger.add(os.sys.stdout, level=\"ERROR\", colorize=True, format=\"{time} | {message}\")\n",
+ "# import_dir(ta_dir, verbose=False)\n",
+ "warnings.simplefilter(\"ignore\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "d52338d2",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:22:45.838232Z",
+ "start_time": "2022-11-28T22:22:45.824847Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "import torch\n",
+ "import pandas as pd\n",
+ "from matplotlib import pyplot as plt\n",
+ "%matplotlib inline"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "20d78524",
+ "metadata": {},
+ "source": [
+ "# Args"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "750cdcc3",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:22:45.852523Z",
+ "start_time": "2022-11-28T22:22:45.839094Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "from run import set_seed, get_args, Exp_Main"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "b3a40300",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:23:31.380478Z",
+ "start_time": "2022-11-28T22:22:50.139838Z"
+ },
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Args in experiment:\n",
+ "Namespace(K=0, activation='sigmoid', batch_size=32, c_out=1, checkpoints='./checkpoints/', d_ff=2048, d_layers=2, d_model=512, damping_learning_rate=0, data='custom', data_path='exchange_rate.csv', dec_in=1, des=\"'Exp'\", devices='0,1,2,3', dropout=0.2, e_layers=2, embed='timeF', enc_in=1, features='S', freq='h', gpu=0, itr=1, label_len=0, learning_rate=0.001, lradj='exponential_with_warmup', min_lr=1e-30, model='ETSformer', model_id='Exchange', n_heads=8, num_workers=10, optim='adam', output_attention=False, patience=5, pred_len=96, root_path='../dataset/exchange_rate/', seq_len=96, smoothing_learning_rate=0, std=0.2, target='OT', train_epochs=15, use_gpu=True, use_multi_gpu=False, warmup_epochs=3)\n",
+ "Use GPU: cuda:0\n",
+ ">>>>>>>start training : Exchange_ETSformer_custom_ftS_sl96_pl96_dm512_nh8_el2_dl2_df2048_K0_lr0.001_'Exp'_0>>>>>>>>>>>>>>>>>>>>>>>>>>\n",
+ "train 5120\n",
+ "val 665\n",
+ "test 1422\n",
+ "\titers: 100, epoch: 1 | loss: 0.1855393\n",
+ "\tspeed: 0.0262s/iter; left time: 60.1997s\n",
+ "Epoch: 1 cost time: 4.017645359039307\n",
+ "Epoch: 1, Steps: 160 | Train Loss: 0.3291200 Vali Loss: 0.1620757 Test Loss: 0.0996447\n",
+ "Validation loss decreased (inf --> 0.162076). Saving model ...\n",
+ "Updating learning rate to 0.00025\n",
+ "\titers: 100, epoch: 2 | loss: 0.3449063\n",
+ "\tspeed: 0.0523s/iter; left time: 111.9286s\n",
+ "Epoch: 2 cost time: 4.011619567871094\n",
+ "Epoch: 2, Steps: 160 | Train Loss: 0.2371088 Vali Loss: 0.1372457 Test Loss: 0.0956475\n",
+ "Validation loss decreased (0.162076 --> 0.137246). Saving model ...\n",
+ "Updating learning rate to 0.0005\n",
+ "\titers: 100, epoch: 3 | loss: 0.1758220\n",
+ "\tspeed: 0.0541s/iter; left time: 107.2494s\n",
+ "Epoch: 3 cost time: 4.069975852966309\n",
+ "Epoch: 3, Steps: 160 | Train Loss: 0.2245417 Vali Loss: 0.1412140 Test Loss: 0.0931368\n",
+ "EarlyStopping counter: 1 out of 5\n",
+ "Updating learning rate to 0.00075\n",
+ "\titers: 100, epoch: 4 | loss: 0.2099838\n",
+ "\tspeed: 0.0532s/iter; left time: 96.8687s\n",
+ "Epoch: 4 cost time: 3.987823724746704\n",
+ "Epoch: 4, Steps: 160 | Train Loss: 0.2288409 Vali Loss: 0.1397144 Test Loss: 0.0937123\n",
+ "EarlyStopping counter: 2 out of 5\n",
+ "Updating learning rate to 0.001\n",
+ "\titers: 100, epoch: 5 | loss: 0.2285676\n",
+ "\tspeed: 0.0525s/iter; left time: 87.2150s\n",
+ "Epoch: 5 cost time: 4.027522563934326\n",
+ "Epoch: 5, Steps: 160 | Train Loss: 0.2344545 Vali Loss: 0.1622206 Test Loss: 0.0896547\n",
+ "EarlyStopping counter: 3 out of 5\n",
+ "Updating learning rate to 0.0005\n",
+ "\titers: 100, epoch: 6 | loss: 0.2818964\n",
+ "\tspeed: 0.0529s/iter; left time: 79.3673s\n",
+ "Epoch: 6 cost time: 4.119000196456909\n",
+ "Epoch: 6, Steps: 160 | Train Loss: 0.2204486 Vali Loss: 0.1501924 Test Loss: 0.0886038\n",
+ "EarlyStopping counter: 4 out of 5\n",
+ "Updating learning rate to 0.00025\n",
+ "\titers: 100, epoch: 7 | loss: 0.1605041\n",
+ "\tspeed: 0.0566s/iter; left time: 75.9389s\n",
+ "Epoch: 7 cost time: 4.324657917022705\n",
+ "Epoch: 7, Steps: 160 | Train Loss: 0.2194144 Vali Loss: 0.1449849 Test Loss: 0.0917771\n",
+ "EarlyStopping counter: 5 out of 5\n",
+ "Early stopping\n",
+ ">>>>>>>testing : Exchange_ETSformer_custom_ftS_sl96_pl96_dm512_nh8_el2_dl2_df2048_K0_lr0.001_'Exp'_0<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
+ "val 665\n",
+ "loading model\n",
+ "test shape: (20, 32, 96, 1) (20, 32, 96, 1)\n",
+ "test shape: (640, 96, 1) (640, 96, 1)\n",
+ "mse:0.13651615381240845, mae:0.2945910394191742\n",
+ "test 1422\n",
+ "loading model\n",
+ "test shape: (44, 32, 96, 1) (44, 32, 96, 1)\n",
+ "test shape: (1408, 96, 1) (1408, 96, 1)\n",
+ "mse:0.09564752131700516, mae:0.2282976359128952\n"
+ ]
+ }
+ ],
+ "source": [
+ "# mimic cli args to avoid code duplication\n",
+ "argv = \"\"\"python -u run.py \\\n",
+ " --root_path ../dataset/exchange_rate/ \\\n",
+ " --data_path exchange_rate.csv \\\n",
+ " --model_id Exchange \\\n",
+ " --model ETSformer \\\n",
+ " --data custom \\\n",
+ " --features S \\\n",
+ " --seq_len 96 \\\n",
+ " --pred_len 96 \\\n",
+ " --e_layers 2 \\\n",
+ " --d_layers 2 \\\n",
+ " --enc_in 1 \\\n",
+ " --dec_in 1 \\\n",
+ " --c_out 1 \\\n",
+ " --des 'Exp' \\\n",
+ " --K 0 \\\n",
+ " --learning_rate 1e-3 \\\n",
+ " --itr 1\n",
+ "\"\"\"\n",
+ "argv = argv.replace(\"\\\\n\", \"\").split()[3:]\n",
+ "args = get_args(argv)\n",
+ "args\n",
+ "\n",
+ "\n",
+ "Exp = Exp_Main\n",
+ "ii=0\n",
+ "set_seed(ii)\n",
+ "# setting record of experiments\n",
+ "setting = '{}_{}_{}_ft{}_sl{}_pl{}_dm{}_nh{}_el{}_dl{}_df{}_K{}_lr{}_{}_{}'.format(\n",
+ " args.model_id,\n",
+ " args.model,\n",
+ " args.data,\n",
+ " args.features,\n",
+ " args.seq_len,\n",
+ " args.pred_len,\n",
+ " args.d_model,\n",
+ " args.n_heads,\n",
+ " args.e_layers,\n",
+ " args.d_layers,\n",
+ " args.d_ff,\n",
+ " args.K,\n",
+ " args.learning_rate,\n",
+ " args.des, ii)\n",
+ "\n",
+ "# if os.path.exists(os.path.join(args.checkpoints, setting)):\n",
+ "# print('skipping exists')\n",
+ "# continue\n",
+ "\n",
+ "exp = Exp(args) # set experiments\n",
+ "print('>>>>>>>start training : {}>>>>>>>>>>>>>>>>>>>>>>>>>>'.format(setting))\n",
+ "exp.train(setting)\n",
+ "\n",
+ "print('>>>>>>>testing : {}<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'.format(setting))\n",
+ "exp.test(setting, data='val')\n",
+ "exp.test(setting, data='test')\n",
+ "\n",
+ "torch.cuda.empty_cache()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "a4576bab",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:23:31.395648Z",
+ "start_time": "2022-11-28T22:23:31.381989Z"
+ },
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "72811788",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T05:28:20.356399Z",
+ "start_time": "2022-11-28T05:28:20.339961Z"
+ }
+ },
+ "source": [
+ "# Plot"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "92b67ed7",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:23:31.420696Z",
+ "start_time": "2022-11-28T22:23:31.396542Z"
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "\"Exchange_ETSformer_custom_ftS_sl96_pl96_dm512_nh8_el2_dl2_df2048_K0_lr0.001_'Exp'_0\""
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "setting"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "ebea79f7",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:23:31.445965Z",
+ "start_time": "2022-11-28T22:23:31.421995Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "test 1422\n"
+ ]
+ }
+ ],
+ "source": [
+ "ds, dl = exp._get_data('test')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "9833f218",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:23:32.217460Z",
+ "start_time": "2022-11-28T22:23:31.446941Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "test 1422\n",
+ "loading model\n",
+ "test shape: (44, 32, 96, 1) (44, 32, 96, 1)\n",
+ "test shape: (1408, 96, 1) (1408, 96, 1)\n",
+ "mse:0.09564752131700516, mae:0.2282976359128952\n"
+ ]
+ }
+ ],
+ "source": [
+ "preds, trues = exp.test(setting, data='test')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "658546f2",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:23:32.231941Z",
+ "start_time": "2022-11-28T22:23:32.218766Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "%matplotlib inline"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "5c88dbf7",
+ "metadata": {
+ "ExecuteTime": {
+ "end_time": "2022-11-28T22:23:32.440081Z",
+ "start_time": "2022-11-28T22:23:32.232751Z"
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "i=990\n",
+ "(batch_x, batch_y, batch_x_mark, batch_y_mark) = ds[i]\n",
+ "l1 = batch_x.shape[0]\n",
+ "l2 = batch_y.shape[0]\n",
+ "plt.plot(range(l1), batch_x[:, -1], label='past')\n",
+ "plt.plot(range(l1, l1+l2), batch_y[:, -1], color='blue', ls='--', label='true')\n",
+ "plt.plot(range(l1, l1+l2), preds[i], label='pred');\n",
+ "plt.legend(loc='lower left')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "692aadfa",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2dd11010",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e4413025",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "deeptime",
+ "language": "python",
+ "name": "deeptime"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.13"
+ },
+ "toc": {
+ "base_numbering": 1,
+ "nav_menu": {},
+ "number_sections": true,
+ "sideBar": true,
+ "skip_h1_title": false,
+ "title_cell": "Table of Contents",
+ "title_sidebar": "Contents",
+ "toc_cell": false,
+ "toc_position": {},
+ "toc_section_display": true,
+ "toc_window_display": false
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/run.py b/run.py
index a4da50f..fb17e73 100644
--- a/run.py
+++ b/run.py
@@ -13,112 +13,119 @@ def set_seed(seed):
seed += 1
torch.manual_seed(seed)
-parser = argparse.ArgumentParser(description='ETSformer: Exponential Smoothing Transformers for Time-series Forecasting')
-# basic config
-parser.add_argument('--model_id', type=str, required=True, default='test', help='model id')
-parser.add_argument('--model', type=str, required=True, default='ETSformer',
- help='model name, options: [ETSformer]')
+def get_args(argv=None):
+ parser = argparse.ArgumentParser(description='ETSformer: Exponential Smoothing Transformers for Time-series Forecasting')
-# data loader
-parser.add_argument('--data', type=str, required=True, default='ETTm1', help='dataset type')
-parser.add_argument('--root_path', type=str, default='./data/ETT/', help='root path of the data file')
-parser.add_argument('--data_path', type=str, default='ETTh1.csv', help='data file')
-parser.add_argument('--features', type=str, default='M',
- help='forecasting task, options:[M, S, MS]; M:multivariate predict multivariate, S:univariate predict univariate, MS:multivariate predict univariate')
-parser.add_argument('--target', type=str, default='OT', help='target feature in S or MS task')
-parser.add_argument('--freq', type=str, default='h',
- help='freq for time features encoding, options:[s:secondly, t:minutely, h:hourly, d:daily, b:business days, w:weekly, m:monthly], you can also use more detailed freq like 15min or 3h')
-parser.add_argument('--checkpoints', type=str, default='./checkpoints/', help='location of model checkpoints')
+ # basic config
+ parser.add_argument('--model_id', type=str, required=True, default='test', help='model id')
+ parser.add_argument('--model', type=str, required=True, default='ETSformer',
+ help='model name, options: [ETSformer]')
-# forecasting task
-parser.add_argument('--seq_len', type=int, required=True, help='input sequence length')
-parser.add_argument('--label_len', type=int, default=0, help='start token length')
-parser.add_argument('--pred_len', type=int, required=True, help='prediction sequence length')
+ # data loader
+ parser.add_argument('--data', type=str, required=True, default='ETTm1', help='dataset type')
+ parser.add_argument('--root_path', type=str, default='./data/ETT/', help='root path of the data file')
+ parser.add_argument('--data_path', type=str, default='ETTh1.csv', help='data file')
+ parser.add_argument('--features', type=str, default='M',
+ help='forecasting task, options:[M, S, MS]; M:multivariate predict multivariate, S:univariate predict univariate, MS:multivariate predict univariate')
+ parser.add_argument('--target', type=str, default='OT', help='target feature in S or MS task')
+ parser.add_argument('--freq', type=str, default='h',
+ help='freq for time features encoding, options:[s:secondly, t:minutely, h:hourly, d:daily, b:business days, w:weekly, m:monthly], you can also use more detailed freq like 15min or 3h')
+ parser.add_argument('--checkpoints', type=str, default='./checkpoints/', help='location of model checkpoints')
-# model define
-parser.add_argument('--enc_in', type=int, default=7, help='encoder input size')
-parser.add_argument('--dec_in', type=int, default=7, help='decoder input size')
-parser.add_argument('--c_out', type=int, default=7, help='output size')
-parser.add_argument('--d_model', type=int, default=512, help='dimension of model')
-parser.add_argument('--n_heads', type=int, default=8, help='num of heads')
-parser.add_argument('--e_layers', type=int, default=2, help='num of encoder layers')
-parser.add_argument('--d_layers', type=int, default=1, help='num of decoder layers')
-parser.add_argument('--d_ff', type=int, default=2048, help='dimension of fcn')
-parser.add_argument('--K', type=int, default=1, help='Top-K Fourier bases')
-parser.add_argument('--dropout', type=float, default=0.2, help='dropout')
-parser.add_argument('--embed', type=str, default='timeF',
- help='time features encoding, options:[timeF, fixed, learned]')
-parser.add_argument('--activation', type=str, default='sigmoid', help='activation')
+ # forecasting task
+ parser.add_argument('--seq_len', type=int, required=True, help='input sequence length')
+ parser.add_argument('--label_len', type=int, default=0, help='start token length')
+ parser.add_argument('--pred_len', type=int, required=True, help='prediction sequence length')
-parser.add_argument('--min_lr', type=float, default=1e-30)
-parser.add_argument('--warmup_epochs', type=int, default=3)
-parser.add_argument('--std', type=float, default=0.2)
+ # model define
+ parser.add_argument('--enc_in', type=int, default=7, help='encoder input size')
+ parser.add_argument('--dec_in', type=int, default=7, help='decoder input size')
+ parser.add_argument('--c_out', type=int, default=7, help='output size')
+ parser.add_argument('--d_model', type=int, default=512, help='dimension of model')
+ parser.add_argument('--n_heads', type=int, default=8, help='num of heads')
+ parser.add_argument('--e_layers', type=int, default=2, help='num of encoder layers')
+ parser.add_argument('--d_layers', type=int, default=1, help='num of decoder layers')
+ parser.add_argument('--d_ff', type=int, default=2048, help='dimension of fcn')
+ parser.add_argument('--K', type=int, default=1, help='Top-K Fourier bases')
+ parser.add_argument('--dropout', type=float, default=0.2, help='dropout')
+ parser.add_argument('--embed', type=str, default='timeF',
+ help='time features encoding, options:[timeF, fixed, learned]')
+ parser.add_argument('--activation', type=str, default='sigmoid', help='activation')
-parser.add_argument('--smoothing_learning_rate', type=float, default=0, help='optimizer learning rate')
-parser.add_argument('--damping_learning_rate', type=float, default=0, help='optimizer learning rate')
-parser.add_argument('--output_attention', type=bool, default=False)
+ parser.add_argument('--min_lr', type=float, default=1e-30)
+ parser.add_argument('--warmup_epochs', type=int, default=3)
+ parser.add_argument('--std', type=float, default=0.2)
-# optimization
-parser.add_argument('--optim', type=str, default='adam', help='optimizer')
-parser.add_argument('--num_workers', type=int, default=10, help='data loader num workers')
-parser.add_argument('--itr', type=int, default=1, help='experiments times')
-parser.add_argument('--train_epochs', type=int, default=15, help='train epochs')
-parser.add_argument('--batch_size', type=int, default=32, help='batch size of train input data')
-parser.add_argument('--patience', type=int, default=5, help='early stopping patience')
-parser.add_argument('--learning_rate', type=float, default=1e-4, help='optimizer learning rate')
-parser.add_argument('--des', type=str, default='test', help='exp description')
-parser.add_argument('--lradj', type=str, default='exponential_with_warmup', help='adjust learning rate')
+ parser.add_argument('--smoothing_learning_rate', type=float, default=0, help='optimizer learning rate')
+ parser.add_argument('--damping_learning_rate', type=float, default=0, help='optimizer learning rate')
+ parser.add_argument('--output_attention', type=bool, default=False)
-# GPU
-parser.add_argument('--use_gpu', type=bool, default=True, help='use gpu')
-parser.add_argument('--gpu', type=int, default=0, help='gpu')
-parser.add_argument('--use_multi_gpu', action='store_true', help='use multiple gpus', default=False)
-parser.add_argument('--devices', type=str, default='0,1,2,3', help='device ids of multile gpus')
+ # optimization
+ parser.add_argument('--optim', type=str, default='adam', help='optimizer')
+ parser.add_argument('--num_workers', type=int, default=10, help='data loader num workers')
+ parser.add_argument('--itr', type=int, default=1, help='experiments times')
+ parser.add_argument('--train_epochs', type=int, default=15, help='train epochs')
+ parser.add_argument('--batch_size', type=int, default=32, help='batch size of train input data')
+ parser.add_argument('--patience', type=int, default=5, help='early stopping patience')
+ parser.add_argument('--learning_rate', type=float, default=1e-4, help='optimizer learning rate')
+ parser.add_argument('--des', type=str, default='test', help='exp description')
+ parser.add_argument('--lradj', type=str, default='exponential_with_warmup', help='adjust learning rate')
-args = parser.parse_args()
+ # GPU
+ parser.add_argument('--use_gpu', type=bool, default=True, help='use gpu')
+ parser.add_argument('--gpu', type=int, default=0, help='gpu')
+ parser.add_argument('--use_multi_gpu', action='store_true', help='use multiple gpus', default=False)
+ parser.add_argument('--devices', type=str, default='0,1,2,3', help='device ids of multile gpus')
-args.use_gpu = True if torch.cuda.is_available() and args.use_gpu else False
+ args = parser.parse_args(argv)
-if args.use_gpu and args.use_multi_gpu:
- args.dvices = args.devices.replace(' ', '')
- device_ids = args.devices.split(',')
- args.device_ids = [int(id_) for id_ in device_ids]
- args.gpu = args.device_ids[0]
+ args.use_gpu = True if torch.cuda.is_available() and args.use_gpu else False
-print('Args in experiment:')
-print(args)
+ if args.use_gpu and args.use_multi_gpu:
+ args.dvices = args.devices.replace(' ', '')
+ device_ids = args.devices.split(',')
+ args.device_ids = [int(id_) for id_ in device_ids]
+ args.gpu = args.device_ids[0]
-Exp = Exp_Main
+ print('Args in experiment:')
+ print(args)
+ return args
-for ii in range(args.itr):
- set_seed(ii)
- # setting record of experiments
- setting = '{}_{}_{}_ft{}_sl{}_pl{}_dm{}_nh{}_el{}_dl{}_df{}_K{}_lr{}_{}_{}'.format(
- args.model_id,
- args.model,
- args.data,
- args.features,
- args.seq_len,
- args.pred_len,
- args.d_model,
- args.n_heads,
- args.e_layers,
- args.d_layers,
- args.d_ff,
- args.K,
- args.learning_rate,
- args.des, ii)
+if __name__=="__main__":
+
+ args = get_args()
- if os.path.exists(os.path.join(args.checkpoints, setting)):
- continue
+ Exp = Exp_Main
- exp = Exp(args) # set experiments
- print('>>>>>>>start training : {}>>>>>>>>>>>>>>>>>>>>>>>>>>'.format(setting))
- exp.train(setting)
+ for ii in range(args.itr):
+ set_seed(ii)
+ # setting record of experiments
+ setting = '{}_{}_{}_ft{}_sl{}_pl{}_dm{}_nh{}_el{}_dl{}_df{}_K{}_lr{}_{}_{}'.format(
+ args.model_id,
+ args.model,
+ args.data,
+ args.features,
+ args.seq_len,
+ args.pred_len,
+ args.d_model,
+ args.n_heads,
+ args.e_layers,
+ args.d_layers,
+ args.d_ff,
+ args.K,
+ args.learning_rate,
+ args.des, ii)
- print('>>>>>>>testing : {}<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'.format(setting))
- exp.test(setting, data='val')
- exp.test(setting, data='test')
+ if os.path.exists(os.path.join(args.checkpoints, setting)):
+ continue
- torch.cuda.empty_cache()
+ exp = Exp(args) # set experiments
+ print('>>>>>>>start training : {}>>>>>>>>>>>>>>>>>>>>>>>>>>'.format(setting))
+ exp.train(setting)
+
+ print('>>>>>>>testing : {}<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'.format(setting))
+ exp.test(setting, data='val')
+ exp.test(setting, data='test')
+
+ torch.cuda.empty_cache()