1221 lines
54 KiB
Plaintext
1221 lines
54 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "2bc4ab88",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Constants"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"id": "c767cb34",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import os\n",
|
||
"\n",
|
||
"os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true' # this is required\n",
|
||
"os.environ['CUDA_VISIBLE_DEVICES'] = '0' # set to '0' for GPU0, '1' for GPU1 or '2' for GPU2. Check \"gpustat\" in a terminal."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"id": "f783fc7f",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"glob_path = '/opt/iui-datarelease3-sose2021/*.csv'\n",
|
||
"\n",
|
||
"pickle_file = '../data.pickle'\n",
|
||
"\n",
|
||
"checkpoint_path = \"training_1/cp.ckpt\"\n",
|
||
"checkpoint_dir = os.path.dirname(checkpoint_path)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "bb1c9c9b",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Config"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"id": "3d812543",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Possibilities: 'SYY', 'SYN', 'SNY', 'SNN', \n",
|
||
"# 'JYY', 'JYN', 'JNY', 'JNN'\n",
|
||
"cenario = 'SYN'\n",
|
||
"\n",
|
||
"win_sz = 30\n",
|
||
"stride_sz = 2\n",
|
||
"\n",
|
||
"# divisor for neuron count step downs (hard to describe), e.g. dense_step = 3: layer1=900, layer2 = 300, layer3 = 100, layer4 = 33...\n",
|
||
"dense_steps = 3\n",
|
||
"# amount of dense/dropout layers\n",
|
||
"layer_count = 5\n",
|
||
"# how much to drop\n",
|
||
"drop_count = 0.2"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "8cef4021",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Helper Functions"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"id": "cde65835",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from matplotlib import pyplot as plt\n",
|
||
"\n",
|
||
"def pplot(dd):\n",
|
||
" x = dd.shape[0]\n",
|
||
" fix = int(x/3)+1\n",
|
||
" fiy = 3\n",
|
||
" fig, axs = plt.subplots(fix, fiy, figsize=(3*fiy, 9*fix))\n",
|
||
" \n",
|
||
" for i in range(x):\n",
|
||
" axs[int(i/3)][i%3].plot(dd[i])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "476851ec",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Loading Data"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"id": "199e4435",
|
||
"metadata": {
|
||
"tags": []
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"from glob import glob\n",
|
||
"import pandas as pd\n",
|
||
"from tqdm import tqdm\n",
|
||
"\n",
|
||
"def dl_from_blob(filename, user_filter=None):\n",
|
||
" \n",
|
||
" dic_data = []\n",
|
||
" \n",
|
||
" for p in tqdm(glob(glob_path)):\n",
|
||
" path = p\n",
|
||
" filename = path.split('/')[-1].split('.')[0]\n",
|
||
" splitname = filename.split('_')\n",
|
||
" user = int(splitname[0][1:])\n",
|
||
" if (user_filter):\n",
|
||
" if (user != user_filter):\n",
|
||
" continue\n",
|
||
" scenario = splitname[1][len('Scenario'):]\n",
|
||
" heightnorm = splitname[2][len('HeightNormalization'):] == 'True'\n",
|
||
" armnorm = splitname[3][len('ArmNormalization'):] == 'True'\n",
|
||
" rep = int(splitname[4][len('Repetition'):])\n",
|
||
" session = int(splitname[5][len('Session'):])\n",
|
||
" data = pd.read_csv(path)\n",
|
||
" dic_data.append(\n",
|
||
" {\n",
|
||
" 'filename': path,\n",
|
||
" 'user': user,\n",
|
||
" 'scenario': scenario,\n",
|
||
" 'heightnorm': heightnorm,\n",
|
||
" 'armnorm': armnorm,\n",
|
||
" 'rep': rep,\n",
|
||
" 'session': session,\n",
|
||
" 'data': data \n",
|
||
" }\n",
|
||
" )\n",
|
||
" return dic_data"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"id": "9e2817c1",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import pickle\n",
|
||
"\n",
|
||
"def save_pickle(f, structure):\n",
|
||
" _p = open(f, 'wb')\n",
|
||
" pickle.dump(structure, _p)\n",
|
||
" _p.close()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"id": "12c5098e",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def load_pickles(f) -> list:\n",
|
||
" _p = open(pickle_file, 'rb')\n",
|
||
" _d = pickle.load(_p)\n",
|
||
" _p.close()\n",
|
||
" \n",
|
||
" return _d"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"id": "00ee7490",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Loading data...\n",
|
||
"../data.pickle found...\n",
|
||
"768\n",
|
||
"CPU times: user 548 ms, sys: 2.56 s, total: 3.11 s\n",
|
||
"Wall time: 3.11 s\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"%%time\n",
|
||
"\n",
|
||
"def load_data() -> list:\n",
|
||
" if os.path.isfile(pickle_file):\n",
|
||
" print(f'{pickle_file} found...')\n",
|
||
" return load_pickles(pickle_file)\n",
|
||
" print(f'Didn\\'t find {pickle_file}...')\n",
|
||
" all_data = dl_from_blob(glob_path)\n",
|
||
" print(f'Creating {pickle_file}...')\n",
|
||
" save_pickle(pickle_file, all_data)\n",
|
||
" return all_data\n",
|
||
"\n",
|
||
"print(\"Loading data...\")\n",
|
||
"dic_data = load_data()\n",
|
||
"print(len(dic_data))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"id": "d1db1537",
|
||
"metadata": {
|
||
"tags": []
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"CPU times: user 95 µs, sys: 297 µs, total: 392 µs\n",
|
||
"Wall time: 396 µs\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"%%time\n",
|
||
"\n",
|
||
"# Categorized Data\n",
|
||
"cdata = dict() \n",
|
||
"# Sorting, HeightNorm, ArmNorm\n",
|
||
"cdata['SYY'] = list() \n",
|
||
"cdata['SYN'] = list() \n",
|
||
"cdata['SNY'] = list() \n",
|
||
"cdata['SNN'] = list() \n",
|
||
"\n",
|
||
"# Jenga, HeightNorm, ArmNorm\n",
|
||
"cdata['JYY'] = list() \n",
|
||
"cdata['JYN'] = list() \n",
|
||
"cdata['JNY'] = list() \n",
|
||
"cdata['JNN'] = list() \n",
|
||
"\n",
|
||
"for d in dic_data:\n",
|
||
" if d['scenario'] == 'Sorting':\n",
|
||
" if d['heightnorm']:\n",
|
||
" if d['armnorm']:\n",
|
||
" cdata['SYY'].append(d)\n",
|
||
" else:\n",
|
||
" cdata['SYN'].append(d)\n",
|
||
" else:\n",
|
||
" if d['armnorm']:\n",
|
||
" cdata['SNY'].append(d)\n",
|
||
" else:\n",
|
||
" cdata['SNN'].append(d)\n",
|
||
" elif d['scenario'] == 'Jenga':\n",
|
||
" if d['heightnorm']:\n",
|
||
" if d['armnorm']:\n",
|
||
" cdata['JYY'].append(d)\n",
|
||
" else:\n",
|
||
" cdata['JYN'].append(d)\n",
|
||
" else:\n",
|
||
" if d['armnorm']:\n",
|
||
" cdata['JNY'].append(d)\n",
|
||
" else:\n",
|
||
" cdata['JNN'].append(d)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "46382aad",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Preprocessing"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"id": "f7842338",
|
||
"metadata": {
|
||
"tags": []
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def drop(entry, data=True) -> pd.DataFrame:\n",
|
||
" droptable = ['participantID', 'FrameID', 'Scenario', 'HeightNormalization', 'ArmNormalization', 'Repetition', 'Session', 'Unnamed: 0']\n",
|
||
" if data:\n",
|
||
" centry = pickle.loads(pickle.dumps(entry['data']))\n",
|
||
" else:\n",
|
||
" centry = pickle.loads(pickle.dumps(entry))\n",
|
||
"\n",
|
||
" return centry.drop(droptable, axis=1)\n",
|
||
" \n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"id": "b73d9485",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import numpy as np\n",
|
||
"right_Hand_ident='right_Hand'\n",
|
||
"left_Hand_ident='left_hand'\n",
|
||
"\n",
|
||
"def rem_low_acc(entry, data=True) -> pd.DataFrame:\n",
|
||
" if data:\n",
|
||
" centry = pickle.loads(pickle.dumps(entry['data']))\n",
|
||
" else:\n",
|
||
" centry = pickle.loads(pickle.dumps(entry))\n",
|
||
" \n",
|
||
" centry['LeftHandTrackingAccuracy'] = (centry['LeftHandTrackingAccuracy'] == 'High') * 1.0\n",
|
||
" centry['RightHandTrackingAccuracy'] = (centry['RightHandTrackingAccuracy'] == 'High') * 1.0\n",
|
||
" \n",
|
||
" right_Hand_cols = [c for c in centry if right_Hand_ident in c]\n",
|
||
" left_Hand_cols = [c for c in centry if left_Hand_ident in c]\n",
|
||
" \n",
|
||
" centry.loc[centry['RightHandTrackingAccuracy'] == 0.0, right_Hand_cols] = np.nan\n",
|
||
" centry.loc[centry['LeftHandTrackingAccuracy'] == 0.0, left_Hand_cols] = np.nan\n",
|
||
" \n",
|
||
" return centry\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"id": "1a298d6d",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from tensorflow.keras.preprocessing.sequence import pad_sequences\n",
|
||
"\n",
|
||
"def pad(entry, data=True) -> pd.DataFrame:\n",
|
||
" if data:\n",
|
||
" centry = pickle.loads(pickle.dumps(entry['data']))\n",
|
||
" else:\n",
|
||
" centry = pickle.loads(pickle.dumps(entry))\n",
|
||
" \n",
|
||
" cols = centry.columns\n",
|
||
" pentry = pad_sequences(centry.T.to_numpy(),\n",
|
||
" maxlen=(int(centry.shape[0]/stride_sz)+1)*stride_sz,\n",
|
||
" dtype='float64',\n",
|
||
" padding='pre', \n",
|
||
" truncating='post',\n",
|
||
" value=np.nan\n",
|
||
" ) \n",
|
||
" pdentry = pd.DataFrame(pentry.T, columns=cols)\n",
|
||
" pdentry.loc[0] = [0 for _ in cols]\n",
|
||
" return pdentry"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"id": "3be1bd3f",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def interpol(entry, data=True) -> pd.DataFrame:\n",
|
||
" if data:\n",
|
||
" centry = pickle.loads(pickle.dumps(entry['data']))\n",
|
||
" else:\n",
|
||
" centry = pickle.loads(pickle.dumps(entry))\n",
|
||
" \n",
|
||
" return centry.interpolate(method='linear', axis=0)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 14,
|
||
"id": "2a7f4e26",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"from tensorflow.keras.preprocessing import timeseries_dataset_from_array\n",
|
||
"\n",
|
||
"def slicing(entry, label, data=True):\n",
|
||
" if data:\n",
|
||
" centry = pickle.loads(pickle.dumps(entry['data']))\n",
|
||
" else:\n",
|
||
" centry = pickle.loads(pickle.dumps(entry))\n",
|
||
" \n",
|
||
" return timeseries_dataset_from_array(\n",
|
||
" data=centry, \n",
|
||
" targets=[label for _ in range(centry.shape[0])], \n",
|
||
" sequence_length=win_sz,\n",
|
||
" sequence_stride=stride_sz, \n",
|
||
" batch_size=8, \n",
|
||
" seed=177013\n",
|
||
" )"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"id": "b012b0f7",
|
||
"metadata": {
|
||
"tags": []
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# %%time \n",
|
||
"\n",
|
||
"# acc_data = pd.DataFrame()\n",
|
||
"\n",
|
||
"# for d in tqdm(cdata['SYY']):\n",
|
||
"# acc_data = acc_data.append(d['data'])\n",
|
||
"\n",
|
||
"\n",
|
||
"# dacc_data = drop(acc_data, False)\n",
|
||
"# ddacc_data = rem_low_acc(dacc_data, False)\n",
|
||
"\n",
|
||
"# for c in ddacc_data:\n",
|
||
"# print(f\"{c}: {dacc_data[c].min()}, {dacc_data[c].max()}\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 16,
|
||
"id": "a2440d77",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"100%|██████████| 96/96 [00:09<00:00, 10.55it/s]"
|
||
]
|
||
},
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"CPU times: user 8.07 s, sys: 1.19 s, total: 9.27 s\n",
|
||
"Wall time: 9.1 s\n"
|
||
]
|
||
},
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"%%time\n",
|
||
"\n",
|
||
"classes = 16 # dynamic\n",
|
||
"\n",
|
||
"def preproc(data):\n",
|
||
" res_list = list()\n",
|
||
" \n",
|
||
" for e in tqdm(data):\n",
|
||
" res_list.append(preproc_entry(e))\n",
|
||
" \n",
|
||
" return res_list\n",
|
||
" \n",
|
||
"def preproc_entry(entry, data = True):\n",
|
||
" entry2 = pickle.loads(pickle.dumps(entry))\n",
|
||
" entry2['data'] = drop(entry2, data)\n",
|
||
" \n",
|
||
" entry4 = pickle.loads(pickle.dumps(entry2))\n",
|
||
" entry4['data'] = rem_low_acc(entry4, data)\n",
|
||
" \n",
|
||
" entry5 = pickle.loads(pickle.dumps(entry4))\n",
|
||
" entry5['data'] = pad(entry5, data)\n",
|
||
" \n",
|
||
"# entry6 = pickle.loads(pickle.dumps(entry5))\n",
|
||
"# entry6['data'] = interpol(entry6, data)\n",
|
||
" \n",
|
||
" entry7 = pickle.loads(pickle.dumps(entry5))\n",
|
||
" entry7['data'] = slicing(entry7, entry7['user'], data)\n",
|
||
" \n",
|
||
" return entry7\n",
|
||
"\n",
|
||
"pdata = preproc(cdata[cenario])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 17,
|
||
"id": "11e96fef",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"CPU times: user 96 µs, sys: 107 µs, total: 203 µs\n",
|
||
"Wall time: 214 µs\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"(48, 48)"
|
||
]
|
||
},
|
||
"execution_count": 17,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"%%time\n",
|
||
"train = np.array([x['data'] for x in pdata if x['session'] == 1])\n",
|
||
"test = np.array([x['data'] for x in pdata if x['session'] == 2])\n",
|
||
"\n",
|
||
"len(train), len(test)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 18,
|
||
"id": "1807a2f7",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"CPU times: user 1min, sys: 13.2 s, total: 1min 13s\n",
|
||
"Wall time: 21.1 s\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"%%time\n",
|
||
"\n",
|
||
"X_train = list()\n",
|
||
"y_train = list()\n",
|
||
"\n",
|
||
"X_test = list()\n",
|
||
"y_test = list()\n",
|
||
"\n",
|
||
"# train = list()\n",
|
||
"test = list()\n",
|
||
"\n",
|
||
"for x in pdata:\n",
|
||
" if x['session'] == 1:\n",
|
||
"# train.append(\n",
|
||
"# {\n",
|
||
"# 'label': x['user'],\n",
|
||
"# 'data': list()\n",
|
||
"# })\n",
|
||
" for y in x['data'].unbatch().as_numpy_iterator():\n",
|
||
" X_train.append(y[0])\n",
|
||
" y_train.append(y[1])\n",
|
||
" \n",
|
||
"# train[-1]['data'].append(y[0])\n",
|
||
" if x['session'] == 2:\n",
|
||
" test.append(\n",
|
||
" {\n",
|
||
" 'label': x['user'],\n",
|
||
" 'data': list()\n",
|
||
" })\n",
|
||
" for y in x['data'].unbatch().as_numpy_iterator():\n",
|
||
" X_test.append(y[0])\n",
|
||
" y_test.append(y[1])\n",
|
||
" \n",
|
||
"# test[-1]['data'].append(y[0])\n",
|
||
"\n",
|
||
"X_train = np.array(X_train)\n",
|
||
"y_train = np.array(y_train)\n",
|
||
"X_test = np.array(X_test)\n",
|
||
"y_test = np.array(y_test)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 19,
|
||
"id": "44330b34",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"(37902, 30, 338) (73692, 30, 338) (37902,) (73692,)\n",
|
||
"(32745, 30, 338) (48773, 30, 338) (32745,) (48773,)\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"XX_train = list()\n",
|
||
"yy_train = list()\n",
|
||
"XX_test = list()\n",
|
||
"yy_test = list()\n",
|
||
"\n",
|
||
"for X,y in zip(X_train, y_train):\n",
|
||
" if not np.isnan(X).any():\n",
|
||
" XX_train.append(X)\n",
|
||
" yy_train.append(y)\n",
|
||
"\n",
|
||
"for X,y in zip(X_test, y_test):\n",
|
||
" if not np.isnan(X).any():\n",
|
||
" XX_test.append(X)\n",
|
||
" yy_test.append(y)\n",
|
||
" \n",
|
||
"XX_train = np.array(XX_train)\n",
|
||
"yy_train = np.array(yy_train)\n",
|
||
"XX_test = np.array(XX_test)\n",
|
||
"yy_test = np.array(yy_test)\n",
|
||
"\n",
|
||
"print(np.array(XX_train).shape, X_train.shape, np.array(yy_train).shape, np.array(y_train).shape)\n",
|
||
"print(np.array(XX_test).shape, X_test.shape, np.array(yy_test).shape, np.array(y_test).shape)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 20,
|
||
"id": "bd805e81",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<div>\n",
|
||
"<style scoped>\n",
|
||
" .dataframe tbody tr th:only-of-type {\n",
|
||
" vertical-align: middle;\n",
|
||
" }\n",
|
||
"\n",
|
||
" .dataframe tbody tr th {\n",
|
||
" vertical-align: top;\n",
|
||
" }\n",
|
||
"\n",
|
||
" .dataframe thead th {\n",
|
||
" text-align: right;\n",
|
||
" }\n",
|
||
"</style>\n",
|
||
"<table border=\"1\" class=\"dataframe\">\n",
|
||
" <thead>\n",
|
||
" <tr style=\"text-align: right;\">\n",
|
||
" <th></th>\n",
|
||
" <th>0</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>0</th>\n",
|
||
" <td>11</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>11</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>11</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>11</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>4</th>\n",
|
||
" <td>11</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>...</th>\n",
|
||
" <td>...</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>37897</th>\n",
|
||
" <td>9</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>37898</th>\n",
|
||
" <td>9</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>37899</th>\n",
|
||
" <td>9</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>37900</th>\n",
|
||
" <td>9</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>37901</th>\n",
|
||
" <td>9</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"<p>37902 rows × 1 columns</p>\n",
|
||
"</div>"
|
||
],
|
||
"text/plain": [
|
||
" 0\n",
|
||
"0 11\n",
|
||
"1 11\n",
|
||
"2 11\n",
|
||
"3 11\n",
|
||
"4 11\n",
|
||
"... ..\n",
|
||
"37897 9\n",
|
||
"37898 9\n",
|
||
"37899 9\n",
|
||
"37900 9\n",
|
||
"37901 9\n",
|
||
"\n",
|
||
"[37902 rows x 1 columns]"
|
||
]
|
||
},
|
||
"execution_count": 20,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"a = pd.DataFrame(yy_train)\n",
|
||
"a"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 21,
|
||
"id": "f6416fc1",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"16 0.113055\n",
|
||
"11 0.110680\n",
|
||
"10 0.103662\n",
|
||
"3 0.102739\n",
|
||
"5 0.095404\n",
|
||
"13 0.069469\n",
|
||
"15 0.061738\n",
|
||
"7 0.048625\n",
|
||
"9 0.044826\n",
|
||
"6 0.043955\n",
|
||
"14 0.043375\n",
|
||
"1 0.038890\n",
|
||
"4 0.036489\n",
|
||
"8 0.035433\n",
|
||
"12 0.032030\n",
|
||
"2 0.019630\n",
|
||
"dtype: float64"
|
||
]
|
||
},
|
||
"execution_count": 21,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"b = a.value_counts(normalize=True)\n",
|
||
"b"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"id": "1885329b",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/html": [
|
||
"<div>\n",
|
||
"<style scoped>\n",
|
||
" .dataframe tbody tr th:only-of-type {\n",
|
||
" vertical-align: middle;\n",
|
||
" }\n",
|
||
"\n",
|
||
" .dataframe tbody tr th {\n",
|
||
" vertical-align: top;\n",
|
||
" }\n",
|
||
"\n",
|
||
" .dataframe thead th {\n",
|
||
" text-align: right;\n",
|
||
" }\n",
|
||
"</style>\n",
|
||
"<table border=\"1\" class=\"dataframe\">\n",
|
||
" <thead>\n",
|
||
" <tr style=\"text-align: right;\">\n",
|
||
" <th></th>\n",
|
||
" <th>0</th>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>0</th>\n",
|
||
" <th></th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>16</th>\n",
|
||
" <td>0.113055</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>11</th>\n",
|
||
" <td>0.110680</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>10</th>\n",
|
||
" <td>0.103662</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>0.102739</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>5</th>\n",
|
||
" <td>0.095404</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>13</th>\n",
|
||
" <td>0.069469</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>15</th>\n",
|
||
" <td>0.061738</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>7</th>\n",
|
||
" <td>0.048625</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>9</th>\n",
|
||
" <td>0.044826</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>6</th>\n",
|
||
" <td>0.043955</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>14</th>\n",
|
||
" <td>0.043375</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>0.038890</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>4</th>\n",
|
||
" <td>0.036489</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>8</th>\n",
|
||
" <td>0.035433</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>12</th>\n",
|
||
" <td>0.032030</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>0.019630</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"</div>"
|
||
],
|
||
"text/plain": [
|
||
" 0\n",
|
||
"0 \n",
|
||
"16 0.113055\n",
|
||
"11 0.110680\n",
|
||
"10 0.103662\n",
|
||
"3 0.102739\n",
|
||
"5 0.095404\n",
|
||
"13 0.069469\n",
|
||
"15 0.061738\n",
|
||
"7 0.048625\n",
|
||
"9 0.044826\n",
|
||
"6 0.043955\n",
|
||
"14 0.043375\n",
|
||
"1 0.038890\n",
|
||
"4 0.036489\n",
|
||
"8 0.035433\n",
|
||
"12 0.032030\n",
|
||
"2 0.019630"
|
||
]
|
||
},
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"c = pd.DataFrame(b)\n",
|
||
"c"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 23,
|
||
"id": "7dfe2339",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"<AxesSubplot:ylabel='0'>"
|
||
]
|
||
},
|
||
"execution_count": 23,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
},
|
||
{
|
||
"data": {
|
||
"image/png": "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\n",
|
||
"text/plain": [
|
||
"<Figure size 432x288 with 1 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"c.plot.pie(y=0, legend=False)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 24,
|
||
"id": "fd3f3f1e",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"ename": "SyntaxError",
|
||
"evalue": "unmatched ']' (<ipython-input-24-481b8b7ed782>, line 1)",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[0;36m File \u001b[0;32m\"<ipython-input-24-481b8b7ed782>\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m ]]]\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unmatched ']'\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "615cccc9",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"%%time\n",
|
||
"\n",
|
||
"from sklearn.preprocessing import LabelBinarizer\n",
|
||
"\n",
|
||
"\n",
|
||
"lb = LabelBinarizer()\n",
|
||
"yyy_train = lb.fit_transform(yy_train)\n",
|
||
"yyy_test = lb.fit_transform(yy_test)\n",
|
||
"\n",
|
||
"for e in test:\n",
|
||
" e['label'] = lb.transform([e['label']])\n",
|
||
" e['data'] = np.array(e['data'])\n",
|
||
" \n",
|
||
"# for e in train:\n",
|
||
"# e['label'] = lb.transform([e['label']])\n",
|
||
"# e['data'] = np.array(e['data'])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "f56e5055",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(XX_train.shape)\n",
|
||
"print(yyy_train.shape)\n",
|
||
"print(XX_test.shape)\n",
|
||
"print(yyy_test.shape)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "f046e211",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Building Model"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "53832797",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import tensorflow as tf\n",
|
||
"from tensorflow.keras.regularizers import l2\n",
|
||
"from tensorflow.keras.models import Sequential\n",
|
||
"from tensorflow.keras.layers import Dense, Flatten, BatchNormalization, Dropout\n",
|
||
"from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau\n",
|
||
"from tensorflow.keras.optimizers import Adam\n",
|
||
"\n",
|
||
"def build_model(shape, classes):\n",
|
||
" model = Sequential()\n",
|
||
" \n",
|
||
" ncount = shape[0]*shape[1]\n",
|
||
" \n",
|
||
" model.add(Flatten(input_shape=shape))\n",
|
||
" \n",
|
||
" model.add(Dropout(drop_count))\n",
|
||
" model.add(BatchNormalization())\n",
|
||
" \n",
|
||
" for i in range(1,layer_count):\n",
|
||
" neurons = int(ncount/pow(dense_steps,i))\n",
|
||
" if neurons <= classes*dense_steps:\n",
|
||
" break\n",
|
||
" model.add(Dropout(drop_count*i))\n",
|
||
" model.add(Dense(neurons, activation='relu', \n",
|
||
" kernel_regularizer=l2(0.001))\n",
|
||
" )\n",
|
||
" \n",
|
||
" model.add(Dense(classes, activation='softmax'))\n",
|
||
" \n",
|
||
" model.compile(\n",
|
||
" optimizer=Adam(),\n",
|
||
" loss=\"categorical_crossentropy\", \n",
|
||
" metrics=[\"acc\"],\n",
|
||
" )\n",
|
||
" \n",
|
||
" return model\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "64f2aaa7",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"checkpoint_file = './goat.weights'\n",
|
||
"\n",
|
||
"def train_model(X_train, y_train, X_test, y_test):\n",
|
||
" model = build_model(X_train[0].shape, 16)\n",
|
||
" \n",
|
||
" model.summary()\n",
|
||
" \n",
|
||
" # Create a callback that saves the model's weights\n",
|
||
" model_checkpoint = ModelCheckpoint(filepath=checkpoint_path, monitor='loss', \n",
|
||
"\t\t\tsave_best_only=True)\n",
|
||
" \n",
|
||
" reduce_lr = ReduceLROnPlateau(monitor='loss', factor=0.5, patience=5, min_lr=0.0001)\n",
|
||
"\n",
|
||
" callbacks = [model_checkpoint, reduce_lr]\n",
|
||
" \n",
|
||
" history = model.fit(X_train, \n",
|
||
" y_train,\n",
|
||
" epochs=50,\n",
|
||
" batch_size=32,\n",
|
||
" verbose=2,\n",
|
||
" validation_data=(X_test, y_test),\n",
|
||
" callbacks=callbacks\n",
|
||
" )\n",
|
||
" \n",
|
||
" model.load_weights(checkpoint_path)\n",
|
||
" return model, history\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "858670a8",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"%%time\n",
|
||
"\n",
|
||
"model, history = train_model(np.array(XX_train), np.array(yyy_train), np.array(XX_test), np.array(yyy_test))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "6e905067",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Eval"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "196dae1d",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def predict(model, entry):\n",
|
||
" p_dict = dict()\n",
|
||
" predictions = np.argmax(model.predict(entry['data']), axis=-1)\n",
|
||
" for p in predictions:\n",
|
||
" if p in p_dict:\n",
|
||
" p_dict[p] += 1\n",
|
||
" else:\n",
|
||
" p_dict[p] = 1\n",
|
||
" prediction = max(p_dict, key=p_dict.get)\n",
|
||
" return prediction+1"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "49aebfaa",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"%%time\n",
|
||
"\n",
|
||
"ltest = [lb.inverse_transform(e['label'])[0] for e in test]\n",
|
||
"ptest = [predict(model, e) for e in test]\n",
|
||
"# for e in test:\n",
|
||
"# print(f\"Label: {lb.inverse_transform(e['label'])[0]:2d}\")\n",
|
||
"# print(f\"Prediction: {predict(model, e):2d}\\n_______________\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "6577cf5f",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"%%time\n",
|
||
"\n",
|
||
"ltrain = [lb.inverse_transform(e['label'])[0] for e in train]\n",
|
||
"ptrain = [predict(model, e) for e in train]\n",
|
||
"\n",
|
||
"# for e in train:\n",
|
||
"# print(f\"Label: {lb.inverse_transform(e['label'])[0]:2d}\")\n",
|
||
"# print(f\"Prediction: {predict(model, e):2d}\\n_______________\")\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "d62e2063",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"%%time\n",
|
||
"\n",
|
||
"from sklearn.metrics import confusion_matrix\n",
|
||
"import seaborn as sn\n",
|
||
"\n",
|
||
"from sklearn.metrics import classification_report\n",
|
||
"\n",
|
||
"set_digits = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }\n",
|
||
"\n",
|
||
"train_cm = confusion_matrix(ltrain, ptrain, normalize='true')\n",
|
||
"test_cm = confusion_matrix(ltest, ptest, normalize='true')\n",
|
||
"\n",
|
||
"df_cm = pd.DataFrame(test_cm, index=set_digits, columns=set_digits)\n",
|
||
"plt.figure(figsize = (10,7))\n",
|
||
"sn_plot = sn.heatmap(df_cm, annot=True, cmap=\"Greys\")\n",
|
||
"plt.ylabel(\"True Label\")\n",
|
||
"plt.xlabel(\"Predicted Label\")\n",
|
||
"plt.show()\n",
|
||
"\n",
|
||
"print(classification_report(ltest, ptest, zero_division=0))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "5041115f",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(f'cenario: {cenario}')\n",
|
||
"print(f'win_sz: {win_sz}')\n",
|
||
"print(f'stride_sz: {stride_sz}')\n",
|
||
"print(f'dense_steps: {dense_steps}')\n",
|
||
"print(f'layer_count: {layer_count}')\n",
|
||
"print(f'drop_count: {drop_count}')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "d25d662c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": []
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"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.10"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
}
|