{"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":"SAMPLES_PER_GROUP = 50#1500\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))#1800\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":"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":"BATCH_SIZE=48\nIMG_SCALING = (3, 3)\n\ndef masks_as_image(in_mask_list):\n    # Take the individual ship masks and create a single mask array for all ships\n    #获取单个舰船面罩，并为所有舰船创建单个面罩阵列\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 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需要与RLE方向对齐\n\ndef 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":"train_gen = make_image_gen(train_df)\ntrain_x, train_y = next(train_gen) #返回迭代器的下一个项目。\nprint('x', train_x.shape, train_x.min(), train_x.max())\nprint('y', train_y.shape, train_y.min(), train_y.max())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from skimage.util import montage\nfrom skimage.segmentation import mark_boundaries\n\nmontage_rgb = lambda x: np.stack([montage(x[:, :, :, i]) for i in range(x.shape[3])], -1)\n#np.stack增加纬度，\n\nfig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize = (30, 10))\nbatch_rgb = montage_rgb(train_x)\nbatch_seg = montage(train_y[:, :, :, 0])\nax1.imshow(batch_rgb)\nax1.set_title('Images')#标题\nax2.imshow(batch_seg)\nax2.set_title('Segmentations')\nax3.imshow(mark_boundaries(batch_rgb, batch_seg.astype(int)))#显示遮掩的边缘\nax3.set_title('Outlined Ships')\nfig.savefig('overview.png')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"设置验证集"},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n#将会给出cell的代码运行一次所花费的时间。\nVALID_IMG_COUNT = 900\n\nvalid_x, valid_y = next(make_image_gen(valid_df, VALID_IMG_COUNT))\nprint(valid_x.shape, valid_y.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"扩充数据"},{"metadata":{"trusted":true},"cell_type":"code","source":"AUGMENT_BRIGHTNESS=False\n\nfrom 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":"cur_gen = create_aug_gen(train_gen)\nt_x, t_y = next(cur_gen)\nprint('x', t_x.shape, t_x.dtype, t_x.min(), t_x.max())\nprint('y', t_y.shape, t_y.dtype, t_y.min(), t_y.max())\n# only keep first 9 samples to examine in detail\n#只保留前9个样本进行详细检查\nt_x = t_x[:9]\nt_y = t_y[:9]\nfig, (ax1, ax2) = plt.subplots(1, 2, figsize = (20, 10))\nax1.imshow(montage_rgb(t_x), cmap='gray')\nax1.set_title('images')\nax2.imshow(montage(t_y[:, :, :, 0]), cmap='gray_r')\nax2.set_title('ships')","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\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, [f2, f3, f4, f5]\n","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\ndef 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    [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), interpolation='bilinear')(f5)\n    f4 = UpSampling2D(size=(4, 4), interpolation='bilinear')(f4)\n    f3 = UpSampling2D(size=(2, 2), interpolation='bilinear')(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=128, kernel_size=1)\n\n    z = concatenate([o, y])\n    z = (Conv2D(32, (3, 3), padding='same'))(z)\n    z = (BatchNormalization())(z)\n\n    z = UpSampling2D(size=(4,4), interpolation='bilinear')(z)\n    z = (Conv2D(1, (1, 1), padding='same'))(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":"model=_unet()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras.backend as K\nfrom keras.optimizers import Adam\nfrom keras.losses import binary_crossentropy\n\n## intersection over union评价函数\ndef IoU(y_true, y_pred, eps=1e-6):\n    if np.max(y_true) == 0.0:\n        return IoU(1-y_true, 1-y_pred) ## empty image; calc IoU of zeros\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)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras.backend as K\nfrom keras.optimizers import Adam\nHEIGHT=256\nWIDTH=256\ndef losses(y_true, y_pred):\n    crossloss = K.binary_crossentropy(y_true,y_pred)\n    loss = 4 * K.sum(crossloss)/HEIGHT/WIDTH\n    return loss","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.33,\n                                   patience=1, 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=20) # 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_STEPS=1\nMAX_TRAIN_EPOCHS=9","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def fit():\n    model.compile(optimizer=Adam(1e-3, decay=1e-6), loss=losses, metrics=['binary_accuracy'])\n    \n    step_count = min(MAX_TRAIN_STEPS, train_df.shape[0]//BATCH_SIZE)\n    aug_gen = create_aug_gen(make_image_gen(train_df))\n    loss_history = [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                                           )]\n    return loss_history\n\ni=0\n\nwhile True:    \n    loss_history = fit()\n    i=i+1\n    if np.min([mh.history['val_loss'] for mh in loss_history]) < -0.2:\n        break\n    if i==2:\n        break","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}