<file_sep># -*- coding: utf-8 -*-

import argparse
import pickle

import numpy as np
import keras.utils.np_utils as np_utils

import dataset_io
import nn

def extract_misclassified(image_properties, predictions, labels):
	'''Given a list of image properties and the class probabilities, extract the image properties and
	class probabilities of the misclassified samples.

	image_properties: list type, content can be anything
	predictions: numpy array of shape (samples, classes)
	labels: numpy array of shape (samples, classes), labels in one-hot encoding

	returns wrong_image_properties: the part of image_properties that belongs to misclassified images
	returns wrong_predictions: the part of predictions that belongs to misclassified images'''

	pred_labels = np.argmax(predictions, axis=1) # from one-hot encoding to a class id
	labels = np.argmax(labels, axis=1) # same

	mistakes = pred_labels != labels # check which images are misclassified
	wrong_image_properties = [prop for prop, m in zip(image_properties, mistakes) if m]
	wrong_predictions = predictions[mistakes]

	return wrong_image_properties, wrong_predictions

#~ Parse parameters
parser = argparse.ArgumentParser()
parser.add_argument('weights', help='Path weights in xyz.w file')
parser.add_argument('layout', help='Path network layout specification')
parser.add_argument('data', help='Path to csv file that lists input images')
parser.add_argument('path', help='Location for storing the predictions')
parser.add_argument('-b', '--batchsize', help='Size of the batches to be learned on [default 16]', type=int, default=16)
parser.add_argument('-d', '--datalimit', help='Maximum number of data points to read from DATA [if missing, read all]', type=int, default=None)
parser.add_argument('-m', '--misclassified', help='Only store predictions for missclassified images', action='store_true')
args = parser.parse_args()

#~ Load model
print('Loading model from {0}'.format(args.layout))
layout = nn.load_layout(args.layout)
model, optimizer = nn.build_model_to_layout(layout)

#~ Load weights
print('Loading weights from {0}'.format(args.weights))
model.load_weights(args.weights)

#~ Load data
input_shape = layout[0][1]['input_shape']
resolution = input_shape[1:]
print('Loading data from {0} and rescaling it to {1}x{2}'.format(args.data, resolution[0], resolution[1]))
x_test, y_test, num_classes, image_properties = dataset_io.read_data(args.data, resolution, args.datalimit, return_image_properties=True)
y_test = np_utils.to_categorical(y_test, num_classes)

#~ Create predictions
print('Predicting labels for {0} samples at resolution {1}x{2} in batches of size {3}'.format(x_test.shape[0], resolution[0], resolution[1], args.batchsize))
predictions = model.predict_proba(x_test, batch_size=args.batchsize)

#~ If desired, reduce output to the misclassified images
if args.misclassified:
	print('Reducing output to misclassified samples')
	sample_count = len(image_properties)
	image_properties, predictions = extract_misclassified(image_properties, predictions, y_test)
	print('\tMisclassified images: {0} out of {1}'.format(len(image_properties), sample_count))

#~ Store preditions on disk
print('Storing samples to {0}'.format(args.path))
with open(args.path, 'wb') as out_file:
	pickle.dump((image_properties, predictions), out_file, pickle.HIGHEST_PROTOCOL)

print('Done')
<file_sep># -*- coding: utf-8 -*-

'''Take a network layout and weights, and test its performance on a given data set.
Print score and accuracy.
User can specify batchsize, number of samples to consider (randomly chosen), and keras verbosity'''

import argparse

import theano
theano.config.openmp = True
import keras.utils.np_utils as np_utils

import nn
import dataset_io

#~ Parse parameters
parser = argparse.ArgumentParser()
parser.add_argument('weights', help='Path weights in xyz.w file')
parser.add_argument('layout', help='Path network layout specification')
parser.add_argument('path', help='Path to csv file that lists input images')
parser.add_argument('-b', '--batchsize', help='Size of the batches to be learned on [default 16]', type=int, default=16)
parser.add_argument('-d', '--datalimit', help='Maximum number of data points to read from PATH [if missing, read all]', type=int, default=None)
parser.add_argument('-v', '--verbosity', help='Set the verbosity level of keras (valid values: 0, 1, 2)', type=int, default=1)
args = parser.parse_args()

#~ Load model
print('Loading model from {0}'.format(args.layout))
layout = nn.load_layout(args.layout)
model, optimizer = nn.build_model_to_layout(layout)

#~ Load weights
print('Loading weights from {0}'.format(args.weights))
model.load_weights(args.weights)

#~ Load data
input_shape = layout[0][1]['input_shape']
resolution = input_shape[1:]
print('Loading data from {0} and rescaling it to {1}x{2}'.format(args.path, resolution[0], resolution[1]))
x_test, y_test, num_classes = dataset_io.read_data(args.path, resolution, args.datalimit)
y_test = np_utils.to_categorical(y_test, num_classes)

#~ Test the model
print('Testing on {0} samples at resolution {1}x{2} in batches of size {3}'.format(x_test.shape[0], resolution[0], resolution[1], args.batchsize))
score = model.evaluate(x_test, y_test, batch_size=args.batchsize, show_accuracy=True, verbose=args.verbosity)
print('Test score:', score[0])
print('Test accuracy:', score[1])

print('Done')<file_sep>import theano
import numpy as np

class stepwise_tanh_op(theano.Op):
	__props__ = ()

	def make_node(self, x):
		# check that the theano version has support for __props__.
		# This next line looks like it has a typo,
		# but it's actually a way to detect the theano version
		# is sufficiently recent to support the use of __props__.
		assert hasattr(self, '_props'), "Your version of theano is too old to support __props__."
		x = theano.tensor.as_tensor_variable(x)
		return theano.Apply(self, [x], [x.type()])

	def perform(self, node, inputs, output_storage):
		x = inputs[0]
		z = output_storage[0]
		y = x.copy()
		a = 1
		y[y > a] = a
		y[y < -a] = -a
		z[0] = y

	def infer_shape(self, node, i0_shapes):
		return i0_shapes

	def grad(self, inputs, output_grads):
		g = np.ones(inputs[0].shape)
		a = 1
		g[inputs[0] > a] = 0
		g[inputs[0] < -a] = 0
		return [g[0]]
        #return [output_grads[0]]

	def R_op(self, inputs, eval_points):
		# R_op can receive None as eval_points.
		# That mean there is no diferientiable path through that input
		# If this imply that you cannot compute some outputs,
		# return None for those.
		if eval_points[0] is None:
			return eval_points
		return self.grad(inputs, eval_points)

def create():
	x = theano.tensor.matrix()
	return theano.function([x], stepwise_tanh_op()(x))

if __name__ == "__main__":
	stepwise_tanh = create()
	inp = np.random.rand(5, 4) * 4 - 2
	out = stepwise_tanh(inp)
	#assert numpy.allclose(inp * 2, out)
	print(inp)
	print(out)
<file_sep>import os

def search_folder(path):
	list = ""
	for subdir, dirs, files in os.walk(path):
		for file in files:
			if file[-4:] == ".csv":
				list += subdir + "/" + file + "\n"
	return list

path = "data/GTSRB_TEST/"

list = search_folder(path)[:-1]

with open("csv_list_test.txt", "w") as list_file:
	list_file.write(list)
<file_sep>#!/bin/bash

# Path settings
weights_path="weights/"
results_path="results/"

# Will get path to layout, dataset and out_path for a weight path in $1.
# They are stored in layout, dataset and out_path, respectively
generate_paths() {
	layout_hint="${1%.w}"
	layout_hint=$(echo "$layout_hint" | sed -e "s/[0-9]*$//")
	layout_hint="${layout_hint}layout.txt"
	layout=$(cat "$layout_hint")

	dataset_hint=$(dirname $1)
	dataset_hint="${dataset_hint}/test_dataset.txt"
	dataset=$(cat "$dataset_hint")

	out_path="${1##$weights_path}"
	out_path="${out_path%.w}"
	out_path="${results_path}${out_path}.txt"
}

# Stage 1: Evaluate all weights in $weights_path, and write the output to
# $results_path, keeping the folder structure.

weights=$(find $weights_path -iname "*.w" | sort) # The list of weights to evaluate
for w in $weights ; do
	generate_paths $w

	# If output already exists, don't re-compute it
	if [ -f $out_path ] ; then
		echo "Results for $w exist, skipping"
		continue
	else
		echo "Evaluating $w"
	fi

	# Create output folders if they don't exist
	out_dir="$(dirname $out_path)"
	mkdir -p "$out_dir"
	nice -n 19 python src/test.py $w $layout $dataset > $out_path

	if [ "$?" -ne "0" ] ; then
		echo "Test failed, deleting $out_path"
		rm "$out_path"
	fi
done

# Stage 2: Agglomerate the resulting values in a single file per configuration
# that is gnuplot-readable

results=$(find $results_path -iname "*.txt" | sort) # The list of results to agglomerate

# Remove old files
for result in $results ; do
	out_file="${result%.txt}"
	out_file=$(echo "$out_file" | sed -e "s/[0-9]*$//")
	out_file="${out_file}result.dat"
	rm -f "$out_file"
	#echo "# epoch accuracy" > "$out_file"
	echo "# epoch accuracy" > "$out_file"
done

# Create new ones with fresh values
for result in $results ; do
	# The file to store agglomerated results in
	out_file="${result%.txt}"
	out_file=$(echo "$out_file" | sed -e "s/[0-9]*$//")
	out_file="${out_file}result.dat"

	# Epoch number
	epoch=$(basename "$result")
	epoch="${epoch%.w}"
	epoch=$(echo "$epoch" | sed 's/[^0-9]//g')

	# Accuracy
	accuracy_line=$(tail -n 2 "$result" | head -n 1)
	accuracy=${accuracy_line##"('Test accuracy:', "}
	accuracy=${accuracy%%)}

	# Write to file
	line="$epoch $accuracy"
	echo "$line" >> "$out_file"
done
<file_sep># -*- coding: utf-8 -*-

'''Will train a neural network with a given layout on a data set. The user can opt to load weights
before and store them after training. Furthermore, number of epochs, batchsize, maximum number
of training samples to consider, and keras verbosity can be specified. The user can also chose to
apply slight affine transformations of the input images before each epoch.

For loading and saving weights, specify paths without a filename extension. Two files will be
created / read from, a .w file containing the weights, and a .t file containing the training
parameters like learning rate.'''

import argparse
import pickle

import theano
theano.config.openmp = True
import keras.utils.np_utils as np_utils

import nn
import dataset_io
import distortions

#~ Parse arguments
parser = argparse.ArgumentParser()
parser.add_argument('layout', help='Path network layout specification')
parser.add_argument('path', help='Path to csv file that lists input images')
parser.add_argument('-e', '--epochs', help='Numper of epochs to train for [default 1]', type=int, default=1)
parser.add_argument('-b', '--batchsize', help='Size of the batches to be learned on [default 16]', type=int, default=16)
parser.add_argument('-d', '--datalimit', help='Maximum number of data points to read from PATH [if missing, read all]', type=int, default=None)
parser.add_argument('-m', '--morph', help='Morph training data between epochs', action='store_true')
parser.add_argument('-l', '--load-status', help='Basename of the files to load status from')
parser.add_argument('-s', '--store-status', help='Basename of the files to store status in')
parser.add_argument('-v', '--verbosity', help='Set the verbosity level of keras (valid values: 0, 1, 2)', type=int, default=1)
args = parser.parse_args()

#~ Load model
print('Loading model from {0}'.format(args.layout))
layout = nn.load_layout(args.layout)
model, optimizer = nn.build_model_to_layout(layout)

#~ Load status
if args.load_status:
	print('Loading status from {0}'.format(args.load_status))

	#~ weights
	weight_filename = args.load_status + ".w"
	model.load_weights(weight_filename)

	#~ training parameters
	try:
		train_filename = args.load_status + ".t"
		with open(train_filename, 'rb') as train_file:
			optimizer_state = pickle.load(train_file)
		optimizer.set_state(optimizer_state)
	except IOError:
		print('\t{0} not found: using initial parameters'.format(train_filename))

#~ Load data
input_shape = layout[0][1]['input_shape']
resolution = input_shape[1:]
print('Loading data from {0} and rescaling it to {1}x{2}'.format(args.path, resolution[0], resolution[1]))
x_train, y_train, num_classes = dataset_io.read_data(args.path, resolution, args.datalimit)
y_train = np_utils.to_categorical(y_train, num_classes)

#~ Create distortions callback
if args.morph:
	distcall = distortions.Distortions(x_train, x_train.shape[0])
	callbacks = [distcall]
	print('Distortions will be applied to training data between epochs')
else:
	callbacks = []

#~ Train the model
print('Training on {0} samples in batches of size {1} for {2} epochs'.format(x_train.shape[0], args.batchsize, args.epochs))
model.fit(x_train, y_train, nb_epoch=args.epochs, callbacks=callbacks, batch_size=args.batchsize, show_accuracy=True, verbose=args.verbosity)

#~ Store status
if args.store_status:
	print('Storing status to {0}'.format(args.store_status))

	#~ weights
	weight_filename = args.store_status + ".w"
	model.save_weights(weight_filename, overwrite=True)

	#~ training parameters
	train_filename = args.store_status + ".t"
	optimizer_state = optimizer.get_state()
	with open(train_filename, 'wb') as train_file:
		pickle.dump(optimizer_state, train_file, pickle.HIGHEST_PROTOCOL)

print('Done')
<file_sep># -*- coding: utf-8 -*-

import PIL.Image as pil
import PIL.ImageOps as pilops
import numpy as np
import time
import random
import csv

def create_image_list(filename):
	'''This method takes the path to a .txt file, which contains the paths to the csv files (one per row), which contain the information about the images, which are to be loaded. The csv files contain the filename (with the path relative to the csv file), the width of the image, the height of the image, the coordinates X1, Y1, X2, Y2 of the bounding box (X1 and Y1 are inclusive, X2 and Y2 exclusive) and the class id of the image. Semicolons are used as seperators.'''
	# open file which contains the csv list
	with open(filename, "r") as f:
		# read csv paths from file and save them in a list
		csv_paths = f.readlines()

		# create list, which saves a dictionary for each image
		image_list = []

		# iterate over csv files
		for csv_path in csv_paths:
			# remove possible '\n' at the end of the path
			csv_path = csv_path.strip()

			# open csv file to read images
			with open(csv_path) as csv_file:
				# create csv reader
				csv_reader = csv.reader(csv_file, delimiter=";")

				# skip first line, which contains the headlines
				next(csv_reader)

				# save path to the folder, which contains the images
				folder_path = csv_path[:csv_path.rfind('/')] + "/"

				# iterate over images
				for image_row in csv_reader:
					# build path to image
					image_path = folder_path + image_row[0]

					# append image to image list
					image_list.append({'path': image_path, 'corners':  (int(image_row[3]), int(image_row[4]), int(image_row[5]), int(image_row[6])), 'label': image_row[7]})

	# shuffle images
	random.shuffle(image_list)

	return image_list

def count_classes(image_list):
	classes = set()
	for image in image_list:
		classes.add(image['label'])
	return len(classes)

def read_data(filename, resolution, d=None, normalize=True, autocontrast=True, return_image_properties=False):
	'''This method takes the path to a .txt file containing the paths to the csv files, which save information about the images. For a more detailed description of those files cf. method create_image_list(). In addition, this method takes the 'resolution' to which the images are to be scaled, a parameter 'd' which determines how many images are to be processed, a boolean parameter 'normalize' which controls whether the images shall be normalized to the interval [0,1] and a boolean parameter 'autocontrast' which controls whether a PIL intern method shall be used to increase the contrast of the images. The boolean parameter 'return_image_properties' can be set to 'True' in order to return the image list created by the create_image_list method called within this method.'''
	# create image list
	image_list = create_image_list(filename)

	# count classes
	num_classes = count_classes(image_list)

	# check whether there is a limit for the images to be loaded
	num_images = d if d is not None else len(image_list)

	# create empty arrays with appropriate size
	X = np.empty((num_images, 3, resolution[0], resolution[1]), dtype=float)
	y = np.empty((num_images))

	# iterate over images
	for idx, image in enumerate(image_list):
		if idx >= num_images:
			break

		# open the image
		im = pil.open(image['path'])

		# crop image
		im = im.crop(image['corners'])

		# autocontrast
		if autocontrast:
			im = pilops.autocontrast(im)

		# resize image to desired size
		im = im.resize(resolution)

		# save image as array within the result array
		X[idx] = np.transpose(np.asarray(im), [2,0,1])

		# save label
		y[idx] = image['label']

	# normalize images to range [0,1] if desired
	if normalize:
		X /= 255.0

	if return_image_properties:
		return X, y, num_classes, image_list
	else:
		return X, y, num_classes

if __name__ == "__main__":
	size = (48,48)
	csv_filename = "data/csv_list_train.txt"

	start_time = time.time()
	X_train, y_train = read_data(csv_filename, size, 1000, True, True)
	end_time = time.time()

	print("Execution time: " + str(end_time - start_time) + "s")
<file_sep># -*- coding: utf-8 -*-

import numpy as np
import keras.callbacks
import scipy.ndimage.interpolation as trans

class Distortions(keras.callbacks.Callback):
	def __init__(self, x, number_of_images):
		self.original_x = np.copy(x)
		self.x = x
		self.resolution = x.shape[2:4]
		self.number_of_images = number_of_images

	def cut_image(self, image):
		# ATTENTION! It is assumed that the images are square!

		# image has a smaller resolution than desired
		if image.shape[1] < self.resolution[0]:
			# initialize result image
			res = np.empty((3,self.resolution[0],self.resolution[1]))

			# calculate boundaries
			left = (self.resolution[0] - image.shape[1]) // 2
			top = (self.resolution[1] - image.shape[2]) // 2
			right = left + image.shape[1]
			bottom = top + image.shape[2]

			res[:,left:right,top:bottom] = image

			# interpolate empty pixels (left, right, above, below distorted image)
			res[:,:left,top:bottom] = image[:,0,:].reshape(3,1,-1)
			res[:,right:,top:bottom] = image[:,-1,:].reshape(3,1,-1)
			res[:,left:right,:top] = image[:,:,0].reshape(3,-1,1)
			res[:,left:right,bottom:] = image[:,:,-1].reshape(3,-1,1)

			# interpolate empty pixels (topleft, topright, bottomleft, bottomright corner)
			res[:,:left,:top] = trans.zoom(image[:,0,0].reshape(3,1,1), zoom=[1,left,top])
			res[:,right:,:top] = trans.zoom(image[:,-1,0].reshape(3,1,1), zoom=[1,self.resolution[0]-right,top])
			res[:,:left,bottom:] = trans.zoom(image[:,0,-1].reshape(3,1,1), zoom=[1, left, self.resolution[1]-bottom])
			res[:,right:,bottom:] = trans.zoom(image[:,-1,-1].reshape(3,1,1), zoom=[1, self.resolution[0]-right, self.resolution[1]-bottom])

			return res

		# image has a larger resolution than desired
		else:
			# calculate boundaries
			left = (image.shape[1] - self.resolution[0]) // 2
			top = (image.shape[2] - self.resolution[1]) // 2
			right = left + self.resolution[0]
			bottom = top + self.resolution[1]

			# return result image
			return image[:,left:right,top:bottom]

	def on_epoch_begin(self, epoch, logs={}):
		# create random values for shift, rotation and scaling
		rotate_angles = np.random.uniform(-5., 5., (self.number_of_images))
		scale_factors = np.random.uniform(0.9, 1.1, (self.number_of_images))
		shift_values = np.random.uniform(- 0.1 * self.x.shape[1], 0.1 * self.x.shape[2], (self.number_of_images))

		# iterate over all images and transform them
		for img_id in range(self.number_of_images):
			# shift
			img = trans.shift(self.original_x[img_id], [0, shift_values[img_id], shift_values[img_id]], mode="nearest")

			# rotate
			img = trans.rotate(img, axes=(1,2), angle=rotate_angles[img_id], reshape=False, mode="nearest")

			# scale
			img = trans.zoom(img, zoom=[1,scale_factors[img_id],scale_factors[img_id]], mode="nearest")

			self.x[img_id] = self.cut_image(img)
<file_sep>#!/bin/bash

# To use this, set ADDITIONAL_LIBS to the folder containing the required
# libaries and source this file.

# This script will append to the LD_LIBRARY_PATH environment variable so that
# the libraries located in ADDITIONAL_LIBS will be found by ld when running
# the program. Libraries that need to be found in ADDITIONAL_LIBS if they are
# not found in the regular system paths include:
# libopenblas.so 
# libopenblas.so.0
# libhdf5_serial.so.10
# libhdf5_serial_hl.so.10
# libhdf5_serial_hl.so.10.0.1

ADDITIONAL_LIBS=/path/to/libraries

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ADDITIONAL_LIBS
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
<file_sep>import os
import random
import numpy as np

# variable definitions
inriapath = "data/INRIA"
nb_testimg = 37

# initialize strings which contain the content of the csv file
csv_str_train = "Filename;Width;Height;Roi.X1;Roi.Y1;Roi.X2;Roi.Y2;ClassId"
csv_str_test = "Filename;Width;Height;Roi.X1;Roi.Y1;Roi.X2;Roi.Y2;ClassId"

# determine which images shall be used as test images
test_images = np.empty((15,nb_testimg))
for id, row in enumerate(test_images):
	test_images[id] = random.sample(range(186), nb_testimg)
test_images = test_images.astype(np.int16)

# iterate over files
for path, subdirs, files in os.walk(inriapath):
	# check whether we are in folder 'deFace' and skip it	
	if not path.endswith("deFace"):
		# iterate over file
		for idx, f in enumerate(files):
			# check whether file is an image
			if f.endswith(".jpg"):
				obj_id = int(path[-2:])
				for i in range(nb_testimg):
					if idx == test_images[int(obj_id) - 1, i]:
						csv_str_test += "\nPersonne" + str(obj_id).zfill(2) + "/" + f + ";384;288;0;0;384;288;" + str(obj_id - 1)
						break
				else:
					csv_str_train += "\nPersonne" + str(obj_id).zfill(2) + "/" + f + ";384;288;0;0;384;288;" + str(obj_id - 1)

with open("data/INRIA/INRIA_TRAIN.csv", "w") as text_file:
	text_file.write(csv_str_train)
with open("data/INRIA/INRIA_TEST.csv", "w") as text_file:
	text_file.write(csv_str_test)
<file_sep># study-project-gtsrb
A study project of using convolutional neural networks on the GTSRB dataset.

# Performance
On 6 Intel Xeon X7542 CPUs the implementation currently processes 18432 images
in 15000 seconds. That means it trains about 1,22 images per second.
<file_sep>import argparse
import sys
import os

sys.path.insert(1, os.path.join(sys.path[0], '../src'))
import nn

parser = argparse.ArgumentParser()
parser.add_argument('source_layout', metavar='source-layout', help='Path source network layout specification')
parser.add_argument('source_weights', metavar='source-weights', help='Path sourcce network weights')
parser.add_argument('target_layout', metavar='target-layout', help='Path target network layout specification')
parser.add_argument('target_weights', metavar='target-weights', help='Path target network weights')
parser.add_argument('layerspec', help='Which layers to copy. Format: a-b-...-z where a-z are 0-based layer numbers')
args = parser.parse_args()

#~ Load source model
print('Loading source model from {0}'.format(args.source_layout))
source_layout = nn.load_layout(args.source_layout)
source_model, source_optimizer = nn.build_model_to_layout(source_layout)

#~ Load source weights
print('\tLoading source weights from {0}'.format(args.source_weights))
source_model.load_weights(args.source_weights)

#~ Load target model
print('Loading target model from {0}'.format(args.target_layout))
target_layout = nn.load_layout(args.target_layout)
target_model, target_optimizer = nn.build_model_to_layout(target_layout)

#~ Load target weights
if os.path.isfile(args.target_weights):
	print('\tLoading target weights from {0}'.format(args.target_weights))
	target_model.load_weights(args.target_weights)
else:
	print('\tNot loading target weights. Initialization values will be used where not overwritten.')

layers = args.layerspec.split('-')
layers = [int(l) for l in layers]

#~ Copy layer weights
for layer_idx in layers:
	print('Copying weights on layer {0}'.format(layer_idx))
	weights = source_model.layers[layer_idx].get_weights()
	target_model.layers[layer_idx].set_weights(weights)

#~ Store target weights
print('Storing target weights to {0}'.format(args.target_weights))
target_model.save_weights(args.target_weights, overwrite=True)












<file_sep>import os
import random
import numpy as np

# variable definitions
coilpath = "data/COIL100"
nb_testimg = 14

# initialize strings which contain the content of the csv file
csv_str_train = "Filename;Width;Height;Roi.X1;Roi.Y1;Roi.X2;Roi.Y2;ClassId"
csv_str_test = "Filename;Width;Height;Roi.X1;Roi.Y1;Roi.X2;Roi.Y2;ClassId"

# determine which images shall be used as test images
test_images = np.empty((100,nb_testimg))
for id, row in enumerate(test_images):
	test_images[id] = random.sample(range(72), nb_testimg)
test_images = test_images.astype(np.int16) * 5

# iterate over files
for subdir, dirs, files in os.walk(coilpath):
	for f in files:
		# check whether file is an image
		if f[-4:] == ".png":
			# extract object id and degree from file name
			obj_id, degree = f[3:-4].split('__', 1)
			# append image to respective csv file
			for i in range(nb_testimg):
				if int(degree) == test_images[int(obj_id) - 1, i]:
					csv_str_test += "\nobj" + obj_id + "__" + degree + ".png;128;128;0;0;128;128;" + str(int(obj_id) - 1)
					break
			else:
				csv_str_train += "\nobj" + obj_id + "__" + degree + ".png;128;128;0;0;128;128;" + str(int(obj_id) - 1)

with open("data/COIL100/COIL_TRAIN.csv", "w") as text_file:
	text_file.write(csv_str_train)
with open("data/COIL100/COIL_TEST.csv", "w") as text_file:
	text_file.write(csv_str_test)
<file_sep># -*- coding: utf-8 -*-

import argparse
import json

import theano
theano.config.openmp = True
import keras.models as models
import keras.layers.core as core_layers
import keras.layers.convolutional as conv_layers
import keras.optimizers as optimizers

import stepwise_tanh_op as stanh

def build_model_to_layout(layout, momentum=0.0, nesterov=False):
	model = models.Sequential()

	#stepwise_tanh = stanh.create()
	x = theano.tensor.matrix()
	stepwise_tanh = theano.function([x], stanh.stepwise_tanh_op()(x))

	for ltype, lspec in layout:
		try:
			if lspec['activation'] == 'stepwise_tanh':
				lspec['activation'] = stepwise_tanh
		except KeyError:
			pass

		if ltype == 'conv2D':
			layer = conv_layers.Convolution2D(**lspec)
		elif ltype == 'maxpool2D':
			layer = conv_layers.MaxPooling2D(**lspec)
		elif ltype == 'flatten':
			layer = core_layers.Flatten()
		elif ltype == 'dense':
			layer = core_layers.Dense(**lspec)
		else:
			raise NotImplementedError

		model.add(layer)

	sgd = optimizers.SGD(lr=0.1, decay=1e-6, momentum=momentum, nesterov=nesterov) # TODO parameters
	model.compile(loss='categorical_crossentropy', optimizer=sgd)

	return model, sgd

def get_gtsrb_layout(input_shape, num_classes):
	'''Builds a keras CNN layout according to one column of the Multi-CNN architecture described in
	Multi-column deep neural network for traffic sign classification
	(<NAME> ∗ , <NAME>, <NAME>, <NAME>)'''

	layout = []
	layout.append( ('conv2D', {'nb_filter': 100, 'nb_row': 7, 'nb_col': 7, 'init': 'uniform', 'activation': 'tanh', 'input_shape': input_shape}) )
	layout.append( ('maxpool2D', {'pool_size': (2,2)}) )
	layout.append( ('conv2D', {'nb_filter': 150, 'nb_row': 4, 'nb_col': 4, 'init': 'uniform', 'activation': 'tanh'}) )
	layout.append( ('maxpool2D', {'pool_size': (2,2)}) )
	layout.append( ('conv2D', {'nb_filter': 250, 'nb_row': 4, 'nb_col': 4, 'init': 'uniform', 'activation': 'tanh'}) )
	layout.append( ('maxpool2D', {'pool_size': (2,2)}) )
	layout.append( ('flatten', {}) )
	layout.append( ('dense', {'output_dim': 300, 'init': 'uniform', 'activation': 'tanh'}) )
	layout.append( ('dense', {'output_dim': num_classes, 'init': 'uniform', 'activation': 'softmax'}) )

	return layout

def load_layout(path):
	with open(path) as in_file:
		layout = json.load(in_file)
	return layout

def store_layout(layout, path):
	with open(path, 'w') as out_file:
		json.dump(layout, out_file, indent=2, sort_keys=True)

if __name__ == '__main__':
	#~ Parse arguments
	parser = argparse.ArgumentParser()
	parser.add_argument('path', help='Folder to store known layouts in')
	args = parser.parse_args()

	#~ Make sure path ends in a /
	if args.path[-1] != '/':
		args.path += '/'

	#~ Generate list of models to store
	layouts = []
	layouts.append( ('gtsrb', get_gtsrb_layout, {'input_shape': (3, 48, 48), 'num_classes': 43}) )

	#~ Store models to disk
	for name, function, kwargs in layouts:
		path = args.path + name + '.l'
		store_layout(function(**kwargs), path)
<file_sep># -*- coding: utf-8 -*-

import argparse
import sys
import os

import numpy as np
import PIL.Image as pil_img

sys.path.insert(1, os.path.join(sys.path[0], '../src'))
import nn

def visualize_filters(model, path, filename):
	# add "/" to path, if it does not end on this character
	if path[-1] != "/":
		path += "/"

	# iterate over layers
	for layer_id,layer in enumerate(model.layers):
		# ignore all layers which are not convolutional layers
		if layer.get_config()['name'] != "Convolution2D":
			continue

		# iterate over outputs
		for weight_matrices in layer.get_weights():
			# ignore 1-dimensional filters
			if len(weight_matrices.shape) > 1:
				# get number of output maps, number of filters per input map and the x and y dimensions of the filters
				num_outputs, num_filters, xdim, ydim = weight_matrices.shape

				# calculate the size of the filter collection image and create it
				height = num_filters * (xdim + 1) + 1
				width = num_outputs * (ydim + 1) + 1
				filter_collection = pil_img.new("L", (width, height), "white")

				# iterate over the output maps of the next layer
				for i_id, inputs in enumerate(weight_matrices):
					# iterate over the filters of the maps on the current layer
					for f_id, filter in enumerate(inputs):
						# determine position of the filter in the filter collection
						xpos = i_id * (xdim+1) + 1
						ypos = f_id * (ydim+1) + 1

						# rescale the grayvalues to visualize them
						filter -= np.min(filter)
						filter *= 255./np.max(filter)
						im_filter = pil_img.fromarray(filter)

						# paste the filter into the filter collection
						filter_collection.paste(im_filter, (xpos, ypos))

				# save the filter collection of layer 'id'
				filter_collection.save(path + "weights_on_layer_" + str(layer_id) + "_" + filename + ".png")

if __name__ == "__main__":
	#~ Parse parameters
	parser = argparse.ArgumentParser()
	parser.add_argument('weights', help='Path to the weights which are to be loaded')
	parser.add_argument('layout', help='Path network layout specification')
	parser.add_argument('-s', '--savepath', help='Path to save location of the visualized filters', default='./')
	parser.add_argument('-v', '--verbose', help='Determine whether the programm shall print information in the terminal or not', action="store_true")
	parser.add_argument('-n', '--filename', help='Pass a string which is appended to the created image files.', default='')
	args = parser.parse_args()

	# Load model
	print('Loading model from {0}'.format(args.layout))
	layout = nn.load_layout(args.layout)
	model, optimizer = nn.build_model_to_layout(layout)

	#~ Load weights
	print('Loading weights from \"{0}\"'.format(args.weights))
	model.load_weights(args.weights)

	# visualize filters
	print('Generating visualizations and storing to {0}'.format(args.savepath))
	visualize_filters(model, args.savepath, args.filename)

	print('Done')
<file_sep># -*- coding: utf-8 -*-

'''If executed, this program will display images, together with the specified number of most likely
candidates and their probabilities. For the candidates, class representatives are used that reside
inside a specified class representative folder and are named classCLASSID.ppm'''

import argparse
import pickle

import PIL.Image as pil_img
import PIL.ImageOps as pil_img_ops
import numpy as np
import matplotlib.pyplot as ppt

class Image_Loader():
	'''Provides methods to load an image from a given path and to load an image according to a class
	id, from a folder containing class representatives which has to be passed to __init__.
	All images will be provided in the resolution passed to __init__.'''

	def __init__(self, resolution, class_representative_path):
		'''resolution: 2-tuple of x- and y-resolution
		class_representative_path: path to a folder of class representative images named class$.ppm where $ is the class id'''
		self.resolution = resolution
		self.class_representative_path = class_representative_path

	def get_image(self, path):
		'''load an image and rescale it to the resolution specified in __init__
		path: path to the image file
		returns: the image'''
		image = pil_img.open(path)
		image = image.resize(self.resolution)
		return image

	def get_class_representative(self, class_id):
		'''load image that represents a certain class in the resolution specified in __init__
		class_id: id of the class
		returns: representative image'''
		path = self.class_representative_path.format(class_id)
		return self.get_image(path)

def visualize(image_info, class_ids, probabilites, image_loader):
	'''Displays an image, the most likely candidates and their probabilities
	image_info: iterable that contains dictionaries, where the key "path" provides the path to an image as a string
	class_ids: numpy array of shape (number of samples, number of candidates), contains candidate class ids
	probabilites: numpy array of shape (number of samples, number of candidates), contains candidate class probabilities
	image_loader: Instance of Image_Loader
	'''

	#~ Iterate over sample images with their respective candidates and their probabilities
	for i, c, p in zip(image_info, class_ids, probabilites):
		fig, axes = ppt.subplots(1, c.size + 1, figsize=(12, 6), subplot_kw={'xticks': [], 'yticks': []})

		#~ Load and display the image
		image = image_loader.get_image(i['path'])
		axes[0].imshow(image, interpolation='none')
		axes[0].set_title('Input', y=-0.15)

		#~ Load and display representatives of the candidate classes and their probabilities
		for idx, (class_id, probability) in enumerate(zip(c,p)):
			class_representative = image_loader.get_class_representative(class_id)
			axes[idx+1].imshow(class_representative, interpolation='none')
			axes[idx+1].set_title('{0:.4f}'.format(probability), y=-0.15)

		ppt.show()

def get_candidates(probabilities, num_candidates=3):
	'''Transform the class probabilites into the num_candidates most likely class ids and their probabilites
	probabilites: numpy array of shape (samples, classes)
	num_candidates: integer, the number of candidates to extract
	returns class_ids: numpy array of shape (samples, num_candidates), the ids of the most likely classes
	returns winner_probabilities: numpy array of shape (samples, num_candidates), the corresponding probabilites to class_ids'''

	num_samples = probabilities.shape[0]

	#~ Generate the ids of the most likely classes (the most likely one should be at the lowest index)
	class_ids = np.argsort(probabilities, axis=1)
	class_ids = class_ids[:,-num_candidates:] # Take the num_candidates most likely classes
	class_ids = class_ids[:,::-1] # Put them in descending order

	# Also generate probabilities of the num_candidates most likely classes
	row_indices = np.arange(num_samples).reshape((num_samples, 1))
	winner_probabilities = probabilities[row_indices, class_ids]

	return class_ids, winner_probabilities

if __name__ == '__main__':
	#~ Parse parameters
	parser = argparse.ArgumentParser()
	parser.add_argument('predictions', help='Location of the stored predictions')
	parser.add_argument('representatives', help='Path to the directory containing class representatives')
	parser.add_argument('-c', '--candidates', help='Number of candidates to show for each test image [default 3]', type=int, default=3)
	parser.add_argument('-d', '--datalimit', help='Maximum number of data points to read from DATA [if missing, read all]', type=int, default=None)
	args = parser.parse_args()

	#~ Read data, a list of the sample image properties (including the path), and the class probabilites calculated for them
	#~ Data should be a pickle dump of (image_info, probabilities) akin to the one produced by predict.py
	#~ image_info is a list of {'path': path_as_string} dictionaries (may contain other key-value pairs)
	#~ probabilities is a (number_of_samples, number_of_classes) numpy array.
	with open(args.predictions, 'rb') as in_file:
		image_info, probabilities = pickle.load(in_file)

	#~ Limit the amount of data if specified per parameter
	if args.datalimit:
		image_info = image_info[:args.datalimit]
		probabilities = probabilities[:args.datalimit,...]

	#~ Get class ids and their probabilities of the most likely classes
	class_ids, winner_probabilities = get_candidates(probabilities, num_candidates=args.candidates)

	#~ Actual visualization
	if args.representatives[-1] != '/':
		args.representatives += '/'
	class_representative_path_spec = args.representatives + 'class{0}.ppm'
	image_loader = Image_Loader((48, 48), class_representative_path_spec)
	visualize(image_info, class_ids, winner_probabilities, image_loader)
<file_sep>import sys
import os

for i in range(31,61):
	os.system("python src/train.py layouts/inria_no_filter_train.l data/csv_list_train_inria.txt -m -l weights/inria/gtsrb_filters_" + str(i - 1) + " -s weights/inria/gtsrb_filters_" + str(i))
