{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Giriş","metadata":{}},{"cell_type":"markdown","source":"## Proje Tanımı","metadata":{}},{"cell_type":"markdown","source":"Bu yarışma, çiçekleri sınıflandırmak için makine öğrenmesi algoritmalarının kullanılması üzerine odaklanmaktadır. Yarışma, **TensorFlow Processing Unit** (TPU) hızlandırıcısı üzerinde çalışacak modellerin geliştirilmesine odaklanmaktadır.\n\n![](https://s3.imgbu.com/file/imgbucom-s/2023/06/06/__results___43_05a0f33e5da1a4bb9.png)\n\nAmacımız, verilen çiçek görüntülerini doğru bir şekilde sınıflandıran etkili bir sınıflandırma modeli geliştirmektir. Bu, görsel tanıma ve sınıflandırma yeteneklerimizin önemli bir testidir. Çalışmalarınızı TPU üzerinde çalışacak bir model oluşturmak üzerine odaklamalıyız, çünkü TPU'lar, büyük veri setlerinde hızlandırılmış hesaplama gücü sağlayan özel bir donanım hızlandırıcısıdır.\n\nYarışma veri kümesi, çeşitli **104** çiçek türüne ait çok sayıda görüntü içermektedir. Veri kümesi, eğitim, doğrulama ve test olarak üçe ayrılmıştır. Eğitim veri seti, çiçeklerin farklı açılardan, farklı aydınlatma koşullarında ve farklı çevresel faktörler altında çekilmiş görüntülerini içerir. Doğrulama veri kümesi, eğitim veri setiyle benzer özelliklere sahip çiçek görüntülerini içermektedir ve modelin eğitim sürecinde performansını değerlendirmek için kullanılır. Test veri seti ise, eğitim ve doğrulama veri setleriyle benzer özelliklere sahip çiçek görüntülerini içermektedir ve başarılı bir model, bu veri setinde doğru sınıflandırmalar yapabilmelidir.\n\nYarışmada önceden eğitilmiş **Xception** modelini kullandık. Xception, ImageNet veri kümesiyle eğitilmiş derin öğrenme modelidir ve çeşitli görsel sınıflandırma görevlerinde yüksek başarı elde etmişlerdir. Bu model, çiçek görüntülerinin sınıflandırılması için uygun bir şekilde uyarlana bildiği taktirde sınıflandırmada oldukça yüksek performans sağlamaktadır.","metadata":{}},{"cell_type":"markdown","source":"## Kütüphanelerin Yüklenmesi","metadata":{}},{"cell_type":"code","source":"import math, re, os\nimport numpy as np\nimport tensorflow as tf\n\nprint(\"Tensorflow versiyonu \" + tf.__version__)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-06-06T16:28:40.009936Z","iopub.execute_input":"2023-06-06T16:28:40.010939Z","iopub.status.idle":"2023-06-06T16:28:40.016225Z","shell.execute_reply.started":"2023-06-06T16:28:40.010901Z","shell.execute_reply":"2023-06-06T16:28:40.015253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dağıtım Stratejisi","metadata":{}},{"cell_type":"code","source":"# TPU'yu algıla, uygun dağıtım stratejisini getir\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver() \n    print('TPU üzerinde çalışıyor ', 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.TPUStrategy(tpu)\nelse:\n    strategy = tf.distribute.get_strategy()","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:28:44.907656Z","iopub.execute_input":"2023-06-06T16:28:44.908522Z","iopub.status.idle":"2023-06-06T16:28:54.926511Z","shell.execute_reply.started":"2023-06-06T16:28:44.908482Z","shell.execute_reply":"2023-06-06T16:28:54.925279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Verinin Yüklenmesi","metadata":{}},{"cell_type":"code","source":"GCS_DS_PATH = '/kaggle/input/tpu-getting-started'","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:29:01.752842Z","iopub.execute_input":"2023-06-06T16:29:01.753841Z","iopub.status.idle":"2023-06-06T16:29:01.758396Z","shell.execute_reply.started":"2023-06-06T16:29:01.753803Z","shell.execute_reply":"2023-06-06T16:29:01.757307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_SIZE = [224, 224]\nGCS_PATH = GCS_DS_PATH + '/tfrecords-jpeg-224x224'\nAUTO = tf.data.experimental.AUTOTUNE\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\nCLASSES = ['pink primrose',    'hard-leaved pocket orchid', 'canterbury bells', 'sweet pea',     'wild geranium',     'tiger lily',           'moon orchid',              'bird of paradise', 'monkshood',        'globe thistle',         # 00 - 09\n           'snapdragon',       \"colt's foot\",               'king protea',      'spear thistle', 'yellow iris',       'globe-flower',         'purple coneflower',        'peruvian lily',    'balloon flower',   'giant white arum lily', # 10 - 19\n           'fire lily',        'pincushion flower',         'fritillary',       'red ginger',    'grape hyacinth',    'corn poppy',           'prince of wales feathers', 'stemless gentian', 'artichoke',        'sweet william',         # 20 - 29\n           'carnation',        'garden phlox',              'love in the mist', 'cosmos',        'alpine sea holly',  'ruby-lipped cattleya', 'cape flower',              'great masterwort', 'siam tulip',       'lenten rose',           # 30 - 39\n           'barberton daisy',  'daffodil',                  'sword lily',       'poinsettia',    'bolero deep blue',  'wallflower',           'marigold',                 'buttercup',        'daisy',            'common dandelion',      # 40 - 49\n           'petunia',          'wild pansy',                'primula',          'sunflower',     'lilac hibiscus',    'bishop of llandaff',   'gaura',                    'geranium',         'orange dahlia',    'pink-yellow dahlia',    # 50 - 59\n           'cautleya spicata', 'japanese anemone',          'black-eyed susan', 'silverbush',    'californian poppy', 'osteospermum',         'spring crocus',            'iris',             'windflower',       'tree poppy',            # 60 - 69\n           'gazania',          'azalea',                    'water lily',       'rose',          'thorn apple',       'morning glory',        'passion flower',           'lotus',            'toad lily',        'anthurium',             # 70 - 79\n           'frangipani',       'clematis',                  'hibiscus',         'columbine',     'desert-rose',       'tree mallow',          'magnolia',                 'cyclamen ',        'watercress',       'canna lily',            # 80 - 89\n           'hippeastrum ',     'bee balm',                  'pink quill',       'foxglove',      'bougainvillea',     'camellia',             'mallow',                   'mexican petunia',  'bromelia',         'blanket flower',        # 90 - 99\n           'trumpet creeper',  'blackberry lily',           'common tulip',     'wild rose']                                                                                                                                               # 100 - 102\n\n\ndef decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels=3)\n    image = tf.cast(image, tf.float32) / 255.0\n    image = tf.reshape(image, [*IMAGE_SIZE, 3])\n    return image\n\ndef read_labeled_tfrecord(example):\n    LABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], 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),\n        \"id\": tf.io.FixedLenFeature([], tf.string),\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\n\ndef load_dataset(filenames, labeled=True, ordered=False):\n\n    ignore_order = tf.data.Options()\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    return dataset","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:29:06.983065Z","iopub.execute_input":"2023-06-06T16:29:06.983485Z","iopub.status.idle":"2023-06-06T16:29:07.040523Z","shell.execute_reply.started":"2023-06-06T16:29:06.983455Z","shell.execute_reply":"2023-06-06T16:29:07.039261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Veri Düzeninin Oluşturulması","metadata":{}},{"cell_type":"code","source":"def data_augment(image, label):                    #bu kod data üzerinde augmentation işlemlerini gerçekleştiriyo bu işlem datayı çeşitlendirerek modelimizin daha iyi daha performanslı çalışmasını sağlar.\n    image = tf.image.random_flip_left_right(image) \n                                                   \n    return image, label                            \n\ndef get_training_dataset():\n    dataset = load_dataset(TRAINING_FILENAMES, labeled=True)     # load_dataset fonksiyonu kullanılarak hazırladığımız TRAINING_FILENAMES adlı eğitim veri seti yüklenir.\n                                                                 \n    dataset = dataset.map(data_augment, num_parallel_calls=AUTO) #Daha sonra, map fonksiyonu kullanılarak veri setine data_augment fonksiyonu uygulanır. \n                                                                 \n    dataset = dataset.repeat()  # dataset.repeat() ifadesi, veri setinin tekrarlanabilir bir şekilde kullanılmasını sağlayarak, modelin birden fazla epoch boyunca veri seti üzerinde eğitim yapmasına olanak tanır.\n    dataset = dataset.shuffle(2048) #dataset.shuffle(2048) ifadesi, veri setinin öğelerini karıştırmak için kullanılan bir işlemdir.\n                                    \n\n    dataset = dataset.batch(BATCH_SIZE) # batch sizeımızı belirliyoruz.\n    dataset = dataset.prefetch(AUTO) #prefetch işlemi, modelin eğitim veya değerlendirme aşamasında veri seti üzerinde daha hızlı ilerlemesini sağlar. \n                          \n    return dataset\n\ndef get_validation_dataset(ordered=False):\n    dataset = load_dataset(VALIDATION_FILENAMES, labeled=True, ordered=ordered)# load_dataset fonksiyonu kullanılarak hazırladığımız VALIDATION_FILENAMES adlı doğrulama veri seti yüklenir.\n                                                                              \n    dataset = dataset.batch(BATCH_SIZE)# batch sizeımızı belirliyoruz.\n    dataset = dataset.cache() #dataset.cache() ifadesi, veri setini bellekte önbelleğe alır. Bu, veri setinin daha hızlı erişilebilir olmasını sağlar.\n    dataset = dataset.prefetch(AUTO)#prefetch işlemi, modelin eğitim veya değerlendirme aşamasında veri seti üzerinde daha hızlı ilerlemesini sağlar. \n                                 \n    return dataset\n\ndef get_test_dataset(ordered=False):\n    dataset = load_dataset(TEST_FILENAMES, labeled=False, ordered=ordered)# load_dataset fonksiyonu kullanılarak hazırladığımız TEST_FILENAMES adlı test veri seti yüklenir. labeled = false dememizin sebebi verimizin etiketli olmasını istemiyoruz\n\n    dataset = dataset.batch(BATCH_SIZE)# batch sizeımızı belirliyoruz.\n    dataset = dataset.prefetch(AUTO)#prefetch işlemi, modelin eğitim veya değerlendirme aşamasında veri seti üzerinde daha hızlı ilerlemesini sağlar. \n                                  \n    return dataset\n\ndef count_data_items(filenames):\n    n = [int(re.compile(r\"-([0-9]*)\\.\").search(filename).group(1)) for filename in filenames] #re.compile(r\"-([0-9]*)\\.\").search(filename) ifadesi - den sonra sayı ve daha sonra . şeklinde gelen bir ifade kontrolü yapar serach ifadesi bu ifadenin eşleştiği ilk örneği döndürür.\n                                                                            \n    return np.sum(n)\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)\nprint('Dataset: {} training görseli, {} validation görseli, {} etiketsiz test görseli'.format(NUM_TRAINING_IMAGES, NUM_VALIDATION_IMAGES, NUM_TEST_IMAGES))","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:29:18.846153Z","iopub.execute_input":"2023-06-06T16:29:18.846577Z","iopub.status.idle":"2023-06-06T16:29:18.861908Z","shell.execute_reply.started":"2023-06-06T16:29:18.846537Z","shell.execute_reply":"2023-06-06T16:29:18.860872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the batch size. This will be 16 with TPU off and 128 (=16*8) with TPU on\nBATCH_SIZE = 16 * strategy.num_replicas_in_sync #BATCH_SIZE değerini TPU'nun açık veya kapalı durumuna göre replika sayısı ile çarpmak, TPU'nun paralel işleme yeteneklerinden faydalanmak için yapılan bir işlemdir.\n                                      \nds_train = get_training_dataset()\nds_valid = get_validation_dataset()\nds_test = get_test_dataset()\n\nprint(\"Training:\", ds_train)\nprint (\"Validation:\", ds_valid)\nprint(\"Test:\", ds_test)","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:29:23.434463Z","iopub.execute_input":"2023-06-06T16:29:23.434910Z","iopub.status.idle":"2023-06-06T16:29:23.852040Z","shell.execute_reply.started":"2023-06-06T16:29:23.434877Z","shell.execute_reply":"2023-06-06T16:29:23.850690Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Verinin İncelenmesi","metadata":{}},{"cell_type":"code","source":"from matplotlib import pyplot as plt\n\ndef batch_to_numpy_images_and_labels(data):\n    images, labels = data\n    numpy_images = images.numpy()\n    numpy_labels = labels.numpy()\n    if numpy_labels.dtype == object:\n        numpy_labels = [None for _ in enumerate(numpy_images)]\n    return numpy_images, numpy_labels\n\ndef title_from_label_and_target(label, correct_label):\n    if correct_label is None:\n        return CLASSES[label], True\n    correct = (label == correct_label)\n    return \"{} [{}{}{}]\".format(CLASSES[label], 'OK' if correct else 'NO', u\"\\u2192\" if not correct else '',\n                                CLASSES[correct_label] if not correct else ''), correct\n\ndef display_one_flower(image, title, subplot, red=False, titlesize=16):\n    plt.subplot(*subplot)\n    plt.axis('off')\n    plt.imshow(image)\n    if len(title) > 0:\n        plt.title(title, fontsize=int(titlesize) if not red else int(titlesize/1.2), color='red' if red else 'black', fontdict={'verticalalignment':'center'}, pad=int(titlesize/1.5))\n    return (subplot[0], subplot[1], subplot[2]+1)\n    \ndef display_batch_of_images(databatch, predictions=None):\n    images, labels = batch_to_numpy_images_and_labels(databatch)\n    if labels is None:\n        labels = [None for _ in enumerate(images)]\n        \n    rows = int(math.sqrt(len(images)))\n    cols = len(images)//rows\n        \n    FIGSIZE = 13.0\n    SPACING = 0.1\n    subplot=(rows,cols,1)\n    if rows < cols:\n        plt.figure(figsize=(FIGSIZE,FIGSIZE/cols*rows))\n    else:\n        plt.figure(figsize=(FIGSIZE/rows*cols,FIGSIZE))\n    \n    for i, (image, label) in enumerate(zip(images[:rows*cols], labels[:rows*cols])):\n        title = '' if label is None else CLASSES[label]\n        correct = True\n        if predictions is not None:\n            title, correct = title_from_label_and_target(predictions[i], label)\n        dynamic_titlesize = FIGSIZE*SPACING/max(rows,cols)*40+3\n        subplot = display_one_flower(image, title, subplot, not correct, titlesize=dynamic_titlesize)\n    \n    plt.tight_layout()\n    if label is None and predictions is None:\n        plt.subplots_adjust(wspace=0, hspace=0)\n    else:\n        plt.subplots_adjust(wspace=SPACING, hspace=SPACING)\n    plt.show()\n\n\ndef display_training_curves(training, validation, title, subplot):\n    if subplot%10==1:\n        plt.subplots(figsize=(10,10), facecolor='#F0F0F0')\n        plt.tight_layout()\n    ax = plt.subplot(subplot)\n    ax.set_facecolor('#F8F8F8')\n    ax.plot(training)\n    ax.plot(validation)\n    ax.set_title('model '+ title)\n    ax.set_ylabel(title)\n    ax.set_xlabel('epoch')\n    ax.legend(['train', 'valid.'])","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:29:35.295095Z","iopub.execute_input":"2023-06-06T16:29:35.296211Z","iopub.status.idle":"2023-06-06T16:29:36.562894Z","shell.execute_reply.started":"2023-06-06T16:29:35.296173Z","shell.execute_reply":"2023-06-06T16:29:36.561478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_iter = iter(ds_train.unbatch().batch(20))","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:29:44.014564Z","iopub.execute_input":"2023-06-06T16:29:44.015856Z","iopub.status.idle":"2023-06-06T16:29:44.054873Z","shell.execute_reply.started":"2023-06-06T16:29:44.015808Z","shell.execute_reply":"2023-06-06T16:29:44.053537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"one_batch = next(ds_iter)\ndisplay_batch_of_images(one_batch)","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:29:46.174904Z","iopub.execute_input":"2023-06-06T16:29:46.175951Z","iopub.status.idle":"2023-06-06T16:29:49.467526Z","shell.execute_reply.started":"2023-06-06T16:29:46.175913Z","shell.execute_reply":"2023-06-06T16:29:49.466229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Modelin Oluşturulması","metadata":{}},{"cell_type":"code","source":"EPOCHS = 20   # Epoch, tüm eğitim verilerinin model tarafından bir kez geçirildiği bir eğitim iterasyonunu ifade eder.\n\nwith strategy.scope(): # Mevcut bir dağıtılmış eğitim stratejisi kullanmak için bir içerik yönetici (context manager) tanımlar. \n                       # Ve birden çok işlemci veya birden çok cihaz üzerinde paralel eğitim yapmayı mümkün kılar.\n    pretrained_model = tf.keras.applications.xception.Xception( \n        # Xception modelini TensorFlow Keras API'si kullanarak oluşturur. Bu model, önceden eğitilmiş ağırlıkları ImageNet veri kümesiyle eğitilmiş olan Xception modelidir.\n        weights='imagenet',\n        include_top=False , # Modelin en üstündeki tam bağlantılı katmanların yüklenmeyeceği ve yeni bir sınıflandırma başı eklemek için kullanılacağı demektirç.\n        input_shape=[*IMAGE_SIZE, 3] # Görüntünün boyutunu belirler.\n    )\n    pretrained_model.trainable = False # Bu satırlar, önceden eğitilmiş modellerin eğitilebilirlik durumunu kontrol eder. \n                                        # False olarak ayarlandığında, bu modellerin weightleri eğitim sırasında güncellenmeyecektir.\n    \n    model = tf.keras.Sequential([ # Bir keras modeli oluşturur. Global Average Pooling katmanı ve softmax aktivasyonu ile tam bağlantılı bir sınıflandırma katmanı içerir.\n        pretrained_model,\n        tf.keras.layers.GlobalAveragePooling2D(), \n        # Özellik haritalarının boyutunu azaltır ve her özellik haritasının ortalama değerini alır. Böylece, her özellik haritası tek bir vektörle temsil edilir.\n        tf.keras.layers.Dense(len(CLASSES), activation='softmax')\n        # Bu katmanda her sınıfa karşılık gelen bir çıkış düğümü bulunur. Aktivasyon fonksiyonu olarak softmax kullanılarak, her çıkış düğümünün sınıflara ait olma olasılığı hesaplanır.\n    ])","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:29:58.770132Z","iopub.execute_input":"2023-06-06T16:29:58.771073Z","iopub.status.idle":"2023-06-06T16:30:16.310922Z","shell.execute_reply.started":"2023-06-06T16:29:58.771034Z","shell.execute_reply":"2023-06-06T16:30:16.309656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile( # Modelin derlenmesini sağlar. Optimizasyon algoritması olarak Nadamı kullandık. \n               # Nadam \"Nesterov Adaptive Moment Estimation\" gradient tabanlı bir yöntem kullanarak modelin parametrelerini optimize eder.\n    optimizer='nadam',\n    loss = 'sparse_categorical_crossentropy', # Seyrek kategorik çapraz entropidir. Modeli kullanırkenki kayıbımız belirleyen kayıp fonksiyonudur.\n    metrics=['sparse_categorical_accuracy'], # Modelin performansını izlemek için kullanılan bir metriktir.\n)\nmodel.summary() # Modelin katmanlarını, her katmandaki parametre sayısını ve toplam parametre sayısını gösterir.","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:30:34.388362Z","iopub.execute_input":"2023-06-06T16:30:34.389242Z","iopub.status.idle":"2023-06-06T16:30:34.631936Z","shell.execute_reply.started":"2023-06-06T16:30:34.389199Z","shell.execute_reply":"2023-06-06T16:30:34.630989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Modelin Eğitilmesi","metadata":{}},{"cell_type":"code","source":"EPOCHS = 20 \ndef exponential_lr(epoch, # Bu fonksiyon öğrenme oranını hesaplar ve bunu döndürür.\n                   start_lr = 0.00002 , min_lr = 0.00001, max_lr = 0.0001,\n                   # Başlangıç öğrenme oranı, minimum öğrenme oranı ve maximum öğrenme oranlarını belirledik.\n                   rampup_epochs = 10, sustain_epochs = 4,\n                   # Öğrenme oranının artışını kontrol eden epoch sayısıdır, öğrenme oranının sabit kalacapı epoch sayısıdır.\n                   exp_decay = 0.8): # Öğrenme oranının azalmasını kontrol eden üstel.\n\n    def lr(epoch, start_lr, min_lr, max_lr, rampup_epochs, sustain_epochs, exp_decay):\n        if epoch < rampup_epochs: # Epoch, rampup_epochs değerinden küçükse, öğrenme oranını başlangıçtan maksimum öğrenme oranına doğrusal olarak artırır.\n            lr = ((max_lr - start_lr) /\n                  rampup_epochs * epoch + start_lr)\n        elif epoch < rampup_epochs + sustain_epochs: # Epoch, rampup_epochs ile rampup_epochs + sustain_epochs arasındaysa, öğrenme oranını maksimum öğrenme oranında sabit tutar.\n            lr = max_lr\n        else: # Epoch, rampup_epochs + sustain_epochs değerinden büyükse, öğrenme oranını minimum öğrenme oranından başlayarak üstel bir şekilde azaltır.\n            lr = ((max_lr - min_lr) *\n                  exp_decay**(epoch - rampup_epochs - sustain_epochs) +\n                  min_lr)\n        return lr\n    return lr(epoch,\n              start_lr,\n              min_lr,\n              max_lr,\n              rampup_epochs,\n              sustain_epochs,\n              exp_decay)\n\nlr_callback = tf.keras.callbacks.LearningRateScheduler(exponential_lr, verbose=0) \n# Öğrenme oranını güncellemek için kullanılır. Learning rate schedule oluşturan bir callback oluşturur.\n\nes_callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss',min_delta=0,patience=2,\n    restore_best_weights=True,\n# Belirli bir süre gelişme olmazsa eğitimin sonlandığı kısımdır.\n)\n\nrng = [i for i in range(EPOCHS)] # Epoch sayısını temsil eden bir aralık oluşturur. \ny = [exponential_lr(x) for x in rng] # Her epoch için öğrenme oranını hesaplayıp elde edilen öğrenme oranlarını \"y\" listesine ekler.\nplt.plot(rng, y) # Rng aralığını x ekseni olarak, y listesini y ekseni olarak kullanıp görselleştirmenin yapıldığı kısımdır.\nprint(\"Learning rate schedule: {:.3g} to {:.3g} to {:.3g}\".format(y[0], max(y), y[-1]))","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:30:42.521506Z","iopub.execute_input":"2023-06-06T16:30:42.521873Z","iopub.status.idle":"2023-06-06T16:30:42.777799Z","shell.execute_reply.started":"2023-06-06T16:30:42.521844Z","shell.execute_reply":"2023-06-06T16:30:42.776550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Modelin Uyarlanması","metadata":{}},{"cell_type":"code","source":"# training epochları tanımlama\nSTEPS_PER_EPOCH = NUM_TRAINING_IMAGES // BATCH_SIZE\n\nhistory = model.fit(\n    ds_train,\n    validation_data=ds_valid,\n    epochs=EPOCHS,\n    steps_per_epoch=STEPS_PER_EPOCH,\n    callbacks=[lr_callback,es_callback],\n    verbose = 1,\n)\n\n#verbose=1, her epoch için ilerleme çubuğunu ve kayıp değerlerini yazdırır.\n","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:30:54.250238Z","iopub.execute_input":"2023-06-06T16:30:54.250743Z","iopub.status.idle":"2023-06-06T16:34:03.103774Z","shell.execute_reply.started":"2023-06-06T16:30:54.250701Z","shell.execute_reply":"2023-06-06T16:34:03.102384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_training_curves(\n    history.history['loss'],\n    history.history['val_loss'],\n    'loss',\n    211,\n)\ndisplay_training_curves(\n    history.history['sparse_categorical_accuracy'],\n    history.history['val_sparse_categorical_accuracy'],\n    'accuracy',\n    212,\n)\n\n# 212 2 satır ve 1 sütundan oluşan bir subplot düzenindeki 2. sütunu ifade eder","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:34:41.859868Z","iopub.execute_input":"2023-06-06T16:34:41.860758Z","iopub.status.idle":"2023-06-06T16:34:42.565143Z","shell.execute_reply.started":"2023-06-06T16:34:41.860718Z","shell.execute_reply":"2023-06-06T16:34:42.563911Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Tahminlerin Değerlendirilmesi","metadata":{}},{"cell_type":"code","source":"dataset = get_validation_dataset()\ndataset = dataset.unbatch().batch(20)\nbatch = iter(dataset)\n#unbatch() işlevi, veri kümesini daha önce batch işlemlerinin uygulandığı haliyle geri alır.","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:34:50.210806Z","iopub.execute_input":"2023-06-06T16:34:50.211957Z","iopub.status.idle":"2023-06-06T16:34:50.292795Z","shell.execute_reply.started":"2023-06-06T16:34:50.211916Z","shell.execute_reply":"2023-06-06T16:34:50.291487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, labels = next(batch)\nprobabilities = model.predict(images)\npredictions = np.argmax(probabilities, axis=-1)\ndisplay_batch_of_images((images, labels), predictions)","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:34:52.240910Z","iopub.execute_input":"2023-06-06T16:34:52.241759Z","iopub.status.idle":"2023-06-06T16:35:02.845297Z","shell.execute_reply.started":"2023-06-06T16:34:52.241717Z","shell.execute_reply":"2023-06-06T16:35:02.843594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Test Tahminlerinin Yapılması","metadata":{}},{"cell_type":"code","source":"test_ds = get_test_dataset(ordered=True)\n#ordered=True parametresi, veri kümesinin sıralanmış bir şekilde alınmasını sağlar.\n\nprint('Tahminler hesaplanıyor...')\ntest_images_ds = test_ds.map(lambda image, idnum: image)\nprobabilities = model.predict(test_images_ds)\npredictions = np.argmax(probabilities, axis=-1)\nprint(predictions)","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:35:18.229947Z","iopub.execute_input":"2023-06-06T16:35:18.230798Z","iopub.status.idle":"2023-06-06T16:35:38.567078Z","shell.execute_reply.started":"2023-06-06T16:35:18.230756Z","shell.execute_reply":"2023-06-06T16:35:38.565489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('submission.csv dosyası oluşturuluyor...')\n\n# Test setinden görüntü idlerini alın ve unicode'a dönüştürün\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')\n\n# submission dosyasını yazma\nnp.savetxt(\n    'submission.csv',\n    np.rec.fromarrays([test_ids, predictions]),\n    fmt=['%s', '%d'],\n    delimiter=',',\n    header='id,label',\n    comments='',\n)\n\n#  İlk birkaç tahmine bakın\n# ' %s' format belirteci, bir sütunda yer alacak değerin bir string olduğunu belirtir. \n# ' %d' format belirteci, bir sütunda yer alacak değerin bir tamsayı olduğunu belirtir. \n!head submission.csv","metadata":{"execution":{"iopub.status.busy":"2023-06-06T16:35:47.761695Z","iopub.execute_input":"2023-06-06T16:35:47.762591Z","iopub.status.idle":"2023-06-06T16:35:50.171372Z","shell.execute_reply.started":"2023-06-06T16:35:47.762550Z","shell.execute_reply":"2023-06-06T16:35:50.169868Z"},"trusted":true},"execution_count":null,"outputs":[]}]}