blob: c86fb751348adb69854a1954cb39440310a4f24d [file] [log] [blame]
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Multilayer Perceptron Using Keras and MADlib\n",
"\n",
"E2E classification example using MADlib calling a Keras MLP.\n",
"\n",
"Deep learning works best on very large datasets, but that is not convenient for a quick introduction to the syntax. So in this workbook we use the well known iris data set from https://archive.ics.uci.edu/ml/datasets/iris to help get you started. It is similar to the example in user docs http://madlib.apache.org/docs/latest/index.html\n",
"\n",
"For more realistic examples with images please refer to the deep learning notebooks at\n",
"https://github.com/apache/madlib-site/tree/asf-site/community-artifacts\n",
"\n",
"## Table of contents\n",
"\n",
"<a href=\"#class\">Classification</a>\n",
"\n",
"* <a href=\"#create_input_data\">1. Create input data</a>\n",
"\n",
"* <a href=\"#pp\">2. Call preprocessor for deep learning</a>\n",
"\n",
"* <a href=\"#load\">3. Define and load model architecture</a>\n",
"\n",
"* <a href=\"#train\">4. Train</a>\n",
"\n",
"* <a href=\"#eval\">5. Evaluate</a>\n",
"\n",
"* <a href=\"#pred\">6. Predict</a>\n",
"\n",
"* <a href=\"#pred_byom\">7. Predict BYOM</a>\n",
"\n",
"<a href=\"#class2\">Classification with Other Parameters</a>\n",
"\n",
"* <a href=\"#val_dataset\">1. Validation dataset</a>\n",
"\n",
"* <a href=\"#pred_prob\">2. Predict probabilities</a>\n",
"\n",
"* <a href=\"#warm_start\">3. Warm start</a>\n",
"\n",
"<a href=\"#transfer_learn\">Transfer learning</a>\n",
"\n",
"* <a href=\"#load2\">1. Define and load model architecture with some layers frozen</a>\n",
"\n",
"* <a href=\"#train2\">2. Train transfer model</a>"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/fmcquillan/anaconda/lib/python2.7/site-packages/IPython/config.py:13: ShimWarning: The `IPython.config` package has been deprecated since IPython 4.0. You should import from traitlets.config instead.\n",
" \"You should import from traitlets.config instead.\", ShimWarning)\n",
"/Users/fmcquillan/anaconda/lib/python2.7/site-packages/IPython/utils/traitlets.py:5: UserWarning: IPython.utils.traitlets has moved to a top-level traitlets package.\n",
" warn(\"IPython.utils.traitlets has moved to a top-level traitlets package.\")\n"
]
}
],
"source": [
"%load_ext sql"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"u'Connected: gpadmin@madlib'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Greenplum Database 5.x on GCP (PM demo machine) - direct external IP access\n",
"#%sql postgresql://gpadmin@34.67.65.96:5432/madlib\n",
"\n",
"# Greenplum Database 5.x on GCP - via tunnel\n",
"%sql postgresql://gpadmin@localhost:8000/madlib\n",
" \n",
"# PostgreSQL local\n",
"#%sql postgresql://fmcquillan@localhost:5432/madlib"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>version</th>\n",
" </tr>\n",
" <tr>\n",
" <td>MADlib version: 1.17-dev, git revision: rel/v1.16-54-gec5614f, cmake configuration time: Wed Dec 18 17:08:05 UTC 2019, build type: release, build system: Linux-3.10.0-1062.4.3.el7.x86_64, C compiler: gcc 4.8.5, C++ compiler: g++ 4.8.5</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(u'MADlib version: 1.17-dev, git revision: rel/v1.16-54-gec5614f, cmake configuration time: Wed Dec 18 17:08:05 UTC 2019, build type: release, build system: Linux-3.10.0-1062.4.3.el7.x86_64, C compiler: gcc 4.8.5, C++ compiler: g++ 4.8.5',)]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql select madlib.version();\n",
"#%sql select version();"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"class\"></a>\n",
"# Classification\n",
"\n",
"<a id=\"create_input_data\"></a>\n",
"# 1. Create input data\n",
"\n",
"Load iris data set."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"Done.\n",
"150 rows affected.\n",
"150 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>id</th>\n",
" <th>attributes</th>\n",
" <th>class_text</th>\n",
" </tr>\n",
" <tr>\n",
" <td>1</td>\n",
" <td>[Decimal('5.1'), Decimal('3.5'), Decimal('1.4'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>2</td>\n",
" <td>[Decimal('4.9'), Decimal('3.0'), Decimal('1.4'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>3</td>\n",
" <td>[Decimal('4.7'), Decimal('3.2'), Decimal('1.3'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>4</td>\n",
" <td>[Decimal('4.6'), Decimal('3.1'), Decimal('1.5'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>5</td>\n",
" <td>[Decimal('5.0'), Decimal('3.6'), Decimal('1.4'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>6</td>\n",
" <td>[Decimal('5.4'), Decimal('3.9'), Decimal('1.7'), Decimal('0.4')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>7</td>\n",
" <td>[Decimal('4.6'), Decimal('3.4'), Decimal('1.4'), Decimal('0.3')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>8</td>\n",
" <td>[Decimal('5.0'), Decimal('3.4'), Decimal('1.5'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>9</td>\n",
" <td>[Decimal('4.4'), Decimal('2.9'), Decimal('1.4'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>10</td>\n",
" <td>[Decimal('4.9'), Decimal('3.1'), Decimal('1.5'), Decimal('0.1')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>11</td>\n",
" <td>[Decimal('5.4'), Decimal('3.7'), Decimal('1.5'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>12</td>\n",
" <td>[Decimal('4.8'), Decimal('3.4'), Decimal('1.6'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>13</td>\n",
" <td>[Decimal('4.8'), Decimal('3.0'), Decimal('1.4'), Decimal('0.1')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>14</td>\n",
" <td>[Decimal('4.3'), Decimal('3.0'), Decimal('1.1'), Decimal('0.1')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>15</td>\n",
" <td>[Decimal('5.8'), Decimal('4.0'), Decimal('1.2'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>16</td>\n",
" <td>[Decimal('5.7'), Decimal('4.4'), Decimal('1.5'), Decimal('0.4')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>17</td>\n",
" <td>[Decimal('5.4'), Decimal('3.9'), Decimal('1.3'), Decimal('0.4')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>18</td>\n",
" <td>[Decimal('5.1'), Decimal('3.5'), Decimal('1.4'), Decimal('0.3')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>19</td>\n",
" <td>[Decimal('5.7'), Decimal('3.8'), Decimal('1.7'), Decimal('0.3')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>20</td>\n",
" <td>[Decimal('5.1'), Decimal('3.8'), Decimal('1.5'), Decimal('0.3')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>21</td>\n",
" <td>[Decimal('5.4'), Decimal('3.4'), Decimal('1.7'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>22</td>\n",
" <td>[Decimal('5.1'), Decimal('3.7'), Decimal('1.5'), Decimal('0.4')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>23</td>\n",
" <td>[Decimal('4.6'), Decimal('3.6'), Decimal('1.0'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>24</td>\n",
" <td>[Decimal('5.1'), Decimal('3.3'), Decimal('1.7'), Decimal('0.5')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>25</td>\n",
" <td>[Decimal('4.8'), Decimal('3.4'), Decimal('1.9'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>26</td>\n",
" <td>[Decimal('5.0'), Decimal('3.0'), Decimal('1.6'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>27</td>\n",
" <td>[Decimal('5.0'), Decimal('3.4'), Decimal('1.6'), Decimal('0.4')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>28</td>\n",
" <td>[Decimal('5.2'), Decimal('3.5'), Decimal('1.5'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>29</td>\n",
" <td>[Decimal('5.2'), Decimal('3.4'), Decimal('1.4'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>30</td>\n",
" <td>[Decimal('4.7'), Decimal('3.2'), Decimal('1.6'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>31</td>\n",
" <td>[Decimal('4.8'), Decimal('3.1'), Decimal('1.6'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>32</td>\n",
" <td>[Decimal('5.4'), Decimal('3.4'), Decimal('1.5'), Decimal('0.4')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>33</td>\n",
" <td>[Decimal('5.2'), Decimal('4.1'), Decimal('1.5'), Decimal('0.1')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>34</td>\n",
" <td>[Decimal('5.5'), Decimal('4.2'), Decimal('1.4'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>35</td>\n",
" <td>[Decimal('4.9'), Decimal('3.1'), Decimal('1.5'), Decimal('0.1')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>36</td>\n",
" <td>[Decimal('5.0'), Decimal('3.2'), Decimal('1.2'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>37</td>\n",
" <td>[Decimal('5.5'), Decimal('3.5'), Decimal('1.3'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>38</td>\n",
" <td>[Decimal('4.9'), Decimal('3.1'), Decimal('1.5'), Decimal('0.1')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>39</td>\n",
" <td>[Decimal('4.4'), Decimal('3.0'), Decimal('1.3'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>40</td>\n",
" <td>[Decimal('5.1'), Decimal('3.4'), Decimal('1.5'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>41</td>\n",
" <td>[Decimal('5.0'), Decimal('3.5'), Decimal('1.3'), Decimal('0.3')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>42</td>\n",
" <td>[Decimal('4.5'), Decimal('2.3'), Decimal('1.3'), Decimal('0.3')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>43</td>\n",
" <td>[Decimal('4.4'), Decimal('3.2'), Decimal('1.3'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>44</td>\n",
" <td>[Decimal('5.0'), Decimal('3.5'), Decimal('1.6'), Decimal('0.6')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>45</td>\n",
" <td>[Decimal('5.1'), Decimal('3.8'), Decimal('1.9'), Decimal('0.4')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>46</td>\n",
" <td>[Decimal('4.8'), Decimal('3.0'), Decimal('1.4'), Decimal('0.3')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>47</td>\n",
" <td>[Decimal('5.1'), Decimal('3.8'), Decimal('1.6'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>48</td>\n",
" <td>[Decimal('4.6'), Decimal('3.2'), Decimal('1.4'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>49</td>\n",
" <td>[Decimal('5.3'), Decimal('3.7'), Decimal('1.5'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>50</td>\n",
" <td>[Decimal('5.0'), Decimal('3.3'), Decimal('1.4'), Decimal('0.2')]</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>51</td>\n",
" <td>[Decimal('7.0'), Decimal('3.2'), Decimal('4.7'), Decimal('1.4')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>52</td>\n",
" <td>[Decimal('6.4'), Decimal('3.2'), Decimal('4.5'), Decimal('1.5')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>53</td>\n",
" <td>[Decimal('6.9'), Decimal('3.1'), Decimal('4.9'), Decimal('1.5')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54</td>\n",
" <td>[Decimal('5.5'), Decimal('2.3'), Decimal('4.0'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>55</td>\n",
" <td>[Decimal('6.5'), Decimal('2.8'), Decimal('4.6'), Decimal('1.5')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>56</td>\n",
" <td>[Decimal('5.7'), Decimal('2.8'), Decimal('4.5'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>57</td>\n",
" <td>[Decimal('6.3'), Decimal('3.3'), Decimal('4.7'), Decimal('1.6')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>58</td>\n",
" <td>[Decimal('4.9'), Decimal('2.4'), Decimal('3.3'), Decimal('1.0')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>59</td>\n",
" <td>[Decimal('6.6'), Decimal('2.9'), Decimal('4.6'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>60</td>\n",
" <td>[Decimal('5.2'), Decimal('2.7'), Decimal('3.9'), Decimal('1.4')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>61</td>\n",
" <td>[Decimal('5.0'), Decimal('2.0'), Decimal('3.5'), Decimal('1.0')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>62</td>\n",
" <td>[Decimal('5.9'), Decimal('3.0'), Decimal('4.2'), Decimal('1.5')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>63</td>\n",
" <td>[Decimal('6.0'), Decimal('2.2'), Decimal('4.0'), Decimal('1.0')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>64</td>\n",
" <td>[Decimal('6.1'), Decimal('2.9'), Decimal('4.7'), Decimal('1.4')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>65</td>\n",
" <td>[Decimal('5.6'), Decimal('2.9'), Decimal('3.6'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>66</td>\n",
" <td>[Decimal('6.7'), Decimal('3.1'), Decimal('4.4'), Decimal('1.4')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>67</td>\n",
" <td>[Decimal('5.6'), Decimal('3.0'), Decimal('4.5'), Decimal('1.5')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>68</td>\n",
" <td>[Decimal('5.8'), Decimal('2.7'), Decimal('4.1'), Decimal('1.0')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>69</td>\n",
" <td>[Decimal('6.2'), Decimal('2.2'), Decimal('4.5'), Decimal('1.5')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>70</td>\n",
" <td>[Decimal('5.6'), Decimal('2.5'), Decimal('3.9'), Decimal('1.1')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>71</td>\n",
" <td>[Decimal('5.9'), Decimal('3.2'), Decimal('4.8'), Decimal('1.8')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>72</td>\n",
" <td>[Decimal('6.1'), Decimal('2.8'), Decimal('4.0'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>73</td>\n",
" <td>[Decimal('6.3'), Decimal('2.5'), Decimal('4.9'), Decimal('1.5')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>74</td>\n",
" <td>[Decimal('6.1'), Decimal('2.8'), Decimal('4.7'), Decimal('1.2')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>75</td>\n",
" <td>[Decimal('6.4'), Decimal('2.9'), Decimal('4.3'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>76</td>\n",
" <td>[Decimal('6.6'), Decimal('3.0'), Decimal('4.4'), Decimal('1.4')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>77</td>\n",
" <td>[Decimal('6.8'), Decimal('2.8'), Decimal('4.8'), Decimal('1.4')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>78</td>\n",
" <td>[Decimal('6.7'), Decimal('3.0'), Decimal('5.0'), Decimal('1.7')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>79</td>\n",
" <td>[Decimal('6.0'), Decimal('2.9'), Decimal('4.5'), Decimal('1.5')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>80</td>\n",
" <td>[Decimal('5.7'), Decimal('2.6'), Decimal('3.5'), Decimal('1.0')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>81</td>\n",
" <td>[Decimal('5.5'), Decimal('2.4'), Decimal('3.8'), Decimal('1.1')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>82</td>\n",
" <td>[Decimal('5.5'), Decimal('2.4'), Decimal('3.7'), Decimal('1.0')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>83</td>\n",
" <td>[Decimal('5.8'), Decimal('2.7'), Decimal('3.9'), Decimal('1.2')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>84</td>\n",
" <td>[Decimal('6.0'), Decimal('2.7'), Decimal('5.1'), Decimal('1.6')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>85</td>\n",
" <td>[Decimal('5.4'), Decimal('3.0'), Decimal('4.5'), Decimal('1.5')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>86</td>\n",
" <td>[Decimal('6.0'), Decimal('3.4'), Decimal('4.5'), Decimal('1.6')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>87</td>\n",
" <td>[Decimal('6.7'), Decimal('3.1'), Decimal('4.7'), Decimal('1.5')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>88</td>\n",
" <td>[Decimal('6.3'), Decimal('2.3'), Decimal('4.4'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>89</td>\n",
" <td>[Decimal('5.6'), Decimal('3.0'), Decimal('4.1'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>90</td>\n",
" <td>[Decimal('5.5'), Decimal('2.5'), Decimal('4.0'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>91</td>\n",
" <td>[Decimal('5.5'), Decimal('2.6'), Decimal('4.4'), Decimal('1.2')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>92</td>\n",
" <td>[Decimal('6.1'), Decimal('3.0'), Decimal('4.6'), Decimal('1.4')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>93</td>\n",
" <td>[Decimal('5.8'), Decimal('2.6'), Decimal('4.0'), Decimal('1.2')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>94</td>\n",
" <td>[Decimal('5.0'), Decimal('2.3'), Decimal('3.3'), Decimal('1.0')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>95</td>\n",
" <td>[Decimal('5.6'), Decimal('2.7'), Decimal('4.2'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>96</td>\n",
" <td>[Decimal('5.7'), Decimal('3.0'), Decimal('4.2'), Decimal('1.2')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>97</td>\n",
" <td>[Decimal('5.7'), Decimal('2.9'), Decimal('4.2'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>98</td>\n",
" <td>[Decimal('6.2'), Decimal('2.9'), Decimal('4.3'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>99</td>\n",
" <td>[Decimal('5.1'), Decimal('2.5'), Decimal('3.0'), Decimal('1.1')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>100</td>\n",
" <td>[Decimal('5.7'), Decimal('2.8'), Decimal('4.1'), Decimal('1.3')]</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>101</td>\n",
" <td>[Decimal('6.3'), Decimal('3.3'), Decimal('6.0'), Decimal('2.5')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>102</td>\n",
" <td>[Decimal('5.8'), Decimal('2.7'), Decimal('5.1'), Decimal('1.9')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>103</td>\n",
" <td>[Decimal('7.1'), Decimal('3.0'), Decimal('5.9'), Decimal('2.1')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>104</td>\n",
" <td>[Decimal('6.3'), Decimal('2.9'), Decimal('5.6'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>105</td>\n",
" <td>[Decimal('6.5'), Decimal('3.0'), Decimal('5.8'), Decimal('2.2')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>106</td>\n",
" <td>[Decimal('7.6'), Decimal('3.0'), Decimal('6.6'), Decimal('2.1')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>107</td>\n",
" <td>[Decimal('4.9'), Decimal('2.5'), Decimal('4.5'), Decimal('1.7')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>108</td>\n",
" <td>[Decimal('7.3'), Decimal('2.9'), Decimal('6.3'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>109</td>\n",
" <td>[Decimal('6.7'), Decimal('2.5'), Decimal('5.8'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>110</td>\n",
" <td>[Decimal('7.2'), Decimal('3.6'), Decimal('6.1'), Decimal('2.5')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>111</td>\n",
" <td>[Decimal('6.5'), Decimal('3.2'), Decimal('5.1'), Decimal('2.0')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>112</td>\n",
" <td>[Decimal('6.4'), Decimal('2.7'), Decimal('5.3'), Decimal('1.9')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>113</td>\n",
" <td>[Decimal('6.8'), Decimal('3.0'), Decimal('5.5'), Decimal('2.1')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>114</td>\n",
" <td>[Decimal('5.7'), Decimal('2.5'), Decimal('5.0'), Decimal('2.0')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>115</td>\n",
" <td>[Decimal('5.8'), Decimal('2.8'), Decimal('5.1'), Decimal('2.4')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>116</td>\n",
" <td>[Decimal('6.4'), Decimal('3.2'), Decimal('5.3'), Decimal('2.3')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>117</td>\n",
" <td>[Decimal('6.5'), Decimal('3.0'), Decimal('5.5'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>118</td>\n",
" <td>[Decimal('7.7'), Decimal('3.8'), Decimal('6.7'), Decimal('2.2')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>119</td>\n",
" <td>[Decimal('7.7'), Decimal('2.6'), Decimal('6.9'), Decimal('2.3')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>120</td>\n",
" <td>[Decimal('6.0'), Decimal('2.2'), Decimal('5.0'), Decimal('1.5')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>121</td>\n",
" <td>[Decimal('6.9'), Decimal('3.2'), Decimal('5.7'), Decimal('2.3')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>122</td>\n",
" <td>[Decimal('5.6'), Decimal('2.8'), Decimal('4.9'), Decimal('2.0')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>123</td>\n",
" <td>[Decimal('7.7'), Decimal('2.8'), Decimal('6.7'), Decimal('2.0')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>124</td>\n",
" <td>[Decimal('6.3'), Decimal('2.7'), Decimal('4.9'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>125</td>\n",
" <td>[Decimal('6.7'), Decimal('3.3'), Decimal('5.7'), Decimal('2.1')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>126</td>\n",
" <td>[Decimal('7.2'), Decimal('3.2'), Decimal('6.0'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>127</td>\n",
" <td>[Decimal('6.2'), Decimal('2.8'), Decimal('4.8'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>128</td>\n",
" <td>[Decimal('6.1'), Decimal('3.0'), Decimal('4.9'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>129</td>\n",
" <td>[Decimal('6.4'), Decimal('2.8'), Decimal('5.6'), Decimal('2.1')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>130</td>\n",
" <td>[Decimal('7.2'), Decimal('3.0'), Decimal('5.8'), Decimal('1.6')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>131</td>\n",
" <td>[Decimal('7.4'), Decimal('2.8'), Decimal('6.1'), Decimal('1.9')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>132</td>\n",
" <td>[Decimal('7.9'), Decimal('3.8'), Decimal('6.4'), Decimal('2.0')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>133</td>\n",
" <td>[Decimal('6.4'), Decimal('2.8'), Decimal('5.6'), Decimal('2.2')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>134</td>\n",
" <td>[Decimal('6.3'), Decimal('2.8'), Decimal('5.1'), Decimal('1.5')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>135</td>\n",
" <td>[Decimal('6.1'), Decimal('2.6'), Decimal('5.6'), Decimal('1.4')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>136</td>\n",
" <td>[Decimal('7.7'), Decimal('3.0'), Decimal('6.1'), Decimal('2.3')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>137</td>\n",
" <td>[Decimal('6.3'), Decimal('3.4'), Decimal('5.6'), Decimal('2.4')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>138</td>\n",
" <td>[Decimal('6.4'), Decimal('3.1'), Decimal('5.5'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>139</td>\n",
" <td>[Decimal('6.0'), Decimal('3.0'), Decimal('4.8'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>140</td>\n",
" <td>[Decimal('6.9'), Decimal('3.1'), Decimal('5.4'), Decimal('2.1')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>141</td>\n",
" <td>[Decimal('6.7'), Decimal('3.1'), Decimal('5.6'), Decimal('2.4')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>142</td>\n",
" <td>[Decimal('6.9'), Decimal('3.1'), Decimal('5.1'), Decimal('2.3')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>143</td>\n",
" <td>[Decimal('5.8'), Decimal('2.7'), Decimal('5.1'), Decimal('1.9')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>144</td>\n",
" <td>[Decimal('6.8'), Decimal('3.2'), Decimal('5.9'), Decimal('2.3')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>145</td>\n",
" <td>[Decimal('6.7'), Decimal('3.3'), Decimal('5.7'), Decimal('2.5')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>146</td>\n",
" <td>[Decimal('6.7'), Decimal('3.0'), Decimal('5.2'), Decimal('2.3')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>147</td>\n",
" <td>[Decimal('6.3'), Decimal('2.5'), Decimal('5.0'), Decimal('1.9')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>148</td>\n",
" <td>[Decimal('6.5'), Decimal('3.0'), Decimal('5.2'), Decimal('2.0')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>149</td>\n",
" <td>[Decimal('6.2'), Decimal('3.4'), Decimal('5.4'), Decimal('2.3')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>150</td>\n",
" <td>[Decimal('5.9'), Decimal('3.0'), Decimal('5.1'), Decimal('1.8')]</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(1, [Decimal('5.1'), Decimal('3.5'), Decimal('1.4'), Decimal('0.2')], u'Iris-setosa'),\n",
" (2, [Decimal('4.9'), Decimal('3.0'), Decimal('1.4'), Decimal('0.2')], u'Iris-setosa'),\n",
" (3, [Decimal('4.7'), Decimal('3.2'), Decimal('1.3'), Decimal('0.2')], u'Iris-setosa'),\n",
" (4, [Decimal('4.6'), Decimal('3.1'), Decimal('1.5'), Decimal('0.2')], u'Iris-setosa'),\n",
" (5, [Decimal('5.0'), Decimal('3.6'), Decimal('1.4'), Decimal('0.2')], u'Iris-setosa'),\n",
" (6, [Decimal('5.4'), Decimal('3.9'), Decimal('1.7'), Decimal('0.4')], u'Iris-setosa'),\n",
" (7, [Decimal('4.6'), Decimal('3.4'), Decimal('1.4'), Decimal('0.3')], u'Iris-setosa'),\n",
" (8, [Decimal('5.0'), Decimal('3.4'), Decimal('1.5'), Decimal('0.2')], u'Iris-setosa'),\n",
" (9, [Decimal('4.4'), Decimal('2.9'), Decimal('1.4'), Decimal('0.2')], u'Iris-setosa'),\n",
" (10, [Decimal('4.9'), Decimal('3.1'), Decimal('1.5'), Decimal('0.1')], u'Iris-setosa'),\n",
" (11, [Decimal('5.4'), Decimal('3.7'), Decimal('1.5'), Decimal('0.2')], u'Iris-setosa'),\n",
" (12, [Decimal('4.8'), Decimal('3.4'), Decimal('1.6'), Decimal('0.2')], u'Iris-setosa'),\n",
" (13, [Decimal('4.8'), Decimal('3.0'), Decimal('1.4'), Decimal('0.1')], u'Iris-setosa'),\n",
" (14, [Decimal('4.3'), Decimal('3.0'), Decimal('1.1'), Decimal('0.1')], u'Iris-setosa'),\n",
" (15, [Decimal('5.8'), Decimal('4.0'), Decimal('1.2'), Decimal('0.2')], u'Iris-setosa'),\n",
" (16, [Decimal('5.7'), Decimal('4.4'), Decimal('1.5'), Decimal('0.4')], u'Iris-setosa'),\n",
" (17, [Decimal('5.4'), Decimal('3.9'), Decimal('1.3'), Decimal('0.4')], u'Iris-setosa'),\n",
" (18, [Decimal('5.1'), Decimal('3.5'), Decimal('1.4'), Decimal('0.3')], u'Iris-setosa'),\n",
" (19, [Decimal('5.7'), Decimal('3.8'), Decimal('1.7'), Decimal('0.3')], u'Iris-setosa'),\n",
" (20, [Decimal('5.1'), Decimal('3.8'), Decimal('1.5'), Decimal('0.3')], u'Iris-setosa'),\n",
" (21, [Decimal('5.4'), Decimal('3.4'), Decimal('1.7'), Decimal('0.2')], u'Iris-setosa'),\n",
" (22, [Decimal('5.1'), Decimal('3.7'), Decimal('1.5'), Decimal('0.4')], u'Iris-setosa'),\n",
" (23, [Decimal('4.6'), Decimal('3.6'), Decimal('1.0'), Decimal('0.2')], u'Iris-setosa'),\n",
" (24, [Decimal('5.1'), Decimal('3.3'), Decimal('1.7'), Decimal('0.5')], u'Iris-setosa'),\n",
" (25, [Decimal('4.8'), Decimal('3.4'), Decimal('1.9'), Decimal('0.2')], u'Iris-setosa'),\n",
" (26, [Decimal('5.0'), Decimal('3.0'), Decimal('1.6'), Decimal('0.2')], u'Iris-setosa'),\n",
" (27, [Decimal('5.0'), Decimal('3.4'), Decimal('1.6'), Decimal('0.4')], u'Iris-setosa'),\n",
" (28, [Decimal('5.2'), Decimal('3.5'), Decimal('1.5'), Decimal('0.2')], u'Iris-setosa'),\n",
" (29, [Decimal('5.2'), Decimal('3.4'), Decimal('1.4'), Decimal('0.2')], u'Iris-setosa'),\n",
" (30, [Decimal('4.7'), Decimal('3.2'), Decimal('1.6'), Decimal('0.2')], u'Iris-setosa'),\n",
" (31, [Decimal('4.8'), Decimal('3.1'), Decimal('1.6'), Decimal('0.2')], u'Iris-setosa'),\n",
" (32, [Decimal('5.4'), Decimal('3.4'), Decimal('1.5'), Decimal('0.4')], u'Iris-setosa'),\n",
" (33, [Decimal('5.2'), Decimal('4.1'), Decimal('1.5'), Decimal('0.1')], u'Iris-setosa'),\n",
" (34, [Decimal('5.5'), Decimal('4.2'), Decimal('1.4'), Decimal('0.2')], u'Iris-setosa'),\n",
" (35, [Decimal('4.9'), Decimal('3.1'), Decimal('1.5'), Decimal('0.1')], u'Iris-setosa'),\n",
" (36, [Decimal('5.0'), Decimal('3.2'), Decimal('1.2'), Decimal('0.2')], u'Iris-setosa'),\n",
" (37, [Decimal('5.5'), Decimal('3.5'), Decimal('1.3'), Decimal('0.2')], u'Iris-setosa'),\n",
" (38, [Decimal('4.9'), Decimal('3.1'), Decimal('1.5'), Decimal('0.1')], u'Iris-setosa'),\n",
" (39, [Decimal('4.4'), Decimal('3.0'), Decimal('1.3'), Decimal('0.2')], u'Iris-setosa'),\n",
" (40, [Decimal('5.1'), Decimal('3.4'), Decimal('1.5'), Decimal('0.2')], u'Iris-setosa'),\n",
" (41, [Decimal('5.0'), Decimal('3.5'), Decimal('1.3'), Decimal('0.3')], u'Iris-setosa'),\n",
" (42, [Decimal('4.5'), Decimal('2.3'), Decimal('1.3'), Decimal('0.3')], u'Iris-setosa'),\n",
" (43, [Decimal('4.4'), Decimal('3.2'), Decimal('1.3'), Decimal('0.2')], u'Iris-setosa'),\n",
" (44, [Decimal('5.0'), Decimal('3.5'), Decimal('1.6'), Decimal('0.6')], u'Iris-setosa'),\n",
" (45, [Decimal('5.1'), Decimal('3.8'), Decimal('1.9'), Decimal('0.4')], u'Iris-setosa'),\n",
" (46, [Decimal('4.8'), Decimal('3.0'), Decimal('1.4'), Decimal('0.3')], u'Iris-setosa'),\n",
" (47, [Decimal('5.1'), Decimal('3.8'), Decimal('1.6'), Decimal('0.2')], u'Iris-setosa'),\n",
" (48, [Decimal('4.6'), Decimal('3.2'), Decimal('1.4'), Decimal('0.2')], u'Iris-setosa'),\n",
" (49, [Decimal('5.3'), Decimal('3.7'), Decimal('1.5'), Decimal('0.2')], u'Iris-setosa'),\n",
" (50, [Decimal('5.0'), Decimal('3.3'), Decimal('1.4'), Decimal('0.2')], u'Iris-setosa'),\n",
" (51, [Decimal('7.0'), Decimal('3.2'), Decimal('4.7'), Decimal('1.4')], u'Iris-versicolor'),\n",
" (52, [Decimal('6.4'), Decimal('3.2'), Decimal('4.5'), Decimal('1.5')], u'Iris-versicolor'),\n",
" (53, [Decimal('6.9'), Decimal('3.1'), Decimal('4.9'), Decimal('1.5')], u'Iris-versicolor'),\n",
" (54, [Decimal('5.5'), Decimal('2.3'), Decimal('4.0'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (55, [Decimal('6.5'), Decimal('2.8'), Decimal('4.6'), Decimal('1.5')], u'Iris-versicolor'),\n",
" (56, [Decimal('5.7'), Decimal('2.8'), Decimal('4.5'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (57, [Decimal('6.3'), Decimal('3.3'), Decimal('4.7'), Decimal('1.6')], u'Iris-versicolor'),\n",
" (58, [Decimal('4.9'), Decimal('2.4'), Decimal('3.3'), Decimal('1.0')], u'Iris-versicolor'),\n",
" (59, [Decimal('6.6'), Decimal('2.9'), Decimal('4.6'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (60, [Decimal('5.2'), Decimal('2.7'), Decimal('3.9'), Decimal('1.4')], u'Iris-versicolor'),\n",
" (61, [Decimal('5.0'), Decimal('2.0'), Decimal('3.5'), Decimal('1.0')], u'Iris-versicolor'),\n",
" (62, [Decimal('5.9'), Decimal('3.0'), Decimal('4.2'), Decimal('1.5')], u'Iris-versicolor'),\n",
" (63, [Decimal('6.0'), Decimal('2.2'), Decimal('4.0'), Decimal('1.0')], u'Iris-versicolor'),\n",
" (64, [Decimal('6.1'), Decimal('2.9'), Decimal('4.7'), Decimal('1.4')], u'Iris-versicolor'),\n",
" (65, [Decimal('5.6'), Decimal('2.9'), Decimal('3.6'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (66, [Decimal('6.7'), Decimal('3.1'), Decimal('4.4'), Decimal('1.4')], u'Iris-versicolor'),\n",
" (67, [Decimal('5.6'), Decimal('3.0'), Decimal('4.5'), Decimal('1.5')], u'Iris-versicolor'),\n",
" (68, [Decimal('5.8'), Decimal('2.7'), Decimal('4.1'), Decimal('1.0')], u'Iris-versicolor'),\n",
" (69, [Decimal('6.2'), Decimal('2.2'), Decimal('4.5'), Decimal('1.5')], u'Iris-versicolor'),\n",
" (70, [Decimal('5.6'), Decimal('2.5'), Decimal('3.9'), Decimal('1.1')], u'Iris-versicolor'),\n",
" (71, [Decimal('5.9'), Decimal('3.2'), Decimal('4.8'), Decimal('1.8')], u'Iris-versicolor'),\n",
" (72, [Decimal('6.1'), Decimal('2.8'), Decimal('4.0'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (73, [Decimal('6.3'), Decimal('2.5'), Decimal('4.9'), Decimal('1.5')], u'Iris-versicolor'),\n",
" (74, [Decimal('6.1'), Decimal('2.8'), Decimal('4.7'), Decimal('1.2')], u'Iris-versicolor'),\n",
" (75, [Decimal('6.4'), Decimal('2.9'), Decimal('4.3'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (76, [Decimal('6.6'), Decimal('3.0'), Decimal('4.4'), Decimal('1.4')], u'Iris-versicolor'),\n",
" (77, [Decimal('6.8'), Decimal('2.8'), Decimal('4.8'), Decimal('1.4')], u'Iris-versicolor'),\n",
" (78, [Decimal('6.7'), Decimal('3.0'), Decimal('5.0'), Decimal('1.7')], u'Iris-versicolor'),\n",
" (79, [Decimal('6.0'), Decimal('2.9'), Decimal('4.5'), Decimal('1.5')], u'Iris-versicolor'),\n",
" (80, [Decimal('5.7'), Decimal('2.6'), Decimal('3.5'), Decimal('1.0')], u'Iris-versicolor'),\n",
" (81, [Decimal('5.5'), Decimal('2.4'), Decimal('3.8'), Decimal('1.1')], u'Iris-versicolor'),\n",
" (82, [Decimal('5.5'), Decimal('2.4'), Decimal('3.7'), Decimal('1.0')], u'Iris-versicolor'),\n",
" (83, [Decimal('5.8'), Decimal('2.7'), Decimal('3.9'), Decimal('1.2')], u'Iris-versicolor'),\n",
" (84, [Decimal('6.0'), Decimal('2.7'), Decimal('5.1'), Decimal('1.6')], u'Iris-versicolor'),\n",
" (85, [Decimal('5.4'), Decimal('3.0'), Decimal('4.5'), Decimal('1.5')], u'Iris-versicolor'),\n",
" (86, [Decimal('6.0'), Decimal('3.4'), Decimal('4.5'), Decimal('1.6')], u'Iris-versicolor'),\n",
" (87, [Decimal('6.7'), Decimal('3.1'), Decimal('4.7'), Decimal('1.5')], u'Iris-versicolor'),\n",
" (88, [Decimal('6.3'), Decimal('2.3'), Decimal('4.4'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (89, [Decimal('5.6'), Decimal('3.0'), Decimal('4.1'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (90, [Decimal('5.5'), Decimal('2.5'), Decimal('4.0'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (91, [Decimal('5.5'), Decimal('2.6'), Decimal('4.4'), Decimal('1.2')], u'Iris-versicolor'),\n",
" (92, [Decimal('6.1'), Decimal('3.0'), Decimal('4.6'), Decimal('1.4')], u'Iris-versicolor'),\n",
" (93, [Decimal('5.8'), Decimal('2.6'), Decimal('4.0'), Decimal('1.2')], u'Iris-versicolor'),\n",
" (94, [Decimal('5.0'), Decimal('2.3'), Decimal('3.3'), Decimal('1.0')], u'Iris-versicolor'),\n",
" (95, [Decimal('5.6'), Decimal('2.7'), Decimal('4.2'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (96, [Decimal('5.7'), Decimal('3.0'), Decimal('4.2'), Decimal('1.2')], u'Iris-versicolor'),\n",
" (97, [Decimal('5.7'), Decimal('2.9'), Decimal('4.2'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (98, [Decimal('6.2'), Decimal('2.9'), Decimal('4.3'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (99, [Decimal('5.1'), Decimal('2.5'), Decimal('3.0'), Decimal('1.1')], u'Iris-versicolor'),\n",
" (100, [Decimal('5.7'), Decimal('2.8'), Decimal('4.1'), Decimal('1.3')], u'Iris-versicolor'),\n",
" (101, [Decimal('6.3'), Decimal('3.3'), Decimal('6.0'), Decimal('2.5')], u'Iris-virginica'),\n",
" (102, [Decimal('5.8'), Decimal('2.7'), Decimal('5.1'), Decimal('1.9')], u'Iris-virginica'),\n",
" (103, [Decimal('7.1'), Decimal('3.0'), Decimal('5.9'), Decimal('2.1')], u'Iris-virginica'),\n",
" (104, [Decimal('6.3'), Decimal('2.9'), Decimal('5.6'), Decimal('1.8')], u'Iris-virginica'),\n",
" (105, [Decimal('6.5'), Decimal('3.0'), Decimal('5.8'), Decimal('2.2')], u'Iris-virginica'),\n",
" (106, [Decimal('7.6'), Decimal('3.0'), Decimal('6.6'), Decimal('2.1')], u'Iris-virginica'),\n",
" (107, [Decimal('4.9'), Decimal('2.5'), Decimal('4.5'), Decimal('1.7')], u'Iris-virginica'),\n",
" (108, [Decimal('7.3'), Decimal('2.9'), Decimal('6.3'), Decimal('1.8')], u'Iris-virginica'),\n",
" (109, [Decimal('6.7'), Decimal('2.5'), Decimal('5.8'), Decimal('1.8')], u'Iris-virginica'),\n",
" (110, [Decimal('7.2'), Decimal('3.6'), Decimal('6.1'), Decimal('2.5')], u'Iris-virginica'),\n",
" (111, [Decimal('6.5'), Decimal('3.2'), Decimal('5.1'), Decimal('2.0')], u'Iris-virginica'),\n",
" (112, [Decimal('6.4'), Decimal('2.7'), Decimal('5.3'), Decimal('1.9')], u'Iris-virginica'),\n",
" (113, [Decimal('6.8'), Decimal('3.0'), Decimal('5.5'), Decimal('2.1')], u'Iris-virginica'),\n",
" (114, [Decimal('5.7'), Decimal('2.5'), Decimal('5.0'), Decimal('2.0')], u'Iris-virginica'),\n",
" (115, [Decimal('5.8'), Decimal('2.8'), Decimal('5.1'), Decimal('2.4')], u'Iris-virginica'),\n",
" (116, [Decimal('6.4'), Decimal('3.2'), Decimal('5.3'), Decimal('2.3')], u'Iris-virginica'),\n",
" (117, [Decimal('6.5'), Decimal('3.0'), Decimal('5.5'), Decimal('1.8')], u'Iris-virginica'),\n",
" (118, [Decimal('7.7'), Decimal('3.8'), Decimal('6.7'), Decimal('2.2')], u'Iris-virginica'),\n",
" (119, [Decimal('7.7'), Decimal('2.6'), Decimal('6.9'), Decimal('2.3')], u'Iris-virginica'),\n",
" (120, [Decimal('6.0'), Decimal('2.2'), Decimal('5.0'), Decimal('1.5')], u'Iris-virginica'),\n",
" (121, [Decimal('6.9'), Decimal('3.2'), Decimal('5.7'), Decimal('2.3')], u'Iris-virginica'),\n",
" (122, [Decimal('5.6'), Decimal('2.8'), Decimal('4.9'), Decimal('2.0')], u'Iris-virginica'),\n",
" (123, [Decimal('7.7'), Decimal('2.8'), Decimal('6.7'), Decimal('2.0')], u'Iris-virginica'),\n",
" (124, [Decimal('6.3'), Decimal('2.7'), Decimal('4.9'), Decimal('1.8')], u'Iris-virginica'),\n",
" (125, [Decimal('6.7'), Decimal('3.3'), Decimal('5.7'), Decimal('2.1')], u'Iris-virginica'),\n",
" (126, [Decimal('7.2'), Decimal('3.2'), Decimal('6.0'), Decimal('1.8')], u'Iris-virginica'),\n",
" (127, [Decimal('6.2'), Decimal('2.8'), Decimal('4.8'), Decimal('1.8')], u'Iris-virginica'),\n",
" (128, [Decimal('6.1'), Decimal('3.0'), Decimal('4.9'), Decimal('1.8')], u'Iris-virginica'),\n",
" (129, [Decimal('6.4'), Decimal('2.8'), Decimal('5.6'), Decimal('2.1')], u'Iris-virginica'),\n",
" (130, [Decimal('7.2'), Decimal('3.0'), Decimal('5.8'), Decimal('1.6')], u'Iris-virginica'),\n",
" (131, [Decimal('7.4'), Decimal('2.8'), Decimal('6.1'), Decimal('1.9')], u'Iris-virginica'),\n",
" (132, [Decimal('7.9'), Decimal('3.8'), Decimal('6.4'), Decimal('2.0')], u'Iris-virginica'),\n",
" (133, [Decimal('6.4'), Decimal('2.8'), Decimal('5.6'), Decimal('2.2')], u'Iris-virginica'),\n",
" (134, [Decimal('6.3'), Decimal('2.8'), Decimal('5.1'), Decimal('1.5')], u'Iris-virginica'),\n",
" (135, [Decimal('6.1'), Decimal('2.6'), Decimal('5.6'), Decimal('1.4')], u'Iris-virginica'),\n",
" (136, [Decimal('7.7'), Decimal('3.0'), Decimal('6.1'), Decimal('2.3')], u'Iris-virginica'),\n",
" (137, [Decimal('6.3'), Decimal('3.4'), Decimal('5.6'), Decimal('2.4')], u'Iris-virginica'),\n",
" (138, [Decimal('6.4'), Decimal('3.1'), Decimal('5.5'), Decimal('1.8')], u'Iris-virginica'),\n",
" (139, [Decimal('6.0'), Decimal('3.0'), Decimal('4.8'), Decimal('1.8')], u'Iris-virginica'),\n",
" (140, [Decimal('6.9'), Decimal('3.1'), Decimal('5.4'), Decimal('2.1')], u'Iris-virginica'),\n",
" (141, [Decimal('6.7'), Decimal('3.1'), Decimal('5.6'), Decimal('2.4')], u'Iris-virginica'),\n",
" (142, [Decimal('6.9'), Decimal('3.1'), Decimal('5.1'), Decimal('2.3')], u'Iris-virginica'),\n",
" (143, [Decimal('5.8'), Decimal('2.7'), Decimal('5.1'), Decimal('1.9')], u'Iris-virginica'),\n",
" (144, [Decimal('6.8'), Decimal('3.2'), Decimal('5.9'), Decimal('2.3')], u'Iris-virginica'),\n",
" (145, [Decimal('6.7'), Decimal('3.3'), Decimal('5.7'), Decimal('2.5')], u'Iris-virginica'),\n",
" (146, [Decimal('6.7'), Decimal('3.0'), Decimal('5.2'), Decimal('2.3')], u'Iris-virginica'),\n",
" (147, [Decimal('6.3'), Decimal('2.5'), Decimal('5.0'), Decimal('1.9')], u'Iris-virginica'),\n",
" (148, [Decimal('6.5'), Decimal('3.0'), Decimal('5.2'), Decimal('2.0')], u'Iris-virginica'),\n",
" (149, [Decimal('6.2'), Decimal('3.4'), Decimal('5.4'), Decimal('2.3')], u'Iris-virginica'),\n",
" (150, [Decimal('5.9'), Decimal('3.0'), Decimal('5.1'), Decimal('1.8')], u'Iris-virginica')]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql \n",
"DROP TABLE IF EXISTS iris_data;\n",
"\n",
"CREATE TABLE iris_data(\n",
" id serial,\n",
" attributes numeric[],\n",
" class_text varchar\n",
");\n",
"\n",
"INSERT INTO iris_data(id, attributes, class_text) VALUES\n",
"(1,ARRAY[5.1,3.5,1.4,0.2],'Iris-setosa'),\n",
"(2,ARRAY[4.9,3.0,1.4,0.2],'Iris-setosa'),\n",
"(3,ARRAY[4.7,3.2,1.3,0.2],'Iris-setosa'),\n",
"(4,ARRAY[4.6,3.1,1.5,0.2],'Iris-setosa'),\n",
"(5,ARRAY[5.0,3.6,1.4,0.2],'Iris-setosa'),\n",
"(6,ARRAY[5.4,3.9,1.7,0.4],'Iris-setosa'),\n",
"(7,ARRAY[4.6,3.4,1.4,0.3],'Iris-setosa'),\n",
"(8,ARRAY[5.0,3.4,1.5,0.2],'Iris-setosa'),\n",
"(9,ARRAY[4.4,2.9,1.4,0.2],'Iris-setosa'),\n",
"(10,ARRAY[4.9,3.1,1.5,0.1],'Iris-setosa'),\n",
"(11,ARRAY[5.4,3.7,1.5,0.2],'Iris-setosa'),\n",
"(12,ARRAY[4.8,3.4,1.6,0.2],'Iris-setosa'),\n",
"(13,ARRAY[4.8,3.0,1.4,0.1],'Iris-setosa'),\n",
"(14,ARRAY[4.3,3.0,1.1,0.1],'Iris-setosa'),\n",
"(15,ARRAY[5.8,4.0,1.2,0.2],'Iris-setosa'),\n",
"(16,ARRAY[5.7,4.4,1.5,0.4],'Iris-setosa'),\n",
"(17,ARRAY[5.4,3.9,1.3,0.4],'Iris-setosa'),\n",
"(18,ARRAY[5.1,3.5,1.4,0.3],'Iris-setosa'),\n",
"(19,ARRAY[5.7,3.8,1.7,0.3],'Iris-setosa'),\n",
"(20,ARRAY[5.1,3.8,1.5,0.3],'Iris-setosa'),\n",
"(21,ARRAY[5.4,3.4,1.7,0.2],'Iris-setosa'),\n",
"(22,ARRAY[5.1,3.7,1.5,0.4],'Iris-setosa'),\n",
"(23,ARRAY[4.6,3.6,1.0,0.2],'Iris-setosa'),\n",
"(24,ARRAY[5.1,3.3,1.7,0.5],'Iris-setosa'),\n",
"(25,ARRAY[4.8,3.4,1.9,0.2],'Iris-setosa'),\n",
"(26,ARRAY[5.0,3.0,1.6,0.2],'Iris-setosa'),\n",
"(27,ARRAY[5.0,3.4,1.6,0.4],'Iris-setosa'),\n",
"(28,ARRAY[5.2,3.5,1.5,0.2],'Iris-setosa'),\n",
"(29,ARRAY[5.2,3.4,1.4,0.2],'Iris-setosa'),\n",
"(30,ARRAY[4.7,3.2,1.6,0.2],'Iris-setosa'),\n",
"(31,ARRAY[4.8,3.1,1.6,0.2],'Iris-setosa'),\n",
"(32,ARRAY[5.4,3.4,1.5,0.4],'Iris-setosa'),\n",
"(33,ARRAY[5.2,4.1,1.5,0.1],'Iris-setosa'),\n",
"(34,ARRAY[5.5,4.2,1.4,0.2],'Iris-setosa'),\n",
"(35,ARRAY[4.9,3.1,1.5,0.1],'Iris-setosa'),\n",
"(36,ARRAY[5.0,3.2,1.2,0.2],'Iris-setosa'),\n",
"(37,ARRAY[5.5,3.5,1.3,0.2],'Iris-setosa'),\n",
"(38,ARRAY[4.9,3.1,1.5,0.1],'Iris-setosa'),\n",
"(39,ARRAY[4.4,3.0,1.3,0.2],'Iris-setosa'),\n",
"(40,ARRAY[5.1,3.4,1.5,0.2],'Iris-setosa'),\n",
"(41,ARRAY[5.0,3.5,1.3,0.3],'Iris-setosa'),\n",
"(42,ARRAY[4.5,2.3,1.3,0.3],'Iris-setosa'),\n",
"(43,ARRAY[4.4,3.2,1.3,0.2],'Iris-setosa'),\n",
"(44,ARRAY[5.0,3.5,1.6,0.6],'Iris-setosa'),\n",
"(45,ARRAY[5.1,3.8,1.9,0.4],'Iris-setosa'),\n",
"(46,ARRAY[4.8,3.0,1.4,0.3],'Iris-setosa'),\n",
"(47,ARRAY[5.1,3.8,1.6,0.2],'Iris-setosa'),\n",
"(48,ARRAY[4.6,3.2,1.4,0.2],'Iris-setosa'),\n",
"(49,ARRAY[5.3,3.7,1.5,0.2],'Iris-setosa'),\n",
"(50,ARRAY[5.0,3.3,1.4,0.2],'Iris-setosa'),\n",
"(51,ARRAY[7.0,3.2,4.7,1.4],'Iris-versicolor'),\n",
"(52,ARRAY[6.4,3.2,4.5,1.5],'Iris-versicolor'),\n",
"(53,ARRAY[6.9,3.1,4.9,1.5],'Iris-versicolor'),\n",
"(54,ARRAY[5.5,2.3,4.0,1.3],'Iris-versicolor'),\n",
"(55,ARRAY[6.5,2.8,4.6,1.5],'Iris-versicolor'),\n",
"(56,ARRAY[5.7,2.8,4.5,1.3],'Iris-versicolor'),\n",
"(57,ARRAY[6.3,3.3,4.7,1.6],'Iris-versicolor'),\n",
"(58,ARRAY[4.9,2.4,3.3,1.0],'Iris-versicolor'),\n",
"(59,ARRAY[6.6,2.9,4.6,1.3],'Iris-versicolor'),\n",
"(60,ARRAY[5.2,2.7,3.9,1.4],'Iris-versicolor'),\n",
"(61,ARRAY[5.0,2.0,3.5,1.0],'Iris-versicolor'),\n",
"(62,ARRAY[5.9,3.0,4.2,1.5],'Iris-versicolor'),\n",
"(63,ARRAY[6.0,2.2,4.0,1.0],'Iris-versicolor'),\n",
"(64,ARRAY[6.1,2.9,4.7,1.4],'Iris-versicolor'),\n",
"(65,ARRAY[5.6,2.9,3.6,1.3],'Iris-versicolor'),\n",
"(66,ARRAY[6.7,3.1,4.4,1.4],'Iris-versicolor'),\n",
"(67,ARRAY[5.6,3.0,4.5,1.5],'Iris-versicolor'),\n",
"(68,ARRAY[5.8,2.7,4.1,1.0],'Iris-versicolor'),\n",
"(69,ARRAY[6.2,2.2,4.5,1.5],'Iris-versicolor'),\n",
"(70,ARRAY[5.6,2.5,3.9,1.1],'Iris-versicolor'),\n",
"(71,ARRAY[5.9,3.2,4.8,1.8],'Iris-versicolor'),\n",
"(72,ARRAY[6.1,2.8,4.0,1.3],'Iris-versicolor'),\n",
"(73,ARRAY[6.3,2.5,4.9,1.5],'Iris-versicolor'),\n",
"(74,ARRAY[6.1,2.8,4.7,1.2],'Iris-versicolor'),\n",
"(75,ARRAY[6.4,2.9,4.3,1.3],'Iris-versicolor'),\n",
"(76,ARRAY[6.6,3.0,4.4,1.4],'Iris-versicolor'),\n",
"(77,ARRAY[6.8,2.8,4.8,1.4],'Iris-versicolor'),\n",
"(78,ARRAY[6.7,3.0,5.0,1.7],'Iris-versicolor'),\n",
"(79,ARRAY[6.0,2.9,4.5,1.5],'Iris-versicolor'),\n",
"(80,ARRAY[5.7,2.6,3.5,1.0],'Iris-versicolor'),\n",
"(81,ARRAY[5.5,2.4,3.8,1.1],'Iris-versicolor'),\n",
"(82,ARRAY[5.5,2.4,3.7,1.0],'Iris-versicolor'),\n",
"(83,ARRAY[5.8,2.7,3.9,1.2],'Iris-versicolor'),\n",
"(84,ARRAY[6.0,2.7,5.1,1.6],'Iris-versicolor'),\n",
"(85,ARRAY[5.4,3.0,4.5,1.5],'Iris-versicolor'),\n",
"(86,ARRAY[6.0,3.4,4.5,1.6],'Iris-versicolor'),\n",
"(87,ARRAY[6.7,3.1,4.7,1.5],'Iris-versicolor'),\n",
"(88,ARRAY[6.3,2.3,4.4,1.3],'Iris-versicolor'),\n",
"(89,ARRAY[5.6,3.0,4.1,1.3],'Iris-versicolor'),\n",
"(90,ARRAY[5.5,2.5,4.0,1.3],'Iris-versicolor'),\n",
"(91,ARRAY[5.5,2.6,4.4,1.2],'Iris-versicolor'),\n",
"(92,ARRAY[6.1,3.0,4.6,1.4],'Iris-versicolor'),\n",
"(93,ARRAY[5.8,2.6,4.0,1.2],'Iris-versicolor'),\n",
"(94,ARRAY[5.0,2.3,3.3,1.0],'Iris-versicolor'),\n",
"(95,ARRAY[5.6,2.7,4.2,1.3],'Iris-versicolor'),\n",
"(96,ARRAY[5.7,3.0,4.2,1.2],'Iris-versicolor'),\n",
"(97,ARRAY[5.7,2.9,4.2,1.3],'Iris-versicolor'),\n",
"(98,ARRAY[6.2,2.9,4.3,1.3],'Iris-versicolor'),\n",
"(99,ARRAY[5.1,2.5,3.0,1.1],'Iris-versicolor'),\n",
"(100,ARRAY[5.7,2.8,4.1,1.3],'Iris-versicolor'),\n",
"(101,ARRAY[6.3,3.3,6.0,2.5],'Iris-virginica'),\n",
"(102,ARRAY[5.8,2.7,5.1,1.9],'Iris-virginica'),\n",
"(103,ARRAY[7.1,3.0,5.9,2.1],'Iris-virginica'),\n",
"(104,ARRAY[6.3,2.9,5.6,1.8],'Iris-virginica'),\n",
"(105,ARRAY[6.5,3.0,5.8,2.2],'Iris-virginica'),\n",
"(106,ARRAY[7.6,3.0,6.6,2.1],'Iris-virginica'),\n",
"(107,ARRAY[4.9,2.5,4.5,1.7],'Iris-virginica'),\n",
"(108,ARRAY[7.3,2.9,6.3,1.8],'Iris-virginica'),\n",
"(109,ARRAY[6.7,2.5,5.8,1.8],'Iris-virginica'),\n",
"(110,ARRAY[7.2,3.6,6.1,2.5],'Iris-virginica'),\n",
"(111,ARRAY[6.5,3.2,5.1,2.0],'Iris-virginica'),\n",
"(112,ARRAY[6.4,2.7,5.3,1.9],'Iris-virginica'),\n",
"(113,ARRAY[6.8,3.0,5.5,2.1],'Iris-virginica'),\n",
"(114,ARRAY[5.7,2.5,5.0,2.0],'Iris-virginica'),\n",
"(115,ARRAY[5.8,2.8,5.1,2.4],'Iris-virginica'),\n",
"(116,ARRAY[6.4,3.2,5.3,2.3],'Iris-virginica'),\n",
"(117,ARRAY[6.5,3.0,5.5,1.8],'Iris-virginica'),\n",
"(118,ARRAY[7.7,3.8,6.7,2.2],'Iris-virginica'),\n",
"(119,ARRAY[7.7,2.6,6.9,2.3],'Iris-virginica'),\n",
"(120,ARRAY[6.0,2.2,5.0,1.5],'Iris-virginica'),\n",
"(121,ARRAY[6.9,3.2,5.7,2.3],'Iris-virginica'),\n",
"(122,ARRAY[5.6,2.8,4.9,2.0],'Iris-virginica'),\n",
"(123,ARRAY[7.7,2.8,6.7,2.0],'Iris-virginica'),\n",
"(124,ARRAY[6.3,2.7,4.9,1.8],'Iris-virginica'),\n",
"(125,ARRAY[6.7,3.3,5.7,2.1],'Iris-virginica'),\n",
"(126,ARRAY[7.2,3.2,6.0,1.8],'Iris-virginica'),\n",
"(127,ARRAY[6.2,2.8,4.8,1.8],'Iris-virginica'),\n",
"(128,ARRAY[6.1,3.0,4.9,1.8],'Iris-virginica'),\n",
"(129,ARRAY[6.4,2.8,5.6,2.1],'Iris-virginica'),\n",
"(130,ARRAY[7.2,3.0,5.8,1.6],'Iris-virginica'),\n",
"(131,ARRAY[7.4,2.8,6.1,1.9],'Iris-virginica'),\n",
"(132,ARRAY[7.9,3.8,6.4,2.0],'Iris-virginica'),\n",
"(133,ARRAY[6.4,2.8,5.6,2.2],'Iris-virginica'),\n",
"(134,ARRAY[6.3,2.8,5.1,1.5],'Iris-virginica'),\n",
"(135,ARRAY[6.1,2.6,5.6,1.4],'Iris-virginica'),\n",
"(136,ARRAY[7.7,3.0,6.1,2.3],'Iris-virginica'),\n",
"(137,ARRAY[6.3,3.4,5.6,2.4],'Iris-virginica'),\n",
"(138,ARRAY[6.4,3.1,5.5,1.8],'Iris-virginica'),\n",
"(139,ARRAY[6.0,3.0,4.8,1.8],'Iris-virginica'),\n",
"(140,ARRAY[6.9,3.1,5.4,2.1],'Iris-virginica'),\n",
"(141,ARRAY[6.7,3.1,5.6,2.4],'Iris-virginica'),\n",
"(142,ARRAY[6.9,3.1,5.1,2.3],'Iris-virginica'),\n",
"(143,ARRAY[5.8,2.7,5.1,1.9],'Iris-virginica'),\n",
"(144,ARRAY[6.8,3.2,5.9,2.3],'Iris-virginica'),\n",
"(145,ARRAY[6.7,3.3,5.7,2.5],'Iris-virginica'),\n",
"(146,ARRAY[6.7,3.0,5.2,2.3],'Iris-virginica'),\n",
"(147,ARRAY[6.3,2.5,5.0,1.9],'Iris-virginica'),\n",
"(148,ARRAY[6.5,3.0,5.2,2.0],'Iris-virginica'),\n",
"(149,ARRAY[6.2,3.4,5.4,2.3],'Iris-virginica'),\n",
"(150,ARRAY[5.9,3.0,5.1,1.8],'Iris-virginica');\n",
"\n",
"SELECT * FROM iris_data ORDER BY id;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create a test/validation dataset from the training data"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n",
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>count</th>\n",
" </tr>\n",
" <tr>\n",
" <td>120</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(120L,)]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS iris_train, iris_test;\n",
"\n",
"-- Set seed so results are reproducible\n",
"SELECT setseed(0);\n",
"\n",
"SELECT madlib.train_test_split('iris_data', -- Source table\n",
" 'iris', -- Output table root name\n",
" 0.8, -- Train proportion\n",
" NULL, -- Test proportion (0.2)\n",
" NULL, -- Strata definition\n",
" NULL, -- Output all columns\n",
" NULL, -- Sample without replacement\n",
" TRUE -- Separate output tables\n",
" );\n",
"\n",
"SELECT COUNT(*) FROM iris_train;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"pp\"></a>\n",
"# 2. Call preprocessor for deep learning\n",
"Training dataset (uses training preprocessor):"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n",
"2 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>independent_var_shape</th>\n",
" <th>dependent_var_shape</th>\n",
" <th>buffer_id</th>\n",
" </tr>\n",
" <tr>\n",
" <td>[60, 4]</td>\n",
" <td>[60, 3]</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <td>[60, 4]</td>\n",
" <td>[60, 3]</td>\n",
" <td>1</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[([60, 4], [60, 3], 0), ([60, 4], [60, 3], 1)]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS iris_train_packed, iris_train_packed_summary;\n",
"\n",
"SELECT madlib.training_preprocessor_dl('iris_train', -- Source table\n",
" 'iris_train_packed', -- Output table\n",
" 'class_text', -- Dependent variable\n",
" 'attributes' -- Independent variable\n",
" ); \n",
"\n",
"SELECT independent_var_shape, dependent_var_shape, buffer_id FROM iris_train_packed ORDER BY buffer_id;"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>source_table</th>\n",
" <th>output_table</th>\n",
" <th>dependent_varname</th>\n",
" <th>independent_varname</th>\n",
" <th>dependent_vartype</th>\n",
" <th>class_values</th>\n",
" <th>buffer_size</th>\n",
" <th>normalizing_const</th>\n",
" <th>num_classes</th>\n",
" <th>distribution_rules</th>\n",
" <th>__internal_gpu_config__</th>\n",
" </tr>\n",
" <tr>\n",
" <td>iris_train</td>\n",
" <td>iris_train_packed</td>\n",
" <td>class_text</td>\n",
" <td>attributes</td>\n",
" <td>character varying</td>\n",
" <td>[u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica']</td>\n",
" <td>60</td>\n",
" <td>1.0</td>\n",
" <td>3</td>\n",
" <td>all_segments</td>\n",
" <td>all_segments</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(u'iris_train', u'iris_train_packed', u'class_text', u'attributes', u'character varying', [u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica'], 60, 1.0, 3, 'all_segments', 'all_segments')]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT * FROM iris_train_packed_summary;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Validation dataset (uses validation preprocessor):"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n",
"2 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>independent_var_shape</th>\n",
" <th>dependent_var_shape</th>\n",
" <th>buffer_id</th>\n",
" </tr>\n",
" <tr>\n",
" <td>[15, 4]</td>\n",
" <td>[15, 3]</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <td>[15, 4]</td>\n",
" <td>[15, 3]</td>\n",
" <td>1</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[([15, 4], [15, 3], 0), ([15, 4], [15, 3], 1)]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS iris_test_packed, iris_test_packed_summary;\n",
"\n",
"SELECT madlib.validation_preprocessor_dl('iris_test', -- Source table\n",
" 'iris_test_packed', -- Output table\n",
" 'class_text', -- Dependent variable\n",
" 'attributes', -- Independent variable\n",
" 'iris_train_packed' -- From training preprocessor step\n",
" ); \n",
"\n",
"SELECT independent_var_shape, dependent_var_shape, buffer_id FROM iris_test_packed ORDER BY buffer_id;"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>source_table</th>\n",
" <th>output_table</th>\n",
" <th>dependent_varname</th>\n",
" <th>independent_varname</th>\n",
" <th>dependent_vartype</th>\n",
" <th>class_values</th>\n",
" <th>buffer_size</th>\n",
" <th>normalizing_const</th>\n",
" <th>num_classes</th>\n",
" <th>distribution_rules</th>\n",
" <th>__internal_gpu_config__</th>\n",
" </tr>\n",
" <tr>\n",
" <td>iris_test</td>\n",
" <td>iris_test_packed</td>\n",
" <td>class_text</td>\n",
" <td>attributes</td>\n",
" <td>character varying</td>\n",
" <td>[u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica']</td>\n",
" <td>15</td>\n",
" <td>1.0</td>\n",
" <td>3</td>\n",
" <td>all_segments</td>\n",
" <td>all_segments</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(u'iris_test', u'iris_test_packed', u'class_text', u'attributes', u'character varying', [u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica'], 15, 1.0, 3, 'all_segments', 'all_segments')]"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT * FROM iris_test_packed_summary;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"load\"></a>\n",
"# 3. Define and load model architecture\n",
"Import Keras libraries"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Using TensorFlow backend.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Couldn't import dot_parser, loading of dot files will not be possible.\n"
]
}
],
"source": [
"import keras\n",
"from keras.models import Sequential\n",
"from keras.layers import Dense"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Define model architecture"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"_________________________________________________________________\n",
"Layer (type) Output Shape Param # \n",
"=================================================================\n",
"dense_1 (Dense) (None, 10) 50 \n",
"_________________________________________________________________\n",
"dense_2 (Dense) (None, 10) 110 \n",
"_________________________________________________________________\n",
"dense_3 (Dense) (None, 3) 33 \n",
"=================================================================\n",
"Total params: 193\n",
"Trainable params: 193\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"model_simple = Sequential()\n",
"model_simple.add(Dense(10, activation='relu', input_shape=(4,)))\n",
"model_simple.add(Dense(10, activation='relu'))\n",
"model_simple.add(Dense(3, activation='softmax'))\n",
" \n",
"model_simple.summary()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'{\"class_name\": \"Sequential\", \"keras_version\": \"2.1.6\", \"config\": [{\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_1\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"dtype\": \"float32\", \"activation\": \"relu\", \"trainable\": true, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 10, \"batch_input_shape\": [null, 4], \"use_bias\": true, \"activity_regularizer\": null}}, {\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_2\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"activation\": \"relu\", \"trainable\": true, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 10, \"use_bias\": true, \"activity_regularizer\": null}}, {\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_3\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"activation\": \"softmax\", \"trainable\": true, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 3, \"use_bias\": true, \"activity_regularizer\": null}}], \"backend\": \"tensorflow\"}'"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model_simple.to_json()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Load into model architecture table"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>model_id</th>\n",
" <th>model_arch</th>\n",
" <th>name</th>\n",
" <th>description</th>\n",
" </tr>\n",
" <tr>\n",
" <td>1</td>\n",
" <td>{u'class_name': u'Sequential', u'keras_version': u'2.1.6', u'config': [{u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_1', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'dtype': u'float32', u'activation': u'relu', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'batch_input_shape': [None, 4], u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_2', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'relu', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_3', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'softmax', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 3, u'use_bias': True, u'activity_regularizer': None}}], u'backend': u'tensorflow'}</td>\n",
" <td>Sophie</td>\n",
" <td>A simple model</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(1, {u'class_name': u'Sequential', u'keras_version': u'2.1.6', u'config': [{u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_1', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'dtype': u'float32', u'activation': u'relu', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'batch_input_shape': [None, 4], u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_2', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'relu', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_3', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'softmax', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 3, u'use_bias': True, u'activity_regularizer': None}}], u'backend': u'tensorflow'}, u'Sophie', u'A simple model')]"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS model_arch_library;\n",
"SELECT madlib.load_keras_model('model_arch_library', -- Output table,\n",
" \n",
"$$\n",
"{\"class_name\": \"Sequential\", \"keras_version\": \"2.1.6\", \"config\": [{\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_1\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"dtype\": \"float32\", \"activation\": \"relu\", \"trainable\": true, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 10, \"batch_input_shape\": [null, 4], \"use_bias\": true, \"activity_regularizer\": null}}, {\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_2\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"activation\": \"relu\", \"trainable\": true, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 10, \"use_bias\": true, \"activity_regularizer\": null}}, {\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_3\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"activation\": \"softmax\", \"trainable\": true, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 3, \"use_bias\": true, \"activity_regularizer\": null}}], \"backend\": \"tensorflow\"}\n",
"$$\n",
"::json, -- JSON blob\n",
" NULL, -- Weights\n",
" 'Sophie', -- Name\n",
" 'A simple model' -- Descr\n",
");\n",
"\n",
"SELECT model_id, model_arch, name, description FROM model_arch_library ORDER BY model_id;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"train\"></a>\n",
"# 4. Train\n",
"Train the model:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>madlib_keras_fit</th>\n",
" </tr>\n",
" <tr>\n",
" <td></td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[('',)]"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS iris_model, iris_model_summary;\n",
"\n",
"SELECT madlib.madlib_keras_fit('iris_train_packed', -- source table\n",
" 'iris_model', -- model output table\n",
" 'model_arch_library', -- model arch table\n",
" 1, -- model arch id\n",
" $$ loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] $$, -- compile_params\n",
" $$ batch_size=5, epochs=3 $$, -- fit_params\n",
" 10 -- num_iterations\n",
" );"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"View the model summary:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>source_table</th>\n",
" <th>model</th>\n",
" <th>dependent_varname</th>\n",
" <th>independent_varname</th>\n",
" <th>model_arch_table</th>\n",
" <th>model_id</th>\n",
" <th>compile_params</th>\n",
" <th>fit_params</th>\n",
" <th>num_iterations</th>\n",
" <th>validation_table</th>\n",
" <th>metrics_compute_frequency</th>\n",
" <th>name</th>\n",
" <th>description</th>\n",
" <th>model_type</th>\n",
" <th>model_size</th>\n",
" <th>start_training_time</th>\n",
" <th>end_training_time</th>\n",
" <th>metrics_elapsed_time</th>\n",
" <th>madlib_version</th>\n",
" <th>num_classes</th>\n",
" <th>class_values</th>\n",
" <th>dependent_vartype</th>\n",
" <th>normalizing_const</th>\n",
" <th>metrics_type</th>\n",
" <th>training_metrics_final</th>\n",
" <th>training_loss_final</th>\n",
" <th>training_metrics</th>\n",
" <th>training_loss</th>\n",
" <th>validation_metrics_final</th>\n",
" <th>validation_loss_final</th>\n",
" <th>validation_metrics</th>\n",
" <th>validation_loss</th>\n",
" <th>metrics_iters</th>\n",
" </tr>\n",
" <tr>\n",
" <td>iris_train_packed</td>\n",
" <td>iris_model</td>\n",
" <td>class_text</td>\n",
" <td>attributes</td>\n",
" <td>model_arch_library</td>\n",
" <td>1</td>\n",
" <td> loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] </td>\n",
" <td> batch_size=5, epochs=3 </td>\n",
" <td>10</td>\n",
" <td>None</td>\n",
" <td>10</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" <td>madlib_keras</td>\n",
" <td>0.7900390625</td>\n",
" <td>2019-12-18 18:09:06.678020</td>\n",
" <td>2019-12-18 18:09:09.703493</td>\n",
" <td>[3.02539992332458]</td>\n",
" <td>1.17-dev</td>\n",
" <td>3</td>\n",
" <td>[u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica']</td>\n",
" <td>character varying</td>\n",
" <td>1.0</td>\n",
" <td>[u'accuracy']</td>\n",
" <td>0.958333313465</td>\n",
" <td>0.619696557522</td>\n",
" <td>[0.958333313465118]</td>\n",
" <td>[0.61969655752182]</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" <td>[10]</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(u'iris_train_packed', u'iris_model', u'class_text', u'attributes', u'model_arch_library', 1, u\" loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] \", u' batch_size=5, epochs=3 ', 10, None, 10, None, None, u'madlib_keras', 0.7900390625, datetime.datetime(2019, 12, 18, 18, 9, 6, 678020), datetime.datetime(2019, 12, 18, 18, 9, 9, 703493), [3.02539992332458], u'1.17-dev', 3, [u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica'], u'character varying', 1.0, [u'accuracy'], 0.958333313465, 0.619696557522, [0.958333313465118], [0.61969655752182], None, None, None, None, [10])]"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT * FROM iris_model_summary;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"eval\"></a>\n",
"# 5. Evaluate\n",
"\n",
"Now run evaluate using model we built above:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>loss</th>\n",
" <th>metric</th>\n",
" <th>metrics_type</th>\n",
" </tr>\n",
" <tr>\n",
" <td>0.627631247044</td>\n",
" <td>0.899999976158</td>\n",
" <td>[u'accuracy']</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(0.62763124704361, 0.899999976158142, [u'accuracy'])]"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS iris_validate;\n",
"\n",
"SELECT madlib.madlib_keras_evaluate('iris_model', -- model\n",
" 'iris_test_packed', -- test table\n",
" 'iris_validate' -- output table\n",
" );\n",
"\n",
"SELECT * FROM iris_validate;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"pred\"></a>\n",
"# 6. Predict\n",
"\n",
"Now predict using model we built. We will use the validation data set for prediction as well, which is not usual but serves to show the syntax. The prediction is in the estimated_class_text column:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n",
"30 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>id</th>\n",
" <th>estimated_class_text</th>\n",
" </tr>\n",
" <tr>\n",
" <td>7</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>8</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>9</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>14</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>18</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>28</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>44</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>48</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>56</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>69</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>80</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>83</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>85</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>88</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>89</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>90</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>94</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>97</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>103</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>105</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>111</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>120</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>128</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>131</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>132</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>133</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>136</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>138</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>149</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(7, u'Iris-setosa'),\n",
" (8, u'Iris-setosa'),\n",
" (9, u'Iris-setosa'),\n",
" (14, u'Iris-setosa'),\n",
" (18, u'Iris-setosa'),\n",
" (28, u'Iris-setosa'),\n",
" (44, u'Iris-setosa'),\n",
" (48, u'Iris-setosa'),\n",
" (54, u'Iris-virginica'),\n",
" (56, u'Iris-versicolor'),\n",
" (69, u'Iris-virginica'),\n",
" (80, u'Iris-versicolor'),\n",
" (83, u'Iris-versicolor'),\n",
" (85, u'Iris-versicolor'),\n",
" (88, u'Iris-virginica'),\n",
" (89, u'Iris-versicolor'),\n",
" (90, u'Iris-versicolor'),\n",
" (94, u'Iris-versicolor'),\n",
" (97, u'Iris-versicolor'),\n",
" (103, u'Iris-virginica'),\n",
" (105, u'Iris-virginica'),\n",
" (111, u'Iris-virginica'),\n",
" (120, u'Iris-virginica'),\n",
" (128, u'Iris-virginica'),\n",
" (131, u'Iris-virginica'),\n",
" (132, u'Iris-virginica'),\n",
" (133, u'Iris-virginica'),\n",
" (136, u'Iris-virginica'),\n",
" (138, u'Iris-virginica'),\n",
" (149, u'Iris-virginica')]"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS iris_predict;\n",
"\n",
"SELECT madlib.madlib_keras_predict('iris_model', -- model\n",
" 'iris_test', -- test_table\n",
" 'id', -- id column\n",
" 'attributes', -- independent var\n",
" 'iris_predict' -- output table\n",
" );\n",
"\n",
"SELECT * FROM iris_predict ORDER BY id;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Count missclassifications"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>count</th>\n",
" </tr>\n",
" <tr>\n",
" <td>3</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(3L,)]"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT COUNT(*) FROM iris_predict JOIN iris_test USING (id) \n",
"WHERE iris_predict.estimated_class_text != iris_test.class_text;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Percent missclassifications"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>test_accuracy_percent</th>\n",
" </tr>\n",
" <tr>\n",
" <td>90.00</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(Decimal('90.00'),)]"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT round(count(*)*100/(150*0.2),2) as test_accuracy_percent from\n",
" (select iris_test.class_text as actual, iris_predict.estimated_class_text as estimated\n",
" from iris_predict inner join iris_test\n",
" on iris_test.id=iris_predict.id) q\n",
"WHERE q.actual=q.estimated;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"pred_byom\"></a>\n",
"# 7. Predict BYOM\n",
"The predict BYOM function allows you to do inference on models that have not been trained on MADlib, but rather imported from elsewhere. \n",
"\n",
"We will use the validation dataset for prediction as well, which is not usual but serves to show the syntax.\n",
"\n",
"See load_keras_model()\n",
"http://madlib.apache.org/docs/latest/group__grp__keras__model__arch.html\n",
"for details on how to load the model architecture and weights. In this example we will use weights we already have:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"UPDATE model_arch_library \n",
"SET model_weights = iris_model.model_weights \n",
"FROM iris_model \n",
"WHERE model_arch_library.model_id = 1;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now train using a model from the model architecture table directly without referencing the model table from the MADlib training. \n",
"\n",
"Note that if you specify the class values parameter as we do below, it must reflect how the dependent variable was 1-hot encoded for training. In this example the 'training_preprocessor_dl()' in Step 2 above encoded in the order {'Iris-setosa', 'Iris-versicolor', 'Iris-virginica'} so this is the order we pass in the parameter. If we accidently picked another order that did not match the 1-hot encoding, the predictions would be wrong."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n",
"30 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>id</th>\n",
" <th>estimated_dependent_var</th>\n",
" </tr>\n",
" <tr>\n",
" <td>7</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>8</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>9</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>14</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>18</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>28</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>44</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>48</td>\n",
" <td>Iris-setosa</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>56</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>69</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>80</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>83</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>85</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>88</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>89</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>90</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>94</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>97</td>\n",
" <td>Iris-versicolor</td>\n",
" </tr>\n",
" <tr>\n",
" <td>103</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>105</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>111</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>120</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>128</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>131</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>132</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>133</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>136</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>138</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
" <tr>\n",
" <td>149</td>\n",
" <td>Iris-virginica</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(7, u'Iris-setosa'),\n",
" (8, u'Iris-setosa'),\n",
" (9, u'Iris-setosa'),\n",
" (14, u'Iris-setosa'),\n",
" (18, u'Iris-setosa'),\n",
" (28, u'Iris-setosa'),\n",
" (44, u'Iris-setosa'),\n",
" (48, u'Iris-setosa'),\n",
" (54, u'Iris-virginica'),\n",
" (56, u'Iris-versicolor'),\n",
" (69, u'Iris-virginica'),\n",
" (80, u'Iris-versicolor'),\n",
" (83, u'Iris-versicolor'),\n",
" (85, u'Iris-versicolor'),\n",
" (88, u'Iris-virginica'),\n",
" (89, u'Iris-versicolor'),\n",
" (90, u'Iris-versicolor'),\n",
" (94, u'Iris-versicolor'),\n",
" (97, u'Iris-versicolor'),\n",
" (103, u'Iris-virginica'),\n",
" (105, u'Iris-virginica'),\n",
" (111, u'Iris-virginica'),\n",
" (120, u'Iris-virginica'),\n",
" (128, u'Iris-virginica'),\n",
" (131, u'Iris-virginica'),\n",
" (132, u'Iris-virginica'),\n",
" (133, u'Iris-virginica'),\n",
" (136, u'Iris-virginica'),\n",
" (138, u'Iris-virginica'),\n",
" (149, u'Iris-virginica')]"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS iris_predict_byom;\n",
"\n",
"SELECT madlib.madlib_keras_predict_byom('model_arch_library', -- model arch table\n",
" 1, -- model arch id\n",
" 'iris_test', -- test_table\n",
" 'id', -- id column\n",
" 'attributes', -- independent var\n",
" 'iris_predict_byom', -- output table\n",
" 'response', -- prediction type\n",
" FALSE, -- use GPUs\n",
" ARRAY['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'], -- class values\n",
" 1.0 -- normalizing const\n",
" );\n",
"SELECT * FROM iris_predict_byom ORDER BY id;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Count missclassifications:"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>count</th>\n",
" </tr>\n",
" <tr>\n",
" <td>3</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(3L,)]"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT COUNT(*) FROM iris_predict_byom JOIN iris_test USING (id)\n",
"WHERE iris_predict_byom.estimated_dependent_var != iris_test.class_text;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Percent missclassifications:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>test_accuracy_percent</th>\n",
" </tr>\n",
" <tr>\n",
" <td>90.00</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(Decimal('90.00'),)]"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT round(count(*)*100/(150*0.2),2) as test_accuracy_percent from\n",
" (select iris_test.class_text as actual, iris_predict_byom.estimated_dependent_var as estimated\n",
" from iris_predict_byom inner join iris_test\n",
" on iris_test.id=iris_predict_byom.id) q\n",
"WHERE q.actual=q.estimated;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"class2\"></a>\n",
"# Classification with Other Parameters\n",
"\n",
"<a id=\"val_dataset\"></a>\n",
"# 1. Validation dataset\n",
"Now use a validation dataset and compute metrics every 2nd iteration using the 'metrics_compute_frequency' parameter. This can help reduce run time if you do not need metrics computed at every iteration."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>madlib_keras_fit</th>\n",
" </tr>\n",
" <tr>\n",
" <td></td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[('',)]"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS iris_model, iris_model_summary;\n",
"\n",
"SELECT madlib.madlib_keras_fit('iris_train_packed', -- source table\n",
" 'iris_model', -- model output table\n",
" 'model_arch_library', -- model arch table\n",
" 1, -- model arch id\n",
" $$ loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] $$, -- compile_params\n",
" $$ batch_size=5, epochs=3 $$, -- fit_params\n",
" 10, -- num_iterations\n",
" FALSE, -- use GPUs\n",
" 'iris_test_packed', -- validation dataset\n",
" 2, -- metrics compute frequency\n",
" FALSE, -- warm start\n",
" 'Sophie L.', -- name\n",
" 'Simple MLP for iris dataset' -- description\n",
" );"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"View the model summary:"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>source_table</th>\n",
" <th>model</th>\n",
" <th>dependent_varname</th>\n",
" <th>independent_varname</th>\n",
" <th>model_arch_table</th>\n",
" <th>model_id</th>\n",
" <th>compile_params</th>\n",
" <th>fit_params</th>\n",
" <th>num_iterations</th>\n",
" <th>validation_table</th>\n",
" <th>metrics_compute_frequency</th>\n",
" <th>name</th>\n",
" <th>description</th>\n",
" <th>model_type</th>\n",
" <th>model_size</th>\n",
" <th>start_training_time</th>\n",
" <th>end_training_time</th>\n",
" <th>metrics_elapsed_time</th>\n",
" <th>madlib_version</th>\n",
" <th>num_classes</th>\n",
" <th>class_values</th>\n",
" <th>dependent_vartype</th>\n",
" <th>normalizing_const</th>\n",
" <th>metrics_type</th>\n",
" <th>training_metrics_final</th>\n",
" <th>training_loss_final</th>\n",
" <th>training_metrics</th>\n",
" <th>training_loss</th>\n",
" <th>validation_metrics_final</th>\n",
" <th>validation_loss_final</th>\n",
" <th>validation_metrics</th>\n",
" <th>validation_loss</th>\n",
" <th>metrics_iters</th>\n",
" </tr>\n",
" <tr>\n",
" <td>iris_train_packed</td>\n",
" <td>iris_model</td>\n",
" <td>class_text</td>\n",
" <td>attributes</td>\n",
" <td>model_arch_library</td>\n",
" <td>1</td>\n",
" <td> loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] </td>\n",
" <td> batch_size=5, epochs=3 </td>\n",
" <td>10</td>\n",
" <td>iris_test_packed</td>\n",
" <td>2</td>\n",
" <td>Sophie L.</td>\n",
" <td>Simple MLP for iris dataset</td>\n",
" <td>madlib_keras</td>\n",
" <td>0.7900390625</td>\n",
" <td>2019-12-18 18:09:19.330964</td>\n",
" <td>2019-12-18 18:09:21.010635</td>\n",
" <td>[0.915475130081177, 1.10240316390991, 1.24091100692749, 1.37801814079285, 1.67959213256836]</td>\n",
" <td>1.17-dev</td>\n",
" <td>3</td>\n",
" <td>[u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica']</td>\n",
" <td>character varying</td>\n",
" <td>1.0</td>\n",
" <td>[u'accuracy']</td>\n",
" <td>0.983333349228</td>\n",
" <td>0.308444350958</td>\n",
" <td>[0.949999988079071, 0.975000023841858, 0.975000023841858, 0.983333349227905, 0.983333349227905]</td>\n",
" <td>[0.5235316157341, 0.450434356927872, 0.391158282756805, 0.344655215740204, 0.30844435095787]</td>\n",
" <td>0.933333337307</td>\n",
" <td>0.363271415234</td>\n",
" <td>[0.866666674613953, 0.933333337306976, 0.933333337306976, 0.933333337306976, 0.933333337306976]</td>\n",
" <td>[0.549321353435516, 0.490176409482956, 0.438665509223938, 0.397390514612198, 0.363271415233612]</td>\n",
" <td>[2, 4, 6, 8, 10]</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(u'iris_train_packed', u'iris_model', u'class_text', u'attributes', u'model_arch_library', 1, u\" loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] \", u' batch_size=5, epochs=3 ', 10, u'iris_test_packed', 2, u'Sophie L.', u'Simple MLP for iris dataset', u'madlib_keras', 0.7900390625, datetime.datetime(2019, 12, 18, 18, 9, 19, 330964), datetime.datetime(2019, 12, 18, 18, 9, 21, 10635), [0.915475130081177, 1.10240316390991, 1.24091100692749, 1.37801814079285, 1.67959213256836], u'1.17-dev', 3, [u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica'], u'character varying', 1.0, [u'accuracy'], 0.983333349228, 0.308444350958, [0.949999988079071, 0.975000023841858, 0.975000023841858, 0.983333349227905, 0.983333349227905], [0.5235316157341, 0.450434356927872, 0.391158282756805, 0.344655215740204, 0.30844435095787], 0.933333337307, 0.363271415234, [0.866666674613953, 0.933333337306976, 0.933333337306976, 0.933333337306976, 0.933333337306976], [0.549321353435516, 0.490176409482956, 0.438665509223938, 0.397390514612198, 0.363271415233612], [2, 4, 6, 8, 10])]"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT * FROM iris_model_summary;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Accuracy by iteration"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n",
"1 rows affected.\n",
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x12c58eb50>"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import sys\n",
"import os\n",
"from matplotlib import pyplot as plt\n",
"\n",
"# get accuracy and iteration number\n",
"iters_proxy = %sql SELECT metrics_iters FROM iris_model_summary;\n",
"train_accuracy_proxy = %sql SELECT training_metrics FROM iris_model_summary;\n",
"test_accuracy_proxy = %sql SELECT validation_metrics FROM iris_model_summary;\n",
"\n",
"# get number of points\n",
"num_points_proxy = %sql SELECT array_length(metrics_iters,1) FROM iris_model_summary;\n",
"num_points = num_points_proxy[0]\n",
"\n",
"# reshape to np arrays\n",
"iters = np.array(iters_proxy).reshape(num_points)\n",
"train_accuracy = np.array(train_accuracy_proxy).reshape(num_points)\n",
"test_accuracy = np.array(test_accuracy_proxy).reshape(num_points)\n",
"\n",
"#plot\n",
"plt.title('Iris validation accuracy by iteration')\n",
"plt.xlabel('Iteration number')\n",
"plt.ylabel('Accuracy')\n",
"plt.grid(True)\n",
"plt.plot(iters, train_accuracy, 'g.-', label='Train')\n",
"plt.plot(iters, test_accuracy, 'r.-', label='Test')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Loss by iteration"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x12f1b1c10>"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
},
{
"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": [
"# get loss\n",
"train_loss_proxy = %sql SELECT training_loss FROM iris_model_summary;\n",
"test_loss_proxy = %sql SELECT validation_loss FROM iris_model_summary;\n",
"\n",
"# reshape to np arrays\n",
"train_loss = np.array(train_loss_proxy).reshape(num_points)\n",
"test_loss = np.array(test_loss_proxy).reshape(num_points)\n",
"\n",
"#plot\n",
"plt.title('Iris validation loss by iteration')\n",
"plt.xlabel('Iteration number')\n",
"plt.ylabel('Loss')\n",
"plt.grid(True)\n",
"plt.plot(iters, train_loss, 'g.-', label='Train')\n",
"plt.plot(iters, test_loss, 'r.-', label='Test')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Accuracy by time"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x12f24bbd0>"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
},
{
"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": [
"# get time\n",
"time_proxy = %sql SELECT metrics_elapsed_time FROM iris_model_summary;\n",
"\n",
"# reshape to np arrays\n",
"time = np.array(time_proxy).reshape(num_points)/60.0\n",
"\n",
"#plot\n",
"plt.title('Iris validation accuracy by time')\n",
"plt.xlabel('Time (min)')\n",
"plt.ylabel('Accuracy')\n",
"plt.grid(True)\n",
"plt.plot(time, train_accuracy, 'g.-', label='Train')\n",
"plt.plot(time, test_accuracy, 'r.-', label='Test')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Time to achieve a given accuracy"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x12f344210>"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
},
{
"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": [
"#plot\n",
"plt.title('Iris time by validation accuracy')\n",
"plt.xlabel('Accuracy')\n",
"plt.ylabel('Time (min)')\n",
"plt.grid(True)\n",
"plt.plot(train_accuracy, time, 'g.-', label='Train')\n",
"plt.plot(test_accuracy, time, 'r.-', label='Test')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"pred_prob\"></a>\n",
"# 2. Predict probabilities\n",
"Predict with probabilities for each class:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n",
"30 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>id</th>\n",
" <th>prob_Iris-setosa</th>\n",
" <th>prob_Iris-versicolor</th>\n",
" <th>prob_Iris-virginica</th>\n",
" </tr>\n",
" <tr>\n",
" <td>7</td>\n",
" <td>0.89789814</td>\n",
" <td>0.0880069</td>\n",
" <td>0.014094983</td>\n",
" </tr>\n",
" <tr>\n",
" <td>8</td>\n",
" <td>0.90666765</td>\n",
" <td>0.081442654</td>\n",
" <td>0.011889744</td>\n",
" </tr>\n",
" <tr>\n",
" <td>9</td>\n",
" <td>0.8795763</td>\n",
" <td>0.1017618</td>\n",
" <td>0.018661851</td>\n",
" </tr>\n",
" <tr>\n",
" <td>14</td>\n",
" <td>0.8874597</td>\n",
" <td>0.095630445</td>\n",
" <td>0.016909808</td>\n",
" </tr>\n",
" <tr>\n",
" <td>18</td>\n",
" <td>0.9102227</td>\n",
" <td>0.078691445</td>\n",
" <td>0.011085836</td>\n",
" </tr>\n",
" <tr>\n",
" <td>28</td>\n",
" <td>0.9124432</td>\n",
" <td>0.077006854</td>\n",
" <td>0.010549883</td>\n",
" </tr>\n",
" <tr>\n",
" <td>44</td>\n",
" <td>0.90255314</td>\n",
" <td>0.08451119</td>\n",
" <td>0.012935703</td>\n",
" </tr>\n",
" <tr>\n",
" <td>48</td>\n",
" <td>0.89486533</td>\n",
" <td>0.09027297</td>\n",
" <td>0.014861753</td>\n",
" </tr>\n",
" <tr>\n",
" <td>54</td>\n",
" <td>0.026524143</td>\n",
" <td>0.51825184</td>\n",
" <td>0.45522407</td>\n",
" </tr>\n",
" <tr>\n",
" <td>56</td>\n",
" <td>0.020466398</td>\n",
" <td>0.538594</td>\n",
" <td>0.4409396</td>\n",
" </tr>\n",
" <tr>\n",
" <td>69</td>\n",
" <td>0.009856132</td>\n",
" <td>0.38160574</td>\n",
" <td>0.60853815</td>\n",
" </tr>\n",
" <tr>\n",
" <td>80</td>\n",
" <td>0.088389054</td>\n",
" <td>0.68402624</td>\n",
" <td>0.22758465</td>\n",
" </tr>\n",
" <tr>\n",
" <td>83</td>\n",
" <td>0.04700892</td>\n",
" <td>0.6974011</td>\n",
" <td>0.25559002</td>\n",
" </tr>\n",
" <tr>\n",
" <td>85</td>\n",
" <td>0.02379873</td>\n",
" <td>0.53655416</td>\n",
" <td>0.4396471</td>\n",
" </tr>\n",
" <tr>\n",
" <td>88</td>\n",
" <td>0.014446292</td>\n",
" <td>0.48625696</td>\n",
" <td>0.4992967</td>\n",
" </tr>\n",
" <tr>\n",
" <td>89</td>\n",
" <td>0.045492876</td>\n",
" <td>0.6929876</td>\n",
" <td>0.26151955</td>\n",
" </tr>\n",
" <tr>\n",
" <td>90</td>\n",
" <td>0.032893542</td>\n",
" <td>0.57819253</td>\n",
" <td>0.38891393</td>\n",
" </tr>\n",
" <tr>\n",
" <td>94</td>\n",
" <td>0.078232706</td>\n",
" <td>0.6571468</td>\n",
" <td>0.26462048</td>\n",
" </tr>\n",
" <tr>\n",
" <td>97</td>\n",
" <td>0.036127776</td>\n",
" <td>0.6550248</td>\n",
" <td>0.30884746</td>\n",
" </tr>\n",
" <tr>\n",
" <td>103</td>\n",
" <td>0.0017510698</td>\n",
" <td>0.222155</td>\n",
" <td>0.7760939</td>\n",
" </tr>\n",
" <tr>\n",
" <td>105</td>\n",
" <td>0.001789655</td>\n",
" <td>0.1864191</td>\n",
" <td>0.81179124</td>\n",
" </tr>\n",
" <tr>\n",
" <td>111</td>\n",
" <td>0.010464086</td>\n",
" <td>0.46730253</td>\n",
" <td>0.52223337</td>\n",
" </tr>\n",
" <tr>\n",
" <td>120</td>\n",
" <td>0.0034266405</td>\n",
" <td>0.21947922</td>\n",
" <td>0.7770942</td>\n",
" </tr>\n",
" <tr>\n",
" <td>128</td>\n",
" <td>0.011816905</td>\n",
" <td>0.4490503</td>\n",
" <td>0.5391328</td>\n",
" </tr>\n",
" <tr>\n",
" <td>131</td>\n",
" <td>0.0009711725</td>\n",
" <td>0.17797765</td>\n",
" <td>0.82105124</td>\n",
" </tr>\n",
" <tr>\n",
" <td>132</td>\n",
" <td>0.0024771853</td>\n",
" <td>0.395437</td>\n",
" <td>0.6020858</td>\n",
" </tr>\n",
" <tr>\n",
" <td>133</td>\n",
" <td>0.0019595844</td>\n",
" <td>0.18066718</td>\n",
" <td>0.8173732</td>\n",
" </tr>\n",
" <tr>\n",
" <td>136</td>\n",
" <td>0.0012088934</td>\n",
" <td>0.20632832</td>\n",
" <td>0.7924628</td>\n",
" </tr>\n",
" <tr>\n",
" <td>138</td>\n",
" <td>0.0045178244</td>\n",
" <td>0.3225387</td>\n",
" <td>0.6729434</td>\n",
" </tr>\n",
" <tr>\n",
" <td>149</td>\n",
" <td>0.006746102</td>\n",
" <td>0.3544818</td>\n",
" <td>0.6387721</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(7, 0.89789814, 0.0880069, 0.014094983),\n",
" (8, 0.90666765, 0.081442654, 0.011889744),\n",
" (9, 0.8795763, 0.1017618, 0.018661851),\n",
" (14, 0.8874597, 0.095630445, 0.016909808),\n",
" (18, 0.9102227, 0.078691445, 0.011085836),\n",
" (28, 0.9124432, 0.077006854, 0.010549883),\n",
" (44, 0.90255314, 0.08451119, 0.012935703),\n",
" (48, 0.89486533, 0.09027297, 0.014861753),\n",
" (54, 0.026524143, 0.51825184, 0.45522407),\n",
" (56, 0.020466398, 0.538594, 0.4409396),\n",
" (69, 0.009856132, 0.38160574, 0.60853815),\n",
" (80, 0.088389054, 0.68402624, 0.22758465),\n",
" (83, 0.04700892, 0.6974011, 0.25559002),\n",
" (85, 0.02379873, 0.53655416, 0.4396471),\n",
" (88, 0.014446292, 0.48625696, 0.4992967),\n",
" (89, 0.045492876, 0.6929876, 0.26151955),\n",
" (90, 0.032893542, 0.57819253, 0.38891393),\n",
" (94, 0.078232706, 0.6571468, 0.26462048),\n",
" (97, 0.036127776, 0.6550248, 0.30884746),\n",
" (103, 0.0017510698, 0.222155, 0.7760939),\n",
" (105, 0.001789655, 0.1864191, 0.81179124),\n",
" (111, 0.010464086, 0.46730253, 0.52223337),\n",
" (120, 0.0034266405, 0.21947922, 0.7770942),\n",
" (128, 0.011816905, 0.4490503, 0.5391328),\n",
" (131, 0.0009711725, 0.17797765, 0.82105124),\n",
" (132, 0.0024771853, 0.395437, 0.6020858),\n",
" (133, 0.0019595844, 0.18066718, 0.8173732),\n",
" (136, 0.0012088934, 0.20632832, 0.7924628),\n",
" (138, 0.0045178244, 0.3225387, 0.6729434),\n",
" (149, 0.006746102, 0.3544818, 0.6387721)]"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS iris_predict;\n",
"\n",
"SELECT madlib.madlib_keras_predict('iris_model', -- model\n",
" 'iris_test', -- test_table\n",
" 'id', -- id column\n",
" 'attributes', -- independent var\n",
" 'iris_predict', -- output table\n",
" 'prob' -- response type\n",
" );\n",
"\n",
"SELECT * FROM iris_predict ORDER BY id;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"warm_start\"></a>\n",
"# 3. Warm start\n",
"Next, use the warm_start parameter to continue learning, using the coefficients from the run above. Note that we don't drop the model table or model summary table:"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>madlib_keras_fit</th>\n",
" </tr>\n",
" <tr>\n",
" <td></td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[('',)]"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT madlib.madlib_keras_fit('iris_train_packed', -- source table\n",
" 'iris_model', -- model output table\n",
" 'model_arch_library', -- model arch table\n",
" 1, -- model arch id\n",
" $$ loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] $$, -- compile_params\n",
" $$ batch_size=5, epochs=3 $$, -- fit_params\n",
" 10, -- num_iterations\n",
" FALSE, -- use GPUs\n",
" 'iris_test_packed', -- validation dataset\n",
" 2, -- metrics compute frequency\n",
" TRUE, -- warm start\n",
" 'Sophie L.', -- name \n",
" 'Simple MLP for iris dataset' -- description\n",
" );"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the summary table and plots below note that the loss and accuracy values pick up from where the previous run left off:"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>source_table</th>\n",
" <th>model</th>\n",
" <th>dependent_varname</th>\n",
" <th>independent_varname</th>\n",
" <th>model_arch_table</th>\n",
" <th>model_id</th>\n",
" <th>compile_params</th>\n",
" <th>fit_params</th>\n",
" <th>num_iterations</th>\n",
" <th>validation_table</th>\n",
" <th>metrics_compute_frequency</th>\n",
" <th>name</th>\n",
" <th>description</th>\n",
" <th>model_type</th>\n",
" <th>model_size</th>\n",
" <th>start_training_time</th>\n",
" <th>end_training_time</th>\n",
" <th>metrics_elapsed_time</th>\n",
" <th>madlib_version</th>\n",
" <th>num_classes</th>\n",
" <th>class_values</th>\n",
" <th>dependent_vartype</th>\n",
" <th>normalizing_const</th>\n",
" <th>metrics_type</th>\n",
" <th>training_metrics_final</th>\n",
" <th>training_loss_final</th>\n",
" <th>training_metrics</th>\n",
" <th>training_loss</th>\n",
" <th>validation_metrics_final</th>\n",
" <th>validation_loss_final</th>\n",
" <th>validation_metrics</th>\n",
" <th>validation_loss</th>\n",
" <th>metrics_iters</th>\n",
" </tr>\n",
" <tr>\n",
" <td>iris_train_packed</td>\n",
" <td>iris_model</td>\n",
" <td>class_text</td>\n",
" <td>attributes</td>\n",
" <td>model_arch_library</td>\n",
" <td>1</td>\n",
" <td> loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] </td>\n",
" <td> batch_size=5, epochs=3 </td>\n",
" <td>10</td>\n",
" <td>iris_test_packed</td>\n",
" <td>2</td>\n",
" <td>Sophie L.</td>\n",
" <td>Simple MLP for iris dataset</td>\n",
" <td>madlib_keras</td>\n",
" <td>0.7900390625</td>\n",
" <td>2019-12-18 18:09:27.128581</td>\n",
" <td>2019-12-18 18:09:28.838569</td>\n",
" <td>[0.982600927352905, 1.11963605880737, 1.24473285675049, 1.41093587875366, 1.70990204811096]</td>\n",
" <td>1.17-dev</td>\n",
" <td>3</td>\n",
" <td>[u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica']</td>\n",
" <td>character varying</td>\n",
" <td>1.0</td>\n",
" <td>[u'accuracy']</td>\n",
" <td>0.983333349228</td>\n",
" <td>0.198354303837</td>\n",
" <td>[0.966666638851166, 0.983333349227905, 0.975000023841858, 0.983333349227905, 0.983333349227905]</td>\n",
" <td>[0.27795821428299, 0.251547634601593, 0.231610581278801, 0.213408783078194, 0.198354303836823]</td>\n",
" <td>0.966666638851</td>\n",
" <td>0.255444854498</td>\n",
" <td>[0.933333337306976, 0.966666638851166, 0.933333337306976, 0.966666638851166, 0.966666638851166]</td>\n",
" <td>[0.333956837654114, 0.309911340475082, 0.291009396314621, 0.271284729242325, 0.25544485449791]</td>\n",
" <td>[2, 4, 6, 8, 10]</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(u'iris_train_packed', u'iris_model', u'class_text', u'attributes', u'model_arch_library', 1, u\" loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] \", u' batch_size=5, epochs=3 ', 10, u'iris_test_packed', 2, u'Sophie L.', u'Simple MLP for iris dataset', u'madlib_keras', 0.7900390625, datetime.datetime(2019, 12, 18, 18, 9, 27, 128581), datetime.datetime(2019, 12, 18, 18, 9, 28, 838569), [0.982600927352905, 1.11963605880737, 1.24473285675049, 1.41093587875366, 1.70990204811096], u'1.17-dev', 3, [u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica'], u'character varying', 1.0, [u'accuracy'], 0.983333349228, 0.198354303837, [0.966666638851166, 0.983333349227905, 0.975000023841858, 0.983333349227905, 0.983333349227905], [0.27795821428299, 0.251547634601593, 0.231610581278801, 0.213408783078194, 0.198354303836823], 0.966666638851, 0.255444854498, [0.933333337306976, 0.966666638851166, 0.933333337306976, 0.966666638851166, 0.966666638851166], [0.333956837654114, 0.309911340475082, 0.291009396314621, 0.271284729242325, 0.25544485449791], [2, 4, 6, 8, 10])]"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT * FROM iris_model_summary;"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n",
"1 rows affected.\n",
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x12f4c0110>"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
},
{
"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": [
"import pandas as pd\n",
"import numpy as np\n",
"import sys\n",
"import os\n",
"from matplotlib import pyplot as plt\n",
"\n",
"# get accuracy and iteration number\n",
"iters_proxy = %sql SELECT metrics_iters FROM iris_model_summary;\n",
"train_accuracy_proxy = %sql SELECT training_metrics FROM iris_model_summary;\n",
"test_accuracy_proxy = %sql SELECT validation_metrics FROM iris_model_summary;\n",
"\n",
"# get number of points\n",
"num_points_proxy = %sql SELECT array_length(metrics_iters,1) FROM iris_model_summary;\n",
"num_points = num_points_proxy[0]\n",
"\n",
"# reshape to np arrays\n",
"iters = np.array(iters_proxy).reshape(num_points)\n",
"train_accuracy = np.array(train_accuracy_proxy).reshape(num_points)\n",
"test_accuracy = np.array(test_accuracy_proxy).reshape(num_points)\n",
"\n",
"#plot\n",
"plt.title('Iris validation accuracy by iteration - warm start')\n",
"plt.xlabel('Iteration number')\n",
"plt.ylabel('Accuracy')\n",
"plt.grid(True)\n",
"plt.plot(iters, train_accuracy, 'g.-', label='Train')\n",
"plt.plot(iters, test_accuracy, 'r.-', label='Test')\n",
"plt.legend()"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x12f560f10>"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
},
{
"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": [
"# get loss\n",
"train_loss_proxy = %sql SELECT training_loss FROM iris_model_summary;\n",
"test_loss_proxy = %sql SELECT validation_loss FROM iris_model_summary;\n",
"\n",
"# reshape to np arrays\n",
"train_loss = np.array(train_loss_proxy).reshape(num_points)\n",
"test_loss = np.array(test_loss_proxy).reshape(num_points)\n",
"\n",
"#plot\n",
"plt.title('Iris validation loss by iteration - warm start')\n",
"plt.xlabel('Iteration number')\n",
"plt.ylabel('Loss')\n",
"plt.grid(True)\n",
"plt.plot(iters, train_loss, 'g.-', label='Train')\n",
"plt.plot(iters, test_loss, 'r.-', label='Test')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"transfer_learn\"></a>\n",
"# Transfer learning\n",
"\n",
"<a id=\"load2\"></a>\n",
"# 1. Define and load model architecture with some layers frozen\n",
"Here we want to start with initial weights from a pre-trained model rather than training from scratch. We also want to use a model architecture with the earlier feature layer(s) frozen to save on training time. The example below is somewhat contrived but gives you the idea of the steps.\n",
"\n",
"First define a model architecture with the 1st hidden layer frozen:"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"_________________________________________________________________\n",
"Layer (type) Output Shape Param # \n",
"=================================================================\n",
"dense_4 (Dense) (None, 10) 50 \n",
"_________________________________________________________________\n",
"dense_5 (Dense) (None, 10) 110 \n",
"_________________________________________________________________\n",
"dense_6 (Dense) (None, 3) 33 \n",
"=================================================================\n",
"Total params: 193\n",
"Trainable params: 143\n",
"Non-trainable params: 50\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"model_transfer = Sequential()\n",
"model_transfer.add(Dense(10, activation='relu', input_shape=(4,), trainable=False))\n",
"model_transfer.add(Dense(10, activation='relu'))\n",
"model_transfer.add(Dense(3, activation='softmax'))\n",
" \n",
"model_transfer.summary()"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'{\"class_name\": \"Sequential\", \"keras_version\": \"2.1.6\", \"config\": [{\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_4\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"dtype\": \"float32\", \"activation\": \"relu\", \"trainable\": false, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 10, \"batch_input_shape\": [null, 4], \"use_bias\": true, \"activity_regularizer\": null}}, {\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_5\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"activation\": \"relu\", \"trainable\": true, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 10, \"use_bias\": true, \"activity_regularizer\": null}}, {\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_6\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"activation\": \"softmax\", \"trainable\": true, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 3, \"use_bias\": true, \"activity_regularizer\": null}}], \"backend\": \"tensorflow\"}'"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model_transfer.to_json()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Load transfer model into model architecture table"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n",
"2 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>model_id</th>\n",
" <th>model_arch</th>\n",
" <th>name</th>\n",
" <th>description</th>\n",
" </tr>\n",
" <tr>\n",
" <td>1</td>\n",
" <td>{u'class_name': u'Sequential', u'keras_version': u'2.1.6', u'config': [{u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_1', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'dtype': u'float32', u'activation': u'relu', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'batch_input_shape': [None, 4], u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_2', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'relu', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_3', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'softmax', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 3, u'use_bias': True, u'activity_regularizer': None}}], u'backend': u'tensorflow'}</td>\n",
" <td>Sophie</td>\n",
" <td>A simple model</td>\n",
" </tr>\n",
" <tr>\n",
" <td>2</td>\n",
" <td>{u'class_name': u'Sequential', u'keras_version': u'2.1.6', u'config': [{u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_2', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'dtype': u'float32', u'activation': u'relu', u'trainable': False, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'batch_input_shape': [None, 4], u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_3', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'relu', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_4', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'softmax', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 3, u'use_bias': True, u'activity_regularizer': None}}], u'backend': u'tensorflow'}</td>\n",
" <td>Maria</td>\n",
" <td>A transfer model</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(1, {u'class_name': u'Sequential', u'keras_version': u'2.1.6', u'config': [{u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_1', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'dtype': u'float32', u'activation': u'relu', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'batch_input_shape': [None, 4], u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_2', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'relu', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_3', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'softmax', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 3, u'use_bias': True, u'activity_regularizer': None}}], u'backend': u'tensorflow'}, u'Sophie', u'A simple model'),\n",
" (2, {u'class_name': u'Sequential', u'keras_version': u'2.1.6', u'config': [{u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_2', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'dtype': u'float32', u'activation': u'relu', u'trainable': False, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'batch_input_shape': [None, 4], u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_3', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'relu', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 10, u'use_bias': True, u'activity_regularizer': None}}, {u'class_name': u'Dense', u'config': {u'kernel_initializer': {u'class_name': u'VarianceScaling', u'config': {u'distribution': u'uniform', u'scale': 1.0, u'seed': None, u'mode': u'fan_avg'}}, u'name': u'dense_4', u'kernel_constraint': None, u'bias_regularizer': None, u'bias_constraint': None, u'activation': u'softmax', u'trainable': True, u'kernel_regularizer': None, u'bias_initializer': {u'class_name': u'Zeros', u'config': {}}, u'units': 3, u'use_bias': True, u'activity_regularizer': None}}], u'backend': u'tensorflow'}, u'Maria', u'A transfer model')]"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT madlib.load_keras_model('model_arch_library', -- Output table, \n",
"$$\n",
"{\"class_name\": \"Sequential\", \"keras_version\": \"2.1.6\", \"config\": [{\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_2\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"dtype\": \"float32\", \"activation\": \"relu\", \"trainable\": false, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 10, \"batch_input_shape\": [null, 4], \"use_bias\": true, \"activity_regularizer\": null}}, {\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_3\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"activation\": \"relu\", \"trainable\": true, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 10, \"use_bias\": true, \"activity_regularizer\": null}}, {\"class_name\": \"Dense\", \"config\": {\"kernel_initializer\": {\"class_name\": \"VarianceScaling\", \"config\": {\"distribution\": \"uniform\", \"scale\": 1.0, \"seed\": null, \"mode\": \"fan_avg\"}}, \"name\": \"dense_4\", \"kernel_constraint\": null, \"bias_regularizer\": null, \"bias_constraint\": null, \"activation\": \"softmax\", \"trainable\": true, \"kernel_regularizer\": null, \"bias_initializer\": {\"class_name\": \"Zeros\", \"config\": {}}, \"units\": 3, \"use_bias\": true, \"activity_regularizer\": null}}], \"backend\": \"tensorflow\"}\n",
"$$\n",
"::json, -- JSON blob\n",
" NULL, -- Weights\n",
" 'Maria', -- Name\n",
" 'A transfer model' -- Descr\n",
");\n",
"\n",
"SELECT model_id, model_arch, name, description FROM model_arch_library ORDER BY model_id;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id=\"train2\"></a>\n",
"# 2. Train transfer model\n",
"\n",
"Fetch the weights from a previous MADlib run. (Normally these would be downloaded from a source that trained the same model architecture on a related dataset.)"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"UPDATE model_arch_library \n",
"SET model_weights = iris_model.model_weights \n",
"FROM iris_model \n",
"WHERE model_arch_library.model_id = 2;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now train the model using the transfer model and the pre-trained weights:"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>madlib_keras_fit</th>\n",
" </tr>\n",
" <tr>\n",
" <td></td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[('',)]"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS iris_model, iris_model_summary;\n",
"\n",
"SELECT madlib.madlib_keras_fit('iris_train_packed', -- source table\n",
" 'iris_model', -- model output table\n",
" 'model_arch_library', -- model arch table\n",
" 2, -- model arch id\n",
" $$ loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] $$, -- compile_params\n",
" $$ batch_size=5, epochs=3 $$, -- fit_params\n",
" 10, -- num_iterations\n",
" FALSE, -- use GPUs\n",
" 'iris_test_packed', -- validation dataset\n",
" 2 -- metrics compute frequency\n",
" );"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>source_table</th>\n",
" <th>model</th>\n",
" <th>dependent_varname</th>\n",
" <th>independent_varname</th>\n",
" <th>model_arch_table</th>\n",
" <th>model_id</th>\n",
" <th>compile_params</th>\n",
" <th>fit_params</th>\n",
" <th>num_iterations</th>\n",
" <th>validation_table</th>\n",
" <th>metrics_compute_frequency</th>\n",
" <th>name</th>\n",
" <th>description</th>\n",
" <th>model_type</th>\n",
" <th>model_size</th>\n",
" <th>start_training_time</th>\n",
" <th>end_training_time</th>\n",
" <th>metrics_elapsed_time</th>\n",
" <th>madlib_version</th>\n",
" <th>num_classes</th>\n",
" <th>class_values</th>\n",
" <th>dependent_vartype</th>\n",
" <th>normalizing_const</th>\n",
" <th>metrics_type</th>\n",
" <th>training_metrics_final</th>\n",
" <th>training_loss_final</th>\n",
" <th>training_metrics</th>\n",
" <th>training_loss</th>\n",
" <th>validation_metrics_final</th>\n",
" <th>validation_loss_final</th>\n",
" <th>validation_metrics</th>\n",
" <th>validation_loss</th>\n",
" <th>metrics_iters</th>\n",
" </tr>\n",
" <tr>\n",
" <td>iris_train_packed</td>\n",
" <td>iris_model</td>\n",
" <td>class_text</td>\n",
" <td>attributes</td>\n",
" <td>model_arch_library</td>\n",
" <td>2</td>\n",
" <td> loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] </td>\n",
" <td> batch_size=5, epochs=3 </td>\n",
" <td>10</td>\n",
" <td>iris_test_packed</td>\n",
" <td>2</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" <td>madlib_keras</td>\n",
" <td>0.7900390625</td>\n",
" <td>2019-12-18 18:09:32.439417</td>\n",
" <td>2019-12-18 18:09:34.068824</td>\n",
" <td>[0.853152990341187, 0.990938901901245, 1.11821985244751, 1.24195981025696, 1.62932586669922]</td>\n",
" <td>1.17-dev</td>\n",
" <td>3</td>\n",
" <td>[u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica']</td>\n",
" <td>character varying</td>\n",
" <td>1.0</td>\n",
" <td>[u'accuracy']</td>\n",
" <td>0.983333349228</td>\n",
" <td>0.155750438571</td>\n",
" <td>[0.983333349227905, 0.983333349227905, 0.975000023841858, 0.975000023841858, 0.983333349227905]</td>\n",
" <td>[0.187174424529076, 0.17763115465641, 0.169175431132317, 0.161857321858406, 0.155750438570976]</td>\n",
" <td>0.966666638851</td>\n",
" <td>0.211615949869</td>\n",
" <td>[0.966666638851166, 0.966666638851166, 0.966666638851166, 0.966666638851166, 0.966666638851166]</td>\n",
" <td>[0.244408145546913, 0.234545931220055, 0.225818797945976, 0.218266576528549, 0.211615949869156]</td>\n",
" <td>[2, 4, 6, 8, 10]</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(u'iris_train_packed', u'iris_model', u'class_text', u'attributes', u'model_arch_library', 2, u\" loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'] \", u' batch_size=5, epochs=3 ', 10, u'iris_test_packed', 2, None, None, u'madlib_keras', 0.7900390625, datetime.datetime(2019, 12, 18, 18, 9, 32, 439417), datetime.datetime(2019, 12, 18, 18, 9, 34, 68824), [0.853152990341187, 0.990938901901245, 1.11821985244751, 1.24195981025696, 1.62932586669922], u'1.17-dev', 3, [u'Iris-setosa', u'Iris-versicolor', u'Iris-virginica'], u'character varying', 1.0, [u'accuracy'], 0.983333349228, 0.155750438571, [0.983333349227905, 0.983333349227905, 0.975000023841858, 0.975000023841858, 0.983333349227905], [0.187174424529076, 0.17763115465641, 0.169175431132317, 0.161857321858406, 0.155750438570976], 0.966666638851, 0.211615949869, [0.966666638851166, 0.966666638851166, 0.966666638851166, 0.966666638851166, 0.966666638851166], [0.244408145546913, 0.234545931220055, 0.225818797945976, 0.218266576528549, 0.211615949869156], [2, 4, 6, 8, 10])]"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"SELECT * FROM iris_model_summary;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note loss picks up from where the last training left off:"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n",
"1 rows affected.\n",
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x12f85fdd0>"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
},
{
"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": [
"import pandas as pd\n",
"import numpy as np\n",
"import sys\n",
"import os\n",
"from matplotlib import pyplot as plt\n",
"\n",
"# get accuracy and iteration number\n",
"iters_proxy = %sql SELECT metrics_iters FROM iris_model_summary;\n",
"train_accuracy_proxy = %sql SELECT training_metrics FROM iris_model_summary;\n",
"test_accuracy_proxy = %sql SELECT validation_metrics FROM iris_model_summary;\n",
"\n",
"# get number of points\n",
"num_points_proxy = %sql SELECT array_length(metrics_iters,1) FROM iris_model_summary;\n",
"num_points = num_points_proxy[0]\n",
"\n",
"# reshape to np arrays\n",
"iters = np.array(iters_proxy).reshape(num_points)\n",
"train_accuracy = np.array(train_accuracy_proxy).reshape(num_points)\n",
"test_accuracy = np.array(test_accuracy_proxy).reshape(num_points)\n",
"\n",
"#plot\n",
"plt.title('Iris validation accuracy by iteration - transfer learn')\n",
"plt.xlabel('Iteration number')\n",
"plt.ylabel('Accuracy')\n",
"plt.grid(True)\n",
"plt.plot(iters, train_accuracy, 'g.-', label='Train')\n",
"plt.plot(iters, test_accuracy, 'r.-', label='Test')\n",
"plt.legend()"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x12f8d5990>"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
},
{
"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": [
"# get loss\n",
"train_loss_proxy = %sql SELECT training_loss FROM iris_model_summary;\n",
"test_loss_proxy = %sql SELECT validation_loss FROM iris_model_summary;\n",
"\n",
"# reshape to np arrays\n",
"train_loss = np.array(train_loss_proxy).reshape(num_points)\n",
"test_loss = np.array(test_loss_proxy).reshape(num_points)\n",
"\n",
"#plot\n",
"plt.title('Iris validation loss by iteration - transfer learn')\n",
"plt.xlabel('Iteration number')\n",
"plt.ylabel('Loss')\n",
"plt.grid(True)\n",
"plt.plot(iters, train_loss, 'g.-', label='Train')\n",
"plt.plot(iters, test_loss, 'r.-', label='Test')\n",
"plt.legend()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 1
}