# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: 'Python 3.8.5 64-bit (''base'': conda)'
#     name: python361264bitpy36condab15cfc676c924d3bb5d13a94d0f7deaa
# ---

# ## Homework-3: MNIST Classification with ConvNet
#
# ### **Deadline: 2021.04.06 23:59:00 **
#
# ### In this homework, you need to
# - #### implement the forward and backward functions for ConvLayer (`layers/conv_layer.py`)
# - #### implement the forward and backward functions for PoolingLayer (`layers/pooling_layer.py`)
# - #### implement the forward and backward functions for DropoutLayer (`layers/dropout_layer.py`)

# +
import numpy as np
import matplotlib.pyplot as plt
# %matplotlib inline
import tensorflow.compat.v1 as tf
tf.disable_eager_execution()

from network import Network
from solver import train, test
from plot import plot_loss_and_acc
# -

# ## Load MNIST Dataset
# We use tensorflow tools to load dataset for convenience.

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()


# +
def decode_image(image):
    # Normalize from [0, 255.] to [0., 1.0], and then subtract by the mean value
    image = tf.cast(image, tf.float32)
    image = tf.reshape(image, [1, 28, 28])
    image = image / 255.0
    image = image - tf.reduce_mean(image)
    return image

def decode_label(label):
    # Encode label with one-hot encoding
    return tf.one_hot(label, depth=10)


# -

# Data Preprocessing
x_train = tf.data.Dataset.from_tensor_slices(x_train).map(decode_image)
y_train = tf.data.Dataset.from_tensor_slices(y_train).map(decode_label)
data_train = tf.data.Dataset.zip((x_train, y_train))
x_test = tf.data.Dataset.from_tensor_slices(x_test).map(decode_image)
y_test = tf.data.Dataset.from_tensor_slices(y_test).map(decode_label)
data_test = tf.data.Dataset.zip((x_test, y_test))

# ## Set Hyperparameters
# You can modify hyperparameters by yourself.

# +
batch_size = 100
max_epoch = 10
init_std = 0.1

learning_rate = 0.001
weight_decay = 0.005

disp_freq = 50
# -

# ## Criterion and Optimizer

# +
from criterion import SoftmaxCrossEntropyLossLayer
from optimizer import SGD

criterion = SoftmaxCrossEntropyLossLayer()
sgd = SGD(learning_rate, weight_decay)
# -

# ## ConvNet

# +
from layers import FCLayer, ReLULayer, ConvLayer, MaxPoolingLayer, ReshapeLayer

convNet = Network()
convNet.add(ConvLayer(1, 8, 3, 1))
convNet.add(ReLULayer())
convNet.add(MaxPoolingLayer(2, 0))
convNet.add(ConvLayer(8, 16, 3, 1))
convNet.add(ReLULayer())
convNet.add(MaxPoolingLayer(2, 0))
convNet.add(ReshapeLayer((batch_size, 16, 7, 7), (batch_size, 784)))
convNet.add(FCLayer(784, 128))
convNet.add(ReLULayer())
convNet.add(FCLayer(128, 10))

# + tags=[]
# Train
convNet.is_training = True
convNet, conv_loss, conv_acc = train(convNet, criterion, sgd, data_train, max_epoch, batch_size, disp_freq)
# -

# Test
convNet.is_training = False
test(convNet, criterion, data_test, batch_size, disp_freq)

# ## Plot

plot_loss_and_acc({'ConvNet': [conv_loss, conv_acc]})

# ### ~~You have finished homework3, congratulations!~~  
#
# **Next, according to the requirements (4):**
# ### **You need to implement the Dropout layer and train the network again.**

# +
from layers import DropoutLayer
from layers import FCLayer, ReLULayer, ConvLayer, MaxPoolingLayer, ReshapeLayer, DropoutLayer

# build your network
convNet = Network()
convNet.add(ConvLayer(1, 8, 3, 1))
convNet.add(ReLULayer())
convNet.add(DropoutLayer(0.5))
convNet.add(MaxPoolingLayer(2, 0))
convNet.add(ConvLayer(8, 16, 3, 1))
convNet.add(ReLULayer())
convNet.add(MaxPoolingLayer(2, 0))
convNet.add(ReshapeLayer((batch_size, 16, 7, 7), (batch_size, 784)))
convNet.add(FCLayer(784, 128))
convNet.add(ReLULayer())
convNet.add(FCLayer(128, 10))



# training
convNet.is_training = True
convNet, conv_loss, conv_acc = train(convNet, criterion, sgd, data_train, max_epoch, batch_size, disp_freq)

# testing
convNet.is_training = False
test(convNet, criterion, data_test, batch_size, disp_freq)
# -

plot_loss_and_acc({'ConvNet': [conv_loss, conv_acc]})



StarcoderdataJupyterScriptsDedupFiltered