RNN - Week 1

The first week covers different types of RNNs and the basic concept of feeding forward the outcome of previous steps in a sequence to the next.

Different types of RNNs

  • Many-to-many, multiple inputs and outputs. This can be split into two types, where input and output is of same size or not.
  • Many-to-one, multiple inputs, one output.
  • One-to-one, Standard neural network.
  • One-to-many, one input, multiple outputs.
  • Attention based, to be explored in week 4…

Usecases well suited for RNNs

  • Input and output lengths might vary
  • Sharing features learned for certain positions across the full input
  • With a large vocabulary, the amount of parameters becomes very large for traditional networks

A side note is that the two last points sounds like something that 1D convolution also might reduce, but hopefully it will become clearer as the course goes on how they would or wouldn’t work in the use cases covered by RNNs.

More …

The Lift

Another weekly challenge from CodeWars, The Lift. This time slightly more challenging, and took some time to get it right.

class Dinglemouse(object):

    def __init__(self, queues, capacity):
        self.queues = [list(x) for x in queues]
        self.capacity = capacity

    def theLift(self):
        stops = [0]
        elevator = []

        people_waiting = True

        while people_waiting:
            people_waiting = False

            # Going up
            for floor in range(0, len(self.queues)):
                stop_at_floor = False

                for person in elevator[:]:
                    if person == floor:
                        elevator.remove(person)
                        stop_at_floor = True

                for person in self.queues[floor][:]:
                    if person > floor:
                        stop_at_floor = True
                        if self.capacity > len(elevator):
                            elevator.append(person)
                            self.queues[floor].remove(person)
                        else:
                            people_waiting = True

                if stop_at_floor and not stops[-1] == floor:
                    stops.append(floor)

            # Going down
            for floor in range(len(self.queues) -1, -1, -1):
                stop_at_floor = False

                for person in elevator[:]:
                    if person == floor:
                        elevator.remove(person)
                        stop_at_floor = True

                for person in self.queues[floor][:]:
                    if person < floor:
                        stop_at_floor = True

                        if self.capacity > len(elevator):
                            elevator.append(person)
                            self.queues[floor].remove(person)
                        else:
                            people_waiting = True

                if stop_at_floor and not stops[-1] == floor:
                    stops.append(floor)

        if stops[-1] != 0:
            stops.append(0)

        return stops
# Floors:    G     1      2        3     4      5      6         Answers:
tests = [[ ( (),   (),    (5,5,5), (),   (),    (),    () ),     [0, 2, 5, 0]          ],
         [ ( (),   (),    (1,1),   (),   (),    (),    () ),     [0, 2, 1, 0]          ],
         [ ( (),   (3,),  (4,),    (),   (5,),  (),    () ),     [0, 1, 2, 3, 4, 5, 0] ],
         [ ( (),   (0,),  (),      (),   (2,),  (3,),  () ),     [0, 5, 4, 3, 2, 1, 0] ]]

assert(Dinglemouse(tests[0][0], 5).theLift() == tests[0][1])
assert(Dinglemouse(tests[1][0], 5).theLift() == tests[1][1])
assert(Dinglemouse(tests[2][0], 5).theLift() == tests[2][1])
assert(Dinglemouse(tests[3][0], 5).theLift() == tests[3][1])

Comparing Solution to others

My initial solution felt like spaghetti code, but after looking at others solutions I think it’s quite ok. What I feel would improve the code a lot would be to refactor it a bit to break out the nested conditionals into semantic operations, and in order to reduce code duplication.

One neat thing in order to be able to remove items from a list while iterating through it is to create an anonymous copy in order to avoid unexpected behaviour;

More …

CNN - Week 4

Week 4 covered challenges for doing face verification and recognition and how to do neural style transfer.

More …

Python is Awesome!

Every now and then, I visit CodeWars and try some Katas to get inspired and hopefully learn some new tricks in Python.

Figuring out a solution yourself is rewarding, but comparing your solution afterwards to others is where it really shines and where you learn to really make the most out of Python as a language, and do some code review on your own code.

One of this weeks challenges was Kebabize and is about string transformation. Below is my initial solution;

def kebabize_v1(string):
    string = ['-' + char.lower() if char.isupper() else char for char in string]
    string = [char if not char.isdigit() else '' for char in string]
    string = ''.join(string)
    string = string.strip('-')

    return string

assert(kebabize_v1('myCamelCasedString') == 'my-camel-cased-string')
assert(kebabize_v1('myCamelHas3Humps') == 'my-camel-has-humps')
assert(kebabize_v1('SOS') == 's-o-s')
assert(kebabize_v1('42') == '')
assert(kebabize_v1('CodeWars') == 'code-wars')
More …