I am confused about using linspace in Julia 0.7. Here is the what I entered in the REPL and the result:
julia> a = linspace(0.1,1.1,6)
┌ Warning: `linspace(start, stop, length::Integer)` is deprecated, use `range(start, stop=stop, length=length)` instead.
│ caller = top-level scope
└ # Core :0
0.1:0.2:1.1
My question is about the deprecated warning and the suggested use of range. The range statement doesn't do the same thing as the linspace command.
If you enter the a = linspace(0.1,1.1,6) and collect(a), you get the following:
julia> collect(a)
6-element Array{Float64,1}:
0.1
0.3
0.5
0.7
0.9
1.1
If you enter b = range(0.1,1.1,6) and collect(b), you get:
julia> collect(b)
6-element Array{Float64,1}:
0.1
1.2
2.3
3.4
4.5
5.6
This is obviously not the same.
Why is linspace deprecated (perhaps a different question) and a non-equivalent range command suggested?
My actual question is: Is it safe to keep using linspace for the desired results it provides, and, if not, what should I be using instead?
You should use LinRange, as documented here.
A range with len linearly spaced elements between its start and stop. The size of the spacing is controlled by len, which must be an Int.
julia> LinRange(1.5, 5.5, 9)
9-element LinRange{Float64}:
1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5
Edit 2021: As of version 1.7 you can use the range function for this:
jl> range(1.5, 5.5, 9)
1.5:0.5:5.5
For version 1.6 you have to write: range(1.5, 5.5, length=9).
Following the deprecations, it is now:
julia> range(0.1, stop = 1.1, length = 6) |> collect
6-element Array{Float64,1}:
0.1
0.3
0.5
0.7
0.9
1.1
In your example, the second argument is a step, not the stop, notice this method is also deprecated, you have to use keyword arguments now:
julia> #which range(0.1, 1.1, 6)
range(start, step, length) in Base at deprecated.jl:53
Related
In julia, we can use function map to round, for instance,
map(round, [1.00211111, 3.444444])
Then, the output is
2-element Vector{Float64}:
1.0
3.0
I want to save 3 digits. So I try this:
map(round(digits=3), [1.00211111, 3.444444])
But it generated errors. How can I do if I want to save 3 digits?
For this scenario just use broadcasting:
julia> round.([1.00211111, 3.444444], digits=3)
2-element Vector{Float64}:
1.002
3.444
However, if you want to use map, you can provide a lambda as an argument:
julia> map(x -> round(x, digits=3), [1.00211111, 3.444444])
2-element Vector{Float64}:
1.002
3.444
In PyTorch, you commonly have to zero our the gradients before doing back propagation. Is this the case in Flux? If so, what is the programatic way of doing this?
tl;dr
No, there is no need.
explanation
Flux used to use Tracker, a differentiation system in which each tracked array may hold a gradient. I think this is a similar design to pytorch. Back-propagating twice can lead to the problem which zeroing is intended to avoid (although the defaults try to protect you):
julia> using Tracker
julia> x_tr = Tracker.param([1 2 3])
Tracked 1×3 Matrix{Float64}:
1.0 2.0 3.0
julia> y_tr = sum(abs2, x_tr)
14.0 (tracked)
julia> Tracker.back!(y_tr, 1; once=false)
julia> x_tr.grad
1×3 Matrix{Float64}:
2.0 4.0 6.0
julia> Tracker.back!(y_tr, 1; once=false) # by default (i.e. with once=true) this would be an error
julia> x_tr.grad
1×3 Matrix{Float64}:
4.0 8.0 12.0
Now it uses Zygote, which does not use tracked array types. Instead, the evaluation to be traced must happen with the call to Zygote.gradient, it can then see and manipulate the source code to write new code for the gradient. Repeated calls to this generate the same gradients each time; there is no stored state to need cleaning up.
julia> using Zygote
julia> x = [1 2 3] # an ordinary Array
1×3 Matrix{Int64}:
1 2 3
julia> Zygote.gradient(x -> sum(abs2, x), x)
([2 4 6],)
julia> Zygote.gradient(x -> sum(abs2, x), x)
([2 4 6],)
julia> y, bk = Zygote.pullback(x -> sum(abs2, x), x);
julia> bk(1.0)
([2.0 4.0 6.0],)
julia> bk(1.0)
([2.0 4.0 6.0],)
Tracker can also be used this way, rather than handling param and back! yourself:
julia> Tracker.gradient(x -> sum(abs2, x), [1, 2, 3])
([2.0, 4.0, 6.0] (tracked),)
I create a new struct called HousingData, and also define function such as iterate and length. However, when I use the function collect for my HousingData object, I run into the following error.
TypeError: in typeassert, expected Integer, got a value of type Float64
import Base: length, size, iterate
struct HousingData
x
y
batchsize::Int
shuffle::Bool
num_instances::Int
function HousingData(
x, y; batchsize::Int=100, shuffle::Bool=false, dtype::Type=Array{Float64})
new(convert(dtype,x),convert(dtype,y),batchsize,shuffle,size(y)[end])
end
end
function length(d::HousingData)
return ceil(d.num_instances/d.batchsize)
end
function iterate(d::HousingData, state=ifelse(
d.shuffle, randperm(d.num_instances), collect(1:d.num_instances)))
if(length(state)==0)
return nothing
end
return ((d.x[:,state[1]],d.y[:,state[1]]),state[2:end])
end
x1 = randn(5, 100); y1 = rand(1, 100);
obj = HousingData(x1,y1; batchsize=20)
collect(obj)
There are multiple problems in your code. The first one is related to length not returning an integer, but rather a float. This is explained by the behavior of ceil:
julia> ceil(3.8)
4.0 # Notice: 4.0 (Float64) and not 4 (Int)
You can easily fix this:
function length(d::HousingData)
return Int(ceil(d.num_instances/d.batchsize))
end
Another problem lies in the logic of your iteration function, which is not consistent with the advertised length. To take a smaller example than yours:
julia> x1 = [i+j/10 for i in 1:2, j in 1:6]
2×6 Array{Float64,2}:
1.1 1.2 1.3 1.4 1.5 1.6
2.1 2.2 2.3 2.4 2.5 2.6
# As an aside, unless you really want to work with 1xN matrices
# it is more idiomatic in Julia to use 1D Vectors in such situations
julia> y1 = [Float64(j) for i in 1:1, j in 1:6]
1×6 Array{Float64,2}:
1.0 2.0 3.0 4.0 5.0 6.0
julia> obj = HousingData(x1,y1; batchsize=3)
HousingData([1.1 1.2 … 1.5 1.6; 2.1 2.2 … 2.5 2.6], [1.0 2.0 … 5.0 6.0], 3, false, 6)
julia> length(obj)
2
julia> for (i, e) in enumerate(obj)
println("$i -> $e")
end
1 -> ([1.1, 2.1], [1.0])
2 -> ([1.2, 2.2], [2.0])
3 -> ([1.3, 2.3], [3.0])
4 -> ([1.4, 2.4], [4.0])
5 -> ([1.5, 2.5], [5.0])
6 -> ([1.6, 2.6], [6.0])
The iterator produces 6 elements, whereas the length of this object is only 2. This explains why collect errors out:
julia> collect(obj)
ERROR: ArgumentError: destination has fewer elements than required
Knowing your code, you're probably the best person to fix its logic.
Suppose we have to take multiple input in one line in Python 3 then:-
1st method:-
x, y = input(), input()
2nd method:-
x, y = input().split()
3rd method:-
Using list comprehension
x, y = [int(x) for x in [x, y]]
4th method:-
x, y = map(int, input().split())
So these are the methods I know in python 3.
Can anyone tell me the alternate code in Julia?
readdlm(IOBuffer(readline()))
The best simple parser for all occasions is readdlm.
It will provide you processing any user input as an array and hence will be most robust for any circumstances:
julia> using DelimitedFiles
julia> readdlm(IOBuffer(readline()))
z b c
1×3 Array{Any,2}:
"z" "b" "c"
julia> readdlm(IOBuffer(readline()))
1 2
1×2 Array{Float64,2}:
1.0 2.0
Since it is an Array the same multi-argument assignment will work as in Python
julia> x, y = readdlm(IOBuffer(readline()))
1 2 3
1×3 Array{Float64,2}:
1.0 2.0 3.0
julia> x, y
(1.0, 2.0)
As we can't directly use input function I implemented like this in Julia.
function input()
x, y= readline(stdin), readline(stdin)
end
So I hope you liked this one.
I want to get the absolute value of the following array:
x = [1.1 -22.3 3.01, -1]
i.e.: I want an output of the type: x2 = [1.1 22.3 3.01 1]
However when I type:
abs(x)
I get an error:
ERROR: MethodError: no method matching abs(::Array{Float64,2})
Closest candidates are:
abs(::Pkg.Resolve.MaxSum.FieldValues.FieldValue) at /Users/vagrant/worker/juliapro-release-osx1011-0_6/build/tmp_julia/Julia-1.0.app/Contents/Resources/julia/share/julia/stdlib/v1.0/Pkg/src/resolve/FieldValues.jl:67
abs(::Pkg.Resolve.VersionWeights.VersionWeight) at /Users/vagrant/worker/juliapro-release-osx1011-0_6/build/tmp_julia/Julia-1.0.app/Contents/Resources/julia/share/julia/stdlib/v1.0/Pkg/src/resolve/VersionWeights.jl:40
abs(::Missing) at missing.jl:79
...
Stacktrace:
[1] top-level scope at none:0
Julia does not automatically apply scalar functions, like abs, to elements of an array. You should instead tell Julia this is what you want, and broadcast the scalar function abs over your array, see https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting-1. This can be done as
julia> x = [1.1, -22.3, 3.01, -1];
julia> broadcast(abs, x)
4-element Array{Float64,1}:
1.1
22.3
3.01
1.0
or you can use "dot-notation", which is more ideomatic:
julia> abs.(x)
4-element Array{Float64,1}:
1.1
22.3
3.01
1.0