{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"BATCH_SIZE = 48\nEDGE_CROP = 16\nGAUSSIAN_NOISE = 0.1\nUPSAMPLE_MODE = 'SIMPLE'\n# downsampling inside the network\nNET_SCALING = (1, 1)\n# downsampling in preprocessing\nIMG_SCALING = (3, 3)\n# number of validation images to use\nVALID_IMG_COUNT = 900\n# maximum number of steps_per_epoch in training\nMAX_TRAIN_STEPS = 9\nMAX_TRAIN_EPOCHS = 99\nAUGMENT_BRIGHTNESS = False","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom skimage.io import imread\nimport matplotlib.pyplot as plt\nfrom matplotlib.cm import get_cmap\nfrom skimage.segmentation import mark_boundaries\n# from skimage.util import montage2d as montage\nfrom skimage.util import montage\nfrom skimage.morphology import binary_opening, disk, label\nimport gc; gc.enable() ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"montage_rgb = lambda x: np.stack([montage(x[:, :, :, i]) for i in range(x.shape[3])], -1)\nship_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')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def multi_rle_encode(img, **kwargs):\n    '''\n    Encode connected regions as separated masks\n    将连接区域编码为分离的掩码\n    '''\n    labels = label(img)\n    if img.ndim > 2:\n        return [rle_encode(np.sum(labels==k, axis=2), **kwargs) for k in np.unique(labels[labels>0])]\n    else:\n        return [rle_encode(labels==k, **kwargs) for k in np.unique(labels[labels>0])]\n\n# ref: https://www.kaggle.com/paulorzp/run-length-encode-and-decode\ndef rle_encode(img, min_max_threshold=1e-3, max_mean_threshold=None):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    if np.max(img) < min_max_threshold:\n        return '' ## no need to encode if it's all zeros\n    if max_mean_threshold and np.mean(img) > max_mean_threshold:\n        return '' ## ignore overfilled mask\n    pixels = img.T.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)\n\ndef rle_decode(mask_rle, shape=(768, 768)):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (height,width) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n    '''\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n    starts -= 1\n    ends = starts + lengths\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape).T  # Needed to align to RLE direction\n\ndef masks_as_image(in_mask_list):\n    # Take the individual ship masks and create a single mask array for all ships\n    all_masks = np.zeros((768, 768), dtype = np.uint8)\n    for mask in in_mask_list:\n        if isinstance(mask, str):\n            all_masks |= rle_decode(mask)\n    return all_masks\n\ndef masks_as_color(in_mask_list):\n    # Take the individual ship masks and create a color mask array for each ships\n    all_masks = np.zeros((768, 768), dtype = np.float)\n    scale = lambda x: (len(in_mask_list)+x+1) / (len(in_mask_list)*2) ## scale the heatmap image to shift \n    for i,mask in enumerate(in_mask_list):\n        if isinstance(mask, str):\n            all_masks[:,:] += scale(i) * rle_decode(mask)\n    return all_masks","execution_count":null,"outputs":[]},{"metadata":{"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)\nunique_img_ids = masks.groupby('ImageId').agg({'ships': 'sum'}).reset_index()","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)\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\nunique_img_ids['file_size_kb'].hist()#绘制直方图\nmasks.drop(['ships'], axis=1, inplace=True)\nunique_img_ids.sample(7)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"unique_img_ids['ships'].hist(bins=unique_img_ids['ships'].max())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"unique_img_ids = unique_img_ids[unique_img_ids['ships']!=0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"SAMPLES_PER_GROUP = 1800\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的不要\nbalanced_train_df['ships'].hist(bins=balanced_train_df['ships'].max())\nprint(balanced_train_df.shape[0], 'masks')","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 sklearn.model_selection import train_test_split\ntrain_ids, valid_ids = train_test_split(balanced_train_df, \n                 test_size = 0.2, \n                 stratify = balanced_train_df['ships'])\n#stratify使训练和测试的ships比例一样\ntrain_df = pd.merge(masks, train_ids)\nvalid_df = pd.merge(masks, valid_ids)\nprint(train_df.shape[0], 'training masks')\nprint(valid_df.shape[0], 'validation masks')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_image_gen(in_df, batch_size = BATCH_SIZE):\n    all_batches = list(in_df.groupby('ImageId'))\n    out_rgb = []\n    out_mask = []\n    while True:\n        np.random.shuffle(all_batches)\n        for c_img_id, c_masks in all_batches:\n            rgb_path = os.path.join(train_image_dir, c_img_id)\n            c_img = imread(rgb_path)\n            c_mask = np.expand_dims(masks_as_image(c_masks['EncodedPixels'].values), -1)\n            if IMG_SCALING is not None:\n                c_img = c_img[::IMG_SCALING[0], ::IMG_SCALING[1]]\n                c_mask = c_mask[::IMG_SCALING[0], ::IMG_SCALING[1]]\n            out_rgb += [c_img]\n            out_mask += [c_mask]\n            if len(out_rgb)>=batch_size:\n                yield np.stack(out_rgb, 0)/255.0, np.stack(out_mask, 0)\n                out_rgb, out_mask=[], []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_x, valid_y = next(make_image_gen(valid_df, VALID_IMG_COUNT))\nprint(valid_x.shape, valid_y.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\ndg_args = dict(featurewise_center = False, \n                  samplewise_center = False,\n                  rotation_range = 45, \n                  width_shift_range = 0.1, \n                  height_shift_range = 0.1, \n                  shear_range = 0.01,\n                  zoom_range = [0.9, 1.25],  \n                  horizontal_flip = True, \n                  vertical_flip = True,\n                  fill_mode = 'reflect',\n                   data_format = 'channels_last')\n# brightness can be problematic since it seems to change the labels differently from the images \n#亮度可能有问题，因为它似乎改变了不同于图像的标签\nif AUGMENT_BRIGHTNESS:\n    dg_args[' brightness_range'] = [0.5, 1.5]\nimage_gen = ImageDataGenerator(**dg_args)\n#**kwargs 表示关键字参数，它本质上是一个 dict\nif AUGMENT_BRIGHTNESS:\n    dg_args.pop('brightness_range')\nlabel_gen = ImageDataGenerator(**dg_args)\n#pop删除 arrayObject 的最后一个元素\n\ndef create_aug_gen(in_gen, seed = None):\n    np.random.seed(seed if seed is not None else np.random.choice(range(9999)))\n    for in_x, in_y in in_gen:\n        seed = np.random.choice(range(9999))\n        ##保持种子同步否则对图像的增强与遮罩不同\n        # keep the seeds syncronized otherwise the augmentation to the images is different from the masks\n        g_x = image_gen.flow(255*in_x, \n                             batch_size = in_x.shape[0], \n                             seed = seed, \n                             shuffle=True)\n        g_y = label_gen.flow(in_y, \n                             batch_size = in_x.shape[0], \n                             seed = seed, \n                             shuffle=True)\n\n        yield next(g_x)/255.0, next(g_y)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.preprocessing import image\nfrom keras.models import Model\nfrom keras import layers\nfrom keras.layers import Activation, AveragePooling2D, BatchNormalization, Concatenate\nfrom keras.layers import Conv2D, Dense, GlobalAveragePooling2D, GlobalMaxPooling2D, Input, Lambda, MaxPooling2D\nfrom keras.layers import SeparableConv2D, DepthwiseConv2D\nfrom keras.layers import Add, Multiply, Reshape\nfrom keras.applications.imagenet_utils import decode_predictions\nfrom keras.utils.data_utils import get_file\nfrom keras import backend as K\n\nfrom keras.utils.generic_utils import get_custom_objects\n\n\ndef relu6(x):\n    # relu函数\n    return K.relu(x, max_value=6.0)\n\n\nget_custom_objects().update({'relu6': Activation(relu6)})\n\n\ndef hard_swish(x):\n    # 利用relu函数乘上x模拟sigmoid\n    return x * K.relu(x + 3.0, max_value=6.0) / 6.0\n\n\nget_custom_objects().update({'hard_swish': Activation(hard_swish)})\n\n\ndef return_activation(x, nl):\n    # 用于判断使用哪个激活函数\n    if nl == 'HS':\n        x = Activation(hard_swish)(x)\n    if nl == 'RE':\n        x = Activation(relu6)(x)\n    return x\n\n\ndef channel_split(x, name=''):\n    in_channels = x.shape.as_list()[-1]\n    ip = in_channels // 2\n    c_hat = Lambda(lambda z: z[:, :, :, 0:ip])(x)\n    c = Lambda(lambda z: z[:, :, :, ip:])(x)\n\n    return c_hat, c\n\n\ndef channel_shuffle(x):\n    height, width, channels = x.shape.as_list()[1:]\n    channels_per_split = channels // 2\n\n    x = K.reshape(x, [-1, height, width, 2, channels_per_split])\n    x = K.permute_dimensions(x, (0, 1, 2, 4, 3))\n    x = K.reshape(x, [-1, height, width, channels])\n\n    return x\n\n\ndef squeeze(inputs):\n    # 注意力机制单元\n    input_channels = int(inputs.shape[-1])\n\n    x = GlobalAveragePooling2D()(inputs)\n    x = Dense(int(input_channels / 4))(x)\n    x = Activation(relu6)(x)\n    x = Dense(input_channels)(x)\n    x = Activation(hard_swish)(x)\n    x = Reshape((1, 1, input_channels))(x)\n    x = Multiply()([inputs, x])\n\n    return x\n\n\ndef _shuffle_unit(inputs, out_channels, sq, nl, strides=2, stage=1, block=1):\n    bn_axis = -1  # 通道在后还是在前\n    prefix = 'stage%d/block%d' % (stage, block)\n\n    branch_channels = out_channels // 2\n\n    if strides == 2:\n        x_1 = DepthwiseConv2D(kernel_size=3, strides=2, padding='same',\n                              use_bias=False, name='%s/3x3dwconv_1' % prefix)(inputs)\n        x_1 = BatchNormalization(axis=bn_axis, name='%s/bn_3x3dwconv_1' % prefix)(x_1)\n        x_1 = Conv2D(filters=branch_channels, kernel_size=1, strides=1, padding='same',\n                     use_bias=False, name='%s/1x1conv_1' % prefix)(x_1)\n        x_1 = BatchNormalization(axis=bn_axis, name='%s/bn_1x1conv_1' % prefix)(x_1)\n        x_1 = Activation('relu6')(x_1)\n\n        x_2 = Conv2D(filters=branch_channels, kernel_size=1, strides=1, padding='same',\n                     use_bias=False, name='%s/1x1conv_2' % prefix)(inputs)\n        x_2 = BatchNormalization(axis=bn_axis, name='%s/bn_1x1conv_2' % prefix)(x_2)\n        x_2 = Activation('relu6')(x_2)\n        x_2 = DepthwiseConv2D(kernel_size=3, strides=2, padding='same',\n                              use_bias=False, name='%s/3x3dwconv_2' % prefix)(x_2)\n        x_2 = BatchNormalization(axis=bn_axis, name='%s/bn_3x3dwconv_2' % prefix)(x_2)\n        x_2 = Conv2D(filters=branch_channels, kernel_size=1, strides=1, padding='same',\n                     use_bias=False, name='%s/1x1conv_3' % prefix)(x_2)\n        x_2 = BatchNormalization(axis=bn_axis, name='%s/bn_1x1conv_3' % prefix)(x_2)\n        x_2 = Activation('relu6')(x_2)\n\n        x = Concatenate(axis=bn_axis, name='%s/concat' % prefix)([x_1, x_2])\n\n    if strides == 1:\n        c_hat, c = channel_split(inputs, name='%s/split' % prefix)\n\n        c = Conv2D(filters=branch_channels, kernel_size=1, strides=1, padding='same',\n                   use_bias=False, name='%s/1x1conv_4' % prefix)(c)\n        # c = BatchNormalization(axis=bn_axis, name='%s/bn_1x1conv_4' % prefix)(c)\n        # c = Activation('relu6')(c)\n        c = DepthwiseConv2D(kernel_size=3, strides=1, padding='same',\n                            use_bias=False, name='%s/3x3dwconv_3' % prefix)(c)\n        c = BatchNormalization(axis=bn_axis, name='%s/bn_3x3dwconv_3' % prefix)(c)\n        # c = Activation('relu6')(c)\n        c = return_activation(c, nl)\n        # 引入注意力机制\n        if sq:\n            c = squeeze(c)\n        # 下降通道数\n        c = Conv2D(filters=branch_channels, kernel_size=1, strides=1, padding='same',\n                   use_bias=False, name='%s/1x1conv_5' % prefix)(c)\n        c = BatchNormalization(axis=bn_axis, name='%s/bn_1x1conv_4' % prefix)(c)\n        x = Concatenate(axis=bn_axis, name='%s/concat' % prefix)([c_hat, c])\n\n    x = Lambda(channel_shuffle, name='%s/channel_shuffle' % prefix)(x)\n\n    return x\n\n\ndef exblock(inputs, out_channels, sq, stage=1, block=1):\n    prefix = 'stage%d/block%d' % (stage, block)\n\n    residual = Conv2D(out_channels, (1, 1), strides=(2, 2), padding='same', use_bias=False)(inputs)\n    residual = BatchNormalization()(residual)\n\n    x = SeparableConv2D(out_channels, (3, 3), padding='same', use_bias=False, name='%s/_sepconv1' % prefix)(inputs)\n    x = BatchNormalization(name='%s/_sepconv1_bn' % prefix)(x)\n    x = Activation('hard_swish', name='%s/_sepconv2_ac_hs' % prefix)(x)\n    x = SeparableConv2D(out_channels, (3, 3), padding='same', use_bias=False, name='%s/_sepconv2' % prefix)(x)\n    # 引入注意力机制\n    if sq:\n        x = squeeze(x)\n\n    x = BatchNormalization(name='%s/_sepconv2_bn' % prefix)(x)\n\n    x = MaxPooling2D((3, 3), strides=(2, 2), padding='same', name='%s/_pool' % prefix)(x)\n    x = layers.add([x, residual])\n\n    return x\n\n\ndef inception_unit(inputs, channel1, channel2, channel3, ):\n    branch_0 = Conv2D(channel1, (1, 1), strides=(1, 1), padding='same', use_bias=False)(inputs)\n    branch_0 = BatchNormalization(axis=-1, scale=False, name='stage1X1_1BN')(branch_0)\n    branch_0 = Activation('relu6', name='stage1X1_1ac')(branch_0)\n\n    branch_1 = Conv2D(channel2, (3, 3), strides=(1, 1), padding='same', use_bias=False)(inputs)\n    branch_1 = BatchNormalization(axis=-1, scale=False, name='stage3X3_1BN')(branch_1)\n    branch_1 = Activation('relu6', name='stage3X3_1ac')(branch_1)\n\n    branch_pool = AveragePooling2D(3, strides=1, padding='same')(inputs)\n    branch_pool = Conv2D(channel3, (1, 1), strides=(1, 1), padding='same', use_bias=False)(branch_pool)\n    branch_pool = BatchNormalization(axis=-1, scale=False, name='stagep1X1_1BN')(branch_pool)\n    branch_pool = Activation('relu6', name='stagep1X1_1ac')(branch_pool)\n\n    branches = [branch_0, branch_1, branch_pool]\n\n    x = Concatenate(name='mixed_5b')(branches)\n\n    return x\n\n\ndef qzynetnew(input_shape=[256, 256, 3], classes=2,target=1):\n    input_shape = [256, 256, 3]\n\n    img_input = Input(shape=input_shape)\n\n    x = Conv2D(32, (3, 3), strides=(1, 1), padding='same', use_bias=False)(img_input)\n    x = BatchNormalization(axis=-1, scale=False, name='stage0.1X1_1BN')(x)\n    x = Activation('relu6', name='stage0.1X1_1ac')(x)\n    x = Conv2D(64, (3, 3), strides=(2, 2), padding='same', use_bias=False)(x)\n    x = BatchNormalization(axis=-1, scale=False, name='stage00.1X1_1BN')(x)\n    x = Activation('relu6', name='stage00.1X1_1ac')(x)\n    x = MaxPooling2D(3, strides=1,padding='same')(x)#2\n    #   x=_shuffle_unit(x, 128, sq=False, nl='RE',strides=1, stage=2, block=1)\n    #   x=_shuffle_unit(x, 128, sq=False, nl='RE',strides=1, stage=2, block=2)\n\n    #   x=_shuffle_unit(x, 128, sq=False, nl='RE',strides=2, stage=2, block=3)#128,128,128 -> 64 x 64 x 128\n\n    #   x=_shuffle_unit(x, 128, sq=False, nl='RE',strides=1, stage=2, block=4)\n    #   x=_shuffle_unit(x, 128, sq=False, nl='RE',strides=1, stage=2, block=5)\n    f1=x\n    x = exblock(x, 128, sq=True, stage=1, block=1)\n    f2=x\n\n    x = exblock(x, 192, sq=True, stage=1, block=2)\n    # x=_shuffle_unit(x, 256, sq=False, nl='RE',strides=2, stage=2, block=6)#64,64,128 -> 32 x 32 x 256\n    x = inception_unit(x, 116, 116, 24)\n    x = _shuffle_unit(x, 256, sq=False, nl='RE', strides=1, stage=2, block=7)\n    x = _shuffle_unit(x, 256, sq=False, nl='RE', strides=1, stage=2, block=8)\n    f3= x\n\n    x = _shuffle_unit(x, 512, sq=False, nl='RE', strides=2, stage=2, block=9)  # 32,32,256 -> 16 x 16 x 512\n\n    x = _shuffle_unit(x, 512, sq=False, nl='RE', strides=1, stage=2, block=10)\n    x = _shuffle_unit(x, 512, sq=False, nl='RE', strides=1, stage=2, block=11)\n    x = _shuffle_unit(x, 512, sq=False, nl='RE', strides=1, stage=2, block=12)\n    f4= x\n\n    x = _shuffle_unit(x, 1024, sq=False, nl='RE', strides=2, stage=2, block=13)  # 16 x 16 x 512 -> 8 x 8 x 1024\n\n    x = _shuffle_unit(x, 1024, sq=False, nl='RE', strides=1, stage=2, block=14)\n    f5= x\n\n    if target == 1:\n         x = GlobalAveragePooling2D(name='global_max_pool')(x)\n         x = Dense(classes, name='fc')(x)\n         x = Activation('softmax')(x)\n\n         inputs = img_input\n    # 创建模型\n         model = Model(inputs, x, name='qzynet')\n         return model\n\n    if target == 2:\n         return img_input, [f1, f2, f3, f4, f5]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.preprocessing import image\nfrom keras.models import Model\nfrom keras import layers\nfrom keras.layers import Activation, AveragePooling2D, BatchNormalization, Concatenate\nfrom keras.layers import Conv2D, Dense, GlobalAveragePooling2D, GlobalMaxPooling2D, Input, Lambda, MaxPooling2D\nfrom keras.layers import SeparableConv2D, DepthwiseConv2D\nfrom keras.layers import Add, Multiply, Reshape\nfrom keras.layers import ZeroPadding2D, UpSampling2D, concatenate\nfrom keras.applications.imagenet_utils import decode_predictions\nfrom keras.utils.data_utils import get_file\nfrom keras import backend as K\n\n# from qzynetwork1 import qzynetnew\n\nIMAGE_ORDERING = 'channels_last'\nMERGE_AXIS = -1\n\ndef conv_block(tensor, num_filters, kernel_size, padding='same', strides=1, dilation_rate=1, w_init='he_normal'):\n    x = (Conv2D(filters=num_filters,\n                               kernel_size=kernel_size,\n                               padding=padding,\n                               strides=strides,\n                               dilation_rate=dilation_rate,\n                               kernel_initializer=w_init,\n                               use_bias=False))(tensor)\n    x = (BatchNormalization())(x)\n    x =  Activation('relu')(x)\n\n    return x\n\n\ndef sepconv_block(tensor, num_filters, kernel_size, padding='same', strides=1, dilation_rate=1, w_init='he_normal'):\n    x = (SeparableConv2D(filters=num_filters,\n                                        depth_multiplier=1,\n                                        kernel_size=kernel_size,\n                                        padding=padding,\n                                        strides=strides,\n                                        dilation_rate=dilation_rate,\n                                        depthwise_initializer=w_init,\n                                        use_bias=False))(tensor)\n    x =(BatchNormalization())(x)\n    x = Activation('relu')(x)\n    return x\n\n\n# def JPU(encoder=qzynetnew, out_channels=512):\n#     img_inputs, levels = encoder(input_shape=[256, 256, 3], classes=2,target=2)\n#     [f2, f3, f4, f5] = levels  # f5:8,f4:16,f3:32,f2:64\n#     #h=128\n#     #w=128\n#\n#     # yc = UpSampling2D(size=(2, 2), interpolation='bilinear')(yc)#得到128\n#     # for i in range(1, 4):\n#     #     levels[i] = conv_block(levels[i], out_channels, 3)\n#     #     if i != 1:\n#     #         h_t, w_t = levels[i].shape.as_list()[1:3]\n#     #         scale = (h // h_t, w // w_t)\n#     #         levels[i] = tf.keras.layers.UpSampling2D(\n#     #             size=scale, interpolation='bilinear')(levels[i])\n#     # yc = tf.keras.layers.Concatenate(axis=-1)(levels[1:])\n#     ym = []\n#     for rate in [1, 2]:\n#         ym.append(sepconv_block(yc, 512, 3, dilation_rate=rate))\n#     y = Concatenate(axis=-1)(ym)\n#\n#     y = conv_block(y, num_filters=128, kernel_size=1)\n#     # return  y\n#     model = Model(img_inputs,y,name='jpu')\n#\n#     return model\n\ndef _unet(n_classes=2, encoder=qzynetnew,  input_height=256, input_width=256):\n    img_input, levels = encoder(input_shape=[256, 256, 3], classes=2,target=2)\n    [f1, f2, f3, f4, f5] = levels#f5:8,f4:16,f3:32,f2:64\n\n    o = f5\n    # 8,8,512\n    o = (ZeroPadding2D((1, 1), data_format=IMAGE_ORDERING))(o)\n    o = (Conv2D(512, (3, 3), padding='valid', data_format=IMAGE_ORDERING))(o)\n    o = (BatchNormalization())(o)\n\n    # 16,16,512\n    o = (UpSampling2D((2, 2), data_format=IMAGE_ORDERING))(o)\n    # 16,16,768\n    o = (concatenate([o, f4], axis=MERGE_AXIS))\n    o = (ZeroPadding2D((1, 1), data_format=IMAGE_ORDERING))(o)\n    # 16,16,256\n    o = (Conv2D(256, (3, 3), padding='valid', data_format=IMAGE_ORDERING))(o)\n    o = (BatchNormalization())(o)\n\n    # 32,32,256\n    o = (UpSampling2D((2, 2), data_format=IMAGE_ORDERING))(o)\n    # 32,32,384\n    o = (concatenate([o, f3], axis=MERGE_AXIS))\n    o = (ZeroPadding2D((1, 1), data_format=IMAGE_ORDERING))(o)\n    # 32,32,128\n    o = (Conv2D(128, (3, 3), padding='valid', data_format=IMAGE_ORDERING))(o)\n    o = (BatchNormalization())(o)\n    # 64,64,64\n    o = (UpSampling2D((2, 2), data_format=IMAGE_ORDERING))(o)\n\n    o = (concatenate([o, f2], axis=MERGE_AXIS))\n\n    o = (ZeroPadding2D((1, 1), data_format=IMAGE_ORDERING))(o)\n    o = (Conv2D(128, (3, 3), padding='valid', data_format=IMAGE_ORDERING))(o)\n    o = (BatchNormalization())(o)\n\n    f5 = conv_block(f5, 96, 3)#8\n    f4 = conv_block(f4, 64, 3)#16\n    f3 = conv_block(f3, 32, 3)#32\n    f5 = UpSampling2D(size=(8, 8))(f5)\n    f4 = UpSampling2D(size=(4, 4))(f4)\n    f3 = UpSampling2D(size=(2, 2))(f3)\n    yc = Concatenate(axis=-1)([f3,f4,f5])\n    ym = []\n    for rate in [1, 2]:\n        ym.append(sepconv_block(yc, 64, 3, dilation_rate=rate))\n    y = Concatenate(axis=-1)(ym)\n    y = conv_block(y, num_filters=64, kernel_size=1)\n\n    z = concatenate([o, y])\n    z = (Conv2D(64, (3, 3), padding='same'))(z)#得到64*64*32\n    z = (BatchNormalization())(z)\n\n    z = UpSampling2D(size=(2,2))(z)\n\n    \n    z = (concatenate([z, f1], axis=MERGE_AXIS))\n    z = (ZeroPadding2D((1, 1), data_format=IMAGE_ORDERING))(z)\n    z = (Conv2D(32, (3, 3), padding='valid', data_format=IMAGE_ORDERING))(z)\n    z = (BatchNormalization())(z)\n    z = (UpSampling2D((2, 2), data_format=IMAGE_ORDERING))(z)\n    \n    z = (Conv2D(1, (1, 1), padding='same'))(z)\n    z = Activation('sigmoid')(z)\n    model = Model(input=img_input, output=z, name='jpu_unet')\n\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"seg_model=_unet()\nseg_model.load_weights(\"../input/qzy-tversky-40/seg_model_weights.best.hdf5\")\n# seg_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras.backend as K\nimport tensorflow as tf\nfrom keras.optimizers import Adam\n\ndef IoU(y_true, y_pred, eps=1e-6):\n    intersection = K.sum(y_true * y_pred, axis=[1,2,3])\n    union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3]) - intersection\n    return K.mean( (intersection + eps) / (union + eps), axis=0)\n\ndef dice_coef(y_true, y_pred):\n    y_true_f = K.flatten(y_true)\n    y_pred = K.cast(y_pred, 'float32')\n    y_pred_f = K.cast(K.greater(K.flatten(y_pred), 0.5), 'float32')\n    intersection = y_true_f * y_pred_f\n    score = 2. * K.sum(intersection) / (K.sum(y_true_f) + K.sum(y_pred_f))\n    return score\n\ndef dice_loss(y_true, y_pred):\n    smooth = 1.\n    y_true_f = K.flatten(y_true)\n    y_pred_f = K.flatten(y_pred)\n    intersection = y_true_f * y_pred_f\n    score = (2. * K.sum(intersection) + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)\n    return 1. - score\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def binary_iou_focal_loss(gamma=2, alpha=0.25):\n    \"\"\"\n    Binary form of focal loss.\n    适用于二分类问题的focal loss\n    \n    focal_loss(p_t) = -alpha_t * (1 - p_t)**gamma * log(p_t)\n        where p = sigmoid(x), p_t = p or 1 - p depending on if the label is 1 or 0, respectively.\n    References:\n        https://arxiv.org/pdf/1708.02002.pdf\n    Usage:\n     model.compile(loss=[binary_focal_loss(alpha=.25, gamma=2)], metrics=[\"accuracy\"], optimizer=adam)\n    \"\"\"\n    alpha = tf.constant(alpha, dtype=tf.float32)\n    gamma = tf.constant(gamma, dtype=tf.float32)\n\n    def binary_focal_loss_fixed(y_true, y_pred):\n        \"\"\"\n        y_true shape need be (None,1)\n        y_pred need be compute after sigmoid\n        \"\"\"\n        eps=1e-6\n        y_true = tf.cast(y_true, tf.float32)\n        alpha_t = y_true*alpha + (K.ones_like(y_true)-y_true)*(1-alpha)\n    \n        p_t = y_true*y_pred + (K.ones_like(y_true)-y_true)*(K.ones_like(y_true)-y_pred) + K.epsilon()\n        focal_loss = - alpha_t * K.pow((K.ones_like(y_true)-p_t),gamma) * K.log(p_t)\n        \n        smooth=1\n        y_true_pos = K.flatten(y_true)\n        y_pred_pos = K.flatten(y_pred)\n        true_pos = K.sum(y_true_pos * y_pred_pos)\n        false_neg = K.sum(y_true_pos * (1-y_pred_pos))\n        false_pos = K.sum((1-y_true_pos)*y_pred_pos)\n        alpha1 = 0.7\n        loss1=(true_pos + smooth)/(true_pos + alpha1*false_neg + (1-alpha1)*false_pos + smooth)\n        \n        loss2=(1.-loss1)+focal_loss\n        \n        return K.mean(loss2)\n    return binary_focal_loss_fixed\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def IoUloss(y_true, y_pred, eps=1e-6):\n    intersection = K.sum(y_true * y_pred, axis=[1,2,3])\n    union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3]) - intersection\n    return 1-K.mean( (intersection + eps) / (union + eps), axis=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def mixed():\n#     loss =binary_focal_loss(alpha=.25, gamma=2) + IoUloss(y_true, y_pred, eps=1e-6)\n#     losses=K.mean(loss)\n#     return losses","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('seg_model')\n\ncheckpoint = ModelCheckpoint(weight_path, monitor='val_loss', verbose=1, save_best_only=True, mode='min', save_weights_only=True)\n#weight_path保存模型的路径，monitor：需要监视的值，verbose：信息展示模式，save_best_only：当设置为True时，监测值有改进时才会保存当前的模型\n#save_weights_only：若设置为True，则只保存模型权重，否则将保存整个模型（包括模型结构，配置信息等）\nreduceLROnPlat = ReduceLROnPlateau(monitor='val_loss', factor=0.6,\n                                   patience=2, verbose=1, mode='min',\n                                   min_delta=0.0001, cooldown=0, min_lr=1e-8)\n\n#当指标停止提升时，降低学习速率。\n#monitor：要监测的数量。patience：没有提升的epoch数，之后学习率将降低。verbose：int。0：安静，1：更新消息。\n#mode：{auto，min，max}之一。在min模式下，当监测量停止下降时，lr将减少；在max模式下，当监测数量停止增加时，它将减少；\n#在auto模式下，从监测数量的名称自动推断方向。\n#min_delta：对于测量新的最优化的阀值，仅关注重大变化。\n#cooldown：在学习速率被降低之后，重新恢复正常操作之前等待的epoch数量。\n#min_lr：学习率的下限。\n\n\nearly = EarlyStopping(monitor=\"val_loss\", mode=\"min\", verbose=2,\n                      patience=10) # probably needs to be more patient, but kaggle time is limited\n#目的：防止过拟合\n#monitor: 需要监视的量，val_loss，val_acc\n#patience: 当early stop被激活(如发现loss相比上一个epoch训练没有下降)，则经过patience个epoch后停止训练\n#verbose: 信息展示模式\n#mode: 'auto','min','max'之一，在min模式训练，如果检测值停止下降则终止训练。在max模式下，当检测值不再上升的时候则停止训练。\n\ncallbacks_list = [checkpoint, early, reduceLROnPlat]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"MAX_TRAIN_EPOCHS=40\nBATCH_SIZE=30\nMAX_TRAIN_STEPS=300","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"seg_model.compile(optimizer=Adam(1e-2, decay=1e-6), loss=binary_iou_focal_loss(alpha=.25, gamma=2), metrics=[IoU,dice_coef,'binary_accuracy'])#tversky_loss\n\nstep_count = min(MAX_TRAIN_STEPS, train_df.shape[0]//BATCH_SIZE)\naug_gen = create_aug_gen(make_image_gen(train_df))\nloss_history = [seg_model.fit_generator(aug_gen,\n                                 steps_per_epoch=step_count,\n                                 epochs=MAX_TRAIN_EPOCHS,\n                                 validation_data=(valid_x, valid_y),\n                                 callbacks=callbacks_list,\n                                workers=1 # the generator is not very thread safe\n                                           )]","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['IoU'] for mh in loss_history]), 'b-',\n                 epochs, np.concatenate([mh.history['val_IoU'] for mh in loss_history]), 'r-')\n    ax2.legend(['Training', 'Validation'])\n    ax2.set_title('IoU Accuracy (%)')\n\nshow_loss(loss_history)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"seg_model.load_weights(weight_path)\nseg_model.save_weights('seg_model111.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def predict(img, path=test_image_dir):\n    c_img = imread(os.path.join(path, c_img_name))\n    c_img = c_img[::IMG_SCALING[0], ::IMG_SCALING[1]]\n    c_img = np.expand_dims(c_img, 0)/255.0\n    \n    cur_seg = seg_model.predict(c_img)[0]\n    cur_seg = binary_opening(cur_seg>0.6, np.expand_dims(disk(2), -1))\n    return cur_seg, c_img\n\ndef pred_encode(img):\n    cur_seg, _ = predict(img)\n    cur_rles = rle_encode(cur_seg)\n    return [img, cur_rles if len(cur_rles) > 0 else None]\n\n## Get a sample of each group of ship count\nsamples = train_df.groupby('ships').apply(lambda x: x.sample(2))#1\n\nfig, m_axs = plt.subplots(samples.shape[0], 3, figsize = (11, samples.shape[0]*4))\n[c_ax.axis('off') for c_ax in m_axs.flatten()]\n\nfor (ax1, ax2, ax3), c_img_name in zip(m_axs, samples.ImageId.values):\n    first_seg, first_img = predict(c_img_name, train_image_dir)\n    ax1.imshow(first_img[0])\n    ax1.set_title('Image')\n    ax2.imshow(first_seg[:, :, 0])\n    ax2.set_title('Prediction')\n    ground_truth = masks_as_color(masks.query('ImageId==\"{}\"'.format(c_img_name))['EncodedPixels'])\n    ax3.imshow(ground_truth)\n    ax3.set_title('Ground Truth')\n    \nfig.savefig('predictions.png')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}