ENV["MOCHA_CUDA_DEVICE"]=1
ENV["MOCHA_USE_NATIVE_EXT"] = "false"
ENV["MOCHA_USE_CUDA"] = "true"
using Mocha
using UnicodePlots
function draw_line!(rise,run, out=zeros(Float64,(10,10)))
len = minimum(size(out))÷2-1
if abs(run)>abs(rise)
range = run>0 ? (0:1:len) : (0:-1:-len)
for x in range
y = -trunc(Int64,(rise/run)*x)
out[end÷2+y,end÷2+x]=1 #Julia is backwards for column first
end
else
range = rise>0 ? (0:1:len) : (0:-1:-len)
for y in range
x = -trunc(Int64,(run/rise)*y)
out[end÷2+y,end÷2+x]=1 #Julia is backwards for column first
end
end
return out
end
function show_results_summary(pred, actual)
errors = abs(pred.-actual)
mean_error = mean(errors)
@show mean_error
@show std(errors)
@show minimum(errors)
@show median(errors)
@show maximum(errors)
accurancy= mean([ŷ==y for (ŷ,y) in zip(pred, actual)])
accurancy_todefault_epsilon= mean([ŷ≈y for (ŷ,y) in zip(pred, actual)])
accurancy_to_point001= mean([isapprox(ŷ,y, atol=0.001) for (ŷ,y) in zip(pred, actual)])
accurancy_to_point01= mean([isapprox(ŷ,y, atol=0.01) for (ŷ,y) in zip(pred, actual)])
accurancy_to_point1= mean([isapprox(ŷ,y, atol=0.1) for (ŷ,y) in zip(pred, actual)])
@show accurancy
@show accurancy_todefault_epsilon
@show accurancy_to_point001
@show accurancy_to_point01
@show accurancy_to_point1
nothing
end
function random_angle_rise_run()
quadrents=[(1,1,0),(1,-1,π),(-1,-1,-π),(-1,1,0)]
quadrent=rand(quadrents)
angle = rand(Float32)*π/2
if angle==π/2
rise,run = (1,0)
else
rise= num(Rational(tan(angle)))
run = den(Rational(tan(angle)))
end
rise*=quadrent[1]
run*=quadrent[2]
angle=angle*quadrent[1]*quadrent[2]+quadrent[3]
@assert(isapprox(angle,atan2(rise,run), atol=0.0001), "$angle != $(atan2(rise,run))")
angle,rise,run
end
random_angle_rise_run()
function make_data(n_cases, img_width, img_height)
X = Matrix{Float64}(img_width*img_height,n_cases)
Y_angles = Vector{Float64}(n_cases)
for ii in 1:n_cases
angle,rise,run = random_angle_rise_run()
img = draw_line!(rise,run, zeros(Float64,(img_height,img_width)))
X[:,ii] = img[:]
Y_angles[ii]=angle
end
X,Y_angles'
end
#Define various encoders for angles
encode_scaled(Y_angles)=((Y_angles+π)/2π)
decode_scaled(Y_scaled)=(Y_scaled[:]*2π-π)'
encode_cossin(Y_angles) = [cos(Y_angles); sin(Y_angles)]
decode_cossin(Y_cossin) = atan2(Y_cossin[2,:], Y_cossin[1,:])'
function encode_binned(Y_angles,n_bins = 500)
Ys = encode_scaled(Y_angles)
ret = zeros(n_bins, length(Ys))
for (ii,y) in enumerate(Ys)
idx=1+round(Int64, y*(n_bins-1))
ret[idx,ii]=1
end
ret
end
function decode_binned(Y_codes,n_bins = 500)
ret = Vector{Float64}(size(Y_codes,2))
for ii in 1:size(Y_codes,2)
idx = indmax(Y_codes[:,ii])[1]
ret[ii]=(idx.-1)./(n_bins-1)
end
decode_scaled(ret)
end
function eval_angular_encoding(encode, decode; img_width=101,img_height=101, cases=1000, max_iter=1000, softmax=false)
##Prep Data
xs,ys_angles = make_data(cases,img_width,img_height);
xs_test, ys_test_angles = make_data(cases,img_width,img_height); #Since it is syntetic data we can generate a testset as largeas the training set
ys_code = encode(ys_angles)
ys_test_code = encode(ys_test_angles)
#@assert(softmax || decode(ys_code)≈ys_angles) #if it is softmax, then it is coded in a form that is not conging to decode perfect
#Train Net
@show size(ys_code)
data_layer = MemoryDataLayer(batch_size=50, data=Array[xs, ys_code], tops=[:data, :label])
ip_layer = InnerProductLayer(name="ip", output_dim=500, tops=[:ip], bottoms=[:data], neuron=Neurons.Sigmoid())
label_dim = size(data_layer.data[data_layer.tops.==:label][1],1)
@show label_dim
pred_layer = pred_layer = InnerProductLayer(name="pred", output_dim=label_dim, tops=[:pred], bottoms=[:ip])
loss_layer = SquareLossLayer(name="sqloss", bottoms=[:pred, :label])
if softmax #overwrite it
#pred_layer = SoftmaxLayer(name="pred",tops=[:pred], bottoms=[:ip])
#loss_layer = MultinomialLogisticLossLayer(bottoms=[:pred, :label])
loss_layer = SoftlabelSoftmaxLossLayer(name="smloss", bottoms=[:pred, :label])
end
backend = DefaultBackend()
init(backend)
net = Net("Training", backend, [data_layer,ip_layer,pred_layer,loss_layer])
method = SGD()
params = make_solver_parameters(method, max_iter=max_iter, lr_policy=LRPolicy.Fixed(0.01), mom_policy=MomPolicy.Fixed(0.9))
solver = Solver(method, params)
add_coffee_break(solver, TrainingSummary(), every_n_iter=100)
solve(solver, net) #Train the net on the training data
#Evaluate Net
println("-------Evaluating on Test-------")
data_layer_test = MemoryDataLayer(batch_size=cases, data=Array[xs_test, ys_test_code], tops=[:data, :label])
test_net = Net("Test", backend, [data_layer_test,ip_layer,pred_layer])
forward_epoch(test_net) #Run the net on the test data
pred_code = to_array(test_net.output_blobs[:pred])
pred=decode(pred_code)
#shutdown(backend)
(pred,ys_test_angles)
end
@time pred_binned, actual_binned = eval_angular_encoding(encode_binned, decode_binned; softmax=true)
#Time CPU_with_OpenMP = 61.688237 seconds (381.43 M allocations: 12.276 GB, 2.01% gc time)
#Time CPU = 58.084438 seconds (381.30 M allocations: 12.270 GB, 2.02% gc time)
#Time GTX960 = 27.612926 seconds (825.41 k allocations: 4.685 GB, 1.43% gc time)
#Time Tesla K40 = 13.499364 seconds (9.65 M allocations: 5.052 GB, 2.34% gc time)
println(" = 500 bins; 1,000 Iter ")
show_results_summary(pred_binned, actual_binned)
@time pred_scaled_1k, actual_scaled_1k = eval_angular_encoding(encode_scaled, decode_scaled)
#Time CPU = 37.183113 seconds (957.24 k allocations: 4.836 GB, 1.13% gc time)
#Time CPU_with_OpenMP = 30.487064 seconds (955.99 k allocations: 4.836 GB, 1.64% gc time)
#Time GTX960 = 26.231840 seconds (1.19 M allocations: 4.491 GB, 1.60% gc time)
#time Tesla K40 = 7.613501 seconds (1.06 M allocations: 4.486 GB, 4.11% gc time)
println(" = scaled to 0-1; 1,000 iter ")
show_results_summary(pred_scaled_1k, actual_scaled_1k)
@time pred_cossin_1k, actual_cossin_1k = eval_angular_encoding(encode_cossin, decode_cossin)
#Time CPU = 32.189825 seconds (890.98 k allocations: 4.834 GB, 1.35% gc time)
#Time CPU_with_OpenMP = 33.969061 seconds (890.57 k allocations: 4.834 GB, 1.55% gc time)
#Time GTX960 = 26.175433 seconds (830.20 k allocations: 4.475 GB, 1.49% gc time)
#Time Tesla K40 = 7.570600 seconds (964.25 k allocations: 4.482 GB, 3.57% gc time)
println(" = Sin/Cos; 1,000 iter ")
show_results_summary(pred_cossin_1k, actual_cossin_1k)
@time pred_scaled_10k, actual_scaled_10k = eval_angular_encoding(encode_scaled, decode_scaled, max_iter=10_000)
#Time CPU = 340.415832 seconds (3.40 M allocations: 39.112 GB, 0.55% gc time)
#Time CPU_with_OpenMP = 331.426570 seconds (3.40 M allocations: 39.112 GB, 0.64% gc time)
#time GTX960 = 251.337496 seconds (4.26 M allocations: 38.784 GB, 1.01% gc time)
#time Tesla K40 = 67.574583 seconds (4.12 M allocations: 38.778 GB, 2.39% gc time)
println(" = scaled to 0-1; 10,000 iter ")
show_results_summary(pred_scaled_10k, actual_scaled_10k)
@time pred_cossin_10k, actual_cossin_10k = eval_angular_encoding(encode_cossin, decode_cossin;max_iter=10_000)
#time Tesla K40 = 72.630029 seconds (13.26 M allocations: 39.162 GB, 2.45% gc time)
println(" = Sin/Cos; 10,000 iter")
show_results_summary(pred_cossin_10k, actual_cossin_10k)