Knet笔记
Knet(发音为“kay-net”)是Koç大学的深度学习框架,它基于julia,使用动态计算图,支持GPU操作和自动区分。
版本控制及权限控制
本文使用的版本:Knet 1.0.0、AutoGrad 1.0.0、(CUDAapi 0.5.0)
(不控制版本的话每次使用时都会自动更新,自动更新可能会有bug)
Pkg.add("Knet")
Pkg.rm("AutoGrad")
Pkg.add(PackageSpec(name="AutoGrad",version="1.0.0"))
Pkg.build("Knet")
Pkg.pin(PackageSpec(name="Knet",version="1.0.0"))
Pkg.rm("AutoGrad")
Pkg.add(PackageSpec(name="AutoGrad",version="1.0.0"))
Pkg.build("AutoGrad")
Pkg.pin(PackageSpec(name="AutoGrad",version="1.0.0"))
赋予权限:sudo chmod -R 777 ~/.julia/
example
- 线性回归
using Knet
#定义模型:
#其中x每列是一个数据,列数是数据的数目;y列数为数据的数目。
#w第一个元素为行向量,第二个元素为标量。w为一个参数列表,可以为元组,数组,字典。
#grad函数返回一个可以计算loss梯度的函数,该函数的参数传递与loss相同,且第一个为参数。
predict(w,x) = w[1]*x .+ w[2]
loss(w,x,y) = mean(abs2,y-predict(w,x))
lossgradient = grad(loss)
#参数传递默认为引用
#把数据集x,y合并传递参数data,再在里面展开(x,y)
#函数train!和train区别??,有默认值的参数放';'后。
function train(w, data; lr=.1)
for (x,y) in data
dw = lossgradient(w, x, y)
for i in 1:length(w)
w[i] -= lr * dw[i]
end
end
return w
end
#训练也可以使用类似@time weights = [ copy(train!(w, [(x, y)])) for epoch=1:10 ]的语句
#Any[..]可将不同类型的数据捆绑在一起,作为一个整体传递参数
include(Knet.dir("data","housing.jl"))
x,y = housing()
w = Any[ 0.1*randn(1,13), 0.0 ]
for i=1:10; train(w, [(x,y)]); println(loss(w,x,y)); end
- softmax分类
`
前提知识:
张量中一般最后一维度为样本数量,如(784,N)
softmax与线性模型的区别在于最后目标函数是负对数似然
数据集标准形式为(..,N),x和y合并成训练形式(xi,yi),训练形式的xi(yi)为从x(yi)中抽取lengthofbatch个构成
`
`GZip需要提前安装`
using Knet,GZip
`定义模型:
#nll(~,~)用于计算Negative Log-Likelihood(负对数似然),[预测值(前)减真实值(后)],用作损失函数。
#w[1]为(10,784)大小,w[2]为(10,1)大小
#x为(28,28,1,sizeofbatch)大小,通过mat转化为(784,sizeofbatch);y0为(sizeofbatch,)大小`
predict(w,x)=w[1]*mat(x) .+ w[2]
loss(w,x,y0)=nll(predict(w,x),y0)`预测为(10*sizeofbatch)大小,真实值为(sizeofbatch,)大小`
lossgrad=grad(loss)
function train(w,data;lr=0.1)
for (xtrb,ytrb) in data
print(size(ytrb))
dw=lossgrad(w,xtrb,ytrb)
w-=lr.*dw
end
return w
end
`#minibatch将数据集张量转化为小批量的数据集[(xi,yi)...],可混洗。第三个参数为每批的大小。
#x~为(28*28*1*N),y~为长度为N的Uint8`
include(Knet.dir("data/mnist.jl"))
xtrn,ytrn,xtst,ytst=mnist()
dtrn=minibatch(xtrn,ytrn,100)
dtst=minibatch(xtst,ytst,100)
#
w=Any[0.1f0*randn(Float32,10,784),zeros(Float32,10,1)]
println((:epoch, 0, :trn, accuracy(w,dtrn,predict), :tst, accuracy(w,dtst,predict)))
train(w, dtrn; lr=0.5)
for epoch=1:10
train(w, dtrn; lr=0.5)
println((:epoch, epoch, :trn, accuracy(w,dtrn,predict), :tst, accuracy(w,dtst,predict)))
end
[未完成待续……]