-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCVMVariance.jl
151 lines (133 loc) · 3.91 KB
/
CVMVariance.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
module Variance
require("Corpora.jl")
require("CommonTools.jl")
require("CVMAbstract.jl")
require("DataTypes.jl")
## Imports
using DataTypes
using Base.LinAlg.BLAS.axpy!
using Corpora.Token
using Corpora.text
using CommonTools: tanh, square!, l2sq, l2sq_distance, mult_by_0!
using CommonTools: add!, subtract_vec_matrix!
using Base.LinAlg.BLAS.scal!
using CommonTools.CVMIntermediates
using CVMAbstractModel
import CVMAbstractModel: compose!, store_gradients!
## Exports
export VarianceModel
export compose
export compose!
export store_gradients!
export VarianceParameters
immutable VarianceModel <: AbstractModel
wordvecdim::Int64;
margin::Float;
regularizer::Float;
lr_init::Float;
lr_min::Float;
niter::Int64;
gamma::Float;
nnoise::Int64;
batchsize::Int64;
end
type VarianceParameters <: AbstractParameters
wordvecs::Matrix{Float};
gradients::Matrix{Float};
end
VarianceParameters() = VarianceParameters(Array(Float,0,0), Array(Float,0,0))
function l2sq!(v1::DenseArray{Float,1}, v2::DenseArray{Float,1},
o::DenseArray{Float,1})
@simd for i=1:size(v1,1)
o[i] += (v1[i]-v2[i])^2
end
end
function compose!(model::VarianceModel, local1::Vector{Float},
s::Vector{Token}, o::Vector{Float})
# Calculate the mean
m = local1
mult_by_0!(m)
#= m = zeros(Float, model.wordvecdim) =#
for i=1:size(s,1)
#= Base.LinAlg.BLAS.axpy!(const_one, s[i].vector, m) =#
add!(s[i].vector, m)
#@simd for j=1:model.wordvecdim
# m[j] += s[i].vector[j]
#end
end
scal!(model.wordvecdim, 1.0/size(s,1), m, 1)
mult_by_0!(o);
tmp = 0.0
for i=1:size(s,1)
l2sq!(s[i].vector, m, o)
#= @simd for j=1:model.wordvecdim =#
#= tmp = s[i].vector[j] - m[j] =#
#= o[j] += tmp * tmp =#
#= #o[j] += (s[i].vector[j] - m[j])^2 =#
#= end =#
end
scal!(model.wordvecdim, 1.0/size(s,1), o, 1)
return o
end
function compose!(model::VarianceModel, s::Vector{Token},
intermediate::CVMIntermediates)
return compose!(model, intermediate.local1, s, intermediate.result)
end
function compose(model::VarianceModel, s::Vector{Token})
# Calculate the mean
m = zeros(Float, model.wordvecdim)
for i=1:size(s,1)
add!(s[i].vector,m)
end
# Calculate the output
o = zeros(Float, model.wordvecdim)
for i=1:size(s,1)
@simd for j=1:model.wordvecdim
o[j] += (s[i].vector[j] .- m[j])^2
end
end
return o
end
function multstore!(scalar::Float, vec::DenseArray{Float,1},
idx, m::DenseArray{Float,2})
@simd for j=1:size(vec,1)
m[j,idx] = scalar
m[j,idx] *= vec[j]
end
end
function store_gradients!(model::VarianceModel,
pre_grad::Vector{Float},
s::Vector{Token}, intermediate::CVMIntermediates;
intermediates_precomputed::Bool=false)
#= result = Array(Float64,(model.wordvecdim,size(s,1))) =#
result = intermediate.ofull
tmp_scaling = 2.0/size(s,1)
for i=1:size(s,1)
multstore!(tmp_scaling, s[i].vector, i, result)
end
m = zeros(model.wordvecdim)
for i=1:size(s,1)
#= Base.LinAlg.BLAS.axpy!(const_one, s[i].vector, m) =#
add!(s[i].vector,m)
#@simd for j=1:model.wordvecdim
# m[j] += s[i].vector[j]
#end
end
factor = 2.0/(size(s,1)^2)
scal!(model.wordvecdim, factor, m,1)
for i=1:size(s,1)
subtract_vec_matrix!(m, i, result)
#= @simd for j=1:model.wordvecdim =#
#= result[j,i] -= m[j] =#
#= end =#
end
tmp = intermediate.local1
#= tmp = Array(Float,model.wordvecdim) =#
for i=1:size(s,1)
@simd for j=1:model.wordvecdim
tmp[j] = result[j,i] * pre_grad[j]
end
add!(tmp, s[i].gradient)
end
end
end