{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"tpu1vmV38","dataSources":[{"sourceId":21154,"databundleVersionId":1243559,"sourceType":"competition"}],"dockerImageVersionId":30617,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Протестировал арххитектуры: \n1) VGG19(6 версия блокнота), скор на тесте: ![image.png](attachment:a04276a1-e384-46ca-9a0c-1f2b3e68c902.png)\n\n2) DenseNet121(7 версия блокнота), скор на тесте: ![image.png](attachment:ba877bb3-d010-4e5f-861b-26c01df48e55.png)\n\n3) EfficientNetB7(3 версия блокнота), скор на тесте: ![image.png](attachment:42954623-9287-414c-b2c0-79956ab8b1a4.png)","metadata":{},"attachments":{"a04276a1-e384-46ca-9a0c-1f2b3e68c902.png":{"image/png":"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"},"ba877bb3-d010-4e5f-861b-26c01df48e55.png":{"image/png":"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"},"42954623-9287-414c-b2c0-79956ab8b1a4.png":{"image/png":"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"}}},{"cell_type":"code","source":"# !pip install -q efficientnet","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#предварительно обученные модели\nfrom tensorflow.keras.applications.vgg16 import VGG16\nfrom tensorflow.keras.applications.vgg19 import VGG19\nfrom tensorflow.keras.applications.inception_v3 import InceptionV3\nfrom tensorflow.keras.applications.inception_resnet_v2 import InceptionResNetV2\nfrom tensorflow.keras.applications.densenet import DenseNet121, DenseNet169, DenseNet201 \nfrom tensorflow.keras.applications.xception import Xception\nfrom tensorflow.keras.applications.resnet50 import ResNet50\nfrom tensorflow.keras.applications.resnet_v2 import ResNet50V2, ResNet101V2, ResNet152V2\nfrom tensorflow.keras.applications.nasnet import NASNetLarge\n# from efficientnet.tfkeras import EfficientNetB7, EfficientNetL2, EfficientNetB0, EfficientNetB1\n\n# To ignore warinings\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport tensorflow as tf\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.layers import Dense, Flatten\nfrom tensorflow.keras.layers import Dropout, BatchNormalization, GaussianDropout\nfrom tensorflow.keras.layers import GlobalAveragePooling2D\nfrom tensorflow.keras.callbacks import ModelCheckpoint\n#  библиотека для работы с наборами данных на Kaggle\nfrom kaggle_datasets import KaggleDatasets\nimport re\nimport numpy as np\nimport random\nimport matplotlib.pyplot as plt\n%matplotlib inline \nprint(\"Tensorflow version \" + tf.__version__)","metadata":{"execution":{"iopub.status.busy":"2023-12-11T15:32:08.243126Z","iopub.execute_input":"2023-12-11T15:32:08.243519Z","iopub.status.idle":"2023-12-11T15:32:08.254130Z","shell.execute_reply.started":"2023-12-11T15:32:08.243487Z","shell.execute_reply":"2023-12-11T15:32:08.253328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"AUTO = tf.data.experimental.AUTOTUNE\n# Обнаружение оборудования, возврат соответствующей стратегии распространения: TPU, GPU, CPU\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()  # Обнаружение TPU. Параметры среды не требуются, если задана переменная среды TPU_NAME. На Kaggle это всегда так.\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)\nelse:\n    strategy = tf.distribute.get_strategy() # стратегия распространения по умолчанию в Tensorflow. Работает на CPU и одном GPU.\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"GCS_DS_PATH = KaggleDatasets().get_gcs_path() #получаем путь к наборам данных","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_SIZE = [512, 512] # при таком размере графическому процессору не хватит памяти. Используйте TPU\nEPOCHS = 30\nBATCH_SIZE = 16 * strategy.num_replicas_in_sync\n\nGCS_PATH_SELECT = { # available image sizes\n    192: GCS_DS_PATH + '/tfrecords-jpeg-192x192',\n    224: GCS_DS_PATH + '/tfrecords-jpeg-224x224',\n    331: GCS_DS_PATH + '/tfrecords-jpeg-331x331',\n    512: GCS_DS_PATH + '/tfrecords-jpeg-512x512'\n}\nGCS_PATH = GCS_PATH_SELECT[IMAGE_SIZE[0]]\n\nTRAINING_FILENAMES = tf.io.gfile.glob(GCS_PATH + '/train/*.tfrec')\nVALIDATION_FILENAMES = tf.io.gfile.glob(GCS_PATH + '/val/*.tfrec')\nTEST_FILENAMES = tf.io.gfile.glob(GCS_PATH + '/test/*.tfrec')\n\nSEED = 2020","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def decode_image(image_data):\n    \"\"\"Декодирует изображение в vyjujvthye. vfnhbwe (тензор)\n    Нормализует данные и преобразовывает изображения к указанному размеру\"\"\"\n    image = tf.image.decode_jpeg(image_data, channels=3) # Декодирование изображения в формате JPEG в тензор uint8.\n    image = tf.cast(image, tf.float32) / 255.0  # преобразовать изображение в плавающее в диапазоне [0, 1]\n    image = tf.reshape(image, [*IMAGE_SIZE, 3]) # явный размер, необходимый для TPU\n#     image = tf.keras.applications.inception_resnet_v2.preprocess_input(image)\n    return image\n\ndef read_labeled_tfrecord(example):\n    LABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string), # tf.string означает байтовую строку\n        \"class\": tf.io.FixedLenFeature([], tf.int64),  # [] означает отдельный элемент\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT) # парсим отдельный пример в указанном формате\n    image = decode_image(example['image']) # преобразуем изображение к нужному нам формату\n    label = tf.cast(example['class'], tf.int32)\n    return image, label # возвращает набор данных пар (изображение, метка)\n\ndef read_unlabeled_tfrecord(example):\n    UNLABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string), # tf.string означает байтовую строку\n        \"id\": tf.io.FixedLenFeature([], tf.string),  # [] означает отдельный элемент\n        # класс отсутствует, задача этого конкурса - предсказать классы цветов для тестового набора данных\n    }\n    example = tf.io.parse_single_example(example, UNLABELED_TFREC_FORMAT)\n    image = decode_image(example['image']) # преобразуем изображение к нужному нам формату\n    idnum = example['id']\n    return image, idnum # returns a dataset of image(s)\n\ndef load_dataset(filenames, labeled=True, ordered=False):\n    \"\"\"Читает из TFRecords. Для оптимальной производительности одновременное чтение из нескольких\n    файлов без учета порядка данных. Порядок не имеет значения, поскольку мы все равно будем перетасовывать данные\"\"\"\n\n    ignore_order = tf.data.Options() # Представляет параметры для tf.data.Dataset.\n    if not ordered:\n        ignore_order.experimental_deterministic = False # отключить порядок, увеличить скорость\n\n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTO) # автоматически чередует чтение из нескольких файлов\n    dataset = dataset.with_options(ignore_order) # использует данные сразу после их поступления, а не в исходном порядке\n    dataset = dataset.map(read_labeled_tfrecord if labeled else read_unlabeled_tfrecord, num_parallel_calls=AUTO)\n    # возвращает набор данных пар (изображение, метка), если метка = Истина, или пар (изображение, идентификатор), если метка = Ложь\n    return dataset\n\ndef data_augment(image, label):\n    # data augmentation. Thanks to the dataset.prefetch(AUTO) statement in the next function (below),\n    # this happens essentially for free on TPU. Data pipeline code is executed on the \"CPU\" part\n    # of the TPU while the TPU itself is computing gradients.\n    flag = random.randint(1,3)\n    coef_1 = random.randint(70, 90) * 0.01\n    coef_2 = random.randint(70, 90) * 0.01\n    if flag == 1:\n        image = tf.image.random_flip_left_right(image, seed=SEED)\n    elif flag == 2:\n        image = tf.image.random_flip_up_down(image, seed=SEED)\n    else:\n        image = tf.image.random_crop(image, [int(IMAGE_SIZE[0]*coef_1), int(IMAGE_SIZE[0]*coef_2), 3],seed=SEED)\n    return image, label   \n\ndef get_training_dataset():\n    dataset = load_dataset(TRAINING_FILENAMES, labeled=True)\n    dataset = dataset.map(data_augment, num_parallel_calls=AUTO)\n    dataset = dataset.repeat() # набор обучающих данных должен повторяться в течение нескольких эпох\n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO) #готовим следующий набор, пока предыдущий обучается\n    return dataset\n\ndef get_validation_dataset():\n    dataset = load_dataset(VALIDATION_FILENAMES, labeled=True, ordered=False)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.cache() # кешируем набор\n    dataset = dataset.prefetch(AUTO) #готовим следующий набор, пока предыдущий обучается\n    return dataset\n\ndef get_test_dataset(ordered=False):\n    dataset = load_dataset(TEST_FILENAMES, labeled=False, ordered=ordered)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO) #готовим следующий набор, пока предыдущий обучается\n    return dataset\n                               \ndef count_data_items(filenames):\n    # the number of data items is written in the name of the .tfrec files, i.e. flowers00-230.tfrec = 230 data items\n    n = [int(re.compile(r\"-([0-9]*)\\.\").search(filename).group(1)) for filename in filenames]\n    return np.sum(n)\n\n# training_dataset = get_training_dataset()\n# validation_dataset = get_validation_dataset()\n\nNUM_TRAINING_IMAGES = count_data_items(TRAINING_FILENAMES)\nNUM_VALIDATION_IMAGES = count_data_items(VALIDATION_FILENAMES)\nNUM_TEST_IMAGES = count_data_items(TEST_FILENAMES)\nSTEPS_PER_EPOCH = NUM_TRAINING_IMAGES // BATCH_SIZE\nprint('Dataset: {} training images, {} validation images, {} unlabeled test images'.format(NUM_TRAINING_IMAGES, NUM_VALIDATION_IMAGES, NUM_TEST_IMAGES))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# функция управляющая изменениями шага обучения в процессе тренировки нейронной сети\nLR_START = 0.00001\nLR_MAX = 0.00005 * strategy.num_replicas_in_sync#0.0001\nLR_MIN = 0.00001\nLR_RAMPUP_EPOCHS = 5\nLR_SUSTAIN_EPOCHS = 0\nLR_EXP_DECAY = .75\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\n# построим график изменения шага обучение в зависимости от эпох\nrng = [i for i in range(EPOCHS)]\ny = [lrfn(x) for x in rng]\nplt.plot(rng, y)\nprint(\"Learning rate schedule: {:.3g} to {:.3g} to {:.3g}\".format(y[0], max(y), y[-1]))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model(use_model):\n    # noisy-student\n    base_model = use_model(weights='imagenet', \n                      include_top=False, pooling='avg',\n                      input_shape=(*IMAGE_SIZE, 3))\n#     base_model.trainable = False\n    x = base_model.output\n    predictions = Dense(104, activation='softmax')(x)\n    return Model(inputs=base_model.input, outputs=predictions)\n\n\nwith strategy.scope():    \n    model = get_model(DenseNet121) # тут подставить свою модель\n        \nmodel.compile(\n    optimizer='nadam',\n    loss = 'sparse_categorical_crossentropy',\n    metrics=['sparse_categorical_accuracy']\n)\n# Визуализируем архитектуру модели\n# tf.keras.utils.plot_model(\n#     model, to_file='model.png', show_shapes=True, show_layer_names=True,\n# )","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(get_training_dataset(), \n          steps_per_epoch=STEPS_PER_EPOCH, \n          epochs=EPOCHS, \n          callbacks=[lr_callback, ModelCheckpoint(filepath='my_dense_net_121.h5', monitor='val_loss',\n                                  save_best_only=True)],\n          validation_data=get_validation_dataset(),\n          workers = 3)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history['sparse_categorical_accuracy'], \n         label='Оценка точности на обучающем наборе')\nplt.plot(history.history['val_sparse_categorical_accuracy'], \n         label='Оценка точности на проверочном наборе')\nplt.xlabel('Эпоха обучения')\nplt.ylabel('Оценка точности')\nplt.legend()\nplt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history['loss'], \n         label='Оценка потерь на обучающем наборе')\nplt.plot(history.history['val_loss'], \n         label='Оценка потерь на проверочном наборе')\nplt.xlabel('Эпоха обучения')\nplt.ylabel('Оценка потерь')\nplt.legend()\nplt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = tf.keras.models.load_model('my_dense_net_121.h5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Поскольку мы разделяем набор данных и выполняем итерацию отдельно для изображений и идентификаторов, порядок имеет значение.\ntest_ds = get_test_dataset(ordered=True) \n\nprint('Вычисляем предсказания...')\ntest_images_ds = test_ds.map(lambda image, idnum: image)\nprobabilities = model.predict(test_images_ds)\npredictions = np.argmax(probabilities, axis=-1)\nprint(predictions)\n\nprint('Создание файла submission.csv...')\ntest_ids_ds = test_ds.map(lambda image, idnum: idnum).unbatch()\ntest_ids = next(iter(test_ids_ds.batch(NUM_TEST_IMAGES))).numpy().astype('U') # все в одной партии\nnp.savetxt('submission.csv', np.rec.fromarrays([test_ids, predictions]), fmt=['%s', '%d'], delimiter=',', header='id,label', comments='')","metadata":{},"execution_count":null,"outputs":[]}]}