{"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":"code","source":"import tensorflow as tf\nimport pandas as pd\nimport numpy as np\n\nimport matplotlib.pyplot as plt\n%matplotlib inline\nrandom_seed = 42\n\n(x_train, y_train), (_, _) = tf.keras.datasets.mnist.load_data()\nfrom sklearn.model_selection import train_test_split\nx_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.1, random_state=random_seed)\nplt.imshow(x_train[2], cmap='gray'); # 54,000 train + 6,000 validation","metadata":{"execution":{"iopub.status.busy":"2022-03-15T17:32:19.165304Z","iopub.execute_input":"2022-03-15T17:32:19.165550Z","iopub.status.idle":"2022-03-15T17:32:19.630572Z","shell.execute_reply.started":"2022-03-15T17:32:19.165518Z","shell.execute_reply":"2022-03-15T17:32:19.629862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train = (x_train / 255.).reshape(54000, 28, 28, 1)\nX_val = (x_val / 255.).reshape(6000, 28, 28, 1)\n\nfrom tensorflow.keras.utils import to_categorical\nY_train = to_categorical(y_train, num_classes = 10)\nY_val = to_categorical(y_val, num_classes = 10)","metadata":{"execution":{"iopub.status.busy":"2022-03-15T17:32:21.575777Z","iopub.execute_input":"2022-03-15T17:32:21.576069Z","iopub.status.idle":"2022-03-15T17:32:21.699176Z","shell.execute_reply.started":"2022-03-15T17:32:21.576037Z","shell.execute_reply":"2022-03-15T17:32:21.698420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten\nfrom tensorflow.keras.models import Model, Sequential\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau, ModelCheckpoint\n\nmodel = Sequential([\n    Conv2D(filters = 6, kernel_size = 5, strides = 1, activation = 'relu', input_shape = (28,28,1)),\n    MaxPooling2D(pool_size = 2, strides = 2, name = 'max_pool_1'),\n    Conv2D(filters = 16, kernel_size = 5, strides = 1, activation = 'relu'),\n    MaxPooling2D(pool_size = 2, strides = 2, name = 'max_pool_2'),\n    \n    Flatten(name = 'flatten'),\n    Dense(units = 120, activation = 'relu'),\n    Dense(units = 84, activation = 'relu'),\n    Dense(units = 10, activation = 'softmax')   \n])\n\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-03-15T17:32:22.399629Z","iopub.execute_input":"2022-03-15T17:32:22.399870Z","iopub.status.idle":"2022-03-15T17:32:24.713697Z","shell.execute_reply.started":"2022-03-15T17:32:22.399840Z","shell.execute_reply":"2022-03-15T17:32:24.713045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def split_and_flip_pixels(image_orig):\n    image = image_orig.copy()\n        \n    def get_point(ax, p):\n        if ax == 0: return (0, p)\n        if ax == 1: return (p, 0)\n        if ax == 2: return (27, p)\n        if ax == 3: return (p, 27)\n    \n    a = np.random.randint(27)\n    b = np.random.randint(27)       \n    a_edge = np.argmax(np.random.rand(4))\n    b_edge = np.argmax(np.random.rand(3))\n    swap_ = np.argmax(np.random.rand(2))\n    \n    a_point = get_point(a_edge, a) # Choose a point along a random edge.\n    b_point = get_point((a_edge+b_edge+1)%4, b) # Choose a point along a different edge.\n    a_point, b_point = sorted([a_point, b_point])\n\n    num_points = max(abs(a_point[1]-b_point[1])+1, abs(a_point[0]-b_point[0])+1) # Number of points along the linspace\n    x_points = np.round(np.linspace(a_point[0], b_point[0], num_points)).astype(np.int32)\n    y_points = np.round(np.linspace(a_point[1], b_point[1], num_points)).astype(np.int32)\n    points = set(zip(x_points, y_points))\n    pts = {x:y for x,y in points}\n\n    for x,y in pts.items(): # Flip pixels on the line\n        if not swap_: image[:y,x] = 1. - image[:y,x]\n        else: image[y:,x] = 1. - image[y:,x]\n        \n    # Flip pixels to the left or right of the line\n    if not swap_ and a_point[1] == 27:\n        image[:,:a_point[0]] = 1. - image[:,:a_point[0]]\n    if not swap_ and b_point[1] == 27:\n        try: image[:,b_point[0]+1:] = 1. - image[:,b_point[0]+1:]\n        except: pass\n    if swap_ and a_point[1] == 0:\n        image[:,:a_point[0]] = 1. - image[:,:a_point[0]]\n    if swap_ and b_point[1] == 0:\n        try: image[:,b_point[0]+1:] = 1. - image[:,b_point[0]+1:]\n        except: pass\n\n    return image\n\ntmp = split_and_flip_pixels(X_train[2]);\nplt.imshow(tmp, cmap='gray');","metadata":{"execution":{"iopub.status.busy":"2022-03-15T17:32:25.947919Z","iopub.execute_input":"2022-03-15T17:32:25.948436Z","iopub.status.idle":"2022-03-15T17:32:26.163603Z","shell.execute_reply.started":"2022-03-15T17:32:25.948393Z","shell.execute_reply":"2022-03-15T17:32:26.162848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datagen = ImageDataGenerator(\n    rotation_range = 20,  # randomly rotate images in the range (degrees, 0 to 180)\n    zoom_range = 0.1, # Randomly zoom image \n    width_shift_range = 0.1,  # randomly shift images horizontally (fraction of total width)\n    height_shift_range = 0.1,  # randomly shift images vertically (fraction of total height)\n    horizontal_flip = .3,  # randomly flip images\n    vertical_flip = .3,   # randomly flip images\n    preprocessing_function = split_and_flip_pixels\n)  \n\ntrain_samples = datagen.flow(X_train, Y_train, batch_size=64)\nval_samples = datagen.flow(X_val, Y_val, batch_size=64)\n\nrows = 5\ncols = 5\nfig, axs = plt.subplots(rows, cols, figsize=(28, 15))\nidx1 = np.random.randint(0, len(train_samples), rows*cols)\nidx2 = np.random.randint(0, 64, rows*cols)\nidxs = zip(idx1, idx2)\n\nfor i, (j, k) in enumerate(idxs):\n    axs[i%rows,i//rows].imshow(train_samples[j][0][k], cmap='gray')\n    axs[i%rows,i//rows].axis('off')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-15T17:32:28.455726Z","iopub.execute_input":"2022-03-15T17:32:28.456284Z","iopub.status.idle":"2022-03-15T17:32:30.571519Z","shell.execute_reply.started":"2022-03-15T17:32:28.456246Z","shell.execute_reply":"2022-03-15T17:32:30.570843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint_filepath = './checkpoint'\nlearning_rate = ReduceLROnPlateau(monitor='val_loss', factor=0.8, patience=3)\nmodel_checkpoint = ModelCheckpoint(filepath=checkpoint_filepath, save_weights_only=False, monitor='val_loss', mode='min', save_best_only=True)\nhistory = model.fit(train_samples, epochs=100, callbacks=[learning_rate, model_checkpoint], validation_data=val_samples, verbose=2)","metadata":{"execution":{"iopub.status.busy":"2022-03-15T17:33:14.776754Z","iopub.execute_input":"2022-03-15T17:33:14.777050Z","iopub.status.idle":"2022-03-15T17:37:57.341923Z","shell.execute_reply.started":"2022-03-15T17:33:14.777015Z","shell.execute_reply":"2022-03-15T17:37:57.340534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1 = tf.keras.models.load_model(checkpoint_filepath)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samples = val_samples\npreds = model1.predict(samples)\nlosses = tf.keras.metrics.categorical_crossentropy(samples.y, preds)","metadata":{"execution":{"iopub.status.busy":"2022-03-09T22:53:06.650159Z","iopub.execute_input":"2022-03-09T22:53:06.650469Z","iopub.status.idle":"2022-03-09T22:53:10.340984Z","shell.execute_reply.started":"2022-03-09T22:53:06.650429Z","shell.execute_reply":"2022-03-09T22:53:10.340114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rows = 3\ncols = 5\nworst = np.argsort(losses)[-rows*cols:]\n\nfig, axs = plt.subplots(rows, cols, figsize=(28, 15))\nfor i in range(rows*cols):\n    axs[i%rows,i//rows].title.set_text(str(losses[worst[i]].numpy()))\n    axs[i%rows,i//rows].imshow(samples[worst[i]//844][0][worst[i]%64], cmap='gray')\n    axs[i%rows,i//rows].axis('off')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-09T22:53:10.34503Z","iopub.execute_input":"2022-03-09T22:53:10.345246Z","iopub.status.idle":"2022-03-09T22:53:11.726886Z","shell.execute_reply.started":"2022-03-09T22:53:10.345218Z","shell.execute_reply":"2022-03-09T22:53:11.725686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rows = 3\ncols = 5\nbest = np.argsort(losses)[:rows*cols]\n\nfig, axs = plt.subplots(rows, cols, figsize=(28, 15))\nfor i in range(rows*cols):\n    axs[i%rows,i//rows].title.set_text(str(losses[best[i]].numpy()))\n    axs[i%rows,i//rows].imshow(samples[best[i]//844][0][best[i]%64], cmap='gray')\n    axs[i%rows,i//rows].axis('off')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-09T22:53:11.728547Z","iopub.execute_input":"2022-03-09T22:53:11.728946Z","iopub.status.idle":"2022-03-09T22:53:13.643558Z","shell.execute_reply.started":"2022-03-09T22:53:11.728913Z","shell.execute_reply":"2022-03-09T22:53:13.643032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}