{"cells":[{"metadata":{"_uuid":"5626b1cd-dde0-4d00-ad49-3b27bfa603cb","_cell_guid":"f5e85040-63af-4583-a990-28d22388fc60","trusted":true},"cell_type":"code","source":"# 以狗分类为例子，可以自由使用所有方法以及其组合，可以自由更改数据集\n# baseline：EfficientNetB0，可以自由更改网络\n\n# 可以选择启用哪些方法\n\nbool_random_flip_left_right=0\nbool_random_flip_up_down=0\nbool_random_brightness=0\nbool_random_contrast=0\nbool_random_hue=0\nbool_random_saturation=0\ncutmix_rate=0.\nmixup_rate= 0.\ngridmask_rate = 0.\n\npre_trained='imagenet' # None,'imagenet','noisy-student'\ndense_activation='softmax' #'softmax','sigmoid'\nbool_lr_scheduler=0\n\ntta_times=0\n\n#focal_loss和label_smoothing最多同时使用一个\nbool_focal_loss = 0\nlabel_smoothing_rate=0.\n\n# 暂未引入，后续引入\n# 旋转\n# 交叉验证\n# adversarial validation","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1674e332-c9a5-4d91-86e2-6bece6384cef","_cell_guid":"4b7548d1-da40-4f6b-8b3f-f14fa77ba22d","trusted":true},"cell_type":"code","source":"#tta只有在使用了data_aug时才允许启用\nbool_tta =  tta_times and max(  bool_random_flip_left_right,\n                                bool_random_flip_up_down,\n                                bool_random_brightness,\n                                bool_random_contrast,\n                                bool_random_hue,\n                                bool_random_saturation)\n\nprint(bool_tta)\n\nassert (bool_focal_loss and label_smoothing_rate) == 0 , 'focal_loss和label_smoothing最多同时使用一个'","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b7a7bee7-312c-4aa1-beb9-a0d144446c93","_cell_guid":"f26a7863-74ff-4704-ade8-3b7a044eac2b","trusted":true},"cell_type":"code","source":"#导入和安装包\n!pip install -U efficientnet\n!pip install tensorflow_addons\nimport numpy as np\nimport pandas as pd\nimport os\nimport tensorflow as tf\nimport random, re, math\nfrom tensorflow.keras.layers import Dense\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras import optimizers\nimport tensorflow_addons as tfa\n\nfrom kaggle_datasets import KaggleDatasets\nimport efficientnet.tfkeras as efn\n\nprint(tf.__version__)\nprint(tf.keras.__version__)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ab776d0f-4983-4a0e-9d7c-9ab925249f4d","_cell_guid":"e75099ed-41ab-47db-bdce-386194a66968","trusted":true},"cell_type":"code","source":"#针对不同硬件产生不同配置\nAUTO = tf.data.experimental.AUTOTUNE\n# Detect hardware, return appropriate distribution strategy\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()  # TPU detection. No parameters necessary if TPU_NAME environment variable is set. On Kaggle this is always the case.\n    print('Running on TPU ', tpu.master())\nexcept ValueError:\n    tpu = None\n\nif tpu:\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\n    GCS_DS_PATH = KaggleDatasets().get_gcs_path()\n    print(GCS_DS_PATH)\n    # 如果连接失败，直接令GCS_DS_PATH='gs://kds-5a2f14e545dc319d4c7dadd6e05fe609d2674d9e2dea10e40102f4ea'\nelse:\n    strategy = tf.distribute.get_strategy() # default distribution strategy in Tensorflow. Works on CPU and single GPU.\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)\n\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9d42d9ae-1368-44c3-af18-912d062c7813","_cell_guid":"e4f30aff-e019-442d-9491-dc22d3dc9b28","trusted":true},"cell_type":"code","source":"#针对狗分类数据集，更换数据集时更换整个这大段\n\n#超参数，根据数据和策略调参\nBATCH_SIZE = 8 * strategy.num_replicas_in_sync\nimg_size = 299\nEPOCHS = 20\nlr_if_without_scheduler = 0.0003\n\n\npath = '../input/dog-breed-identification/'\n\n#训练集部分\ndf = pd.read_csv(path+'labels.csv')\ndf2 = pd.read_csv(path+'sample_submission.csv')\nprint(df.head())\n\nbreed = set(df['breed'])\n#类别数\nnb_classes = len(breed)\n\nn = len(df)\nclass_to_num = dict(zip(breed, range(nb_classes)))\ntrain_labels = np.zeros((n, nb_classes), dtype=np.uint8)\nfor i in range(n):\n    train_labels[i][class_to_num[df['breed'][i]]] = 1\n\nprint('\\n',train_labels[0])\n\ntrain_paths = df[:1].id.apply(lambda x: (path+'train/') + x + '.jpg').values\nfrom matplotlib import pyplot as plt\n#随便看一张\nimg = plt.imread(train_paths[0])\nprint('\\n',img.shape)\nplt.imshow(img)\n\n\nif tpu:\n    path = GCS_DS_PATH+'/'\n\ntrain_paths = df.id.apply(lambda x: (path+'train/') + x + '.jpg').values\n\n\n\ntest_paths = df2.id.apply(lambda x: (path+'test/') + x + '.jpg').values","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"04e20365-92f1-4735-be52-9daab71b0fdd","_cell_guid":"c65b7909-60cc-4147-9fb6-faf9897e01e6","trusted":true},"cell_type":"code","source":"def decode_image(filename, label=None, image_size=(img_size, img_size)):\n    bits = tf.io.read_file(filename)\n    image = tf.image.decode_jpeg(bits, channels=3)\n    image = tf.cast(image, tf.float32) / 255.0\n    image = tf.image.resize(image, image_size)\n    if label is None:\n        return image\n    else:\n        return image, label\n\n# 只能写入test data 也能用的 aug   \ndef data_aug(image, label=None):\n    if bool_random_flip_left_right:\n        image = tf.image.random_flip_left_right(image)\n    if bool_random_flip_up_down:    \n        image = tf.image.random_flip_up_down(image)\n    if bool_random_brightness:\n        image = tf.image.random_brightness(image,0.2)\n    if bool_random_contrast:\n        image = tf.image.random_contrast(image,0.6,1.4)\n    if bool_random_hue:\n        image = tf.image.random_hue(image,0.07)\n    if bool_random_saturation:\n        image = tf.image.random_saturation(image,0.5,1.5)\n    \n    if label is None:\n        return image\n    else:\n        return image, label","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"70b8ed8f-35a4-4c56-8402-f32d0c3f49b9","_cell_guid":"95adfb55-249f-4b5b-96a8-0b20046a7662","trusted":true},"cell_type":"code","source":"# 在batch内部互相随机取图\ndef cutmix(image, label, PROBABILITY = cutmix_rate):\n    # input image - is a batch of images of size [n,dim,dim,3] not a single image of [dim,dim,3]\n    # output - a batch of images with cutmix applied\n    \n    DIM = img_size    \n    imgs = []; labs = []\n    \n    for j in range(BATCH_SIZE):\n        \n        #random_uniform( shape, minval=0, maxval=None)        \n        # DO CUTMIX WITH PROBABILITY DEFINED ABOVE\n        P = tf.cast(tf.random.uniform([], 0, 1) <= PROBABILITY, tf.int32)\n        \n        # CHOOSE RANDOM IMAGE TO CUTMIX WITH\n        k = tf.cast(tf.random.uniform([], 0, BATCH_SIZE), tf.int32)\n        \n        # CHOOSE RANDOM LOCATION\n        #选一个随机的中心点\n        x = tf.cast(tf.random.uniform([], 0, DIM), tf.int32)\n        y = tf.cast(tf.random.uniform([], 0, DIM), tf.int32)\n        \n        # Beta(1, 1)等于均匀分布\n        b = tf.random.uniform([], 0, 1) # this is beta dist with alpha=1.0\n        \n        #P只随机出0或1，就是裁剪或是不裁剪\n        WIDTH = tf.cast(DIM * tf.math.sqrt(1-b),tf.int32) * P\n        ya = tf.math.maximum(0,y-WIDTH//2)\n        yb = tf.math.minimum(DIM,y+WIDTH//2)\n        xa = tf.math.maximum(0,x-WIDTH//2)\n        xb = tf.math.minimum(DIM,x+WIDTH//2)\n        \n        # MAKE CUTMIX IMAGE\n        one = image[j,ya:yb,0:xa,:]\n        two = image[k,ya:yb,xa:xb,:]\n        three = image[j,ya:yb,xb:DIM,:]        \n        #得出了ya:yb区间内的输出图像\n        middle = tf.concat([one,two,three],axis=1)\n        #得到了完整输出图像\n        img = tf.concat([image[j,0:ya,:,:],middle,image[j,yb:DIM,:,:]],axis=0)\n        imgs.append(img)\n        \n        # MAKE CUTMIX LABEL\n        #按面积来加权的\n        a = tf.cast(WIDTH*WIDTH/DIM/DIM,tf.float32)\n        lab1 = label[j,]\n        lab2 = label[k,]\n        labs.append((1-a)*lab1 + a*lab2)\n\n    image2 = tf.reshape(tf.stack(imgs),(BATCH_SIZE,DIM,DIM,3))\n    label2 = tf.reshape(tf.stack(labs),(BATCH_SIZE, nb_classes))\n    return image2,label2","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2420f249-b5f7-4e02-84f5-5fd8c3653554","_cell_guid":"1cbe8720-ec70-4bde-908c-3afb55dd90b3","trusted":true},"cell_type":"code","source":"def mixup(image, label, PROBABILITY = mixup_rate):\n    # input image - is a batch of images of size [n,dim,dim,3] not a single image of [dim,dim,3]\n    # output - a batch of images with mixup applied\n    DIM = img_size\n    \n    imgs = []; labs = []\n    for j in range(BATCH_SIZE):\n        \n        # CHOOSE RANDOM\n        k = tf.cast( tf.random.uniform([],0,BATCH_SIZE),tf.int32)\n        a = tf.random.uniform([],0,1) # this is beta dist with alpha=1.0\n\n        #根据概率抽取执不执行mixup\n        P = tf.cast(tf.random.uniform([], 0, 1) <= PROBABILITY, tf.int32)\n        if P==1:\n            a=0.\n        \n        # MAKE MIXUP IMAGE\n        img1 = image[j,]\n        img2 = image[k,]\n        imgs.append((1-a)*img1 + a*img2)\n        \n        # MAKE CUTMIX LABEL\n        lab1 = label[j,]\n        lab2 = label[k,]\n        labs.append((1-a)*lab1 + a*lab2)\n            \n    # RESHAPE HACK SO TPU COMPILER KNOWS SHAPE OF OUTPUT TENSOR (maybe use Python typing instead?)\n    image2 = tf.reshape(tf.stack(imgs),(BATCH_SIZE,DIM,DIM,3))\n    label2 = tf.reshape(tf.stack(labs),(BATCH_SIZE,nb_classes))\n    return image2,label2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def transform(image, inv_mat, image_shape):\n    h, w, c = image_shape\n    cx, cy = w//2, h//2\n    new_xs = tf.repeat( tf.range(-cx, cx, 1), h)\n    new_ys = tf.tile( tf.range(-cy, cy, 1), [w])\n    new_zs = tf.ones([h*w], dtype=tf.int32)\n    old_coords = tf.matmul(inv_mat, tf.cast(tf.stack([new_xs, new_ys, new_zs]), tf.float32))\n    old_coords_x, old_coords_y = tf.round(old_coords[0, :] + w//2), tf.round(old_coords[1, :] + h//2)\n    clip_mask_x = tf.logical_or(old_coords_x<0, old_coords_x>w-1)\n    clip_mask_y = tf.logical_or(old_coords_y<0, old_coords_y>h-1)\n    clip_mask = tf.logical_or(clip_mask_x, clip_mask_y)\n    old_coords_x = tf.boolean_mask(old_coords_x, tf.logical_not(clip_mask))\n    old_coords_y = tf.boolean_mask(old_coords_y, tf.logical_not(clip_mask))\n    new_coords_x = tf.boolean_mask(new_xs+cx, tf.logical_not(clip_mask))\n    new_coords_y = tf.boolean_mask(new_ys+cy, tf.logical_not(clip_mask))\n    old_coords = tf.cast(tf.stack([old_coords_y, old_coords_x]), tf.int32)\n    new_coords = tf.cast(tf.stack([new_coords_y, new_coords_x]), tf.int64)\n    rotated_image_values = tf.gather_nd(image, tf.transpose(old_coords))\n    rotated_image_channel = list()\n    for i in range(c):\n        vals = rotated_image_values[:,i]\n        sparse_channel = tf.SparseTensor(tf.transpose(new_coords), vals, [h, w])\n        rotated_image_channel.append(tf.sparse.to_dense(sparse_channel, default_value=0, validate_indices=False))\n    return tf.transpose(tf.stack(rotated_image_channel), [1,2,0])\n\ndef random_rotate(image, angle, image_shape):\n    def get_rotation_mat_inv(angle):\n        # transform to radian\n        angle = math.pi * angle / 180\n        cos_val = tf.math.cos(angle)\n        sin_val = tf.math.sin(angle)\n        one = tf.constant([1], tf.float32)\n        zero = tf.constant([0], tf.float32)\n        rot_mat_inv = tf.concat([cos_val, sin_val, zero, -sin_val, cos_val, zero, zero, zero, one], axis=0)\n        rot_mat_inv = tf.reshape(rot_mat_inv, [3,3])\n        return rot_mat_inv\n    angle = float(angle) * tf.random.normal([1],dtype='float32')\n    rot_mat_inv = get_rotation_mat_inv(angle)\n    return transform(image, rot_mat_inv, image_shape)\n\n\ndef GridMask(image_height, image_width, d1, d2, rotate_angle=1, ratio=0.5):\n    h, w = image_height, image_width\n    hh = int(np.ceil(np.sqrt(h*h+w*w)))\n    hh = hh+1 if hh%2==1 else hh\n    d = tf.random.uniform(shape=[], minval=d1, maxval=d2, dtype=tf.int32)\n    l = tf.cast(tf.cast(d,tf.float32)*ratio+0.5, tf.int32)\n\n    st_h = tf.random.uniform(shape=[], minval=0, maxval=d, dtype=tf.int32)\n    st_w = tf.random.uniform(shape=[], minval=0, maxval=d, dtype=tf.int32)\n\n    y_ranges = tf.range(-1 * d + st_h, -1 * d + st_h + l)\n    x_ranges = tf.range(-1 * d + st_w, -1 * d + st_w + l)\n\n    for i in range(0, hh//d+1):\n        s1 = i * d + st_h\n        s2 = i * d + st_w\n        y_ranges = tf.concat([y_ranges, tf.range(s1,s1+l)], axis=0)\n        x_ranges = tf.concat([x_ranges, tf.range(s2,s2+l)], axis=0)\n\n    x_clip_mask = tf.logical_or(x_ranges < 0 , x_ranges > hh-1)\n    y_clip_mask = tf.logical_or(y_ranges < 0 , y_ranges > hh-1)\n    clip_mask = tf.logical_or(x_clip_mask, y_clip_mask)\n\n    x_ranges = tf.boolean_mask(x_ranges, tf.logical_not(clip_mask))\n    y_ranges = tf.boolean_mask(y_ranges, tf.logical_not(clip_mask))\n\n    hh_ranges = tf.tile(tf.range(0,hh), [tf.cast(tf.reduce_sum(tf.ones_like(x_ranges)), tf.int32)])\n    x_ranges = tf.repeat(x_ranges, hh)\n    y_ranges = tf.repeat(y_ranges, hh)\n\n    y_hh_indices = tf.transpose(tf.stack([y_ranges, hh_ranges]))\n    x_hh_indices = tf.transpose(tf.stack([hh_ranges, x_ranges]))\n\n    y_mask_sparse = tf.SparseTensor(tf.cast(y_hh_indices, tf.int64),  tf.zeros_like(y_ranges), [hh, hh])\n    y_mask = tf.sparse.to_dense(y_mask_sparse, 1, False)\n\n    x_mask_sparse = tf.SparseTensor(tf.cast(x_hh_indices, tf.int64), tf.zeros_like(x_ranges), [hh, hh])\n    x_mask = tf.sparse.to_dense(x_mask_sparse, 1, False)\n\n    mask = tf.expand_dims( tf.clip_by_value(x_mask + y_mask, 0, 1), axis=-1)\n\n    mask = random_rotate(mask, rotate_angle, [hh, hh, 1])\n    mask = tf.image.crop_to_bounding_box(mask, (hh-h)//2, (hh-w)//2, image_height, image_width)\n\n    return mask\n\ndef apply_grid_mask(image, image_shape, PROBABILITY = gridmask_rate):\n    AugParams = {\n        'd1' : 100,\n        'd2': 160,\n        'rotate' : 45,\n        'ratio' : 0.3\n    }\n    \n        \n    mask = GridMask(image_shape[0], image_shape[1], AugParams['d1'], AugParams['d2'], AugParams['rotate'], AugParams['ratio'])\n    if image_shape[-1] == 3:\n        mask = tf.concat([mask, mask, mask], axis=-1)\n        mask = tf.cast(mask,tf.float32)\n        #print(mask.shape) # (299,299,3)\n\n# 会报错，放弃\n#     imgs = []\n#     BATCH_SIZE=len(image)\n#     for j in range(BATCH_SIZE):\n#         P = tf.cast(tf.random.uniform([], 0, 1) <= PROBABILITY, tf.int32)\n#         if P==1:\n#             imgs.append(image[j,]*mask)\n#         else:\n#             imgs.append(image[j,])\n#     return tf.cast(imgs,tf.float32)\n\n        \n    # 整个batch启用或者不启用\n    P = tf.cast(tf.random.uniform([], 0, 1) <= PROBABILITY, tf.int32)\n    if P==1:\n        return image*mask\n    else:\n        return image\n\ndef gridmask(img_batch, label_batch):\n    return apply_grid_mask(img_batch, (img_size,img_size, 3)), label_batch","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ac9f4f60-009f-4ecf-bf61-102a3e866a64","_cell_guid":"4771f2b0-36dd-4786-8e2a-fa55725af14a","trusted":true},"cell_type":"code","source":"# num_parallel_calls并发处理数据的并发数\n\ntrain_dataset = (\n    tf.data.Dataset\n    .from_tensor_slices((train_paths, train_labels.astype(np.float32)))\n    .map(decode_image, num_parallel_calls=AUTO)\n    .map(data_aug, num_parallel_calls=AUTO)\n    .shuffle(512)\n    .batch(BATCH_SIZE,drop_remainder=True)\n    )\n\n\nif cutmix_rate:  \n    print('启用cutmix')\n    train_dataset =train_dataset.map(cutmix, num_parallel_calls=AUTO)\nif mixup_rate:  \n    print('启用mixup')\n    train_dataset =train_dataset.map(mixup, num_parallel_calls=AUTO)\nif gridmask_rate:\n    print('启用gridmask')\n    train_dataset =train_dataset.map(gridmask, num_parallel_calls=AUTO)\nif (cutmix_rate or mixup_rate):\n    train_dataset =train_dataset.unbatch().shuffle(512).batch(BATCH_SIZE)\n\n\n# repeat()代表无限制复制原始数据，这里可以用count指明复制份数，但要注意要比fit中的epochs大才可\n# 直接调用repeat()的话，生成的序列就会无限重复下去\n# prefetch: prefetch next batch while training (autotune prefetch buffer size)\ntrain_dataset = train_dataset.repeat().prefetch(AUTO)\n\n\nview_dataset = train_dataset.repeat(1)\nit = view_dataset.__iter__()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b189aae7-9a99-438f-b18d-30e7884e9e9e","_cell_guid":"0a40bdca-6a21-4013-8ed9-5f7c637e8b8b","trusted":true},"cell_type":"code","source":"#看看train_dataset 是否正常显示\nshow_x, show_y = it.next()\nprint(show_x.shape,'\\n\\n',show_y[0])\n\nplt.figure(figsize=(12, 6))\nfor i in range(len(show_x[:8])):\n    plt.subplot(2, 4, i+1)\n    plt.imshow(show_x[i])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c082b01f-1171-49eb-b8fc-c6e0115a10e5","_cell_guid":"fd062eed-d107-4b2f-a91d-d132aad16fff","trusted":true},"cell_type":"code","source":"#生成测试集\ndef re_produce_test_dataset(test_paths):\n    test_dataset = (\n        tf.data.Dataset\n        .from_tensor_slices(test_paths)\n        .map(decode_image, num_parallel_calls=AUTO)\n        )\n    if bool_tta:\n        test_dataset = test_dataset.map(data_aug, num_parallel_calls=AUTO)\n\n    test_dataset = test_dataset.batch(BATCH_SIZE)\n    return test_dataset","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5abcf959-8974-4af0-a295-bd548a2bda9e","_cell_guid":"dcb80997-fe50-4547-8618-32c97618a8c1","trusted":true},"cell_type":"code","source":"#tta时可重复运行这块观察是否多次运行时生成了不同的测试数据\ntest_dataset = re_produce_test_dataset(test_paths[:8])\n\nview_dataset = test_dataset.repeat(1)\nit = view_dataset.__iter__()\nshow_x= it.next()\nprint(show_x.shape,)\n\nplt.figure(figsize=(12, 6))\nfor i in range(len(show_x)):\n    plt.subplot(2, 4, i+1)\n    plt.imshow(show_x[i])\n    ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2d6bcebd-274f-4475-a887-dd300d2949cd","_cell_guid":"3f19415e-73d6-43cc-8fa4-60c04b467c79","trusted":true},"cell_type":"code","source":"#lr_scheduler\n#数值按实际情况设置\n\nLR_START = 0.00003\nLR_MAX = 0.0003 * strategy.num_replicas_in_sync\nLR_MIN = 0.00003\nLR_RAMPUP_EPOCHS = 3\nLR_SUSTAIN_EPOCHS = 4\nLR_EXP_DECAY = .8\n\ndef lrfn(epoch):\n    if epoch < LR_RAMPUP_EPOCHS:\n        lr = (LR_MAX - LR_START) / LR_RAMPUP_EPOCHS * epoch + LR_START\n    elif epoch < LR_RAMPUP_EPOCHS + LR_SUSTAIN_EPOCHS:\n        lr = LR_MAX\n    else:\n        lr = (LR_MAX - LR_MIN) * LR_EXP_DECAY**(epoch - LR_RAMPUP_EPOCHS - LR_SUSTAIN_EPOCHS) + LR_MIN\n    return lr\n    \nlr_callback = tf.keras.callbacks.LearningRateScheduler(lrfn, verbose=True)\n\nrng = [i for i in range(EPOCHS)]\ny = [lrfn(x) for x in rng]\nif bool_lr_scheduler:\n    plt.plot(rng, y)\n    print(\"Learning rate schedule: {:.3g} to {:.3g} to {:.3g}\".format(y[0], max(y), y[-1]))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0ab821b4-0b1f-4aa8-bfd4-53f0baef86a8","_cell_guid":"4d5b35e1-f24f-4ed9-b1bc-44ae6ab4cb4b","trusted":true},"cell_type":"code","source":"#创建模型\ndef get_model():\n    base_model =  efn.EfficientNetB0(weights=pre_trained, include_top=False, pooling='avg', input_shape=(img_size, img_size, 3))\n    x = base_model.output\n    predictions = Dense(nb_classes, activation=dense_activation)(x)\n    return Model(inputs=base_model.input, outputs=predictions)\n\nwith strategy.scope():\n    model = get_model()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"64f23ce8-14e6-45dc-8e8a-9f36cc4eb6c0","_cell_guid":"a5798339-6a9f-496f-bff6-02f65cca2910","trusted":true},"cell_type":"code","source":"if label_smoothing_rate:\n    print('启用label_smoothing')\n    my_loss=tf.keras.losses.CategoricalCrossentropy(label_smoothing=label_smoothing_rate)\nelif bool_focal_loss:\n    \n    my_loss = tfa.losses.SigmoidFocalCrossEntropy(reduction=tf.keras.losses.Reduction.AUTO)\n\nelse:\n    my_loss='categorical_crossentropy'\n        \nmodel.compile(optimizer=tf.keras.optimizers.Adam(lr_if_without_scheduler), \n              loss=my_loss,\n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"99e16a37-f5c5-40b7-a539-8855b4587429","_cell_guid":"66f608aa-7ad0-4dac-94d5-2edef2161541","trusted":true},"cell_type":"code","source":"callbacks=[]\nif bool_lr_scheduler:\n    callbacks.append(lr_callback)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9578fdf3-7439-4796-bf4a-64abb8c33da5","_cell_guid":"d73d9be1-baf4-46c3-ab6a-822c02480e87","trusted":true},"cell_type":"code","source":"model.fit(\n    train_dataset, \n    steps_per_epoch=train_labels.shape[0] // BATCH_SIZE,\n    callbacks=callbacks,\n    epochs=EPOCHS\n)\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"74f57752-b42e-4743-a8c9-b3d262b89e8e","_cell_guid":"6472f7f3-0519-421d-b01e-319a0bcebda7","trusted":true},"cell_type":"code","source":"if bool_tta:\n    probabilities = []\n    for i in range(tta_times+1):\n        print('TTA Number: ',i,'\\n')\n        test_dataset = re_produce_test_dataset(test_paths)\n        probabilities.append(model.predict(test_dataset))\n    y_pred = np.mean(probabilities,axis =0)\n    \nelse:\n    test_dataset = re_produce_test_dataset(test_paths)\n    y_pred = model.predict(test_dataset)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ec691fed-5d1f-4e5b-a5c6-f9829486797a","_cell_guid":"49c084db-874b-41b0-ad1d-185ac7d1e895","trusted":true},"cell_type":"code","source":"#针对不同数据不同后处理\nfor b in breed:\n    df2[b] = y_pred[:,class_to_num[b]]\ndf2.to_csv('pred.csv', index=None)\ndf2.head()","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}