# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     name: python3
# ---

# + [markdown] id="view-in-github" colab_type="text"
# <a href="https://colab.research.google.com/github/vandyahmad24/aplikasi-point-smk/blob/master/Laithan_Augmentor_binari.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>

# + [markdown] id="KQsre_lt7ppS" colab_type="text"
#
# # Latihan 01
#
# Pada latihan ini, kita akan mencoba mencoba membedakan dua jenis gambar, gambar 5 dan s terbalik menggunakan Convolutional Neural Network (CNN) sederhana.
#
# Latihan ini menggunakan teknik klasifikasi secara biner, alias hanya bisa membedakan 2 jenis kategori. Teknik untuk mengenali pattern gambar lebih dari 2 kategori akan dibahas di akhir kode.
#
# ## Install Library
#
# Pertama, mari kita install library Augmentor terlebih dahulu

# + id="xj9CzzRn6pLV" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 153} outputId="ded942cb-22d8-487d-9431-e647acabb306"
# !pip install Augmentor

# + [markdown] id="z10BtVIN89uT" colab_type="text"
# ## Download File
#
# Jalankan perintah berikut untuk mendownload file `Latihan 1.zip` dari link google drive yang sudah dibagikan. Perintah `gdown` digunakan untuk mendownload file google drive yang sudah tershare secara publik dengan cara memanggil `id` file tersebut.

# + id="IsL7DW67mqDH" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 306} outputId="71ceea45-002a-4cd7-e745-e409db735b47"
# !gdown --id 1kl8kRaxdYlewKTeYtdyUk_8Nb2Aygu_h
# !unzip Latihan\ 1.zip

# + [markdown] id="48EmZEkj9MIB" colab_type="text"
# ## Persiapan Dataset
#
# Persiapankan dataset test dengan menyalin file `5.png` dan `s.png` ke folder test.

# + id="3l5AlU3w5m45" colab_type="code" colab={}
# !cp dataset/train/5/5.png /content/dataset/test/5/
# !cp dataset/train/s/s.png /content/dataset/test/s/

# + [markdown] id="5rwBxzPe906J" colab_type="text"
# Sekarang, mari perbanyak masing-masing dataset train dan test dengan Augmentor.

# + id="FedPLrJg5Fn8" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 173} outputId="a9b6c43a-b97a-45cd-b4e8-4f14b52ff5ca"
import Augmentor
import os

def perbanyak_(ini, sebanyak_ini):
  source_dir = ini
  output_dir = "."
  p = Augmentor.Pipeline(source_directory=source_dir, output_directory=output_dir)
  p.random_distortion(probability=1, grid_width=4, grid_height=4, magnitude=1)
  p.rotate(probability=0.7, max_left_rotation=13, max_right_rotation=13)
  p.zoom_random(probability=0.5, percentage_area=0.9)
  p.crop_random(probability=0.6, percentage_area=0.9)
  p.resize(probability=1.0, width=64, height=64)

  p.sample(sebanyak_ini)

perbanyak_("dataset/test/5", 30)
perbanyak_("dataset/test/s", 30)
perbanyak_("dataset/train/5", 270)
perbanyak_("dataset/train/s", 270)

# + [markdown] id="XveY9KT4-AVs" colab_type="text"
# Dan jangan lupa, hapuslah file original `5.png` dan `s.png` dari folder `train` untuk kita sisakan file original di folder `test`. Dengan ini kita mendapatkan 270 varian gambar 5 dan 270 varian gambar s untuk training, dan kita juga mendapatkan 31 varian gambar 5 dan 31 varian gambar s untuk testing.

# + id="Z_W1qNBb6xmk" colab_type="code" colab={}
# !rm dataset/train/5/5.png
# !rm dataset/train/s/s.png

# + [markdown] id="WIpTwlmR-czZ" colab_type="text"
# ## FIle Training
#
# Berikut adalah teknik untuk menampilkan 20 file yang ada pada folder `train/5` dan test `test/s`. Gunakan `glob` untuk mengambil daftar file pada suatu folder.
#
# Jika anda menggunakan `jupyter notebook`, maka tambahkanlah baris `%matplotlib inline` di bawah `import matplotlib.pyplot as plt` untuk mengaktifkan penampil fungsi plot pada `notebook` anda.

# + id="Z3WiJkrUAVVw" colab_type="code" colab={}
import glob
import matplotlib.pyplot as plt
# #%matplotlib inline

def tampilkan_6_kali_5_gambar_pada_alamat(ini):
  a = glob.glob(ini)

  w=10
  h=10
  fig=plt.figure(figsize=(8, 8))
  columns = 6
  rows = 5
  for i in range(1, columns*rows +1):
      img = plt.imread(a[i])
      fig.add_subplot(rows, columns, i)
      plt.imshow(img)
  plt.show()


# + id="raqZNzdg-z35" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 475} outputId="0ff3f54c-569e-4690-bf75-a1d480e4036a"
tampilkan_6_kali_5_gambar_pada_alamat("dataset/train/5/*")

# + id="oUq5eRLIey1L" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 475} outputId="1bf9cd7c-203e-4f17-d5e4-616421e80ac7"
tampilkan_6_kali_5_gambar_pada_alamat("dataset/test/s/*")

# + [markdown] id="iZuCw4zpe9If" colab_type="text"
# ## Fase Training
#
# Pada fase training ini, dipergunakan arsitektur CNN sederhana yang terdiri atas 1 layer konvolusi, 1 layer pooling, 1 layer flatten, yang terkoneksi dengan 2 fully connected layer lainnya.
#
# Hasil akhir penentuan ada pada bagian node paling akhir di mana
#
# `model.add(Dense(units = 1, activation = 'sigmoid'))`

# + id="lCJtLmVC62mZ" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 34} outputId="c6749013-fb78-46c8-e9f9-b26d47c65b1b"
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Activation
from keras.preprocessing.image import ImageDataGenerator

size_ = 16

model = Sequential()

model.add(Conv2D(4, (3, 3), input_shape = (size_, size_, 3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Flatten())

model.add(Dense(units = 8, activation = 'relu'))
model.add(Dense(units = 1, activation = 'sigmoid'))

model.compile(optimizer = 'sgd', loss = 'binary_crossentropy', metrics = ['accuracy'])

# + [markdown] id="E4TiRAxtfwlS" colab_type="text"
# Berikut adalah arsitektur akhir CNN yang akan kita pergunakan.

# + id="LBth8YW3fu0W" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 323} outputId="9ee11637-4fd8-497b-c56c-eb00921a3d0d"
model.summary()

# + [markdown] id="R7VkOZVrf_Q7" colab_type="text"
# Sekarang, mari kita set konfigurasi di mana lokasi data train dan data test kita berada.

# + id="SDw3GPoZf-Jd" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 51} outputId="5ded9855-05ca-4211-c2af-357c46a9ad57"
train = ImageDataGenerator(rescale = 1./255)
test = ImageDataGenerator(rescale = 1./255)
train_data = train.flow_from_directory('dataset/train', target_size = (size_, size_), batch_size = 32, class_mode = 'binary')
test_data = test.flow_from_directory('dataset/test', target_size = (size_, size_), batch_size = 32, class_mode = 'binary')

# + [markdown] id="BPgaJ4M6gNX5" colab_type="text"
# Pastikan isi folder `dataset/train`nya hanya terdiri atas 2 folder saja, tanpa ada folder tambahan `.ipynb_checkpoints`.

# + id="aaARZOT77BgJ" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 102} outputId="e628b54a-3ec5-4e34-eada-14d3a61ca1b6"
# !ls -al dataset/train/

# + [markdown] id="E62EgblfgaPn" colab_type="text"
# Sekarang, mari kita train model kita menggunakan 10 kali epoch (perulangan).

# + id="OV_OwOze7Osw" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 597} outputId="68c1624a-ee7b-48b9-da54-6a0a5341dfac"
model.fit_generator(train_data, steps_per_epoch = 100, epochs = 100, validation_data = test_data, validation_steps = 100)

# + [markdown] id="ijrKRUZ-g8p2" colab_type="text"
# Seperti yang bisa dilihat, jika model anda sudah benar, maka seharusnya nilai akurasi akan meningkat perlahan hingga mendekati 1.000 (alias 100%).

# + [markdown] id="RoboJrIohe0U" colab_type="text"
# ## Fase Testing
#
# Pada fase ini, mari kita test keakuratan model yang sudah kita buat, apakah dia benar-benar bisa mengenali gambar `5` dan `s` dengan benar. Mari kita ambil 2 contoh file yang akan kita coba test keakuratan modelnya.
#
#

# + id="PI9bCedghJc5" colab_type="code" colab={}
a = "dataset/test/5/5.png"
b = "dataset/test/s/s.png"


# + [markdown] id="ihVG0P6XjGxB" colab_type="text"
# Berikut adalah isi kedua gambar yang akan kita test.

# + id="TzLzqhGdif3M" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 301} outputId="4575b94d-bcbf-471c-9d74-9fb53417a645"
def tampilkan_(ini):
  fig = plt.figure(figsize=(2, 2))
  img = plt.imread(ini)
  plt.imshow(img)
  plt.show()

tampilkan_(a)
tampilkan_(b)


# + [markdown] id="DghGE9XYjVEw" colab_type="text"
# Karena hasil prediksi dalam bentuk angka, maka kita perlu membangun kamus, yang mana hasil prediksi tadi yang masih berupa angka, ditautkan dengan nama sebenarnya. Berikut adalah teknik membangun kamus tersebut.

# + id="VyuJfXxPjxmw" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 34} outputId="a32f383e-1525-41e1-fa57-9d1ed49f5f45"
def switch_dict_key_values(this_dict):
    return dict((v,k) for k,v in this_dict.items())

nama_train_data = switch_dict_key_values(train_data.class_indices)
print(nama_train_data)

# + [markdown] id="3UeJQUX1j125" colab_type="text"
# Sekarang terlihat bahwa `0` merepresentasikan `5` dan `1` merepresentasikan `s`.
#
# Untuk test pertama kita, mari kita coba `5` terlebih dahulu.

# + id="HwGMKQzYkDTf" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 34} outputId="e7833546-d981-4dbe-f8aa-6d0cfc27b902"
from keras.preprocessing import image
import numpy as np

img = image.load_img(a, target_size = (size_, size_))
img = image.img_to_array(img)
img = np.expand_dims(img, axis = 0)

hasil = model.predict_classes(img)
print("File gambar [", a, "] diprediksi sebagai", hasil, "alias terbaca sebagai :: ", nama_train_data[hasil[0][0]], ".")

# + [markdown] id="84urio2JR0Cx" colab_type="text"
# Untuk mengecek probabilitas pada `class 1`, maka `img` bisa kita paksa untuk dibagi dengan bilangan `255.`.

# + id="oDFAt87lE6W2" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 34} outputId="d33da496-ec90-4edb-f5a2-7fa583faf4d4"
hasil = model.predict(img/255.)
print(hasil)

# + [markdown] id="WuS0F5dHlnOS" colab_type="text"
# Untuk test kedua kita, mari kita coba `s` sebagai file testing.

# + id="-2SWc4bqliDp" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 34} outputId="2a534b6e-d532-405f-8e0b-134f6a1950f3"
img = image.load_img(b, target_size = (size_, size_))
img = image.img_to_array(img)
img = np.expand_dims(img, axis = 0)

hasil = model.predict_classes(img)
print("File gambar [", b, "] diprediksi sebagai", hasil, "alias terbaca sebagai :: ", nama_train_data[hasil[0][0]], ".")

# + [markdown] id="ad-iq_xGSBZu" colab_type="text"
# Untuk mengecek probabilitas pada `class 1`, maka `img` bisa kita paksa untuk dibagi dengan bilangan `255.`.

# + id="AQ7Eh_oJF13X" colab_type="code" colab={"base_uri": "https://localhost:8080/", "height": 34} outputId="f3718ff3-3531-4f49-ef12-f24c5da84788"
hasil = model.predict(img/255.)
print(hasil)

# + id="6My13etl_2fF" colab_type="code" colab={}
lol = glob.glob("dataset/test/5/*.png")

total = 0
for haha in lol:
  img = image.load_img(haha, target_size = (16, 16))
  img = image.img_to_array(img)
  img = np.expand_dims(img, axis = 0)

  hasil = model.predict_classes(img)
  #print("File gambar [s] diprediksi sebagai", hasil, "alias terbaca sebagai :: ", nama_train_data[hasil[0][0]], ".")
  total += (0 == hasil[0][0])*1
print(total/len(lol))

# + [markdown] id="w2V1RMuOmNT4" colab_type="text"
# ## Kasus Non-Binary
#
# Bagaimana jika data yang ingin kita prediksi jenisnya jumlahnya ada lebih dari 2? Untuk kasus seperti ini, kita perlu mengganti mode dari `binary` menjadi `categorical`.
#
# ### 1. Bagian Import
# Berikut baris yang perlu anda tambahkan pada bagian `import`.
#
# `from keras.metrics import categorical_accuracy`
#
# ### 2. Bagian Training
#
# Pada bagian `activation`, ganti isi `units` dengan jumlah kategori yang ingin prediksi jenisnya. Jika anda menginginkan model anda dapat memprediksi 10 jenis gambar yang berbeda, maka gantilah menjadi 10. Adapun bagian `activation`, cobalah untuk menggantinya dengan `softmax`.
#
# `model.add(Dense(units = 10, activation = 'softmax'))`
#
# Pada bagian `model.compile`, gunakan categorical pada parameter-parameternya.
#
# `model.compile(optimizer = 'sgd', loss = 'categorical_crossentropy', metrics = [categorical_accuracy])`
#
# ### 3. Bagian Konfigurasi Lokasi Folder
#
# Pada bagian konfigurasi lokasi folder, gantilah setiap `train` dan `test` dari `binary` menjadi `categorical`.
#
# `train_data = train.flow_from_directory('dataset/train', target_size = (size_, size_), batch_size = 32, class_mode = 'categorical')`
#
# `test_data = test.flow_from_directory('dataset/test', target_size = (size_, size_), batch_size = 32, class_mode = 'categorical')`
#
# Akhir kata, selamat mencoba.

StarcoderdataJupyterScriptsDedupFiltered