{"cells":[{"metadata":{},"cell_type":"markdown","source":"This Kernel for someone want to deep dive into image classification. I use CNN for classification model. If you found this Kernel helpful please up vote it. If you have some feedback and question don't forget to comment below. \n\nI have simplier model with \n* https://www.kaggle.com/uysimty/get-start-image-classification"},{"metadata":{"_uuid":"fe76d1d1ded592430e7548feacfa38dc42f085d9"},"cell_type":"markdown","source":"# Import Library"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nfrom keras.preprocessing.image import ImageDataGenerator, load_img\nfrom keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split\nfrom keras.optimizers import RMSprop,SGD,Adam\nimport matplotlib.pyplot as plt\nimport random\nimport os\nprint(os.listdir(\"../input/fiveclasses/Five_classes_128\"))\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Define Constants"},{"metadata":{"trusted":true},"cell_type":"code","source":"FAST_RUN = False\nIMAGE_WIDTH=128\nIMAGE_HEIGHT=128\nIMAGE_SIZE=(IMAGE_WIDTH, IMAGE_HEIGHT)\nIMAGE_CHANNELS=1","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7335a579cc0268fba5d34d6f7558f33c187eedb3"},"cell_type":"markdown","source":"1. # Prepare Traning Data"},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"folders = os.listdir(\"../input/fiveclasses/Five_classes_128\")\ncategories = []\nfilenames = []\nfor folder in folders:\n    for filename in os.listdir(\"../input/fiveclasses/Five_classes_128/\"+folder):\n        categories.append (str(folder.split('_')[-1]))\n        filenames.append(\"../input/fiveclasses/Five_classes_128/\"+folder+\"/\"+filename)\n    #     if category == 'norm':\n    #         categories.append(1)\n    #     elif category == 'nude':\n    #         categories.append(0)\n    #     else:\n    #         categories.append(2)\n\n\ndf = pd.DataFrame({\n    'filename': filenames,\n    'category': categories\n})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"915bb9ba7063ab4d5c07c542419ae119003a5f98"},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"72bf69e817f67f5a2eaff8561217e22077248553"},"cell_type":"code","source":"# df.tail()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a999484fc35b73373fafe2253ae9db7ff46fdb90"},"cell_type":"markdown","source":"### See Total In count"},{"metadata":{"trusted":true,"_uuid":"fa26f0bc7a6d835a24989790b20f3c6f32946f45"},"cell_type":"code","source":"df['category'].value_counts().plot.bar()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['category'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3a08da58107777a1dd05c4a4bf5c484484923cac"},"cell_type":"markdown","source":"From our data we have 11932 cats and 11979 non-cats"},{"metadata":{"_uuid":"b244e6b7715a04fc6df92dd6dfa3d35c473ca600"},"cell_type":"markdown","source":"# Build Model\n\n<img src=\"https://i.imgur.com/ebkMGGu.jpg\" width=\"100%\"/>"},{"metadata":{},"cell_type":"markdown","source":"* **Input Layer**: It represent input image data. It will reshape image into single diminsion array. Example your image is 64x64 = 4096, it will convert to (4096,1) array.\n* **Conv Layer**: This layer will extract features from image.\n* **Pooling Layer**: This layerreduce the spatial volume of input image after convolution.\n* **Fully Connected Layer**: It connect the network from a layer to another layer\n* **Output Layer**: It is the predicted values layer. "},{"metadata":{"trusted":true,"_uuid":"8c9f833c1441b657c779844912d0b8028218d454"},"cell_type":"code","source":"# from keras.models import Sequential\n# from keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation, BatchNormalization\n# from keras.optimizers import RMSprop,SGD,Adam\n# model = Sequential()\n\n# model.add(Conv2D(64, (3, 3), activation='relu', input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS)))\n# model.add(MaxPooling2D())\n# model.add(Dropout(0.25))\n# model.add(BatchNormalization())\n\n# model.add(Conv2D(128, (1, 1), padding='same',activation='relu'))\n# model.add(MaxPooling2D())\n# model.add(Dropout(0.25))\n# model.add(BatchNormalization())\n\n# model.add(Conv2D(256, (3, 3), padding='same',activation='relu'))\n# model.add(MaxPooling2D())\n# model.add(Dropout(0.25))\n# model.add(BatchNormalization())\n\n# model.add(Conv2D(64, (1, 1), padding='same', activation='relu'))\n# model.add(MaxPooling2D())\n# model.add(Dropout(0.25))\n# model.add(BatchNormalization())\n\n# model.add(Conv2D(128, (3, 3),padding='same', activation='relu'))\n# model.add(MaxPooling2D())\n# model.add(Dropout(0.25))\n# model.add(BatchNormalization())\n\n# # model.add(Conv2D(128, (7, 7),padding='same', activation='relu'))\n# # model.add(MaxPooling2D())\n# # model.add(Dropout(0.25))\n# # model.add(BatchNormalization())\n\n# # model.add(Conv2D(256, (7, 7),padding='same', activation='relu'))\n# # model.add(Dropout(0.25))\n# # model.add(BatchNormalization())\n# # model.add(Conv2D(256, (7, 7),padding='same', activation='relu'))\n\n\n# model.add(Flatten())\n# model.add(Dense(2048, activation='relu'))\n# model.add(Dropout(0.5))\n# model.add(BatchNormalization())\n# model.add(Dense(3, activation='softmax')) # 2 because we have 2 (cat and non-cat) decisions\n\n\n# model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.001), metrics=['accuracy'])\n\n# model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model = Sequential()\n# model.add(Conv2D(filters=16, kernel_size=(5, 5), activation=\"relu\", input_shape=(112,112,3)))\n# model.add(MaxPooling2D(pool_size=(2, 2)))\n# model.add(Dropout(0.25))\n\n# model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu'))\n# model.add(MaxPooling2D(pool_size=(2, 2)))\n# model.add(Dropout(0.25))\n\n# model.add(Conv2D(filters=64, kernel_size=(5, 5), activation=\"relu\"))\n# model.add(MaxPooling2D(pool_size=(2, 2)))\n# model.add(Dropout(0.25))\n\n# model.add(Conv2D(filters=64, kernel_size=(5, 5), activation='relu'))\n# model.add(MaxPooling2D(pool_size=(2, 2)))\n# model.add(Dropout(0.25))\n\n# model.add(Flatten())\n# model.add(Dense(128, activation='relu'))\n# model.add(Dropout(0.5))\n# model.add(Dense(64, activation='relu'))\n# model.add(Dropout(0.5))\n# model.add(Dense(3, activation='softmax'))\n\n# model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.001), metrics=['accuracy'])\n\n# model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from keras.applications import InceptionV3\n\n# # #Load the MODEL\n# # # conv = VGG16(weights='imagenet', include_top=False, input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, 3))\n# conv = InceptionV3(weights='imagenet', include_top=False, input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, 3))\n# # conv = ResNet50(weights='imagenet', include_top=False, input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, 3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # Freeze all the layers BUT LAST FEW\n# for layer in conv.layers[:-2]:\n#     layer.trainable = False\n\n# # Freeze all the layers   \n# # for layer in conv.layers:\n# #     layer.trainable = False\n\n# # Check the trainable status of the individual layers\n# for layer in conv.layers:\n#     print(layer, layer.trainable)\n\n\n# from keras import models\n# from keras import layers\n# from keras import optimizers\n\n# # Create the model\n# model = models.Sequential()\n\n# # Add the current convolutional base model\n# model.add(conv)\n\n# # Add new layers\n# model.add(layers.GlobalAveragePooling2D())\n# model.add(layers.Dense(1024, activation='relu'))\n# model.add(layers.Dropout(0.5))\n# model.add(layers.Dense(3, activation='softmax'))\n\n# # Show a summary of the model. Check the number of trainable parameters\n# model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from keras.layers import Input\n# from keras import backend as K\n# from keras import layers\n# from keras.models import Model\n# from keras.utils.data_utils import get_file","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_tf_dim_ordering_tf_kernels.h5'\n# WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'\n\n\n# def identity_block(input_tensor, kernel_size, filters, stage, block):\n#     \"\"\"The identity block is the block that has no conv layer at shortcut.\n#     # Arguments\n#         input_tensor: input tensor\n#         kernel_size: default 3, the kernel size of middle conv layer at main path\n#         filters: list of integers, the filters of 3 conv layer at main path\n#         stage: integer, current stage label, used for generating layer names\n#         block: 'a','b'keras.., current block label, used for generating layer names\n#     # Returns\n#         Output tensor for the block.\n#     \"\"\"\n#     filters1, filters2, filters3 = filters\n#     if K.image_data_format() == 'channels_last':\n#         bn_axis = 3\n#     else:\n#         bn_axis = 1\n#     conv_name_base = 'res' + str(stage) + block + '_branch'\n#     bn_name_base = 'bn' + str(stage) + block + '_branch'\n\n#     x = Conv2D(filters1, (1, 1), name=conv_name_base + '2a')(input_tensor)\n#     x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)\n#     x = Activation('relu')(x)\n\n#     x = Conv2D(filters2, kernel_size,\n#                padding='same', name=conv_name_base + '2b')(x)\n#     x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)\n#     x = Activation('relu')(x)\n\n#     x = Conv2D(filters3, (1, 1), name=conv_name_base + '2c')(x)\n#     x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)\n\n#     x = layers.add([x, input_tensor])\n#     x = Activation('relu')(x)\n#     return x\n\n\n# def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)):\n#     \"\"\"A block that has a conv layer at shortcut.\n#     # Arguments\n#         input_tensor: input tensor\n#         kernel_size: default 3, the kernel size of middle conv layer at main path\n#         filters: list of integers, the filters of 3 conv layer at main path\n#         stage: integer, current stage label, used for generating layer names\n#         block: 'a','b'keras.., current block label, used for generating layer names\n#     # Returns\n#         Output tensor for the block.\n#     Note that from stage 3, the first conv layer at main path is with strides=(2,2)\n#     And the shortcut should have strides=(2,2) as well\n#     \"\"\"\n#     filters1, filters2, filters3 = filters\n#     if K.image_data_format() == 'channels_last':\n#         bn_axis = 3\n#     else:\n#         bn_axis = 1\n#     conv_name_base = 'res' + str(stage) + block + '_branch'\n#     bn_name_base = 'bn' + str(stage) + block + '_branch'\n\n#     x = Conv2D(filters1, (1, 1), strides=strides,\n#                name=conv_name_base + '2a')(input_tensor)\n#     x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)\n#     x = Activation('relu')(x)\n\n#     x = Conv2D(filters2, kernel_size, padding='same',\n#                name=conv_name_base + '2b')(x)\n#     x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)\n#     x = Activation('relu')(x)\n\n#     x = Conv2D(filters3, (1, 1), name=conv_name_base + '2c')(x)\n#     x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)\n\n#     shortcut = Conv2D(filters3, (1, 1), strides=strides,\n#                       name=conv_name_base + '1')(input_tensor)\n#     shortcut = BatchNormalization(axis=bn_axis, name=bn_name_base + '1')(shortcut)\n\n#     x = layers.add([x, shortcut])\n#     x = Activation('relu')(x)\n#     return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def ResNet50(include_top=True, weights='imagenet',\n#              input_tensor=None, input_shape=None,\n#              pooling=None,\n#              classes=1000):\n#     if weights not in {'imagenet', None}:\n#         raise ValueError('The `weights` argument should be either '\n#                          '`None` (random initialization) or `imagenet` '\n#                          '(pre-training on ImageNet).')\n\n#     if weights == 'imagenet' and include_top and classes != 1000:\n#         raise ValueError('If using `weights` as imagenet with `include_top`'\n#                          ' as true, `classes` should be 1000')\n\n#     if input_tensor is None:\n#         img_input = Input(shape=input_shape)\n#     else:\n#         if not K.is_keras_tensor(input_tensor):\n#             img_input = Input(tensor=input_tensor, shape=input_shape)\n#         else:\n#             img_input = input_tensor\n#     if K.image_data_format() == 'channels_last':\n#         bn_axis = 3\n#     else:\n#         bn_axis = 1\n\n#     x = Conv2D(64, (7, 7), strides=(2, 2), padding='same', name='conv1')(img_input)\n#     x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x)\n#     x = Activation('relu')(x)\n#     x = MaxPooling2D((3, 3), strides=(2, 2), padding=\"same\")(x)\n\n#     x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))\n#     x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')\n#     x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')\n\n#     x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')\n#     x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')\n#     x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')\n#     x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')\n\n#     x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a')\n#     x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b')\n#     x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c')\n#     x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d')\n#     x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e')\n#     x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f')\n\n#     x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a')\n#     x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')\n#     x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')\n\n# #     x = AveragePooling2D((7, 7), name='avg_pool')(x)\n\n# #     if include_top:\n# #         x = Flatten()(x)\n# #         x = Dense(classes, activation='softmax', name='fc1000')(x)\n# #     else:\n# #         if pooling == 'avg':\n# #             x = GlobalAveragePooling2D()(x)\n# #         elif pooling == 'max':\n# #             x = GlobalMaxPooling2D()(x)\n\n#     # Ensure that the model takes into account\n#     # any potential predecessors of `input_tensor`.\n#     if input_tensor is not None:\n#         inputs = get_source_inputs(input_tensor)\n#     else:\n#         inputs = img_input\n#     # Create model.\n#     model = Model(inputs, x, name='resnet50')\n\n#     # load weights\n#     if weights == 'imagenet':\n#         if include_top:\n#             weights_path = get_file('resnet50_weights_tf_dim_ordering_tf_kernels.h5',\n#                                     WEIGHTS_PATH,\n#                                     cache_subdir='models',\n#                                     md5_hash='a7b3fe01876f51b976af0dea6bc144eb')\n#         else:\n#             weights_path = get_file('resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5',\n#                                     WEIGHTS_PATH_NO_TOP,\n#                                     cache_subdir='models',\n#                                     md5_hash='a268eb855778b3df3c7506639542a6af')\n#         model.load_weights(weights_path,by_name=True)\n#     return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model_base=ResNet50(input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, 3), include_top=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation, BatchNormalization\n\nmodel = Sequential()\n\nmodel.add(Conv2D(32, (3, 3), activation='relu', input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS)))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(64, (3, 3), activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(128, (3, 3), activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.5))\nmodel.add(Dense(5, activation='softmax')) # 2 because we have cat and dog classes\n\nmodel.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])\n\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# ПОШЛА ЖАРА с конвертацией"},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.load_weights(\"../input/wwwwwww/model3.h5\",by_name=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.save('trained_model4.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# import tensorflow as tf\n# converter = tf.lite.TFLiteConverter.from_keras_model_file( 'trained_model4.h5' )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# tflite_buffer = converter.convert()\n# open( 'model3.tflite' , 'wb' ).write( tflite_buffer )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# interpreter = tf.contrib.lite.Interpreter(model_path=\"model3.tflite\")\n# interpreter.allocate_tensors()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Evaluation of converted model\n:::"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Далее иет кусок про проверку работоспособности tflite modelи на одном тестовом изображении\n#в векторе должны быть вероятности, но никак не 1 и не 0.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# input_details = interpreter.get_input_details()\n# output_details = interpreter.get_output_details()\n\n# # Test model on random input data\n# #print(input_details[0]['shape'])\n# sample_test = test_df1.head(1)\n# #sample_test.head()\n# #fn = sample_test[5].item()\n# #print(fn)\n# filename=sample_test['filename'].item()\n# #print(filename)\n# #filename=sample_test['filename']\n# category = sample_test['cat_prob'].item()\n# #print(category)\n# img = load_img(\"../input/cats-vs-noncats1/Test2/Test2/\"+filename, target_size=IMAGE_SIZE)\n# inp=np.ones((1,224,224,3))\n\n# #print(inp.shape)\n# inp[0,:,:,:]=img\n\n\n# #print(input_details[0])\n# input_data = np.array(inp, dtype=np.float32)\n# #print(output_details[0])\n# interpreter.set_tensor(input_details[0]['index'], input_data)\n# interpreter.invoke()\n# output_data = interpreter.get_tensor(output_details[0]['index'])\n# proc=output_data\n# #print(\"% 3.3f\"% (proc)) \n# print(proc)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Compile the model"},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss='categorical_crossentropy',\n              optimizer=Adam(lr=1e-4),\n              metrics=['acc'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"  # Callbacks"},{"metadata":{"trusted":true,"_uuid":"9aa032f0f6da539d23918890d2d131cc3aac8c7a"},"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ReduceLROnPlateau","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"76c9ba4fb7f930c96b2c3e0d6b68ed9fa6a4227b"},"cell_type":"markdown","source":"**Early Stop**\n\nTo prevent over fitting we will stop the learning after 10 epochs and val_loss value not decreased"},{"metadata":{"trusted":true,"_uuid":"3421c5ec428da6c0d8cc1184179a9caff1e01d1c"},"cell_type":"code","source":"earlystop = EarlyStopping(patience=10)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"51d3fe52e911286433cedf6e47332948a253361e"},"cell_type":"markdown","source":"**Learning Rate Reduction**\n\nWe will reduce the learning rate when then accuracy not increase for 2 steps"},{"metadata":{"trusted":true,"_uuid":"8010a5661ad8924d2db24af0f3c00b1593b38901"},"cell_type":"code","source":"learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', \n                                            patience=2, \n                                            verbose=1, \n                                            factor=0.1, \n                                            min_lr=0.00001)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a79cc604199469789f183096d863f7248e5f6aab"},"cell_type":"code","source":"callbacks = [earlystop, learning_rate_reduction]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Prepare data"},{"metadata":{},"cell_type":"markdown","source":"Because we will use image genaretor `with class_mode=\"categorical\"`. We need to convert column category into string. Then imagenerator will convert it one-hot encoding which is good for our classification. \n\nSo we will convert 1 to cats and 0 to non-cat"},{"metadata":{"trusted":true},"cell_type":"code","source":"df[\"category\"] = df[\"category\"].replace({0: 'nude', 1: 'norm',2:'sug'}) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.utils import shuffle\ndf = shuffle(df)\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4eeb7af8dcf02c4ef5ca744c8305c51a2f5cedef"},"cell_type":"code","source":"train_df, validate_df = train_test_split(df, test_size=0.20, random_state=42)\ntrain_df = train_df.reset_index(drop=True)\nvalidate_df = validate_df.reset_index(drop=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b84836337441705eda9d2e655665ffa14d9feead"},"cell_type":"code","source":"# train_df['category'].value_counts().plot.bar()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"19cf03f9a3c39532d6e2d06bd30be49a5afd9d57"},"cell_type":"code","source":"# validate_df['category'].value_counts().plot.bar()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ae3dec0361f0443132d0309d3b883ee80070cf9f"},"cell_type":"code","source":"total_train = train_df.shape[0]\ntotal_validate = validate_df.shape[0]\nbatch_size=5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def preprocessing_f(img):\n    image = np.array(img)\n    #print(image.mean())\n    converted_img = image-image.mean()\n    #print(converted_img.std())\n    return converted_img/max(converted_img.max(),abs(converted_img.min()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def normalization(img):\n    imgarr=np.array(img,dtype=np.float32)\n    imgarr/=128.\n    imgarr-=1\n    return imgarr","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def pad_fun(img):\n#     dim=np.argmax((img.shape[0],img.shape[1]))\n#     if dim==0:\n#         img_=np.concatenate((img,np.ones((img.shape[dim],img.shape[dim]-img.shape[1-dim],3))),axis=1-dim)\n#     else:\n#         img_=np.concatenate((img,np.ones((img.shape[dim]-img.shape[1-dim],img.shape[dim],3))),axis=1-dim)\n#     return img_","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def func(img):\n#     return pad_fun(preprocessing_f(img))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ff760be9104f7d9492467b8d9d3405011aa77d11"},"cell_type":"markdown","source":"# Traning Generator"},{"metadata":{"trusted":true,"_uuid":"4d1c7818703a8a4bac5c036fdea45972aa9e5e9e"},"cell_type":"code","source":"train_datagen = ImageDataGenerator(preprocessing_function=normalization,\n                                       horizontal_flip=True,\n                                       vertical_flip=True)\n    \n\ntrain_generator = train_datagen.flow_from_dataframe(\n    train_df, \n    x_col='filename',\n    y_col='category',\n    target_size=IMAGE_SIZE,\n    class_mode='categorical',\n    batch_size=batch_size,\n    color_mode='grayscale'\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(train_generator)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"np.sum(train_generator[2000][1], axis=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# X_train=np.empty((total_train,224,224,3), dtype=float, order='C')\n# Y_train=np.empty((total_train,3), dtype=float, order='C')\n# for i in range(20):\n#     X_train[i]=train_generator[i][0]\n#     Y_train[i]=train_generator[i][1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IMAGE_SIZE","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"859c7b2857939c19fd2e3bb32839c9f7deb5aa3f"},"cell_type":"markdown","source":"### Validation Generator"},{"metadata":{"trusted":true,"_uuid":"7925e16bcacc89f4484fb6fe47e54d6420af732e"},"cell_type":"code","source":"validation_datagen = ImageDataGenerator(preprocessing_function=normalization,\n                                       horizontal_flip=True,\n                                       vertical_flip=True)\nvalidation_generator = validation_datagen.flow_from_dataframe(\n    validate_df, \n    x_col='filename',\n    y_col='category',\n    target_size=IMAGE_SIZE,\n    class_mode='categorical',\n    batch_size=batch_size,\n    color_mode='grayscale'\n)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6e17fc1f002fedd60febb78fee5e81770640b909"},"cell_type":"markdown","source":"# See how our generator work"},{"metadata":{"trusted":true,"_uuid":"4252cce168ab65f88e44a8ebc2672607bc852af4"},"cell_type":"code","source":"example_df = train_df.sample(n=1).reset_index(drop=True)\nexample_generator = train_datagen.flow_from_dataframe(\n    example_df, \n    \"../input/nudedata-10k/train/train/\", \n    x_col='filename',\n    y_col='category',\n    target_size=IMAGE_SIZE,\n    class_mode='categorical'\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# example_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"23d923dba747f8b47dc75569244cecc6f70df321"},"cell_type":"code","source":"plt.figure(figsize=(12, 12))\n\nfor X_batch, Y_batch in example_generator:\n    image = X_batch[0]\n    plt.imshow(image)\n    break\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"810ddf1373d9db470ed48da4f30ca5a6c1274435"},"cell_type":"markdown","source":"Seem to be nice "},{"metadata":{"_uuid":"5cd8df64e794ed17de326b613a9819e7da977a0e"},"cell_type":"markdown","source":"# Fit Model"},{"metadata":{"trusted":true,"_uuid":"0836a4cc8aa0abf603e0f96573c0c4ff383ad56b"},"cell_type":"code","source":"epochs=3 if FAST_RUN else 40\nhistory = model.fit_generator(\n    train_generator, \n    epochs=40,\n    validation_data=validation_generator,\n    validation_steps=total_validate//batch_size,\n    steps_per_epoch=total_train//batch_size,\n    callbacks=callbacks\n)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"aa1fbc4081ae0de2993188b2bf658a0be5bc0687"},"cell_type":"markdown","source":"# Save Model"},{"metadata":{"trusted":true,"_uuid":"67575a4decdaf79a915d23151626b784ffa82642"},"cell_type":"code","source":"model.save_weights(\"model.h5\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1b76c0a9040bc0babf0a453e567e41e22f8a1e0e"},"cell_type":"markdown","source":"# Virtualize Training"},{"metadata":{"trusted":true,"_uuid":"79055f2dc3e2abb47bea758e0464c86ca42ab431"},"cell_type":"code","source":"fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12))\nax1.plot(history.history['loss'], color='b', label=\"Training loss\")\nax1.plot(history.history['val_loss'], color='r', label=\"validation loss\")\nax1.set_xticks(np.arange(1, 20, 1))\nax1.set_yticks(np.arange(0, 1, 0.1))\n\nax2.plot(history.history['acc'], color='b', label=\"Training accuracy\")\nax2.plot(history.history['val_acc'], color='r',label=\"Validation accuracy\")\nax2.set_xticks(np.arange(1, 20, 1))\n\nlegend = plt.legend(loc='best', shadow=True)\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"764dc66e4b2bc558f3a0f90b80bb802f5b3d45a8"},"cell_type":"markdown","source":"# Prepare Testing Data"},{"metadata":{"trusted":true,"_uuid":"c35e70d3e1e4834dbbf840fa0ea08c049bfcd915"},"cell_type":"code","source":"# test_filenames = os.listdir(\"../input/cats-vs-noncats1/Test2/Test2/\")\n# test_df1 = pd.DataFrame({\n#     'filename': test_filenames,\n#     'non-cat_prob':np.zeros(len(test_filenames)),\n#     'cat_prob':np.zeros(len(test_filenames))\n# })\n# nb_samples = test_df1.shape[0]\n# test_df1 = shuffle(test_df1)\n# test_df1.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"291bc3996dce8d05e174b27d64f03996d3e8038e"},"cell_type":"markdown","source":"# Create Testing Generator"},{"metadata":{"trusted":true,"_uuid":"52249ec1c35fb1be3adef386be245de3794e55aa"},"cell_type":"code","source":"# test_gen = ImageDataGenerator(rescale=1./255)\n# test_generator = test_gen.flow_from_dataframe(\n#     test_df1, \n#     \"../input/cats-vs-noncats1/Test2/Test2/\", \n#     x_col='filename',\n#     y_col=None,\n#     class_mode=None,\n#     target_size=IMAGE_SIZE,\n#     batch_size=batch_size,\n#     shuffle=False\n# )","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2fa580afca2931ec5ce374e732d8c1789d03f2ed"},"cell_type":"markdown","source":"# Predict"},{"metadata":{"trusted":true,"_uuid":"4782eb23fa7d003f0e2415d995894017edb2d896"},"cell_type":"code","source":"# predict = model.predict_generator(test_generator, steps=np.ceil(nb_samples/batch_size))\n# predict[1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# predict[:,0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#pr=pd.DataFrame(predict)\n#pr[(pr>1)].count()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"For categoral classication the prediction will come with probability of each category. So we will pick the category that have the highest probability with numpy average max"},{"metadata":{"trusted":true},"cell_type":"code","source":"#test_df['category'] = np.argmax(predict, axis=-1) # не включаю","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test_df1['non-cat_prob']=predict[:,1]\n# test_df1['cat_prob']=predict[:,0]\n# #test_df1 = shuffle(test_df1)\n# test_df1.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We will convert the predict category back into our generator classes by using `train_generator.class_indices`. It is the classes that image generator map while converting data into computer vision"},{"metadata":{"trusted":true},"cell_type":"code","source":"#label_map = dict((v,k) for k,v in train_generator.class_indices.items()) # не вставлю\n#test_df['category'] = test_df['category'].replace(label_map)# не вставлю","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"From our prepare data part. We map data with `{1: 'cat', 0: 'non-cat'}`. Now we will map the result back to dog is 1 and cat is 0"},{"metadata":{"trusted":true},"cell_type":"code","source":"#test_df['category'] = test_df['category'].replace({ 'cat': 1, 'non-cat': 0 }) # не вставлю","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b00add65fe765529e637c3a9904d710bb7eff1d8"},"cell_type":"markdown","source":"### Virtaulize Result"},{"metadata":{"trusted":true,"_uuid":"d0bf6dd5ff344092fa0121f70bdd60fa5a40e29c"},"cell_type":"code","source":"#test_df['category'].value_counts().plot.bar() #не вставлю","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ce72a83f80d6e012b12b82c8ee3365d671a3b307"},"cell_type":"markdown","source":"### See predicted result with images"},{"metadata":{"trusted":true,"_uuid":"98b41dc83075e6297137fb45bf703c313dd4ae28"},"cell_type":"code","source":"# #test_df1 = shuffle(test_df1)\n# sample_test = test_df1.head(18)\n# sample_test.head()\n# plt.figure(figsize=(12, 24))\n# i=1\n# for index,row in sample_test.iterrows():\n#     filename = row['filename']\n#     category = row['cat_prob']\n#     img = load_img(\"../input/cats-vs-noncats1/Test2/Test2/\"+filename, target_size=IMAGE_SIZE)\n#     plt.subplot(6, 3, i)\n#     plt.imshow(img)\n#     plt.xlabel(filename + '(' + \"{}\".format(category) + ')' )\n#     i=i+1\n# plt.tight_layout()\n# plt.show()","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":4}