{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nfrom skimage.io import imread\nimport matplotlib.pyplot as plt\nimport gc; gc.enable() \nprint(os.listdir(\"../input/airbus-ship-detection\"))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"masks = pd.read_csv(os.path.join('../input/airbus-ship-detection', 'train_ship_segmentations_v2.csv'))\nnot_empty = pd.notna(masks.EncodedPixels)\nprint(not_empty.sum(), 'masks in', masks[not_empty].ImageId.nunique(), 'images')#非空图片中的mask数量\nprint((~not_empty).sum(), 'empty images in', masks.ImageId.nunique(), 'total images')#所有图片中非空图片\nmasks.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"masks['ships'] = masks['EncodedPixels'].map(lambda c_row: 1 if isinstance(c_row, str) else 0)\nmasks.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"unique_img_ids = masks.groupby('ImageId').agg({'ships': 'sum'}).reset_index()\nunique_img_ids.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"unique_img_ids['has_ship'] = unique_img_ids['ships'].map(lambda x: 1.0 if x>0 else 0.0)\n\nunique_img_ids.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ship_dir = '../input/airbus-ship-detection'\ntrain_image_dir = os.path.join(ship_dir, 'train_v2')\ntest_image_dir = os.path.join(ship_dir, 'test_v2')\nunique_img_ids['has_ship_vec'] = unique_img_ids['has_ship'].map(lambda x: [x])\nunique_img_ids['file_size_kb'] = unique_img_ids['ImageId'].map(lambda c_img_id: \n                                                               os.stat(os.path.join(train_image_dir, \n                                                                                    c_img_id)).st_size/1024)\nunique_img_ids.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"unique_img_ids = unique_img_ids[unique_img_ids['file_size_kb'] > 50] # keep only +50kb files\nplt.hist(x = unique_img_ids['file_size_kb'], # 指定绘图数据\n           bins = 6, # 指定直方图中条块的个数\n           color = 'steelblue', # 指定直方图的填充色\n           edgecolor = 'black' # 指定直方图的边框色\n          )\nplt.xticks([50,100,150,200,250,300,350,400,450,500])\nplt.ylabel(\"number\")\nplt.xlabel('file_size_kb')\n#unique_img_ids['file_size_kb'].hist()#绘制直方图\nmasks.drop(['ships'], axis=1, inplace=True)\nunique_img_ids.sample(7)\nplt.title(\"Number of images of each size\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(unique_img_ids['ships'].value_counts())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_0 = unique_img_ids[unique_img_ids['ships']==1].sample(1800)\ntrain_1 = unique_img_ids[unique_img_ids['ships']==2].sample(1800)\ntrain_2 = unique_img_ids[unique_img_ids['ships']==3].sample(1800)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_3 = unique_img_ids[unique_img_ids['ships']!=3]\ntrain_3 = train_3[unique_img_ids['ships']!=2]\ntrain_3 = train_3[unique_img_ids['ships']!=1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"unique_img_ids=pd.concat([train_0,train_1,train_2,train_3])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"SAMPLES_PER_GROUP = 10000\nbalanced_train_df = unique_img_ids.groupby('ships').apply(lambda x: x.sample(SAMPLES_PER_GROUP) if len(x) > SAMPLES_PER_GROUP else x)\n#图片有相同船舶数量，但超出2000的不要\nrect=plt.hist(x = balanced_train_df['ships'], # 指定绘图数据\n           bins = 16, # 指定直方图中条块的个数\n           color = 'steelblue', # 指定直方图的填充色\n           edgecolor = 'black' # 指定直方图的边框色\n          )\nplt.yticks(range(0,1800,300))\nplt.xticks(range(0,15))\nplt.ylabel(\"Number of images\")\nplt.xlabel('Number of ships')\nplt.title(\"Number of images containing different number of vessels\")\n#balanced_train_df['ships'].hist(bins=balanced_train_df['ships'].max()+1)\nprint(balanced_train_df.shape[0], 'images',balanced_train_df.shape)#取出1万张图片\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"balanced_train_df=balanced_train_df.reset_index(drop = True)#删除原来的索引。\nbalanced_train_df=balanced_train_df.sample(frac=1.0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from PIL import Image\nx = np.empty(shape=(20188, 256,256,3),dtype=np.uint8)\ny = np.empty(shape=20188,dtype=np.uint8)\nfor index, image in enumerate(balanced_train_df['ImageId']):\n    image_array= Image.open('../input/airbus-ship-detection/train_v2/' + image).resize((256,256)).convert('RGB')\n    x[index] = image_array\n    y[index]=balanced_train_df[balanced_train_df['ImageId']==image]['has_ship'].iloc[0]\n\nprint(x.shape)\nprint(y.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Set target to one hot target for classification problem\n#为分类问题将目标设置为一个热目标\nfrom sklearn.preprocessing import OneHotEncoder\ny_targets =y.reshape(len(y),-1)\nenc = OneHotEncoder()\nenc.fit(y_targets)\ny = enc.transform(y_targets).toarray()\nprint(y.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nx_train, x_val, y_train, y_val  = train_test_split(x,y,test_size = 0.2,random_state=1,stratify=y)\nx_train.shape, x_val.shape, y_train.shape, y_val.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\n\nfrom keras.preprocessing import image\nfrom keras.models import Model\nfrom keras.layers import Activation,AveragePooling2D,BatchNormalization,Concatenate\nfrom keras.layers import Conv2D,Dense,GlobalAveragePooling2D,GlobalMaxPooling2D,Input,Lambda,MaxPooling2D\nfrom keras.applications.imagenet_utils import decode_predictions\nfrom keras.utils.data_utils import get_file\nfrom keras import backend as K\nBASE_WEIGHT_URL = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.7/'\n\ndef conv2d_bn(x,filters,kernel_size,strides=1,padding='same',activation='relu',use_bias=False,name=None):\n    x = Conv2D(filters,\n               kernel_size,\n               strides=strides,\n               padding=padding,\n               use_bias=use_bias,\n               name=name)(x)\n    if not use_bias:\n        bn_axis = 1 if K.image_data_format() == 'channels_first' else 3\n        bn_name = None if name is None else name + '_bn'\n        x = BatchNormalization(axis=bn_axis, scale=False, name=bn_name)(x)\n    if activation is not None:\n        ac_name = None if name is None else name + '_ac'\n        x = Activation(activation, name=ac_name)(x)\n    return x\n\ndef inception_resnet_block(x, scale, block_type, block_idx, activation='relu'):\n    if block_type == 'block35':\n        branch_0 = conv2d_bn(x, 32, 1)\n        branch_1 = conv2d_bn(x, 32, 1)\n        branch_1 = conv2d_bn(branch_1, 32, 3)\n        branch_2 = conv2d_bn(x, 32, 1)\n        branch_2 = conv2d_bn(branch_2, 48, 3)\n        branch_2 = conv2d_bn(branch_2, 64, 3)\n        branches = [branch_0, branch_1, branch_2]\n    elif block_type == 'block17':\n        branch_0 = conv2d_bn(x, 192, 1)\n        branch_1 = conv2d_bn(x, 128, 1)\n        branch_1 = conv2d_bn(branch_1, 160, [1, 7])\n        branch_1 = conv2d_bn(branch_1, 192, [7, 1])\n        branches = [branch_0, branch_1]\n    elif block_type == 'block8':\n        branch_0 = conv2d_bn(x, 192, 1)\n        branch_1 = conv2d_bn(x, 192, 1)\n        branch_1 = conv2d_bn(branch_1, 224, [1, 3])\n        branch_1 = conv2d_bn(branch_1, 256, [3, 1])\n        branches = [branch_0, branch_1]\n    else:\n        raise ValueError('Unknown Inception-ResNet block type. '\n                         'Expects \"block35\", \"block17\" or \"block8\", '\n                         'but got: ' + str(block_type))\n\n    block_name = block_type + '_' + str(block_idx)\n    mixed = Concatenate(name=block_name + '_mixed')(branches)\n    up = conv2d_bn(mixed,K.int_shape(x)[3],1,activation=None,use_bias=True,name=block_name + '_conv')\n\n    x = Lambda(lambda inputs, scale: inputs[0] + inputs[1] * scale,\n               output_shape=K.int_shape(x)[1:],\n               arguments={'scale': scale},\n               name=block_name)([x, up])\n    if activation is not None:\n        x = Activation(activation, name=block_name + '_ac')(x)\n    return x\n\n\ndef InceptionResNetV2(input_shape=[256,256,3],\n                      classes=2):\n\n    input_shape = [256,256,3]\n\n    img_input = Input(shape=input_shape)\n\n    # Stem block: 299,299,3 -> 35 x 35 x 192\n    x = conv2d_bn(img_input, 32, 3, strides=2, padding='valid')\n    x = conv2d_bn(x, 32, 3, padding='valid')\n    x = conv2d_bn(x, 64, 3)\n    x = MaxPooling2D(3, strides=2)(x)\n    x = conv2d_bn(x, 80, 1, padding='valid')\n    x = conv2d_bn(x, 192, 3, padding='valid')\n    x = MaxPooling2D(3, strides=2)(x)\n\n    # Mixed 5b (Inception-A block):35 x 35 x 192 -> 35 x 35 x 320\n    branch_0 = conv2d_bn(x, 96, 1)\n    branch_1 = conv2d_bn(x, 48, 1)\n    branch_1 = conv2d_bn(branch_1, 64, 5)\n    branch_2 = conv2d_bn(x, 64, 1)\n    branch_2 = conv2d_bn(branch_2, 96, 3)\n    branch_2 = conv2d_bn(branch_2, 96, 3)\n    branch_pool = AveragePooling2D(3, strides=1, padding='same')(x)\n    branch_pool = conv2d_bn(branch_pool, 64, 1)\n    branches = [branch_0, branch_1, branch_2, branch_pool]\n\n    x = Concatenate(name='mixed_5b')(branches)\n\n    # 10次Inception-ResNet-A block:35 x 35 x 320 -> 35 x 35 x 320\n    for block_idx in range(1, 11):\n        x = inception_resnet_block(x,\n                                   scale=0.17,\n                                   block_type='block35',\n                                   block_idx=block_idx)\n\n    # Reduction-A block:35 x 35 x 320 -> 17 x 17 x 1088\n    branch_0 = conv2d_bn(x, 384, 3, strides=2, padding='valid')\n    branch_1 = conv2d_bn(x, 256, 1)\n    branch_1 = conv2d_bn(branch_1, 256, 3)\n    branch_1 = conv2d_bn(branch_1, 384, 3, strides=2, padding='valid')\n    branch_pool = MaxPooling2D(3, strides=2, padding='valid')(x)\n    branches = [branch_0, branch_1, branch_pool]\n    x = Concatenate(name='mixed_6a')(branches)\n\n    # 20次Inception-ResNet-B block: 17 x 17 x 1088 -> 17 x 17 x 1088 \n    for block_idx in range(1, 21):\n        x = inception_resnet_block(x,\n                                   scale=0.1,\n                                   block_type='block17',\n                                   block_idx=block_idx)\n\n\n    # Reduction-B block: 17 x 17 x 1088 -> 8 x 8 x 2080\n    branch_0 = conv2d_bn(x, 256, 1)\n    branch_0 = conv2d_bn(branch_0, 384, 3, strides=2, padding='valid')\n    branch_1 = conv2d_bn(x, 256, 1)\n    branch_1 = conv2d_bn(branch_1, 288, 3, strides=2, padding='valid')\n    branch_2 = conv2d_bn(x, 256, 1)\n    branch_2 = conv2d_bn(branch_2, 288, 3)\n    branch_2 = conv2d_bn(branch_2, 320, 3, strides=2, padding='valid')\n    branch_pool = MaxPooling2D(3, strides=2, padding='valid')(x)\n    branches = [branch_0, branch_1, branch_2, branch_pool]\n    x = Concatenate(name='mixed_7a')(branches)\n\n    # 10次Inception-ResNet-C block: 8 x 8 x 2080 -> 8 x 8 x 2080\n    for block_idx in range(1, 10):\n        x = inception_resnet_block(x,\n                                   scale=0.2,\n                                   block_type='block8',\n                                   block_idx=block_idx)\n    x = inception_resnet_block(x,\n                               scale=1.,\n                               activation=None,\n                               block_type='block8',\n                               block_idx=10)\n\n    # 8 x 8 x 2080 -> 8 x 8 x 1536\n    x = conv2d_bn(x, 1536, 1, name='conv_7b')\n\n    x = GlobalAveragePooling2D(name='avg_pool')(x)\n    x = Dense(classes, activation='sigmoid', name='predictions')(x)\n\n    inputs = img_input\n\n    # 创建模型\n    model = Model(inputs, x, name='inception_resnet_v2')\n\n    return model\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from keras.applications.vgg16 import VGG16 as PTModel\n\n#from keras.applications.resnet50 import ResNet50 as PTModel\n\n#from keras.applications.inception_v3 import InceptionV3 as PTModel\n\n#from keras.applications.xception import Xception as PTModel\n\n#from keras.applications.densenet import DenseNet169 as PTModel\n\n#from keras.applications.densenet import DenseNet121 as PTModel\n\n# from keras.applications.resnet50 import ResNet50 as PTModel","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# img_width, img_height = 256, 256\n# model = PTModel(weights = None, include_top=False, input_shape = (img_width, img_height, 3))\n# #weights=None，‘imagenet’表示不加载权重","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from keras.layers import Dropout, Flatten, Dense, GlobalAveragePooling2D\n# from keras.models import Sequential, Model \n# from keras import backend as K\n# for layer in model.layers:\n#     layer.trainable = False\n\n# x = model.output\n# x = Flatten()(x)\n# x = Dense(1024, activation=\"relu\")(x)\n# x = Dropout(0.5)(x)\n# x = Dense(1024, activation=\"relu\")(x)\n# predictions = Dense(2, activation=\"sigmoid\")(x)\n\n# # creating the final model创建最终模型\n# model_final = Model(input = model.input, output = predictions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_final = InceptionResNetV2()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import Callback\nfrom sklearn.metrics import confusion_matrix, f1_score, precision_score, recall_score\nclass Metrics(Callback):\n    def on_train_begin(self, logs={}):\n        self.val_f1s = []\n        self.val_recalls = []\n        self.val_precisions = []\n\n    def on_epoch_end(self, epoch, logs={}):\n#         val_predict = (np.asarray(self.model.predict(self.validation_data[0]))).round()\n        val_predict = np.argmax(np.asarray(self.model.predict(self.validation_data[0])), axis=1)\n#         val_targ = self.validation_data[1]\n        val_targ = np.argmax(self.validation_data[1], axis=1)\n        _val_f1 = f1_score(val_targ, val_predict, average='macro')\n        _val_recall = recall_score(val_targ, val_predict)\n        _val_precision = precision_score(val_targ, val_predict)\n        self.val_f1s.append(_val_f1)\n        self.val_recalls.append(_val_recall)\n        self.val_precisions.append(_val_precision)\n        print('— val_f1: %f — val_precision: %f — val_recall %f' %(_val_f1, _val_precision, _val_recall))\n#         print(' — val_f1:' ,_val_f1)\n        return\n\nmetrics1 = Metrics()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import ModelCheckpoint, LearningRateScheduler, EarlyStopping, ReduceLROnPlateau\nweight_path=\"{}_weights.best.hdf5\".format('boat_detector')\n\ncheckpoint = ModelCheckpoint(weight_path, monitor='val_loss', verbose=1, \n                             save_best_only=True, mode='min', save_weights_only = True)\n\nreduceLROnPlat = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=2, verbose=1, mode='auto', epsilon=0.01, cooldown=0, min_lr=0.0001)\nearly = EarlyStopping(monitor=\"val_loss\", \n                      mode=\"min\", \n                      patience=3) # probably needs to be more patient, but kaggle time is limited\ncallbacks_list = [checkpoint, early, reduceLROnPlat,metrics1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras import optimizers\ndef fit():\n    epochs = 20\n    lrate = 0.01\n    decay = lrate/epochs\n    #adam = optimizers.Adam(lr=lrate,beta_1=0.9, beta_2=0.999, decay=decay)\n    sgd = optimizers.SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)\n    model_final.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['binary_accuracy'])\n    loss_history=[model_final.fit(x_train, y_train, validation_data=(x_val, y_val),epochs=20, batch_size=50,callbacks=callbacks_list)]\n    \n    return loss_history\nnum=0\n\nwhile True:\n    num=num+1\n#     prefix='%d'%(num)\n    loss_history = fit()\n    model_final.save_weights('my_model_weights%d.h5'% num)\n    if np.min([mh.history['val_loss'] for mh in loss_history]) < 0.01:\n        break\n    if num==1:\n        break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_loss(loss_history):\n    epochs = np.concatenate([mh.epoch for mh in loss_history])\n    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(22, 10))\n    \n    _ = ax1.plot(epochs, np.concatenate([mh.history['loss'] for mh in loss_history]), 'b-',\n                 epochs, np.concatenate([mh.history['val_loss'] for mh in loss_history]), 'r-')\n    ax1.legend(['Training', 'Validation'])#图表，损失函数（训练和验证）的迭代图表\n    ax1.set_title('Loss')\n    \n    _ = ax2.plot(epochs, np.concatenate([mh.history['binary_accuracy'] for mh in loss_history]), 'b-',\n                 epochs, np.concatenate([mh.history['val_binary_accuracy'] for mh in loss_history]), 'r-')\n    ax2.legend(['Training', 'Validation'])#准确率，（训练和迭代的）\n    ax2.set_title('Binary Accuracy (%)')\n\nshow_loss(loss_history)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"unique_img_ids1 = unique_img_ids[20000:30000]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_test = np.empty(shape=(10000, 256,256,3),dtype=np.uint8)#10680 256\ny_test = np.empty(shape=10000,dtype=np.uint8)\nfor index, image in enumerate(unique_img_ids1['ImageId']):\n    image_array= Image.open('../input/airbus-ship-detection/train_v2/' + image).resize((256,256)).convert('RGB') #256\n    x_test[index] = image_array\n    y_test[index]=unique_img_ids1[unique_img_ids1['ImageId']==image]['has_ship'].iloc[0]\n\nprint(x_test.shape)\nprint(y_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_test_targets =y_test.reshape(len(y_test),-1)\nenc = OneHotEncoder()\nenc.fit(y_test_targets)\ny_test = enc.transform(y_test_targets).toarray()\nprint(y_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predict_ship = model_final.evaluate( x_test,y_test)\nacc=predict_ship[1]*100","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print ('Accuracy of random data = '+ str(acc) + \"%\")","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}