{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# CNN-ek - befejező notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 0.) Inicializáló rész" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Az előző notebookban (vagy mnég azelőtt) definiált segédfüggvények átemelése, melyet most is változtatás nélkül fogunk használni." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using TensorFlow backend.\n" ] } ], "source": [ "import tensorflow as tf\n", "from keras import backend as K\n", "config = tf.ConfigProto()\n", "config.gpu_options.per_process_gpu_memory_fraction=0.095\n", "session = tf.Session(config=config) # Letrehozunk egy TF session-t a megfelelo mem. korlattal\n", "K.set_session(session) # atadjuk azt a Kerasnak" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import math\n", "from keras.models import Model\n", "from keras.layers import Input, Dense, Flatten, Conv2D, MaxPooling2D \n", "from keras.layers import Concatenate, Lambda, Average, Add, Dropout\n", "from keras.optimizers import SGD, Adam\n", "from keras.callbacks import ModelCheckpoint, EarlyStopping\n", "from keras.utils import to_categorical\n", "from matplotlib import pyplot as plt\n", "from random import sample as RS\n", "from keras.metrics import top_k_categorical_accuracy\n", "from keras.preprocessing.image import ImageDataGenerator\n", "from sklearn.metrics import confusion_matrix\n", "\n", "def inTop3(x,y):\n", " return(top_k_categorical_accuracy(x,y,k=3))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from keras.datasets import cifar10\n", "\n", "def mintak_cifar10():\n", " (x_tan,y_tan),(x_tst,y_tst)=cifar10.load_data()\n", " x_tan=x_tan.astype('float32')/255.0\n", " x_tst=x_tst.astype('float32')/255.0\n", " classes=['airplane', 'auto', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']\n", " idx=RS(set(range(y_tan.size)),5)\n", " print('Mintakepek es a cimkeik: '+str([x[0] for x in y_tan[idx]]))\n", " print('Cimkehez tartozo osztalyok: '+str([classes[x[0]] for x in y_tan[idx]]))\n", " \n", " (f, sf)=plt.subplots(1, 5)\n", " f.set_size_inches(16, 6)\n", " \n", " for i in range(5):\n", " img = x_tan[idx[i]]\n", " sf[i].imshow(img)\n", " plt.show()\n", " \n", " y_tan=to_categorical(y_tan).astype('float32')\n", " y_tst=to_categorical(y_tst).astype('float32')\n", " return(x_tan,y_tan,x_tst,y_tst,classes)\n", "\n", "def tanitas_earlystop(model, x_tan, y_tan, epn, tol):\n", " \n", " model_checkpoint = ModelCheckpoint('CNN.hdf5', monitor='val_loss', verbose=1, save_best_only=True)\n", " earlystop=EarlyStopping(monitor='val_loss', patience=tol)\n", " hst=model.fit(x=x_tan, y=y_tan, verbose=1, batch_size=32, epochs=epn, callbacks=[earlystop, model_checkpoint], validation_split=0.1)\n", " model.load_weights('CNN.hdf5')\n", " \n", " plt.title('Tanito gorbek')\n", " plt.xlabel('Epoch')\n", " plt.ylabel('Loss')\n", " \n", " epn=len(hst.history['loss'])\n", " \n", " epi=np.linspace(1,epn,epn)\n", " plt.plot(epi, hst.history['loss'], 'b-', epi, hst.history['val_loss'], 'r-')\n", " plt.legend(['tanito', 'validacios'], loc='upper left')\n", " plt.show()\n", " return model\n", "\n", "def teszt(halo, x_test, y_test):\n", " \n", " tmp=halo.evaluate(x_test,y_test)\n", " \n", " y_pred=np.argmax(halo.predict(x_test),axis=1)\n", " print('Confusion Matrix:')\n", " print(confusion_matrix(np.argmax(y_test, axis=1), y_pred))\n", " print()\n", " print('Loss:'+str(tmp[0])+'; Acc:'+str(tmp[1])+'; Top3Acc:'+str(tmp[2]))\n", " print()\n", " return({'loss':tmp[0], 'acc':tmp[1], 'top3acc':tmp[2]})\n", "\n", "def halo_mentes(model,nev):\n", " model_json=model.to_json()\n", " with open(nev+'.json','w') as json_file:\n", " json_file.write(model_json)\n", " model.save_weights(nev+'.hdf5')\n", " \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Olvassuk be az adathalmazt" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Mintakepek es a cimkeik: [2, 1, 9, 2, 1]\n", "Cimkehez tartozo osztalyok: ['bird', 'auto', 'truck', 'bird', 'auto']\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "(x_tan,y_tan,x_tst,y_tst,cimke)=mintak_cifar10()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.) Transfer learning alkalmazása" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sok esetben nincs elég tanítóminta a konvolúciós rétegek tanításához. Gyakoran alkalmazott forgatókönyv ilyenkor más, a feladatunkhoz lehetőleg legjobban hasonlító, de elegendő nagy mintazsámú halmazon betanított konvolúciós rétegekből álló háló, mint jellemzőkiemelő háló alkalmazása. Ennek kimenetét adjuk általában egy 1 rejtett rétegű MLP-nek, melynek feladata ebben az esetben a kapott jellemzők alapján a konkrét probléma megoldása." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Transfer learninges háló létrehozása" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Egészítsük ki úgy az alábbi kódrélszletet, hogy a MobileNet-et transfer learninges jellemzőkiemelőként használja fel. Figyeljük meg, hogy a Keras által külön nem támogatott, de a Tensorflow API-ja által tartalmazott, képeket átméretező réteget hogyan hívhatjuk meg (lambda rétegként)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def atmer(kep):\n", " return(K.tf.image.resize_images(kep, (128,128)))\n", "\n", "from keras.applications import mobilenet\n", "\n", "def get_tfn(x_t, y_t):\n", " bem = Input(shape=x_t[0].shape, dtype='float32')\n", " x = Lambda(atmer, input_shape=x_t[0].shape)(bem)\n", " \n", " rnt = mobilenet.MobileNet(input_shape=(128, 128, 3), include_top=False, input_tensor=x)\n", " \n", " y = MaxPooling2D(pool_size=(2, 2))(rnt.output)\n", " y = Flatten()(y)\n", " y = Dense(120 , activation='tanh')(y)\n", " y = Dense(y_t.shape[1], activation='softmax')(y)\n", " \n", " for layer in rnt.layers:\n", " layer.trainable=False\n", " \n", " model = Model(inputs=bem, outputs=y)\n", " model.compile(optimizer=SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True), loss='categorical_crossentropy', metrics=['accuracy', inTop3])\n", " \n", " print(model.summary())\n", " \n", " return model" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "_________________________________________________________________\n", "Layer (type) Output Shape Param # \n", "=================================================================\n", "input_1 (InputLayer) (None, 32, 32, 3) 0 \n", "_________________________________________________________________\n", "lambda_1 (Lambda) (None, 128, 128, 3) 0 \n", "_________________________________________________________________\n", "conv1_pad (ZeroPadding2D) (None, 129, 129, 3) 0 \n", "_________________________________________________________________\n", "conv1 (Conv2D) (None, 64, 64, 32) 864 \n", "_________________________________________________________________\n", "conv1_bn (BatchNormalization (None, 64, 64, 32) 128 \n", "_________________________________________________________________\n", "conv1_relu (ReLU) (None, 64, 64, 32) 0 \n", "_________________________________________________________________\n", "conv_dw_1 (DepthwiseConv2D) (None, 64, 64, 32) 288 \n", "_________________________________________________________________\n", "conv_dw_1_bn (BatchNormaliza (None, 64, 64, 32) 128 \n", "_________________________________________________________________\n", "conv_dw_1_relu (ReLU) (None, 64, 64, 32) 0 \n", "_________________________________________________________________\n", "conv_pw_1 (Conv2D) (None, 64, 64, 64) 2048 \n", "_________________________________________________________________\n", "conv_pw_1_bn (BatchNormaliza (None, 64, 64, 64) 256 \n", "_________________________________________________________________\n", "conv_pw_1_relu (ReLU) (None, 64, 64, 64) 0 \n", "_________________________________________________________________\n", "conv_pad_2 (ZeroPadding2D) (None, 65, 65, 64) 0 \n", "_________________________________________________________________\n", "conv_dw_2 (DepthwiseConv2D) (None, 32, 32, 64) 576 \n", "_________________________________________________________________\n", "conv_dw_2_bn (BatchNormaliza (None, 32, 32, 64) 256 \n", "_________________________________________________________________\n", "conv_dw_2_relu (ReLU) (None, 32, 32, 64) 0 \n", "_________________________________________________________________\n", "conv_pw_2 (Conv2D) (None, 32, 32, 128) 8192 \n", "_________________________________________________________________\n", "conv_pw_2_bn (BatchNormaliza (None, 32, 32, 128) 512 \n", "_________________________________________________________________\n", "conv_pw_2_relu (ReLU) (None, 32, 32, 128) 0 \n", "_________________________________________________________________\n", "conv_dw_3 (DepthwiseConv2D) (None, 32, 32, 128) 1152 \n", "_________________________________________________________________\n", "conv_dw_3_bn (BatchNormaliza (None, 32, 32, 128) 512 \n", "_________________________________________________________________\n", "conv_dw_3_relu (ReLU) (None, 32, 32, 128) 0 \n", "_________________________________________________________________\n", "conv_pw_3 (Conv2D) (None, 32, 32, 128) 16384 \n", "_________________________________________________________________\n", "conv_pw_3_bn (BatchNormaliza (None, 32, 32, 128) 512 \n", "_________________________________________________________________\n", "conv_pw_3_relu (ReLU) (None, 32, 32, 128) 0 \n", "_________________________________________________________________\n", "conv_pad_4 (ZeroPadding2D) (None, 33, 33, 128) 0 \n", "_________________________________________________________________\n", "conv_dw_4 (DepthwiseConv2D) (None, 16, 16, 128) 1152 \n", "_________________________________________________________________\n", "conv_dw_4_bn (BatchNormaliza (None, 16, 16, 128) 512 \n", "_________________________________________________________________\n", "conv_dw_4_relu (ReLU) (None, 16, 16, 128) 0 \n", "_________________________________________________________________\n", "conv_pw_4 (Conv2D) (None, 16, 16, 256) 32768 \n", "_________________________________________________________________\n", "conv_pw_4_bn (BatchNormaliza (None, 16, 16, 256) 1024 \n", "_________________________________________________________________\n", "conv_pw_4_relu (ReLU) (None, 16, 16, 256) 0 \n", "_________________________________________________________________\n", "conv_dw_5 (DepthwiseConv2D) (None, 16, 16, 256) 2304 \n", "_________________________________________________________________\n", "conv_dw_5_bn (BatchNormaliza (None, 16, 16, 256) 1024 \n", "_________________________________________________________________\n", "conv_dw_5_relu (ReLU) (None, 16, 16, 256) 0 \n", "_________________________________________________________________\n", "conv_pw_5 (Conv2D) (None, 16, 16, 256) 65536 \n", "_________________________________________________________________\n", "conv_pw_5_bn (BatchNormaliza (None, 16, 16, 256) 1024 \n", "_________________________________________________________________\n", "conv_pw_5_relu (ReLU) (None, 16, 16, 256) 0 \n", "_________________________________________________________________\n", "conv_pad_6 (ZeroPadding2D) (None, 17, 17, 256) 0 \n", "_________________________________________________________________\n", "conv_dw_6 (DepthwiseConv2D) (None, 8, 8, 256) 2304 \n", "_________________________________________________________________\n", "conv_dw_6_bn (BatchNormaliza (None, 8, 8, 256) 1024 \n", "_________________________________________________________________\n", "conv_dw_6_relu (ReLU) (None, 8, 8, 256) 0 \n", "_________________________________________________________________\n", "conv_pw_6 (Conv2D) (None, 8, 8, 512) 131072 \n", "_________________________________________________________________\n", "conv_pw_6_bn (BatchNormaliza (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_pw_6_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_dw_7 (DepthwiseConv2D) (None, 8, 8, 512) 4608 \n", "_________________________________________________________________\n", "conv_dw_7_bn (BatchNormaliza (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_dw_7_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_pw_7 (Conv2D) (None, 8, 8, 512) 262144 \n", "_________________________________________________________________\n", "conv_pw_7_bn (BatchNormaliza (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_pw_7_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_dw_8 (DepthwiseConv2D) (None, 8, 8, 512) 4608 \n", "_________________________________________________________________\n", "conv_dw_8_bn (BatchNormaliza (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_dw_8_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_pw_8 (Conv2D) (None, 8, 8, 512) 262144 \n", "_________________________________________________________________\n", "conv_pw_8_bn (BatchNormaliza (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_pw_8_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_dw_9 (DepthwiseConv2D) (None, 8, 8, 512) 4608 \n", "_________________________________________________________________\n", "conv_dw_9_bn (BatchNormaliza (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_dw_9_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_pw_9 (Conv2D) (None, 8, 8, 512) 262144 \n", "_________________________________________________________________\n", "conv_pw_9_bn (BatchNormaliza (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_pw_9_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_dw_10 (DepthwiseConv2D) (None, 8, 8, 512) 4608 \n", "_________________________________________________________________\n", "conv_dw_10_bn (BatchNormaliz (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_dw_10_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_pw_10 (Conv2D) (None, 8, 8, 512) 262144 \n", "_________________________________________________________________\n", "conv_pw_10_bn (BatchNormaliz (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_pw_10_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_dw_11 (DepthwiseConv2D) (None, 8, 8, 512) 4608 \n", "_________________________________________________________________\n", "conv_dw_11_bn (BatchNormaliz (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_dw_11_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_pw_11 (Conv2D) (None, 8, 8, 512) 262144 \n", "_________________________________________________________________\n", "conv_pw_11_bn (BatchNormaliz (None, 8, 8, 512) 2048 \n", "_________________________________________________________________\n", "conv_pw_11_relu (ReLU) (None, 8, 8, 512) 0 \n", "_________________________________________________________________\n", "conv_pad_12 (ZeroPadding2D) (None, 9, 9, 512) 0 \n", "_________________________________________________________________\n", "conv_dw_12 (DepthwiseConv2D) (None, 4, 4, 512) 4608 \n", "_________________________________________________________________\n", "conv_dw_12_bn (BatchNormaliz (None, 4, 4, 512) 2048 \n", "_________________________________________________________________\n", "conv_dw_12_relu (ReLU) (None, 4, 4, 512) 0 \n", "_________________________________________________________________\n", "conv_pw_12 (Conv2D) (None, 4, 4, 1024) 524288 \n", "_________________________________________________________________\n", "conv_pw_12_bn (BatchNormaliz (None, 4, 4, 1024) 4096 \n", "_________________________________________________________________\n", "conv_pw_12_relu (ReLU) (None, 4, 4, 1024) 0 \n", "_________________________________________________________________\n", "conv_dw_13 (DepthwiseConv2D) (None, 4, 4, 1024) 9216 \n", "_________________________________________________________________\n", "conv_dw_13_bn (BatchNormaliz (None, 4, 4, 1024) 4096 \n", "_________________________________________________________________\n", "conv_dw_13_relu (ReLU) (None, 4, 4, 1024) 0 \n", "_________________________________________________________________\n", "conv_pw_13 (Conv2D) (None, 4, 4, 1024) 1048576 \n", "_________________________________________________________________\n", "conv_pw_13_bn (BatchNormaliz (None, 4, 4, 1024) 4096 \n", "_________________________________________________________________\n", "conv_pw_13_relu (ReLU) (None, 4, 4, 1024) 0 \n", "_________________________________________________________________\n", "max_pooling2d_1 (MaxPooling2 (None, 2, 2, 1024) 0 \n", "_________________________________________________________________\n", "flatten_1 (Flatten) (None, 4096) 0 \n", "_________________________________________________________________\n", "dense_1 (Dense) (None, 120) 491640 \n", "_________________________________________________________________\n", "dense_2 (Dense) (None, 10) 1210 \n", "=================================================================\n", "Total params: 3,721,714\n", "Trainable params: 492,850\n", "Non-trainable params: 3,228,864\n", "_________________________________________________________________\n", "None\n", "Train on 45000 samples, validate on 5000 samples\n", "Epoch 1/15\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "36576/45000 [=======================>......] - ETA: 3s - loss: 0.7858 - acc: 0.7337 - inTop3: 0.9314" ] }, { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mtfn\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mget_tfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx_tan\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0my_tan\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mtfn\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtanitas_earlystop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtfn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx_tan\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_tan\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m15\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mhalo_mentes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtfn\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'cnn_tf1'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mtanitas_earlystop\u001b[0;34m(model, x_tan, y_tan, epn, tol)\u001b[0m\n\u001b[1;32m 26\u001b[0m \u001b[0mmodel_checkpoint\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mModelCheckpoint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'CNN.hdf5'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmonitor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'val_loss'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mverbose\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msave_best_only\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[0mearlystop\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mEarlyStopping\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmonitor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'val_loss'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpatience\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtol\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 28\u001b[0;31m \u001b[0mhst\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mx_tan\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0my_tan\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mverbose\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbatch_size\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m32\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mepochs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mepn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcallbacks\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mearlystop\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmodel_checkpoint\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalidation_split\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 29\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload_weights\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'CNN.hdf5'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 30\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/keras/engine/training.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)\u001b[0m\n\u001b[1;32m 1035\u001b[0m \u001b[0minitial_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0minitial_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1036\u001b[0m \u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1037\u001b[0;31m validation_steps=validation_steps)\n\u001b[0m\u001b[1;32m 1038\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1039\u001b[0m def evaluate(self, x=None, y=None,\n", "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/keras/engine/training_arrays.py\u001b[0m in \u001b[0;36mfit_loop\u001b[0;34m(model, f, ins, out_labels, batch_size, epochs, verbose, callbacks, val_f, val_ins, shuffle, callback_metrics, initial_epoch, steps_per_epoch, validation_steps)\u001b[0m\n\u001b[1;32m 197\u001b[0m \u001b[0mins_batch\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mins_batch\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtoarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 198\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 199\u001b[0;31m \u001b[0mouts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mins_batch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 200\u001b[0m \u001b[0mouts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mto_list\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mouts\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 201\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mo\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout_labels\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mouts\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, inputs)\u001b[0m\n\u001b[1;32m 2664\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_legacy_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2665\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2666\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2667\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2668\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mpy_any\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mis_tensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0minputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py\u001b[0m in \u001b[0;36m_call\u001b[0;34m(self, inputs)\u001b[0m\n\u001b[1;32m 2634\u001b[0m \u001b[0msymbol_vals\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2635\u001b[0m session)\n\u001b[0;32m-> 2636\u001b[0;31m \u001b[0mfetched\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_callable_fn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0marray_vals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2637\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfetched\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2638\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/tensorflow/python/client/session.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *args)\u001b[0m\n\u001b[1;32m 1449\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_session\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_created_with_new_api\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1450\u001b[0m return tf_session.TF_SessionRunCallable(\n\u001b[0;32m-> 1451\u001b[0;31m self._session._session, self._handle, args, status, None)\n\u001b[0m\u001b[1;32m 1452\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1453\u001b[0m return tf_session.TF_DeprecatedSessionRunCallable(\n", "\u001b[0;31mKeyboardInterrupt\u001b[0m: " ] } ], "source": [ "tfn=get_tfn(x_tan,y_tan)\n", "tfn=tanitas_earlystop(tfn, x_tan, y_tan, 15, 5)\n", "halo_mentes(tfn,'cnn_tf1')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Önálló feladat - tanítás gyorsítása " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Jelentősen lelassult egy tanító epoch futása, melynek oka, hogy a jellemzőkiemelést végző rétegen át kell kergetni a képeket. Mivel ezt minden epochnál meg kell tenni, ezért ez mindig overhead-et jelent. Érdemes ezért a jellemzőkiemelés eredmnényét egy változóban eltárolni, majd csak az ebben mentett bemenetekre a végső teljesen összekötött rétegeket tanítani. Persze nem alkalmazható a módszer, ha augmentálni is kívánunk futási időben." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def get_RNkim(x_t, y_t=None):\n", " \n", " bem = Input(shape=x_t[0].shape, dtype='float32')\n", " x = Lambda(atmer, input_shape=x_t[0].shape)(bem)\n", " \n", " rnt = mobilenet.MobileNet(input_shape=(128, 128, 3), include_top=False, input_tensor=x)\n", " \n", " y = MaxPooling2D(pool_size=(2, 2))(rnt.output)\n", " y = Flatten()(y)\n", " model=Model(inputs=bem, outputs=y)\n", " \n", " x_jel = model.predict(x_t)\n", " \n", " return (x_jel, model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Definiáljukl a ResNet fölé kerülő hálót, mérete maradjon az előzőeknek megfelelő." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def get_tfMLP(x_t, y_t, bem=None):\n", " \n", " if (bem is None):\n", " bem = Input(shape=x_t[0].shape, dtype='float32')\n", " \n", " y = Dense(120 , activation='tanh')(bem)\n", " y = Dense(y_t.shape[1], activation='softmax')(y)\n", " \n", " model = Model(inputs=bem, outputs=y)\n", " model.compile(optimizer=SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True), loss='categorical_crossentropy', metrics=['accuracy', inTop3])\n", " \n", " print(model.summary())\n", " return model\n", " " ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "_________________________________________________________________\n", "Layer (type) Output Shape Param # \n", "=================================================================\n", "input_2 (InputLayer) (None, 4096) 0 \n", "_________________________________________________________________\n", "dense_1 (Dense) (None, 120) 491640 \n", "_________________________________________________________________\n", "dense_2 (Dense) (None, 10) 1210 \n", "=================================================================\n", "Total params: 492,850\n", "Trainable params: 492,850\n", "Non-trainable params: 0\n", "_________________________________________________________________\n", "None\n", "Train on 45000 samples, validate on 5000 samples\n", "Epoch 1/15\n", "45000/45000 [==============================] - 6s 128us/step - loss: 0.7396 - acc: 0.7509 - inTop3: 0.9416 - val_loss: 0.6609 - val_acc: 0.7702 - val_inTop3: 0.9514\n", "\n", "Epoch 00001: val_loss improved from inf to 0.66093, saving model to CNN.hdf5\n", "Epoch 2/15\n", "45000/45000 [==============================] - 6s 123us/step - loss: 0.6733 - acc: 0.7707 - inTop3: 0.9484 - val_loss: 0.6089 - val_acc: 0.7882 - val_inTop3: 0.9606\n", "\n", "Epoch 00002: val_loss improved from 0.66093 to 0.60889, saving model to CNN.hdf5\n", "Epoch 3/15\n", "45000/45000 [==============================] - 6s 123us/step - loss: 0.6351 - acc: 0.7807 - inTop3: 0.9531 - val_loss: 0.5780 - val_acc: 0.7978 - val_inTop3: 0.9624\n", "\n", "Epoch 00003: val_loss improved from 0.60889 to 0.57802, saving model to CNN.hdf5\n", "Epoch 4/15\n", "45000/45000 [==============================] - 6s 123us/step - loss: 0.6208 - acc: 0.7880 - inTop3: 0.9566 - val_loss: 0.6022 - val_acc: 0.7950 - val_inTop3: 0.9562\n", "\n", "Epoch 00004: val_loss did not improve from 0.57802\n", "Epoch 5/15\n", "45000/45000 [==============================] - 6s 123us/step - loss: 0.5998 - acc: 0.7958 - inTop3: 0.9600 - val_loss: 0.6200 - val_acc: 0.7824 - val_inTop3: 0.9616\n", "\n", "Epoch 00005: val_loss did not improve from 0.57802\n", "Epoch 6/15\n", "45000/45000 [==============================] - 6s 124us/step - loss: 0.5762 - acc: 0.8028 - inTop3: 0.9614 - val_loss: 0.5768 - val_acc: 0.8064 - val_inTop3: 0.9648\n", "\n", "Epoch 00006: val_loss improved from 0.57802 to 0.57683, saving model to CNN.hdf5\n", "Epoch 7/15\n", "45000/45000 [==============================] - 6s 124us/step - loss: 0.5416 - acc: 0.8157 - inTop3: 0.9648 - val_loss: 0.5909 - val_acc: 0.8076 - val_inTop3: 0.9682\n", "\n", "Epoch 00007: val_loss did not improve from 0.57683\n", "Epoch 8/15\n", "45000/45000 [==============================] - 6s 123us/step - loss: 0.5307 - acc: 0.8201 - inTop3: 0.9652 - val_loss: 0.5541 - val_acc: 0.8116 - val_inTop3: 0.9650\n", "\n", "Epoch 00008: val_loss improved from 0.57683 to 0.55408, saving model to CNN.hdf5\n", "Epoch 9/15\n", "45000/45000 [==============================] - 6s 124us/step - loss: 0.5284 - acc: 0.8206 - inTop3: 0.9660 - val_loss: 0.5238 - val_acc: 0.8230 - val_inTop3: 0.9696\n", "\n", "Epoch 00009: val_loss improved from 0.55408 to 0.52382, saving model to CNN.hdf5\n", "Epoch 10/15\n", "45000/45000 [==============================] - 6s 124us/step - loss: 0.5039 - acc: 0.8293 - inTop3: 0.9692 - val_loss: 0.5350 - val_acc: 0.8136 - val_inTop3: 0.9672\n", "\n", "Epoch 00010: val_loss did not improve from 0.52382\n", "Epoch 11/15\n", "45000/45000 [==============================] - 6s 124us/step - loss: 0.4945 - acc: 0.8333 - inTop3: 0.9699 - val_loss: 0.5223 - val_acc: 0.8248 - val_inTop3: 0.9672\n", "\n", "Epoch 00011: val_loss improved from 0.52382 to 0.52227, saving model to CNN.hdf5\n", "Epoch 12/15\n", "45000/45000 [==============================] - 6s 124us/step - loss: 0.4914 - acc: 0.8319 - inTop3: 0.9704 - val_loss: 0.4965 - val_acc: 0.8370 - val_inTop3: 0.9702\n", "\n", "Epoch 00012: val_loss improved from 0.52227 to 0.49650, saving model to CNN.hdf5\n", "Epoch 13/15\n", "45000/45000 [==============================] - 6s 123us/step - loss: 0.4736 - acc: 0.8395 - inTop3: 0.9726 - val_loss: 0.5174 - val_acc: 0.8268 - val_inTop3: 0.9708\n", "\n", "Epoch 00013: val_loss did not improve from 0.49650\n", "Epoch 14/15\n", "45000/45000 [==============================] - 6s 124us/step - loss: 0.4665 - acc: 0.8418 - inTop3: 0.9717 - val_loss: 0.5217 - val_acc: 0.8250 - val_inTop3: 0.9676\n", "\n", "Epoch 00014: val_loss did not improve from 0.49650\n", "Epoch 15/15\n", "45000/45000 [==============================] - 6s 124us/step - loss: 0.4735 - acc: 0.8372 - inTop3: 0.9712 - val_loss: 0.5275 - val_acc: 0.8242 - val_inTop3: 0.9720\n", "\n", "Epoch 00015: val_loss did not improve from 0.49650\n" ] }, { "data": { "image/png": "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MNOnTwdg+PDh7NmzJ1ShOedcthX6ZFG8OMTFwZYtcDD9DschkNdkMXToUDp16gR4snDORU+hTxYA1apZC2PTptBfe/DgwaxcuZLmzZtz5513ct5559GyZUuaNWvGxx9/DMDq1atp1KgR119/PU2aNKFLly7sDfSLDRw4kIkTJ/LSSy+xfv16OnbsSMeOVk7rvffeo1mzZjRt2pT77rsv9ME751xAWAe485M77oD584///N69kJoKJ5wA2R3Dbd4chg/P/Jynn36axYsXM3/+fFJSUtizZw/ly5dn8+bNtG3blh49bGLY8uXLee+993j99de54oor+PDDD+nfv//h69x222288MILzJw5k7i4ONavX899993H3LlzqVSpEl26dGHSpEn07JnhYnfnnMsTb1kElChhrYuUlPDdQ1V54IEHSEhIoFOnTqxbt44/AoMl9erVo3lzq5vYqlUrVq9enem15syZQ4cOHYiPj6dYsWL069eP2bNnhy9451yhVmhaFlm1AFRh2TJLFk2bZr91kRPjxo0jOTmZuXPnUrx4cerWrXt4zULJkiUPn1e0aNHD3VDOOZcfeMsiQASqV4f9+2H79tBdt1y5cuzatQuAHTt2ULVqVYoXL87MmTNZsyZblYEzvFabNm346quv2Lx5M6mpqbz33nucc845oQvcOeeCFJqWRXZUrAglS9pU2ooVQ9O6qFKlCu3ataNp06a0bt2aZcuW0axZMxITEznttNNydK1BgwbRtWtXatasycyZM3n66afp2LEjqsoFF1zAxRdnVgHeOedyL2b24E5MTNT0mx8tXbqURo0a5eg6mzbBb7/BaadB2bKhjDB25Obv6pzLn0RkbqDCd6a8GyqdKlWgWDFrXTjnnDOeLNIpWhTi423cwuvlOeec8WSRgapVbbwiXCVAnHOuoPFkkYHixa07avPm8JQAcc65gsaTxXGklQDxrb2dc86TxXGVLg0VKtjsqEOHoh2Nc85FlyeLTFSvbiu6t2yJ3D3LBubrrl+/nssvvzzDczp06ED6acLZkZSUxG233Zan+JxzhZMvystE2bJQpoxNo42LC08JkOOpWbMmEydODOk1ExMTSUzMcjq1c84dw1sWmQguAbJjR+6uMXjwYEaOHHn450ceeYTHH388w1LlwVavXk3Tpk0B2Lt3L3369KFRo0ZccsklR9WNuvHG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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "K.clear_session()\n", "(x_RN, almod) = get_RNkim(x_tan, y_tan)\n", "tfMLP = get_tfMLP(x_RN,y_tan)\n", "tfMLP = tanitas_earlystop(tfMLP, x_RN, y_tan, 15, 5)\n", "halo_mentes(tfMLP,'tf_MLP')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Eddigi legjobb eredményeket most sikerült elérni: 0.5-ös validációs loss, 82% feletti pontossággal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Önálló feladat - MobileNet, illetve konstruált MLP összekpacsolása egy hálóba" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ahhoz, hogy az egészet egy hálóként tudjuk használni a két részhálót össze kell kapcsolnunk." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "def link_transf(al_halo, fel_halo):\n", " bem = Input(shape=al_halo.layers[0].output_shape[1:4], dtype='float32')\n", " x=al_halo(bem)\n", " y=fel_halo(x)\n", " \n", " model=Model(inputs=bem, outputs=y)\n", " model.compile(optimizer=SGD(lr=0, decay=0), loss='categorical_crossentropy', metrics=['accuracy', inTop3])\n", " return (model)\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "tran_halo=link_transf(almod, tfMLP)\n", "halo_mentes(tran_halo,'transf_CNN')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Teszthalmazon vizsgáljuk meg a háló teljesítményét" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10000/10000 [==============================] - 4s 387us/step\n", "Confusion Matrix:\n", "[[906 4 11 10 15 2 1 6 37 8]\n", " [ 20 929 0 1 0 1 3 1 14 31]\n", " [ 72 0 678 56 91 29 57 5 11 1]\n", " [ 25 2 25 753 49 86 30 17 8 5]\n", " [ 17 1 25 43 829 15 30 36 3 1]\n", " [ 6 3 17 169 39 715 25 26 0 0]\n", " [ 8 1 15 54 22 14 881 0 4 1]\n", " [ 19 2 5 39 71 36 6 817 4 1]\n", " [ 85 13 7 9 7 3 3 1 856 16]\n", " [ 31 77 0 5 2 0 1 5 15 864]]\n", "\n", "Loss:0.5362028652191162; Acc:0.8228; Top3Acc:0.9651\n", "\n" ] }, { "data": { "text/plain": [ "{'loss': 0.5362028652191162, 'acc': 0.8228, 'top3acc': 0.9651}" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "teszt(tran_halo,x_tst,y_tst)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.) Ensemble" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Különböző osztályozási versenyeket megnyerő neurális hálók kivétel nélkül szakértő együttesként, úgynevezett ensemble-ként épülnek fel. Megjegyzés: a dropout, mint exponenciálisan sok szakértőt előállító eljárás is ezen módszerekre vezethető vissza.\n", "\n", "Mi most a k kereszt validáció során betanított hálókból hozzuk létre a szakértő együttesünket." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "def ensemble(mf, x, y, epn, tol, db=3, bm=32):\n", " N=x.shape[0] \n", " M=N//db\n", " idx=set(range(N))\n", " idxt=idx\n", " models=[None]*db\n", " \n", " model_chkp=ModelCheckpoint('enhalo.hdf5', monitor='val_loss', save_best_only=True)\n", " earlystop=EarlyStopping(monitor='val_loss', patience=tol)\n", " bem=Input(shape=x[0].shape, dtype='float32')\n", " \n", " for i in range(db):\n", " print(str(i+1)+'. halo tanitasa:')\n", " idxa=set(RS(idxt,M))\n", " idxt=idxt-idxa\n", " idxat=list(idx-idxa)\n", " idxav=list(idxa)\n", " x_val=x[idxav]\n", " y_val=y[idxav]\n", " x_tan=x[idxat]\n", " y_tan=y[idxat]\n", " models[i]=mf(x, y, bem)\n", " hst=models[i].fit(x=x_tan, y=y_tan, batch_size=bm, epochs=epn, callbacks=[model_chkp, earlystop], validation_data=(x_val, y_val))\n", " models[i].load_weights('enhalo.hdf5')\n", " \n", " kimenetek=[ahalo.output for ahalo in models]\n", " y = Average()(kimenetek)\n", " model = Model(inputs=bem, outputs=y)\n", " model.compile(optimizer=SGD(lr=0, decay=0, momentum=1.0), loss='categorical_crossentropy', metrics=['accuracy', inTop3])\n", " return(model)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1. halo tanitasa:\n", "_________________________________________________________________\n", "Layer (type) Output Shape Param # \n", "=================================================================\n", "input_6 (InputLayer) (None, 4096) 0 \n", "_________________________________________________________________\n", "dense_3 (Dense) (None, 120) 491640 \n", "_________________________________________________________________\n", "dense_4 (Dense) (None, 10) 1210 \n", "=================================================================\n", "Total params: 492,850\n", "Trainable params: 492,850\n", "Non-trainable params: 0\n", "_________________________________________________________________\n", "None\n", "Train on 33334 samples, validate on 16666 samples\n", "Epoch 1/10\n", "33334/33334 [==============================] - 5s 156us/step - loss: 0.7472 - acc: 0.7471 - inTop3: 0.9409 - val_loss: 0.6954 - val_acc: 0.7655 - val_inTop3: 0.9465\n", "Epoch 2/10\n", "33334/33334 [==============================] - 5s 148us/step - loss: 0.6722 - acc: 0.7695 - inTop3: 0.9514 - val_loss: 0.6398 - val_acc: 0.7852 - val_inTop3: 0.9560\n", "Epoch 3/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.6649 - acc: 0.7719 - inTop3: 0.9521 - val_loss: 0.6601 - val_acc: 0.7810 - val_inTop3: 0.9484\n", "Epoch 4/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.6394 - acc: 0.7816 - inTop3: 0.9521 - val_loss: 0.6533 - val_acc: 0.7816 - val_inTop3: 0.9488\n", "Epoch 5/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.6262 - acc: 0.7842 - inTop3: 0.9567 - val_loss: 0.6094 - val_acc: 0.7967 - val_inTop3: 0.9542\n", "Epoch 6/10\n", "33334/33334 [==============================] - 5s 148us/step - loss: 0.6008 - acc: 0.7910 - inTop3: 0.9603 - val_loss: 0.6407 - val_acc: 0.7778 - val_inTop3: 0.9536\n", "Epoch 7/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.5859 - acc: 0.7970 - inTop3: 0.9627 - val_loss: 0.6283 - val_acc: 0.7878 - val_inTop3: 0.9534\n", "Epoch 8/10\n", "33334/33334 [==============================] - 5s 148us/step - loss: 0.5675 - acc: 0.8043 - inTop3: 0.9624 - val_loss: 0.6089 - val_acc: 0.7937 - val_inTop3: 0.9574\n", "Epoch 9/10\n", "33334/33334 [==============================] - 5s 146us/step - loss: 0.5606 - acc: 0.8091 - inTop3: 0.9630 - val_loss: 0.5944 - val_acc: 0.7980 - val_inTop3: 0.9576\n", "Epoch 10/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.5396 - acc: 0.8144 - inTop3: 0.9672 - val_loss: 0.5833 - val_acc: 0.8059 - val_inTop3: 0.9563\n", "2. halo tanitasa:\n", "_________________________________________________________________\n", "Layer (type) Output Shape Param # \n", "=================================================================\n", "input_6 (InputLayer) (None, 4096) 0 \n", "_________________________________________________________________\n", "dense_5 (Dense) (None, 120) 491640 \n", "_________________________________________________________________\n", "dense_6 (Dense) (None, 10) 1210 \n", "=================================================================\n", "Total params: 492,850\n", "Trainable params: 492,850\n", "Non-trainable params: 0\n", "_________________________________________________________________\n", "None\n", "Train on 33334 samples, validate on 16666 samples\n", "Epoch 1/10\n", "33334/33334 [==============================] - 5s 160us/step - loss: 0.7648 - acc: 0.7451 - inTop3: 0.9363 - val_loss: 0.7547 - val_acc: 0.7502 - val_inTop3: 0.9389\n", "Epoch 2/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.7114 - acc: 0.7566 - inTop3: 0.9457 - val_loss: 0.6871 - val_acc: 0.7675 - val_inTop3: 0.9519\n", "Epoch 3/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.6739 - acc: 0.7685 - inTop3: 0.9502 - val_loss: 0.6829 - val_acc: 0.7677 - val_inTop3: 0.9497\n", "Epoch 4/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.6548 - acc: 0.7741 - inTop3: 0.9548 - val_loss: 0.6710 - val_acc: 0.7728 - val_inTop3: 0.9514\n", "Epoch 5/10\n", "33334/33334 [==============================] - 5s 146us/step - loss: 0.6347 - acc: 0.7832 - inTop3: 0.9555 - val_loss: 0.6434 - val_acc: 0.7866 - val_inTop3: 0.9537\n", "Epoch 6/10\n", "33334/33334 [==============================] - 5s 148us/step - loss: 0.6059 - acc: 0.7955 - inTop3: 0.9581 - val_loss: 0.6527 - val_acc: 0.7727 - val_inTop3: 0.9530\n", "Epoch 7/10\n", "33334/33334 [==============================] - 5s 146us/step - loss: 0.5968 - acc: 0.7958 - inTop3: 0.9600 - val_loss: 0.5959 - val_acc: 0.8005 - val_inTop3: 0.9626\n", "Epoch 8/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.5874 - acc: 0.7986 - inTop3: 0.9621 - val_loss: 0.6016 - val_acc: 0.7944 - val_inTop3: 0.9582\n", "Epoch 9/10\n", "33334/33334 [==============================] - 5s 146us/step - loss: 0.5529 - acc: 0.8122 - inTop3: 0.9649 - val_loss: 0.5896 - val_acc: 0.8036 - val_inTop3: 0.9617\n", "Epoch 10/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.5421 - acc: 0.8181 - inTop3: 0.9654 - val_loss: 0.5729 - val_acc: 0.8048 - val_inTop3: 0.9623\n", "3. halo tanitasa:\n", "_________________________________________________________________\n", "Layer (type) Output Shape Param # \n", "=================================================================\n", "input_6 (InputLayer) (None, 4096) 0 \n", "_________________________________________________________________\n", "dense_7 (Dense) (None, 120) 491640 \n", "_________________________________________________________________\n", "dense_8 (Dense) (None, 10) 1210 \n", "=================================================================\n", "Total params: 492,850\n", "Trainable params: 492,850\n", "Non-trainable params: 0\n", "_________________________________________________________________\n", "None\n", "Train on 33334 samples, validate on 16666 samples\n", "Epoch 1/10\n", "33334/33334 [==============================] - 5s 158us/step - loss: 0.7772 - acc: 0.7408 - inTop3: 0.9345 - val_loss: 0.7459 - val_acc: 0.7481 - val_inTop3: 0.9341\n", "Epoch 2/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.6871 - acc: 0.7659 - inTop3: 0.9470 - val_loss: 0.7105 - val_acc: 0.7587 - val_inTop3: 0.9387\n", "Epoch 3/10\n", "33334/33334 [==============================] - 5s 146us/step - loss: 0.6422 - acc: 0.7803 - inTop3: 0.9537 - val_loss: 0.6657 - val_acc: 0.7788 - val_inTop3: 0.9504\n", "Epoch 4/10\n", "33334/33334 [==============================] - 5s 146us/step - loss: 0.6228 - acc: 0.7865 - inTop3: 0.9548 - val_loss: 0.6473 - val_acc: 0.7853 - val_inTop3: 0.9549\n", "Epoch 5/10\n", "33334/33334 [==============================] - 5s 145us/step - loss: 0.6049 - acc: 0.7923 - inTop3: 0.9588 - val_loss: 0.6059 - val_acc: 0.7989 - val_inTop3: 0.9569\n", "Epoch 6/10\n", "33334/33334 [==============================] - 5s 145us/step - loss: 0.5822 - acc: 0.8029 - inTop3: 0.9609 - val_loss: 0.6522 - val_acc: 0.7844 - val_inTop3: 0.9477\n", "Epoch 7/10\n", "33334/33334 [==============================] - 5s 147us/step - loss: 0.5632 - acc: 0.8096 - inTop3: 0.9612 - val_loss: 0.5840 - val_acc: 0.8009 - val_inTop3: 0.9614\n", "Epoch 8/10\n", "33334/33334 [==============================] - 5s 148us/step - loss: 0.5457 - acc: 0.8122 - inTop3: 0.9650 - val_loss: 0.6041 - val_acc: 0.7954 - val_inTop3: 0.9594\n", "Epoch 9/10\n", "33334/33334 [==============================] - 5s 148us/step - loss: 0.5261 - acc: 0.8223 - inTop3: 0.9675 - val_loss: 0.5769 - val_acc: 0.8095 - val_inTop3: 0.9611\n", "Epoch 10/10\n", "33334/33334 [==============================] - 5s 148us/step - loss: 0.5363 - acc: 0.8195 - inTop3: 0.9658 - val_loss: 0.6080 - val_acc: 0.7944 - val_inTop3: 0.9578\n" ] } ], "source": [ "en_tf_halo=ensemble(get_tfMLP, x_RN, y_tan, 10, 3, 3, 32)\n", "en_tf_halo=link_transf(almod, en_tf_halo)\n", "halo_mentes(en_tf_halo,'ensemble_CNN')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Értékeljük ki a szakértő együttesünket." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10000/10000 [==============================] - 4s 426us/step\n", "Confusion Matrix:\n", "[[825 15 18 12 7 1 0 20 85 17]\n", " [ 6 946 2 4 1 1 1 3 11 25]\n", " [ 43 4 755 56 69 19 25 19 6 4]\n", " [ 7 5 43 751 31 78 32 39 7 7]\n", " [ 11 0 53 53 771 17 34 52 8 1]\n", " [ 3 2 29 139 26 713 17 66 4 1]\n", " [ 6 7 26 60 21 16 848 4 9 3]\n", " [ 5 2 12 25 55 26 6 859 7 3]\n", " [ 32 21 13 6 3 0 2 1 909 13]\n", " [ 11 82 3 5 1 0 1 11 21 865]]\n", "\n", "Loss:0.5154574652194976; Acc:0.8242; Top3Acc:0.9673\n", "\n" ] }, { "data": { "text/plain": [ "{'loss': 0.5154574652194976, 'acc': 0.8242, 'top3acc': 0.9673}" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "teszt(en_tf_halo,x_tst,y_tst)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Egy tizeddel sikerült javítanunk (ennél picit hatásosabb szokott lenni)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }