<jupyter_start><jupyter_text>1. CNN (Two dimensional)  1.1 Loading data<jupyter_code>import csv
from math import sqrt
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
import numpy as np

class UltrasonicData:
    """ A custom data type: the data member is 
    - the distances from the car to the surrounding wall at one or multiple sample time
    - and corresponding control commands for the angular velocity.
    """
    def __init__(self, distance, angular):
        self.distance = distance
        self.angular  = angular
        
        
def csv_read(csv_path, length):
    """ Reading raw ultrasonic data from csv file
    
    input: 
     - csv_path: the path of the csv file
     - length: the length of time sequence used in each training data
    output: 
     - Return the shuffled data which is represented in UltrasonicData type.
    """
    
    print("Starting reading data from csv file...")
    # save time-ordered data sequences
    D = []
    agl = []
    # save time-independent data by slicing D with the desired length 
    Data = []
    
    with open(csv_path, 'r') as f:
        f_reader = csv.reader(f)
        for line in f_reader:
            D.append([sqrt(float(line[i])**2 + float(line[i+16])**2) for i in range(16)])
            agl.append(float(line[33]))
    
    # now the data is sorted by time
    print("{} original data has been read in time order.".format(len(D)))
    
    for i in range(len(D)-length+1):
        distance = D[i:i+length]
        # use the value at the final time sequence as a label
        angular = agl[i+length-1] 
        
        Data.append(UltrasonicData(distance, angular))
    
    print("Now we have {} data after slicing with length {}".format(len(Data), length))
    
    return shuffle(Data)


def loading_data_set(csv_path, length, split=0.2):
    """ Loading and spliting dataset
    
    """
    Data = csv_read(csv_path, length)
    training_set, validation_set = train_test_split(Data, test_size=split)
    
    print("The training set size is {}".format(len(training_set)))
    print("The validation set size is {}".format(len(validation_set)))

    
    return training_set, validation_set


def data_generator(Data, batch_size):
    """ A data generator which generating a batch of data every time
    1. The data is reshaped to (batch_size, length*16)
    
    """
    while True:
        data_batch = np.random.choice(a=Data, size=batch_size)
        X = []
        Y = []
    
        for i in range(len(data_batch)):
            data = data_batch[i]
            # repeat coloums and rows 12 times
            array = np.array(data.distance)
            data_repeat = array.repeat(12, axis=0)
            data_repeat = data_repeat.repeat(12, axis=1)

            X.append(data_repeat)
            Y.append(data.angular)
            
        # batch_size, H, W = X.shape
        X = np.array(X)
        
        # add new axis for the gray scale image
        X = X[:, np.newaxis, :,:]
        Y = np.array(Y)
    
        yield shuffle(X,Y)
"""
TESTING DATA LOADING FUNCTION
"""

data_path  = "/media/ubuntu16/Documents/datasets/SonarSet/SIM/Track-I/"
filename = "2019-06-06.csv"
csv_path = data_path + filename
batch_size = 128
lengths = [16,32,48]

for length in lengths:
    training_set, validation_set = loading_data_set(csv_path, length, split=0.2)
    # load data through generator
    
    train_generator = data_generator(training_set, batch_size)
    valid_generator = data_generator(validation_set, batch_size)
    
    x1,y1 = next(train_generator)
    x2,y2 = next(valid_generator)
    print x1.shape, y1.shape
    print x2.shape, y2.shape
    print<jupyter_output>Starting reading data from csv file...
6509 original data has been read in time order.
Now we have 6494 data after slicing with length 16
The training set size is 5195
The validation set size is 1299
(128, 1, 192, 192) (128,)
(128, 1, 192, 192) (128,)

Starting reading data from csv file...
6509 original data has been read in time order.
Now we have 6478 data after slicing with length 32
The training set size is 5182
The validation set size is 1296
(128, 1, 384, 192) (128,)
(128, 1, 384, 192) (128,)

Starting reading data from csv file...
6509 original data has been read in time order.
Now we have 6462 data after slicing with length 48
The training set size is 5169
The validation set size is 1293
(128, 1, 576, 192) (128,)
(128, 1, 576, 192) (128,)<jupyter_text>1.2 Training<jupyter_code>from math import ceil
from keras.models import Model
from keras.layers import Input, Activation, Flatten, Dense, Dropout
from keras.layers import Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from keras.layers.merge import add
from keras import regularizers
from keras import optimizers
from keras.callbacks import ModelCheckpoint
from keras.models import load_model


data_path  = "/media/ubuntu16/Documents/datasets/SonarSet/SIM/Track-I/"
filename = "2019-06-06.csv"
csv_path = data_path + filename

batch_size = 128
epochs = 1000

lengths = [16, 32, 48]

historys = {}
errors = {}

model_path = "/home/ubuntu16/catkin_ws/src/sonar_navigation/h5/"


for length in lengths:
    # reading data from csv
    training_set, validation_set = loading_data_set(csv_path, length, split=0.2)
    # loading data through generator
    train_generator = data_generator(training_set, batch_size)
    valid_generator = data_generator(validation_set, batch_size)
    
    training_steps = ceil(len(training_set)/batch_size)
    validation_steps = ceil(len(validation_set)/batch_size)
    
    prefix = 'resnet8'+'-'+str(length)
    
    img_channel = 1
    img_height  = length*12
    img_width   = 16*12
    
    # Input
    img_input = Input(shape=(img_channel, img_height, img_width))

    x1 = Conv2D(32, (5, 5), strides=[2,2], padding='same', data_format='channels_first')(img_input)
    x1 = MaxPooling2D(pool_size=(3, 3), strides=[2,2], data_format='channels_first')(x1)

    # First residual block
    x2 = BatchNormalization(axis=1)(x1)
    x2 = Activation('relu')(x2)
    x2 = Conv2D(32, (3, 3), strides=[2,2], padding='same',
                data_format='channels_first',
                kernel_initializer="he_normal",
                kernel_regularizer=regularizers.l2(1e-4))(x2)

    x2 = BatchNormalization(axis=1)(x2)
    x2 = Activation('relu')(x2)
    x2 = Conv2D(32, (3, 3), padding='same',
                data_format='channels_first',
                kernel_initializer="he_normal",
                kernel_regularizer=regularizers.l2(1e-4))(x2)

    x1 = Conv2D(32, (1, 1), strides=[2,2], padding='same', data_format='channels_first')(x1)
    x3 = add([x1, x2])

    # Second residual block
    x4 = BatchNormalization(axis=1)(x3)
    x4 = Activation('relu')(x4)
    x4 = Conv2D(64, (3, 3), strides=[2,2], padding='same',
                data_format='channels_first',
                kernel_initializer="he_normal",
                kernel_regularizer=regularizers.l2(1e-4))(x4)

    x4 = BatchNormalization(axis=1)(x4)
    x4 = Activation('relu')(x4)
    x4 = Conv2D(64, (3, 3), padding='same',
                data_format='channels_first',
                kernel_initializer="he_normal",
                kernel_regularizer=regularizers.l2(1e-4))(x4)

    x3 = Conv2D(64, (1, 1), strides=[2,2], padding='same', data_format='channels_first')(x3)
    x5 = add([x3, x4])

    # Third residual block
    x6 = BatchNormalization(axis=1)(x5)
    x6 = Activation('relu')(x6)
    x6 = Conv2D(128, (3, 3), strides=[2,2], padding='same',
                data_format='channels_first',
                kernel_initializer="he_normal",
                kernel_regularizer=regularizers.l2(1e-4))(x6)

    x6 = BatchNormalization(axis=1)(x6)
    x6 = Activation('relu')(x6)
    x6 = Conv2D(128, (3, 3), padding='same',
                data_format='channels_first',
                kernel_initializer="he_normal",
                kernel_regularizer=regularizers.l2(1e-4))(x6)

    x5 = Conv2D(128, (1, 1), strides=[2,2], padding='same', data_format='channels_first')(x5)
    x7 = add([x5, x6])

    x = Flatten(data_format='channels_first')(x7)
    x = Activation('relu')(x)
    x = Dropout(0.5)(x)

    # Steering channel
    steer = Dense(1)(x)

    # Define steering model
    model = Model(inputs=[img_input], outputs=[steer])
    
    optimizer = optimizers.Adam(decay=1e-5)
    
    # compile        
    model.compile(loss='mean_absolute_error', optimizer=optimizer, metrics=['mean_absolute_error'])
    model.summary()
    model_checkpoint = ModelCheckpoint(model_path+prefix+'-'+'best_model.h5', 
                                       monitor='val_mean_absolute_error',
                                       save_best_only=True)
    model_callbacks = [model_checkpoint]

    # fit model
    history = model.fit_generator(generator = train_generator,
                                  steps_per_epoch  = training_steps,
                                  validation_data  = valid_generator,
                                  validation_steps = validation_steps,
                                  epochs  = epochs,
                                  verbose = 1,
                                  callbacks = model_callbacks)
    # save training histroys
    hist_key = prefix + '-'+'mae'
            
    historys[hist_key] = history
        
    # load the saved model
    saved_model = load_model(model_path+prefix+'-'+'best_model.h5')
        
    # evalute model
    train_loss, train_mae = saved_model.evaluate_generator(train_generator, 
                                                               steps=training_steps,
                                                               verbose=0)
    val_loss, val_mae= saved_model.evaluate_generator(valid_generator, 
                                                          steps=validation_steps,
                                                          verbose=0)
    errors[prefix+'-'+'train'] = train_mae
    errors[prefix+'-'+'val'] = val_mae


    print('{}: Train: {}, validation: {}'.format(hist_key, train_mae, val_mae))
    print(" ")<jupyter_output>Using TensorFlow backend.<jupyter_text>resnet8-16-mae: Train: 0.0154573955806, validation: 0.0186197816394resnet8-32-mae: Train: 0.0129737922456, validation: 0.0158780260012resnet8-48-mae: Train: 0.0129472742672, validation: 0.0209106724709  1.4 Training History<jupyter_code>import matplotlib.pyplot as plt

fig, axes = plt.subplots(3,1, figsize=(10, 30))

index = 0
for key in sorted(historys.keys()):
    axes[index].plot(historys[key].history['loss'], label='train')
    axes[index].plot(historys[key].history['val_loss'], label='validate')
    axes[index].set_title(key)
    axes[index].legend()
    axes[index].set_ylim(0, 0.2)
    index +=1
    
plt.show()
errors<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11262672811059908, 'fraction_numerical': 0.04552995391705069, 'mean_word_length': 2.6832993890020367, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '242365', 'license': 'Apache-2.0', 'n_tokens_mistral': 3797, 'n_tokens_neox': 3412, 'n_words': 839, 'path': 'utils/pre_experiments/track-I/track-I_ResNet8.ipynb', 'repo_name': 'wsustcid/Sonar-Navigation', 'size': '10850'}