Преглед на файлове

added implementation of net

Sebastian Vendt преди 6 години
родител
ревизия
11afaa7df7
променени са 2 файла, в които са добавени 190 реда и са изтрити 0 реда
  1. 116 0
      julia/dataManager.jl
  2. 74 0
      julia/net.jl

+ 116 - 0
julia/dataManager.jl

@@ -0,0 +1,116 @@
+module dataManager
+
+using MAT 
+using Base.Iterators: repeated, partition
+using Statistics
+using Flux.Data.MNIST
+using Flux:onehotbatch
+"""
+	make_minibatch(X, Y, idxset)
+	
+loads and bundles training data and labels into batches 
+X should be of size Width x Height x channels x batchsize
+Y should be of size 2 x batchsize
+"""
+function make_minibatch(X, Y, idxset)
+    X_batch = Array{Float32}(undef, size(X, 1), size(X, 2), 1, length(idxset))
+    Y_batch = Array{Float32}(undef, 2, length(idxset))
+    for i in 1:length(idxset)
+        
+        X_batch[:, :, :, i] = Float32.(X[:, :, :, idxset[i]])
+        Y_batch[:, i] = Float32.(Y[:, idxset[i]])
+    end    
+    return (X_batch, Y_batch)
+end
+
+"""
+    make_batch(filepath, batch_size=100, normalize=true)
+    
+Creates batches with size batch_size(default 100) from filenames at given filepath. Images will be normalized if normalize is set (default true). 
+If batch_size equals -1 the batch size will be the size of the dataset
+Structure of the .mat file: 
+
+    fieldname | size
+    ----------------
+       data   | 50 x 6 x N
+  bin_targets | 2 x N
+
+where N denotes the number of samples, 50 is the window size and 6 are the number of channels
+"""
+function make_batch(filepath, filenames...; batch_size=100, normalize_data=true, truncate_data=false)
+    data = Array{Float64}(undef, 0)
+    labels = Array{Float64}(undef, 0)
+    for (i, filename) in enumerate(filenames)
+        # load the data from the mat file
+        file = "$filepath$filename"
+        @debug("Reading $(i) of $(length(filenames)) from $(file)")
+        matfile = matopen(file)
+        # size(images) = (N, width, height, 1)
+        dataPart = read(matfile, "data")
+        # size(bin_targets) = (N, 10)
+        labelsPart = read(matfile, "labels")
+        close(matfile) 
+
+        data = cat(dims=3, data, dataPart)
+        labels = cat(dims=2, labels, labelsPart)   
+        
+    end
+	
+	# add singleton dimension and permute dims so it matches the convention of Flux width x height x channels x batchsize(Setsize)   
+	data = cat(dims=4, data)
+
+    # rearrange the data array 
+	# size(data) = (50, 6, 1, N)
+    data = permutedims(data, (1, 2, 4, 3))
+
+    @debug("Dimension of data $(size(data, 1)) x $(size(data, 2)) x $(size(data, 3)) x $(size(data, 4))")
+    @debug("Dimension of binary targets $(size(bin_targets)) x $(size(bin_targets))")
+    
+    
+    if(normalize_data)
+		normalize!(data, truncate_data)
+	end
+    
+    # Convert to Float32
+    labels = convert(Array{Float32}, labels)
+    data = convert(Array{Float32}, data) 
+	
+    # display one sample of the images depends on PyPlot!
+    # matshow(dropdims(images[:,:,:,10], dims=3), cmap=PyPlot.cm.gray, vmin=0, vmax=255)
+	
+	 if ( batch_size == -1 ) 
+	    batch_size = size(data, 4)
+	 end
+    @debug("Creating batches")
+    idxsets = partition(1:size(data, 4), batch_size)
+    data_set = [make_minibatch(data, labels, i) for i in idxsets];
+    
+    return data_set
+end # function make_batch
+
+"""
+normalize input images along the batch and channel dimension
+input should have standart flux order: Widht x height x channels x batchsize
+if truncate is set to true the last 1% beyond 2.576 sigma will be clipped to 2.576 sigma
+"""
+function normalize!(data; truncate=false)
+	mean_data = mean(data, dims=4)
+    std_data = std(data, mean=mean_data, dims=4)
+	
+	setsize = size(data, 4)
+    
+	@debug("normalize dataset")
+	std_data_tmp = copy(std_data)
+	std_data_tmp[std_data_tmp .== 0] .= 1
+	for i in 1:setsize
+		data[:, :, :, i] = (data[:, :, :, i] - mean_data) ./ std_data_tmp
+	end
+	if(truncate)
+		# truncate the last 1% beyond 2.576 sigma 
+		data[data .> 2.576] .= 2.576
+		data[data .< -2.576] .= -2.576
+	end
+	return (mean_data, std_data)
+end
+
+end # module dataManager

+ 74 - 0
julia/net.jl

@@ -0,0 +1,74 @@
+"""
+Author: Sebastian Vendt, University of Ulm
+
+
+
+"""
+
+using Flux, Statistics
+using Flux: onecold
+using BSON
+using Dates
+using Printf
+using NNlib
+include("./dataManager.jl")
+using .dataManager: make_batch
+using Logging
+import LinearAlgebra: norm
+norm(x::TrackedArray{T}) where T = sqrt(sum(abs2.(x)) + eps(T)) 
+
+
+######################
+# PARAMETERS
+######################
+const batch_size = 100
+const momentum = 0.9f0
+const lambda = 0.0005f0
+init_learning_rate = 0.1f0
+learning_rate = init_learning_rate
+const epochs = 100
+const decay_rate = 0.1f0
+const decay_step = 40
+const usegpu = true
+const printout_interval = 5
+const save_interval = 25
+const time_format = "HH:MM:SS"
+data_size = (50, 1) # MNIST is using 28, 28
+
+# ARCHITECTURE
+inputDense1
+inputDense2
+inputDense3
+classes = 2
+# enter the datasets and models you want to train
+
+dataset_folderpath = "../MATLAB/TrainingData/"
+
+const model_save_location = "../trainedModels/"
+const log_save_location = "../logs/"
+
+
+function adapt_learnrate(epoch_idx)
+    return init_learning_rate * decay_rate^(epoch_idx / decay_step)
+end
+
+
+if usegpu
+    using CuArrays
+end
+
+
+model = Chain(
+	Conv(kernel, channels=>features, relu, pad=map(x -> x ÷ 2, kernel)),
+	MaxPool(pooldims1, stride=()),
+	Conv(relu, pad=map(x -> x ÷ 2, kernel)),
+	MaxPool(),
+	Conv(relu, pad=map(x -> x ÷ 2, kernel)),
+	MaxPool(),
+	flatten, 
+	Dense(inputDense1, inputDense2, σ),
+	Dense(inputDense2, inputDense3, σ),
+	Dense(inputDense3, classes) # identity to output coordinates!
+)
+
+