Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# CNN Approach to Time-series classification\n",
"\n",
"In this notebook we demonstrate a transformation-based approach to time series classification. A time-series is transformed into an image by one of several methods and the classifier is trained directly on the image data.\n",
"\n",
"The notebook automates preprocess of data on any of the 128 UCR time series classification datasets. Download here:\n",
"http://www.timeseriesclassification.com/index.php, unzip, and set your pwd there to run this notebook as is."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from scipy.io import arff\n",
"import seaborn as sns\n",
"from torch.utils.data import Dataset, DataLoader, ConcatDataset\n",
"from fastai import *\n",
"from fastai.vision import * \n",
"from fastai.vision.data import ImageDataBunch\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"from sklearn.metrics import confusion_matrix\n",
"from pyts.image import GASF, GADF, MTF, RecurrencePlots\n",
"import pdb\n",
"from skimage.transform import resize"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'1.0.24'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import fastai\n",
"import warnings\n",
"warnings.filterwarnings('ignore')\n",
"fastai.__version__"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"def cleanup(df):\n",
" #df.sample(df.shape[0], replace=False).reset_index(drop=True)\n",
" df.columns = [k for k in range(df.shape[1]-1)]+['target']\n",
" for k in df.columns[:-1]:\n",
" df[k] = df[k].astype('float')\n",
" if df.target.dtype == 'object':\n",
" df['target'] = df['target'].apply(lambda x: x.decode('ascii')).astype('int')\n",
" if sorted(df.target.unique()) != list(np.arange(df.target.nunique())):\n",
" new_targs = pd.DataFrame({'target':df.target.unique()}).reset_index()\n",
" df = pd.merge(df, new_targs, left_on='target', right_on='target').drop('target',axis=1).rename(columns={'index':'target'})\n",
" ts = pd.melt(df.reset_index(), id_vars=['index','target'], var_name='time').rename(columns={'index':'id'})\n",
" ts = ts.groupby(['id','time','target']).value.mean().reset_index()\n",
" return df, ts\n",
"\n",
"def graph_ts(ts):\n",
" for k in sorted(ts.target.unique()):\n",
" fig, axes = plt.subplots(figsize=(15,5))\n",
" sns.tsplot(ts[ts.target == k], time='time', unit='id', condition='target', value='value', err_style='unit_traces', ax=axes) \n",
" fig, axes = plt.subplots(figsize=(15,5))\n",
" sns.tsplot(ts, time='time', unit='id', condition='target', value='value', err_style='unit_traces', ax=axes)\n",
" return None\n",
"\n",
"def prep_data(task='Oliveoil', cmap='rainbow', method='GASF', image_size=224, graph=False):\n",
" path = Path('TSC/%s'%(task))\n",
" for phase in ['TRAIN','TEST']:\n",
" if graph:\n",
" graph_ts(ts)\n",
" labels = df.target.unique()\n",
" if method == 'GASF':\n",
" transformer = GASF(image_size=image_size)\n",
" elif method == 'GADF':\n",
" transformer = GADF(image_size=image_size)\n",
" elif method == 'MTF':\n",
" transformer = MTF(image_size=image_size)\n",
" elif method == 'RP':\n",
" transformer = RecurrencePlots(dimension=1, epsilon=None, percentage=10)\n",
" else:\n",
" method = 'Unaltered'\n",
" method_path = path/f'{method}'\n",
" method_path.mkdir(exist_ok=True)\n",
" phase_path = method_path/f'{phase}'\n",
" phase_path.mkdir(exist_ok=True)\n",
" if method != 'Unaltered':\n",
" image_data = transformer.fit_transform(df[df.columns[:-1]])\n",
" image_data = resize(image_data, (image_data.shape[0],image_size,image_size))\n",
" for label in labels:\n",
" label_path = phase_path/f'{label}'\n",
" label_path.mkdir(exist_ok=True)\n",
" sub_df = df[df.target == label]\n",
" idxs = sub_df.index\n",
" for idx in idxs:\n",
" plt.imsave(label_path/f'{idx}.png', image_data[idx], cmap=cmap)\n",
" else: \n",
" for label in labels:\n",
" label_path = phase_path/f'{label}'\n",
" label_path.mkdir(exist_ok=True)\n",
" sub_df = df[df.target == label]\n",
" idxs = sub_df.index\n",
" for idx in idxs:\n",
" plt.figure(figsize=(10,10))\n",
" plt.plot(df.iloc[idx].values)\n",
" plt.savefig(label_path/f'{idx}')\n",
" plt.close('all') \n",
" return None\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [],
"source": [
"task='Earthquakes'\n",
"method = 'RP'"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [],
"source": [
"prep_data(task=task, method=method, image_size=128, graph=False)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"phase = 'TRAIN' \n",
"data = arff.loadarff('TSC/%s_%s.arff'%(task,phase))\n",
"df = pd.DataFrame(data[0])\n",
"df, ts = cleanup(df)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(322, 513)"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.shape"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [],
"source": [
"method = 'MTF'"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"torch.Size([48, 3, 128, 128])"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x,y = next(iter(data.valid_dl)) ; x.size()"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [],
"source": [
"path = Path('TSC/Earthquakes/RP/TEST/0')"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"264"
]
},
"execution_count": 91,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(path.ls())"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [],
"source": [
"path = Path('TSC/%s/%s'%(task,method))\n",
"data = (ImageItemList.from_folder(path) \n",
" .split_by_folder(train='TRAIN', valid='TEST')\n",
" .label_from_folder()\n",
" .transform().databunch(bs=32))"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
"cnn = create_cnn(data, models.resnet34, metrics=accuracy)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"cnn.lr_find(); cnn.recorder.plot()"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Total time: 00:06\n",
"epoch train_loss valid_loss accuracy\n",
"1 0.785134 0.651331 0.798137 (00:01)\n",
"2 0.736826 0.673580 0.807453 (00:01)\n",
"3 0.682513 0.878728 0.785714 (00:01)\n",
"4 0.634076 0.483826 0.835404 (00:01)\n",
"5 0.602548 0.438748 0.838509 (00:01)\n",
"\n"
]
}
],
"source": [
"cnn.fit_one_cycle(5, max_lr=2e-3)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAAEKCAYAAADjDHn2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3Xl8VNXZwPHfk52QFRKWEAgBwr4pEVnUKirFFXxd6taKttpFxW629rW11m7avq12sVXrXhUEtIqK4i6VRQhIwhr2kJCNBLKT/Xn/mAkOIWGCyWSWPN/PZz7OPffcuc8xQ57ce849R1QVY4wx5mSCvB2AMcYY32fJwhhjjFuWLIwxxrhlycIYY4xbliyMMca4ZcnCGGOMW5YsjDHGuGXJwhhjjFuWLIwxxrgV4u0AukpCQoIOHTrU22EYY4xf2bBhQ4mqJrqrFzDJYujQoWRkZHg7DGOM8SsiktORenYbyhhjjFuWLIwxxrhlycIYY4xbliyMMca4ZcnCGGOMW5YsjDHGuGXJwhhjjFuWLIwxxo8t3ZDHonUHPH4eSxbGGOPHFq07wH8+P+jx81iyMMYYP7a/tJqhfXt7/DyWLIwxxk9V1jZQUlXP0ARLFsYYY9qRU1oDwNC+kR4/l0eThYjMEZFsEdktIve0sf9hEdnkfO0UkTKXfU0u+5Z5Mk5jjPFH+0urAbrlysJjs86KSDDwKHAhkAesF5FlqrqtpY6q/sCl/p3AaS4fcVRVJ3sqPmOM8Xf7SxzJIsXPryymArtVda+q1gOLgLknqX8dsNCD8RhjTEDZX1pD/5hwIsM8v9qEJ5PFICDXZTvPWXYCEUkBUoEPXYojRCRDRNaKyDzPhWmMMf5pf0k1Kd0wEgo8myykjTJtp+61wFJVbXIpG6Kq6cD1wCMiMvyEE4jc5kwoGYcOHep8xMYY40f2l9aQGgDJIg8Y7LKdDOS3U/daWt2CUtV853/3Ah9zfH9GS50nVDVdVdMTE92uCmiMMQHDMWy2rls6t8GzyWI9kCYiqSIShiMhnDCqSURGAfHAGpeyeBEJd75PAGYC21ofa4wxPVV3DpsFD46GUtVGEbkDWAEEA0+r6lYReQDIUNWWxHEdsEhVXW9RjQEeF5FmHAntQddRVMYY09N157BZ8GCyAFDV5cDyVmX3tdq+v43jVgMTPBmbMcb4s+4cNgv2BLcxxvil7hw2C5YsjDHGL3XnsFmwZGGMMX6pO4fNgiULY4zxOy3DZlMSuqe/AixZGGOM32kZNmtXFsYYY9rVMmzW+iyMMca069gDeXYbyhhjTHv2lVTTL7r7hs2CJQtjjPE7OaXV3fbkdgtLFsYY42f2ldR025xQLSxZGGOMH6mqa+zW2WZbWLIwxhg/0jIn1NBuHAkFliyMMcavHJtt1pKFMcaY9rQMm+2u2WZbWLIwxhg/0jJstnd49w2bBUsWxhjjV3JKq7v9FhRYsjDGGL+yr6SmW5/cbmHJwhhj/ETLsNnunBOqhSULY4zxE3sPVQEwrJufsQBLFsYY4zd2FjmSxcgB0d1+bksWxhjjJ3YWVRIWHERKH+uzMMYY046dRZUMS+xNSHD3/+q2ZGGMMX5iV1EVo7xwCwosWRhjjF+orG3gYNlRRva3ZGGMMaYdu4qdnduWLIwxxrRnV1ElACP7R3nl/JYsjDHGD2QXVhERGsTg+O4fCQUeThYiMkdEskVkt4jc08b+h0Vkk/O1U0TKXPbdJCK7nK+bPBmnMcb4ul3FlaT1iyYoSLxyfo9NWygiwcCjwIVAHrBeRJap6raWOqr6A5f6dwKnOd/3AX4JpAMKbHAee8RT8RpjjC/LLqzkrLQEr53fk1cWU4HdqrpXVeuBRcDck9S/DljofP9V4D1VPexMEO8BczwYqzHG+KzymgaKK+u81rkNnk0Wg4Bcl+08Z9kJRCQFSAU+PJVjReQ2EckQkYxDhw51SdDGGONrdhY7OrdHBWiyaOvGmrZT91pgqao2ncqxqvqEqqaranpiYuKXDNMYY3xbdqEjWaR5aSQUeDZZ5AGDXbaTgfx26l7LF7egTvVYY4wJaLuKKukdFsyguF5ei8GTyWI9kCYiqSIShiMhLGtdSURGAfHAGpfiFcBsEYkXkXhgtrPMGGN6nJ1FVaT1j0bEOyOhwIPJQlUbgTtw/JLfDixW1a0i8oCIXO5S9Tpgkaqqy7GHgV/jSDjrgQecZcYY0+PsLKr02sN4LTy64reqLgeWtyq7r9X2/e0c+zTwtMeCM8YYP1BaVUdpdb1XR0KBPcFtjDE+7diCR5YsjDHGtGfnsTmhLFkYY4xpx86iSmIiQugfE+7VOCxZGGOMD9tVVMVIL4+EAksWxhjjs1SV7KJK0rx8CwosWRhjjM86VFlH+dEGRnl52CxYsjDGGJ/lKyOhwJKFMcb4rOyWkVADLFkYY4xpR2ZuGf2iw0mI8u5IKLBkYYwxPklVWb2nlOnD+3o7FMCShTHG+KTdxVWUVNUxw5KFMcaY9qzeUwrAjOHeW0rVlSULY4zxQav3lJAc34vBfSK9HQpgycIYY3xOU7Oydu9hn7kFBZYsjDHG52wvqKD8aIPP3IICSxbGGONzVu8pAbArC2OMMe1btbuUEf2i6BcT4e1QjrFkYYwxPqS+sZn1+32rvwIsWRhjjE/Jyiujpr7JkoUxxpj2rd5TigicmWrJwhhjTDtW7ylh7MAY4nuHeTuU41iyMMYYH1Hb0MTGnDKfuwUFliyMMcZnbMg5Qn1Ts089X9HCkoUxxviI1XtKCAkSzkjt4+1QTmDJwhhjfMSq3aVMGhxHVHiIt0M5gSULY4zxAbUNTWw+WM6ZPnhVAR5OFiIyR0SyRWS3iNzTTp1rRGSbiGwVkZdcyptEZJPztcyTcRpjjLdtzS+nqVmZPDjO26G0yWPXOiISDDwKXAjkAetFZJmqbnOpkwb8DJipqkdEpJ/LRxxV1cmeis8YY3xJZm45gM8mC09eWUwFdqvqXlWtBxYBc1vVuRV4VFWPAKhqsQfjMcYYn5WZV8aAmAifmg/KlSeTxSAg12U7z1nmaiQwUkRWichaEZnjsi9CRDKc5fM8GKcxxnhdVl45E5NjvR1GuzzZ5S5tlGkb508DzgWSgf+KyHhVLQOGqGq+iAwDPhSRzaq657gTiNwG3AYwZMiQro7fGGO6RXlNA/tKqrlqSrK3Q2mXJ68s8oDBLtvJQH4bdV5X1QZV3Qdk40geqGq+8797gY+B01qfQFWfUNV0VU1PTEzs+hYYY0w3yDpYBsCkZN/srwDPJov1QJqIpIpIGHAt0HpU02vAeQAikoDjttReEYkXkXCX8pnANowxJgBl5Tk6tyf0xNtQqtooIncAK4Bg4GlV3SoiDwAZqrrMuW+2iGwDmoC7VbVURGYAj4tIM46E9qDrKCpjjAkkmbllpCb0JrZXqLdDaZdHHxNU1eXA8lZl97m8V+CHzpdrndXABE/GZowxviIzr4zpw3xv8kBX9gS3McZ4UVFFLUUVdUz04f4KsGRhjDFelZnr7Nwe7Lv9FWDJwhhjvCorr5zgIGFckiULY4wx7cjMK2NU/2giQoO9HcpJWbIwxhgvUVWy8sp9/hYUWLIwxhivySmtofxog08/jNeiQ8lCRIa7PCR3rogsEBHfb50xxviwzDxH57avj4SCjl9ZvAI0icgI4CkgFXjp5IcYY4xpsXxzAf/5PA/H42UOmbnlRIQGMbJ/lBcj65iOPpTX7Hwi+wrgEVX9m4h87snAjDEmUGzLr2DBws9pbFY+3HGI310xnuiIULLyyhifFEtIsO/3CHQ0wgYRuQ64CXjTWea7z6UbY4yPaGhq5u6lmcRFhrJg1gjeysrn8r+vYnNeOVvyy/3iFhR0PFncDEwHfquq+0QkFXjBc2EZY0xgeGLlXrbmV/DrueP54exRLLx1GjX1jcz7xypqG5r9YiQUdDBZqOo2VV2gqgtFJB6IVtUHPRybMcb4tZ1Flfzl/V1cMmEgF00YCMCZw/qyfMHZzByRQFhwEFNS4r0cZcd0qM9CRD4GLnfW3wQcEpFPVPWHJz3QGGN6qKZm5e6lWfQOD+ZXc8cdt69vVDjPzj+DIzX19I0K91KEp6ajt6FiVbUC+B/gGVWdAlzgubCMMca/PfXpXjJzy7j/8nEktJEQgoLEbxIFdDxZhIjIQOAavujgNsYY04aC8qP86d2dXDCmP5dPSvJ2OF2io8niARwLFe1R1fXOdbF3eS4s39LUrLy7tZCm5tZLiBtjzIneyMynrrGZey8Zg4h4O5wu0dEO7iWqOlFVv+vc3quqV3o2NN/xyoY8bvv3BpZuyPV2KMYYP/BmVgETBsWSmtDb26F0mY5O95EsIv8RkWIRKRKRV0Qk2dPB+YoXP8sBHEPgmu3qwhhzEjml1WTllXPpxIHeDqVLdfQ21DPAMiAJGAS84SwLeJvzysnMK+fM1D7sOVTNR9nF3g7JGOPD3swqAOCSHposElX1GVVtdL6eBRI9GJfPeGldDhGhQfzzxikMiuvF4yv3ejskY4wPeyurgNOGxJEcH+ntULpUR5NFiYjcKCLBzteNQKknA/MFlbUNvL4pn8snJdGndxg3zxzKun2H2eRcBtEYY1ztPVTFtoIKLp0YGCOgXHU0WdyCY9hsIVAAXIVjCpCA9tqmfGrqm7jhzBQArp06hOiIEJ5YucfLkRljfNGbWQWIwCUTAusWFHR8NNQBVb1cVRNVtZ+qzsPxgF7AUlVeXJvD+EExTEx2zN0SFR7CjdNSeGdLITml1V6O0Bjja97MyueMlD4MiI3wdihdrjPz4gbEVB+qyiPv7yS/7Ohx5RsPlLGjsJIbzkw5bpz0zTOGEhIUxJP/3dfdoRpjfNjOokp2FlVx6aTAu6qAziWLgHjSZG9JNU+s3Mvsh1eyaN2BYwuTvPhZDlHhISc8fdkvJoJ5pyWxZEMuh6vrvRGyMT6pqq6Rxetz+flrm1m7t/S4RX5c7S6uYv3+w90cnee9mZlPkMBF4wMzWXR08aO2BMQDB8MTo3jnrnP4ySuZ3PPqZt7aXMA9F43mrawCrk5Ppnf4if+LbjtnGIsz8vj3mhzuuiDNC1Eb4xtUlc/2HWZJRh5vbymgpr6J0GDhhbUHmDAolm+dncrFEwZS29DEm1kFLMnIZeMBxwCRv113GpcFyFQYqsqbWQVMG9aXxGj/me/pVJw0WYhIJW0nBQF6uftwEZkD/AUIBp5sa1pzEbkGuN95nkxVvd5ZfhPwc2e136jqc+7O92UN6RvJS9+axovrDvD75du55K+fAnD91JQ264/oF805IxN5ef0B7pg1guCggLjIMuaULVi0iTcy849dhV+dnszYgbH85/ODPPnpXu5atInfvrWditoGahuaGdEviv+9eDTvbyvmR4szSYgKZ/rwvt5uRqdtL6hkb0k13zw71duheIy0d6nY6Q8WCQZ2AhcCecB64DpV3eZSJw1YDMxS1SMi0k9Vi0WkD5ABpONIIhuAKap6pL3zpaena0ZGRqfjzj1cwy9e30JkWDD/uGFKu/Xeyirg9pc28vwtUzlnZI945MSY4+wuruSCP6/kpukp/PSi0USGHf+3Z3Oz8vHOYl76LJfE6HCuSU9m8uA4RISymnquemwNRRW1LP3ODEYNiD52XF1jE69uPEjvNm4D+5qmZuXj7GIe/Wg3mXnlrL/3Avr0DvN2WKdERDaoarq7ep25DeXOVGC3qu51BrQImAtsc6lzK/BoSxJQ1ZbHo78KvKeqh53HvgfMARZ6MF4ABveJ5Nmbp7qtd8HYfsRFhrI4I9eShemRnlm1n7CQIBacn3ZCogDHFNyzRvdn1uj+J+yLiwzjuVumcsWjq5j/zDpe/d4M4iPDWJyRyz8/3kNBeS0AYcHCHC/3AZTXNPDm5nx6h4UQFxlKXGQYvUKDeXdrIQvXHSC/vJZ+0eH86vJxfpcoToUnk8UgwHXmvTzgzFZ1RgKIyCoct6ruV9V32jl2kOdCPXXhIcHMmzyIl9YdoKymnrjIwP2SGNNaWU09r2zMY97kpC+9JsOguF48e/NUrnl8Ddf/6zOO1jdRWFFLeko8v7tiAn/9cBfff3kTS+IimZDsvaVHH/lgJ8+s2t/mvrNGJHDfZWM5f0x/QoM7M17I93kyWbR1I7/1Pa8QIA04F0gG/isi4zt4LCJyG3AbwJAhQzoT65dydXoyz67ez7LMfL4xfWi3n98Yb1m0PpfahmZuntm5e/Rjk2J4/OtTuPnZ9UxOjuPP10xi+vC+iAjjB8Uy79FVfOv59bx++1leeXahpr6RpRvyuHjCAH40exRlNQ2U1dRTUdvA5MHxATWrrDueTIV5wGCX7WQgv406r6tqg6ruA7JxJI+OHIuqPqGq6aqanpjY/beCxiXFMi4phsUZNnW56Tkam5p5fvV+pg/ry5iBMZ3+vJkjEsj65Wxe/vY0ZoxIOPZcU2J0OE/NT6eqtpFvPb+emvpGwDHyaFdRJS9+lsOuospOn/9kXt+UT2VtIzfPTGV4YhRTUuI5f0x/rjgtuUclCvBsslgPpIlIqoiEAdfimLnW1WvAeQAikoDjttReHAstzRaReBGJB2Y7y3zONemD2XKwgq355ceVNzUr/16bQ+7hGi9FZoxnrNhaRH55Lbec1XUjfyJCg9tcJGj0gBj+dv1pbMuv4LbnN7Bg4eec8dsPuPDhldz7ny38eElmu89zdJaq8vyaHEYPiCY9Jd4j5/AnHksWqtoI3IHjl/x2YLGqbhWRB0Tkcme1FUCpiGwDPgLuVtVSZ8f2r3EknPXAAy2d3b5m7uQkwoKDWJKRd6yssamZHy3exC9e28KCRZ/bGhgmoDy9ah9D+kQya3S/bjnfrNH9ufeSsXy6u4Q1e0uZOaIvD105gbvOTyMzr/zYcxtdbeOBI2wvqOAb04cGzGp3neHJPgtUdTmwvFXZfS7vFce0ISdMHaKqTwNPezK+rhAXGcbscf15fdNBfnbxaIJF+MHiTN7IzOe8UYl8lH2IRetzuf7M7u9TMaarZeWVsSHnCL+4dGy3Pl/0zbNSmTs5ib69w4794q6ua+TpVft4ZtU+pnjgL//n1+QQHR7CvNN8e/hudwns7vtucnX6YI7UNPDOlkLucj6kdM9Fo3l6/hmcmdqHh97ZQWlVnbfDNKbTnlm1n6jwEK5J7/6FMhOiwo/7C793eAjXTR3C21sKT5jbrbMOVdaxfHMBV05JbnNYcE9kyaILnDUigYGxEdy9JIu3Nhdw78Vj+M5XhiMi/GbeeKrrGvn92zu8HaYxnVJcUcubWflcNSWZ6IhQb4cDwDempxzrW+hKizNyaWhSvj697VkceiJLFl0gOEi4Jn0w9U3N/OLSsdx6zrBj+9L6R3PrOcNYuiGPdft8stvFmA5ZtN7xC/SmGUO9HcoxyfGRfHXcABauO8DR+qYu+czGpmZeXJvDWSMSGJ4Y1SWfGQgsWXSRO2eN4N0fnMM32xghsmBWGoPievHz1zbT0NTsheiM6ZzGpmZe+uwAZ6cl+NyQ0ZtnplJ+tIFXP89zX7kDPthRTH55LTdOs6sKV3YzrouEBAcxsn90m/t6hQVz/+XjuPX5DJ5YuZfbzxvRzdEZ0zkf7CimsKKWX80d5+1QTnDG0HjGD4rhmVX7uX7qkGP9GuU1jgRS29BM7/BgIsNC6B0WTGyvUPrFRNAvJpzo8BBEhOKKWjbkHGFDzhHe3lJIUmwEF4zpntFe/sKSRTe5cGx/vjquP39ckc0nOw9x1/lpzHA+qWqMr3thbQ4DYyM4v5uGy54KEeHmGan8aEkm/91VwtikGJ76dB//XpNDVV3jSY/tFRpMVEQIhyodA1DCQ4KYlBzH7bNGEBLg03ecKo/NOtvdumrWWU+qbWji5fWOidIKK2o5fUgcC85P4ysjEy1pGJ+191AVs/70CT+6cCR3nu+b67fUNTYx88GPiAgNoqSqjrrGZi6ZMJDbzxtBakJvqusaqalvorq+kSPVDRRX1lJcUUdRRS1lRxsYPSCaKSnxjEuKJSykZyUJX5h11rQSERrMTTOGcu3UwSzJyOOfH+9h/jPr+Z/TBvGbK8bbED3jk1787AAhQcLXpg52X9lLwkOC+eZZqfzfu9nMnZzE984dwYh+X3ROR4QG4/+rZniXXVl4UX1jM//8eA+PfLCTtH5R/OOGKcd9wY3pTrmHa+gbFXbcHy1H65uY9vsPODstgb9ff7oXo3NPVamqa/SZYb3+oqNXFj3resvHhIUEcdcFaTx/y1RKquqZ+/dPeSPzhPkSjfG42oYm5jyyktkPrzxufew3svIpP9rgFyODRMQShQdZsvABZ6cl8taCsxg1IJo7F37Oox/t9nZIpofZXVxFdX0TpVX1fO3xNfxxxQ7qG5t5YW0Oaf2iODO1j7dDNF5mycJHDIztxcvfns6ccQP4ywe7KHSuFGZMd9hR6Jjqe9Ft07hqSjKPfrSHi/6ykqy8cr4+PcUGYBhLFr4kNDiIey8ZQ3Oz8o+P7erCdJ/swgrCQoIYlxTDH66axGM3ns7h6nqiwkO44jSfWqTSeIkNv/Exg/tEcnX6YBaty+XbXxnOoLhe3g7J9AA7CitJ6xd17NmCOeMHcsbQPlTUWoexcbArCx90x6wRKGp9F6bbZBdWMmrA8TMQ9I0K97mpPYz3WLLwQYPievG1MwazJCPXVtozHne4up7iyjrGDOj8EqkmcFmy8FG3nzcCQezqwnjcjsIKgBOuLIxxZcnCRw2M7cX1Zw5hyYY8ckqrvR2OCWDZzpFQoy1ZmJOwZOHDvnvucEKChL99aFcXxnOyCyuJjwwlMTrc26EYH2bJwof1j4ngxmkpvLoxjy0Hy70djglQ2wsrGT0gxp6lMCdlycLH3XHeCPpGhfOjxZnUNXbNSmDGtGhuVnYVnTgSypjWLFn4uPjeYTx05QSyiyp55P1d3g7HBJjcIzXU1DdZf4Vxy5KFH5g1uj9fSx/M45/sYUPOEW+HYwJIyzQfowfasFlzcpYs/MTPLx3DwNhe/HhJZpctTG/MjoJKRGBkf5sa35ycJQs/ER0Ryh+vnsi+kmoeemeHt8MxASK7qIIhfSJt4S3jliULPzJjeALzZwzl2dX7WbOn1NvhmACwo7CSUf2tv8K4Z8nCz/x0zmj6x4Tz1Kf7vB2K8XO1DU3sL6m2/grTIR5NFiIyR0SyRWS3iNzTxv75InJIRDY5X99y2dfkUr7Mk3H6k15hwVw6MYlPdhZTfrTB2+EYP7arqIpmtSe3Tcd4LFmISDDwKHARMBa4TkTGtlH1ZVWd7Hw96VJ+1KX8ck/F6Y8um5REQ5Py7tZCb4di/JjNCWVOhSevLKYCu1V1r6rWA4uAuR48X48xKTmWwX168UZWgbdDMX4su7CS8JAghva1aciNe55MFoOAXJftPGdZa1eKSJaILBWRwS7lESKSISJrRWReWycQkducdTIOHTrUhaH7NhHh0olJrNpdQmlVnbfDMX5qR2ElI/tHExxk03wY9zyZLNr6Bmqr7TeAoao6EXgfeM5l3xBVTQeuBx4RkeEnfJjqE6qarqrpiYmJXRW3X7hsYhJNzco7divKfEk72ljwyJj2eDJZ5AGuVwrJQL5rBVUtVdWWP43/BUxx2Zfv/O9e4GPgNA/G6nfGDIxmWGJv3sjMd1/ZmFZKq+ooqaqzzm3TYZ58Emc9kCYiqcBB4FocVwnHiMhAVW258X45sN1ZHg/UqGqdiCQAM4E/eDBWvyMiXDYxib9+uIviilr6xUR4OyTjo2rqG1mwcBPZRRWk9OnNkL6RtNx5Gm2r45kO8tiVhao2AncAK3AkgcWqulVEHhCRltFNC0Rkq4hkAguA+c7yMUCGs/wj4EFV3eapWP3VZZMGogpvbbaObtO22oYmbnt+Ax/uKGLcwFgq6xp5e3MBL6w9QFhIEGOTLFmYjhHV1t0I/ik9PV0zMjK8HUa3m/PISnqHh/DKd2d4OxTjYxqamvnOvzfwwY5i/nT1JK6cknxsX0VtA/WNzSRE2YJHPZ2IbHD2D5+UPcHt5y6blMSGnCMcLDvq7VCMD2lqVr7/8iY+2FHMr+eNPy5RAMREhFqiMKfEkoWfu3TiQADeyrKObuNwuLqenyzN4q2sAu69eAxfn5bi7ZBMALCpJv1cSt/eTEyO5dlV+yk/2kBqQhTDEnszPCGK2MhQb4dnukF9YzOr95SwancJq3aXsq3A8WT29y9I49Zzhnk5OhMoLFkEgO+dO5yH3snmsU/20tTs6IMKEnjoyolcnT7YzdHGn6kq33txI+9vLyIsOIjTU+L48eyRnDMykYnJcd4OzwQQSxYBYM74gcwZP5CGpmZyD9ewr6SaJ1bu5eevbWFcUqyNeAlgK7YW8v72Ihacn8Z3vzKcXmHB3g7JBCjrswggocFBDEuM4vwx/Xn0htOJ7RXK7S9tpLLWZqcNRFV1jdy/bBtjBsawYNYISxTGoyxZBKiEqHD+fv3pHDhcwz2vbCZQhkj7s6ZmZX9JNR9nF/Pc6v386o2t/HRp1pceyfbIezsprKjlN/PGExJs/5SNZ9ltqAA2NbUPd391FA++vYMzVsczf2aqt0Pqkcpq6lm4Lpd/r9lPfnntsfLIsGCaVfnvrkO88K0zGZbY8XWwtxdU8Mzq/Vw3dTBTUuI9ELUxx7NkEeBuO3sY6/cd5rfLtzN5SDyTB1unZ3fZXVzFM6v28crGPGobmpk+rC93XZDGsMQoUvpGkhgVzraCCr7x1DqueXwNz90ylXFJsW4/t7lZufc/m4ntFcpP54zuhpYYY09w9whlNfVc8tdPAXhrwVnERYZ5OaLAti2/gr99uIu3txQSFhLEvMlJ3DwzlTHtLF+651AVX3/yMyrrGnn25jOYktIHgPKjDWwvqKCwvJY+vcPoFxNOv+gIVmwt5GevbuaPV9loN9N5HX2C25JFD7Ept4yrH1vN2WmJPPmNdIJsDYMutzmvnL9+uIv3thURHR7C/JlDmT9jKH078KT0wbKj3PjkZxSW13JWWgLbCyrIO9J+X8bUoX14+dvTELGfo+kcSxbmBM+t3s8vl23lJ3NG8b1zR3g7nIDy6sY8frg4k5iIEL64ec5PAAAQkElEQVR51jDmzxxKbK9TeyjyUGUdCxZ+TlFFLWOTYhibFMO4pFgGxfXicHU9xZW1FFfUcaSmnmvSBzO4T6SHWmN6ko4mC+uz6EG+MT2FdfsP838rsjl9SDzThvX1dkgB471tRQyK68U73z+b6Igv9+R8YnQ4C2+b1sWRGdM1bLxdDyIiPHTlRIb27c2dCz+nuLLW/UGmQ7bmVzB5cNyXThTG+DpLFj1MVHgI/7jxdCprG7hr4SYam5q9HZLfq6ht4MDhGntS3gQ0SxY90OgBMfxm3gTW7C3lDyuyvR2O39ue75i4z5KFCWTWZ9FDXTUlmay8Mp5YuZdxSTHMnTzI2yH5ra3OZDHOkoUJYHZl0YP94tKxTE3tw0+WZrHlYLlHztHQ1Mzza/bz6a4Sj3y+L9iaX0FClOMZCGMClSWLHiw0OIh/3HA6fXuHcdvzGZRU1XXp5285WM68R1dx3+tbuemZdby+6WCXfr6v2FZQYVcVJuBZsujhEqLCefzr6ZRW13P7ixtp6IIO79qGJv64YgdzH11FcWUdf7l2MmcMjef7L2/ihbU5XRC176hrbGJXUaUlCxPwrM/CMCE5loeunMj3X97Ed/69gQevnEhidMfXZ1ZV8o4cZfPBcjYfLGfFlkL2llRz1ZRkfnHJWGIjQ/nquAHc8dJGfv7aFiprG/nuucM92KLus6uoisZmtc5tE/AsWRgA5p02iLKaen739g5mP/wJv5o7nssmDnQ7ncRjn+zhsU/2UFbjWDMjJEgYlxTDc7dM5SsjE4/ViwgN5p83TuFHizN56J0dVNU1cPdX/X8SvK35jr6ejkwAaIw/s2Rhjpk/M5Wz0hL40ZIsFiz8nOVZBfzmivEktDO30Zo9pTz0zg7OGpHAnPEDmDAollEDogkPaXsRntDgIB7+2mQiQoN49KM9XDxhoN//kt2WX0FUeAgpNvWGCXDWZ2GOM6JfNK98Zzo/nTOaD3cUM+eR/7K7uOqEepW1Dfx4SSZD+/bm8a9P4YYzU5iYHNduomgRHCTce/FYIkKDeGHtAU81o9tsza9gzMBom5jRBDxLFuYEIcFBfPfc4Sy7cyYANz75GQdKa46r88Ab2ygoP8qfrplEZNipXaDGRoZy+aQkXt90kAo/XvK1uVnZXlDB2HamHjcmkFiyMO0aPSCGF741ldrGJq5/ci35zuU/391ayJINeXzv3BGcPuTLrdJ247QUauqb+M9G/x1Om3O4hur6Jr+/lWZMR3g0WYjIHBHJFpHdInJPG/vni8ghEdnkfH3LZd9NIrLL+brJk3Ga9o0eEMPzt0ylvKaBG5/8jB2FFfzs1c2MS4phwflpX/pzJybHMSk5lhfW5vjt+uAtnds2Esr0BB5LFiISDDwKXASMBa4TkbFtVH1ZVSc7X086j+0D/BI4E5gK/FJEbKFhL5mYHMczN59BQXktl/z1UyrrGnn4a5MJC+nc1+eGaSnsKq7is32HuyjS7rU1v4KQICGtf8fXzjbGX3nyymIqsFtV96pqPbAImNvBY78KvKeqh1X1CPAeMMdDcZoOSB/ah6duSicyNJj/vWg0I/tHd/ozL5uYRGyvUL99UG9rfgVp/dsf/WVMIPFkshgE5Lps5znLWrtSRLJEZKmItCwo3NFjTTeaMSKBz++7kPkzU7vk83qFBXPVlGTe2VLol2trbMu3aT5Mz+HJZNHWWMLWN6ffAIaq6kTgfeC5UzgWEblNRDJEJOPQoUOdCtZ0TEhw135lbjhzCI3NyuL1ue4r+5DiilpKquosWZgew5PJIg8Y7LKdDOS7VlDVUlVtmb3uX8CUjh7rPP4JVU1X1fTExMTWu40fGJYYxVkjEnjpswM0NftPR3fLtOQ2bNb0FJ5MFuuBNBFJFZEw4FpgmWsFERnosnk5sN35fgUwW0TinR3bs51lJgDdOC2F/PJa/vRuNuU1Jz53UVXXyJP/3cvVj61m44EjXojwRDYSyvQ0HpvuQ1UbReQOHL/kg4GnVXWriDwAZKjqMmCBiFwONAKHgfnOYw+LyK9xJByAB1TVP4fMGLcuGNOPWaP78Y+P9/DMqv1ccfog5s8YSmyvUJ5etY+XPjtAZW0jkWHB3PzMel7+9jRGD+i+X9JNzUrG/sPERYYxIDaCmIgQthVUkNI30tbcNj2G+OsY99bS09M1IyPD22GYTtiWX8Gzq/fx2qZ86hubCQkSmlW5aPxAbj1nGH17h3HVY6tpVnjlOzMY0rd75mN6YuUefrd8x7HtyLBgGpqauWBMf/5545STHGmM7xORDaqa7raeJQvjaw5X17No/QHKjzZww9SU45LCrqJKrn58DdERISz9zgz6x3h2dbrK2gbO/sNHjBkQww3ThlBYXkt+WS3FlbVcf+YQZgxP8Oj5jfE0SxYmYG3KLeOGf61lUHwvFn97OnGRYR4718Pv7eQvH+zijTvOYkKyTethAk9Hk4XNDWX8zuTBcfzrG+nsL6nhgj+v5M/vZlNY3vXPaRyuruepT/dx0fgBlihMj2fJwvilGSMSWHjbmUxKjuVvH+1m5kMfcvuLG/k4u5g9h6ooq6mnuZNDcR/7ZA819Y388MKRXRS1Mf7LFj8yfmtKSh+emt+HA6U1vPBZDi+vz+WtzQXH9gcHCfGRYcwY3pfrpg5h2rA+J6z8d6S6nm0FFZw+JJ5eYV9M21FUUctzq/cz77RBpHXB1CbG+DtLFsbvDekbyf9ePIYfXDCSjJzDlFbVc7ja8Soor+W9bYUsy8xnWEJvrps6hPGDYlm9p4SVOw+RdbAcVRgQE8FP5oxi3uRBBAUJf/twF82q/OACu6owBixZmADSKyyYs9NOfJL/aP14lm8u4KV1B/jtcsdzn0ECpw2J567z00jrF83jK/fww8WZPLd6P7eclcqidblcN3UIg225VGMAGw1lepjswkpyD9dwRmofYnt98UBdc7Py2qaD/OGdbAoraokIDWLl3efRz8NDc43xto6OhrIrC9OjjBoQzagBJ/ZBBAUJ/3N6MnPGD+C51TkMjI2wRGGMC0sWxriIDAvhu+cO93YYxvgcGzprjDHGLUsWxhhj3LJkYYwxxi1LFsYYY9yyZGGMMcYtSxbGGGPcsmRhjDHGLUsWxhhj3AqY6T5E5BCQ06o4Fih3U3ay7fbeJwAlnQi3rbhOtV5H2ta6rKe0zXW7K9vWXhynUqe9fZ39XlrbTq6z38tAblsKcIuqvnHSo1U1YF/AE+7KTrZ9kvcZXR3XqdbrSNtOoT0B1TbX7a5sW0fbd6ptO1n8Hf3ZWds8+70M5LZ19DMC/TZUW5myddnJttt731kd/ayT1etI21qX9ZS2uW53Zds6+nmn2ra2yn31exnIbTtZvUBuW4c+I2BuQ3UnEcnQDszS6I+sbf7J2uaf/KltgX5l4SlPeDsAD7K2+Sdrm3/ym7bZlYUxxhi37MrCGGOMWz06WYjI0yJSLCJbvsSxU0Rks4jsFpG/ioi47LtTRLJFZKuI/KFroz6lGLu8fSJyv4gcFJFNztfFXR95h+LzyM/Ouf/HIqIiktB1EZ9SfJ74uf1aRLKcP7N3RSSp6yPvUHyeaNsfRWSHs33/EZG4ro+8Q/F5om1XO3+PNIuId/s2Ojtsy59fwDnA6cCWL3HsOmA6IMDbwEXO8vOA94Fw53a/AGvf/cCPA/Fn59w3GFiB45mdhEBpGxDjUmcB8FgAtW02EOJ8/xDwUAC1bQwwCvgYSPdGu1pePfrKQlVXAoddy0RkuIi8IyIbROS/IjK69XEiMhDHP7416viJPg/Mc+7+LvCgqtY5z1Hs2Va0z0Pt8wkebNvDwE8Ar3XmeaJtqlrhUrU3Xmqfh9r2rqo2OquuBZI924q2eaht21U1uzvid6dHJ4t2PAHcqapTgB8D/2ijziAgz2U7z1kGMBI4W0Q+E5FPROQMj0Z76jrbPoA7nJf8T4tIvOdCPWWdapuIXA4cVNVMTwf6JXT65yYivxWRXOAG4D4PxnqquuI72eIWHH+Z+4qubJtX2RrcLkQkCpgBLHG5jR3eVtU2ylr+UgsB4oFpwBnAYhEZ5vyLwau6qH3/BH7t3P418Ccc/0C9qrNtE5FI4F4ctzR8Shf93FDVe4F7ReRnwB3AL7s41FPWVW1zfta9QCPwYlfG+GV1Zdt8gSWL4wUBZao62bVQRIKBDc7NZTh+Ybpe6iYD+c73ecCrzuSwTkSaccz/csiTgXdQp9unqkUux/0LeNOTAZ+CzrZtOJAKZDr/YScDG0VkqqoWejh2d7rie+nqJeAtfCBZ0EVtE5GbgEuB833hDzOnrv65eZc3O0x84QUMxaVDClgNXO18L8Ckdo5bj+PqoaVD6mJn+XeAB5zvRwK5OJ9nCZD2DXSp8wNgUaC0rVWd/Xipg9tDP7c0lzp3AksDqG1zgG1Aorfa5OnvJD7Qwe3V/7HefgELgQKgAccVwTdx/HX5DpDp/ALe186x6cAWYA/w95aEAIQBLzj3bQRmBVj7/g1sBrJw/FU0sLva4+m2tarjtWThoZ/bK87yLBzzAA0KoLbtxvFH2Sbny1sjvTzRtiucn1UHFAErvNE2VbUnuI0xxrhno6GMMca4ZcnCGGOMW5YsjDHGuGXJwhhjjFuWLIwxxrhlycIENBGp6ubzPSkiY7vos5qcs8RuEZE33M2mKiJxIvK9rji3Ma3Z0FkT0ESkSlWjuvDzQvSLSes8yjV2EXkO2Kmqvz1J/aHAm6o6vjviMz2LXVmYHkdEEkXkFRFZ73zNdJZPFZHVIvK587+jnOXzRWSJiLwBvCsi54rIxyKy1LmOwosu6w983LLugIhUOSfvyxSRtSLS31k+3Lm9XkQe6ODVzxq+mPAwSkQ+EJGN4lgDYa6zzoPAcOfVyB+dde92nidLRH7Vhf8bTQ9jycL0RH8BHlbVM4ArgSed5TuAc1T1NByzsv7O5ZjpwE2qOsu5fRrwfWAsMAyY2cZ5egNrVXUSsBK41eX8f3Ge3+0cQM65hM7H8cQ8QC1whaqejmP9lD85k9U9wB5Vnayqd4vIbCANmApMBqaIyDnuzmdMW2wiQdMTXQCMdZkJNEZEooFY4DkRScMx62eoyzHvqarrWgXrVDUPQEQ24ZgT6NNW56nni4kWNwAXOt9P54s1NF4C/q+dOHu5fPYG4D1nuQC/c/7ib8ZxxdG/jeNnO1+fO7ejcCSPle2cz5h2WbIwPVEQMF1Vj7oWisjfgI9U9Qrn/f+PXXZXt/qMOpf3TbT9b6lBv+gUbK/OyRxV1ckiEosj6dwO/BXHehSJwBRVbRCR/UBEG8cL8HtVffwUz2vMCew2lOmJ3sWxngMAItIyhXQscND5fr4Hz78Wx+0vgGvdVVbVchxLof5YREJxxFnsTBTnASnOqpVAtMuhK4BbnOsqICKDRKRfF7XB9DCWLEygixSRPJfXD3H84k13dvpuwzGtPMAfgN+LyCog2IMxfR/4oYisAwYC5e4OUNXPccxcei2OxX3SRSQDx1XGDmedUmCVc6jtH1X1XRy3udaIyGZgKccnE2M6zIbOGtPNnKvyHVVVFZFrgetUda6744zxJuuzMKb7TQH+7hzBVIYPLEtrjDt2ZWGMMcYt67MwxhjjliULY4wxblmyMMYY45YlC2OMMW5ZsjDGGOOWJQtjjDFu/T/f0SLJ0J6y1gAAAABJRU5ErkJggg==\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"cnn.unfreeze() ; cnn.lr_find() ; cnn.recorder.plot()"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Total time: 00:13\n",
"epoch train_loss valid_loss accuracy\n",
"1 0.475293 0.405666 0.854037 (00:01)\n",
"2 0.471815 0.400623 0.857143 (00:01)\n",
"3 0.444360 0.483583 0.860248 (00:01)\n",
"4 0.455074 0.437068 0.869565 (00:01)\n",
"5 0.457793 0.810575 0.854037 (00:01)\n",
"6 0.495422 0.867597 0.854037 (00:01)\n",
"7 0.490892 0.682565 0.866460 (00:01)\n",
"8 0.492190 0.413161 0.863354 (00:01)\n",
"9 0.504963 0.637783 0.850932 (00:01)\n",
"10 0.517931 0.550094 0.850932 (00:01)\n",
"\n"
]
}
],
"source": [
"cnn.fit_one_cycle(10, max_lr = 5e-5)"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [],
"source": [
"class stacked_resnet_cores(nn.Module):\n",
" def __init__(self, dummy_databunch, num_images):\n",
" super().__init__()\n",
" self.resnets = [list(create_cnn(dummy_databunch, models.resnet34).model.children())[0] for _ in range(num_images)]\n",
" self.resnets = torch.nn.ModuleList(self.resnets)\n",
" self.pool = AdaptiveConcatPool2d()\n",
" \n",
" def forward(self, x):\n",
" outputs = []\n",
" for k,j in enumerate(self.resnets):\n",
" output = self.resnets[k](x[:,k*3:(k+1)*3,:,:])\n",
" outputs.append(output)\n",
" outputs = [self.pool(output) for output in outputs]\n",
" output = torch.cat(outputs, dim=1).squeeze()\n",
" return output"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [],
"source": [
"class multi_image_classifier(nn.Module):\n",
" def __init__(self, dummy_databunch, num_images, lin_ftrs, nc, ps=0.2):\n",
" super().__init__()\n",
" self.cores = stacked_resnet_cores(dummy_databunch, num_images)\n",
" nf = 1024 * num_images\n",
" lin_ftrs = [nf, 512, nc] if lin_ftrs is None else [nf] + lin_ftrs + [nc]\n",
" ps = listify(ps)\n",
" if len(ps)==1: ps = [ps[0]/2] * (len(lin_ftrs)-2) + ps\n",
" actns = [nn.ReLU(inplace=True)] * (len(lin_ftrs)-2) + [None]\n",
" self.layers = []\n",
" for ni,no,p,actn in zip(lin_ftrs[:-1],lin_ftrs[1:],ps,actns):\n",
" self.layers += bn_drop_lin(ni,no,True,p,actn)\n",
" self.layers = nn.ModuleList(self.layers)\n",
" self.head = nn.Sequential(self.layers)\n",
" \n",
" def forward(self, x):\n",
" return self.head(self.cores(x))\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {},
"outputs": [],
"source": [
"class multi_image_dataset(Dataset):\n",
" def __init__(self, paths, train=False, valid=False):\n",
" self.x = []\n",
" if train:\n",
" for path in paths:\n",
" data = (ImageItemList.from_folder(path) \n",
" .split_by_folder(train='TRAIN', valid='TEST')\n",
" .label_from_folder()\n",
" ).train\n",
" out = torch.cat([data[k][0].data.unsqueeze(-1) for k in range(len(data))], dim=-1)\n",
" self.x.append(out)\n",
" elif valid:\n",
" for path in paths:\n",
" data = (ImageItemList.from_folder(path) \n",
" .split_by_folder(train='TRAIN', valid='TEST')\n",
" .label_from_folder()\n",
" ).valid\n",
" out = torch.cat([data[k][0].data.unsqueeze(-1) for k in range(len(data))], dim=-1)\n",
" self.x.append(out)\n",
" self.x = torch.cat(self.x, dim=0)\n",
" self.y = data.y\n",
" self.length = out.size(-1)\n",
" \n",
" def __len__(self):\n",
" return self.length\n",
" \n",
" \n",
" def __getitem__(self, idx):\n",
" return self.x[:,:,:,idx], torch.Tensor([int(self.y[idx].cat)]).long().squeeze()"
]
},
{
"cell_type": "code",
"execution_count": 109,
"metadata": {},
"outputs": [],
"source": [
"methods = ['GADF','RP','MTF']\n",
"#for method in methods:\n",
"# prep_data(task=task, method=method, image_size=224)\n",
"paths = [Path('TSC/%s/%s'%(task,method)) for method in methods]"
]
},
{
"cell_type": "code",
"execution_count": 110,
"metadata": {},
"outputs": [],
"source": [
"tr_ds = multi_image_dataset(paths, train=True)\n",
"val_ds = multi_image_dataset(paths, valid=True)"
]
},
{
"cell_type": "code",
"execution_count": 111,
"metadata": {},
"outputs": [],
"source": [
"tr_dl = DataLoader(tr_ds, batch_size = 16, shuffle=True)\n",
"val_dl = DataLoader(val_ds, batch_size = 16, shuffle=True)\n",
"md = DataBunch(tr_dl, val_dl)"
]
},
{
"cell_type": "code",
"execution_count": 112,
"metadata": {},
"outputs": [],
"source": [
"crit = nn.CrossEntropyLoss()\n",
"arch = multi_image_classifier_2(dummy_databunch=data, num_images=2, lin_ftrs=None, nc=4, ps=0.2)"
]
},
{
"cell_type": "code",
"execution_count": 117,
"metadata": {},
"outputs": [],
"source": [
"learn = Learner(md, arch, loss_func = crit, metrics=accuracy)"
]
},
{
"cell_type": "code",
"execution_count": 114,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"learn.lr_find() ; learn.recorder.plot()"
]
},
{
"cell_type": "code",
"execution_count": 118,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Total time: 00:11\n",
"epoch train_loss valid_loss accuracy\n",
"1 0.365040 0.265801 0.878882 (00:02)\n",
"2 0.360374 0.226251 0.928571 (00:02)\n",
"3 0.347392 0.239372 0.869565 (00:02)\n",
"4 0.329797 0.171565 0.931677 (00:02)\n",
"5 0.331179 0.175459 0.962733 (00:02)\n",
"\n"
]
}
],
"source": [
"learn.fit_one_cycle(5, max_lr=1e-4)"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"class multi_image_classifier_2(nn.Module):\n",
" def __init__(self, dummy_databunch, num_images, lin_ftrs, nc, ps=0.2):\n",
" super().__init__()\n",
" self.cores = stacked_resnet_cores(dummy_databunch, num_images)\n",
" nf = 1024 * num_images\n",
" self.lin1 = nn.Linear(nf,512)\n",
" self.lin2 = nn.Linear(512,4)\n",
" self.dp1 = nn.Dropout(0.2)\n",
" self.dp2 = nn.Dropout(0.2)\n",
" \n",
" def forward(self,x):\n",
" x = self.cores(x)\n",
" x = self.lin2(self.dp2(self.lin1(self.dp1(x))))\n",
" return x\n",
" \n",
" \n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"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.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.